Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[UNDERTOW-2518] At WebSocketTimeoutTestCase, use a longer watch timeout #1694

Merged
merged 2 commits into from
Oct 21, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,6 @@
*/
package io.undertow.websockets.core.protocol;

import java.io.IOException;
import java.net.URI;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

import org.junit.After;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.xnio.FutureResult;
import org.xnio.OptionMap;
import org.xnio.Options;

import io.netty.buffer.Unpooled;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketVersion;
Expand All @@ -47,72 +31,78 @@
import io.undertow.websockets.core.BufferedTextMessage;
import io.undertow.websockets.core.WebSocketChannel;
import io.undertow.websockets.core.WebSockets;
import io.undertow.websockets.spi.WebSocketHttpExchange;
import io.undertow.websockets.utils.FrameChecker;
import io.undertow.websockets.utils.WebSocketTestClient;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.xnio.FutureResult;
import org.xnio.OptionMap;
import org.xnio.Options;

import java.io.IOException;
import java.net.URI;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

@RunWith(DefaultServer.class)
@HttpOneOnly
public class WebSocketTimeoutTestCase {

protected void beforeTest(int regularTimeouts, int wsReadTimeout, int wsWriteTimeout) {
DefaultServer.stopServer();
DefaultServer.setServerOptions(OptionMap.builder()
.set(Options.READ_TIMEOUT, regularTimeouts)
.set(Options.WRITE_TIMEOUT, regularTimeouts)
.set(UndertowOptions.WEB_SOCKETS_READ_TIMEOUT, wsReadTimeout)
.set(UndertowOptions.WEB_SOCKETS_WRITE_TIMEOUT, wsWriteTimeout).getMap());
protected static final int TESTABLE_TIMEOUT_VALUE = 2000;
protected static final int NON_TESTABLE_TIMEOUT_VALUE = 30180;
protected static final int DEFAULTS_IO_TIMEOUT_VALUE = 500;
private static ScheduledExecutorService SCHEDULER = null;

@DefaultServer.BeforeServerStarts
public static void beforeTest() {
DefaultServer.setServerOptions(OptionMap.builder()
.set(Options.READ_TIMEOUT, DEFAULTS_IO_TIMEOUT_VALUE)
.set(Options.WRITE_TIMEOUT, DEFAULTS_IO_TIMEOUT_VALUE)
.set(UndertowOptions.WEB_SOCKETS_READ_TIMEOUT, TESTABLE_TIMEOUT_VALUE)
.set(UndertowOptions.WEB_SOCKETS_WRITE_TIMEOUT, NON_TESTABLE_TIMEOUT_VALUE).getMap());
/*
DefaultServer.setUndertowOptions(OptionMap.builder()
.set(Options.READ_TIMEOUT, regularTimeouts)
.set(Options.WRITE_TIMEOUT, regularTimeouts)
.set(UndertowOptions.WEB_SOCKETS_READ_TIMEOUT, wsReadTimeout)
.set(UndertowOptions.WEB_SOCKETS_WRITE_TIMEOUT, wsWriteTimeout).getMap());
DefaultServer.startServer();
.set(UndertowOptions.WEB_SOCKETS_WRITE_TIMEOUT, wsWriteTimeout).getMap());*/
SCHEDULER = Executors.newScheduledThreadPool(2);
}

@After
public void afterTest() {
DefaultServer.stopServer();
DefaultServer.setServerOptions(OptionMap.EMPTY);
DefaultServer.setUndertowOptions(OptionMap.EMPTY);
@DefaultServer.AfterServerStops
public static void afterTest() {
SCHEDULER.shutdown();
DefaultServer.setServerOptions(OptionMap.EMPTY);
}

protected static final int TESTABLE_TIMEOUT_VALUE = 2000;
protected static final int NON_TESTABLE_TIMEOUT_VALUE = 30180;
protected static final int DEFAULTS_IO_TIMEOTU_VALUE = 500;
private ScheduledExecutorService SCHEDULER;

protected WebSocketVersion getVersion() {
return WebSocketVersion.V13;
}


@Test
public void testServerReadTimeout() throws Exception {
beforeTest(DEFAULTS_IO_TIMEOTU_VALUE, TESTABLE_TIMEOUT_VALUE, NON_TESTABLE_TIMEOUT_VALUE);
final AtomicBoolean connected = new AtomicBoolean(false);
DefaultServer.setRootHandler(new WebSocketProtocolHandshakeHandler(new WebSocketConnectionCallback() {
@Override
public void onConnect(final WebSocketHttpExchange exchange, final WebSocketChannel channel) {
connected.set(true);
channel.getReceiveSetter().set(new AbstractReceiveListener() {
@Override
protected void onFullTextMessage(WebSocketChannel channel, BufferedTextMessage message) throws IOException {
String string = message.getData();

if (string.equals("hello")) {
WebSockets.sendText("world", channel, null);
} else {
WebSockets.sendText(string, channel, null);
DefaultServer.setRootHandler(new WebSocketProtocolHandshakeHandler(
(WebSocketConnectionCallback) (exchange, channel) -> {
connected.set(true);
channel.getReceiveSetter().set(new AbstractReceiveListener() {
@Override
protected void onFullTextMessage(WebSocketChannel channel, BufferedTextMessage message) throws IOException {
String string = message.getData();

if (string.equals("hello")) {
WebSockets.sendText("world", channel, null);
} else {
WebSockets.sendText(string, channel, null);
}
}
}
});
channel.resumeReceives();
}
}));
});
channel.resumeReceives();
}));

final FutureResult<?> latch = new FutureResult();
WebSocketTestClient client = new WebSocketTestClient(getVersion(), new URI("ws://" + NetworkUtils.formatPossibleIpv6Address(DefaultServer.getHostAddress("default")) + ":" + DefaultServer.getHostPort("default") + "/"));
Expand All @@ -121,7 +111,7 @@ protected void onFullTextMessage(WebSocketChannel channel, BufferedTextMessage m
latch.getIoFuture().get();

final long watchStart = System.currentTimeMillis();
final long watchTimeout = System.currentTimeMillis()+TESTABLE_TIMEOUT_VALUE+500;
final long watchTimeout = System.currentTimeMillis() + TESTABLE_TIMEOUT_VALUE + 1000;
final FutureResult<Long> timeoutLatch = new FutureResult<Long>();
ReadTimeoutChannelGuard readTimeoutChannelGuard = new ReadTimeoutChannelGuard(client, timeoutLatch, watchTimeout);

Expand All @@ -130,17 +120,17 @@ protected void onFullTextMessage(WebSocketChannel channel, BufferedTextMessage m

final Long watchTimeEnd = timeoutLatch.getIoFuture().get();
if(watchTimeEnd == -1) {
Assert.fail("Timeout did not happen... in time. Were waiting '"+watchTimeout+"' ms, timeout should happen in '"+TESTABLE_TIMEOUT_VALUE+"' ms.");
Assert.fail("Timeout did not happen... in time. Were waiting '" + watchTimeout + "' ms, timeout should happen in '" + TESTABLE_TIMEOUT_VALUE + "' ms.");
} else {
long timeSpent = watchTimeEnd - watchStart;
//lets be generous and give 150ms diff( there is "fuzz" coded for 50ms in undertow as well
if(!(timeSpent<=TESTABLE_TIMEOUT_VALUE+150)) {
Assert.fail("Timeout did not happen... in time. Socket timeout out in '"+timeSpent+"' ms, supposed to happen in '"+TESTABLE_TIMEOUT_VALUE+"' ms.");
//let's be generous and give 150ms diff( there is "fuzz" coded for 50ms in undertow as well
if(!(timeSpent <= TESTABLE_TIMEOUT_VALUE + 250)) {
Assert.fail("Timeout did not happen... in time. Socket timeout out in '" + timeSpent + "' ms, supposed to happen in '" + TESTABLE_TIMEOUT_VALUE + "' ms.");
}
}
}

private static class ReadTimeoutChannelGuard implements Runnable{
private static class ReadTimeoutChannelGuard implements Runnable {
private final WebSocketTestClient channel;
private final FutureResult<Long> resultHandler;
private final long watchEnd;
Expand All @@ -159,7 +149,7 @@ public void setTaskScheduledFuture(ScheduledFuture sf2) {

@Override
public void run() {
if(System.currentTimeMillis() > watchEnd) {
if (System.currentTimeMillis() > watchEnd) {
sf.cancel(false);
if(channelActive()) {
resultHandler.setResult(new Long(-1));
Expand Down
Loading