Skip to content

Commit

Permalink
Merge pull request #1694 from fl4via/UNDERTOW-2518
Browse files Browse the repository at this point in the history
[UNDERTOW-2518] At WebSocketTimeoutTestCase, use a longer watch timeout
  • Loading branch information
fl4via authored Oct 21, 2024
2 parents c5281bf + de88783 commit a2724f4
Showing 1 changed file with 53 additions and 63 deletions.
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

0 comments on commit a2724f4

Please sign in to comment.