Enabling more websocket tests
This commit is contained in:
parent
21b1ecef7b
commit
31705767f0
|
@ -179,7 +179,7 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Rem
|
||||||
|
|
||||||
private void close(CloseInfo closeInfo, FrameCallback callback)
|
private void close(CloseInfo closeInfo, FrameCallback callback)
|
||||||
{
|
{
|
||||||
connectionState.onClosing(); // move to CLOSING state (always)
|
connectionState.onClosing(); // always move to (at least) the CLOSING state (might already be past it, which is ok)
|
||||||
|
|
||||||
if (closeSent.compareAndSet(false, true))
|
if (closeSent.compareAndSet(false, true))
|
||||||
{
|
{
|
||||||
|
@ -192,7 +192,7 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Rem
|
||||||
{
|
{
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("Close Frame Previously Sent: ignoring: {} [{}]", closeInfo, callback);
|
LOG.debug("Close Frame Previously Sent: ignoring: {} [{}]", closeInfo, callback);
|
||||||
callback.succeed();
|
callback.fail(new WebSocketException("Already closed"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,139 +1,141 @@
|
||||||
//
|
//
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
// All rights reserved. This program and the accompanying materials
|
// All rights reserved. This program and the accompanying materials
|
||||||
// are made available under the terms of the Eclipse Public License v1.0
|
// are made available under the terms of the Eclipse Public License v1.0
|
||||||
// and Apache License v2.0 which accompanies this distribution.
|
// and Apache License v2.0 which accompanies this distribution.
|
||||||
//
|
//
|
||||||
// The Eclipse Public License is available at
|
// The Eclipse Public License is available at
|
||||||
// http://www.eclipse.org/legal/epl-v10.html
|
// http://www.eclipse.org/legal/epl-v10.html
|
||||||
//
|
//
|
||||||
// The Apache License v2.0 is available at
|
// The Apache License v2.0 is available at
|
||||||
// http://www.opensource.org/licenses/apache2.0.php
|
// http://www.opensource.org/licenses/apache2.0.php
|
||||||
//
|
//
|
||||||
// You may elect to redistribute this code under either of these licenses.
|
// You may elect to redistribute this code under either of these licenses.
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
//
|
//
|
||||||
|
|
||||||
package org.eclipse.jetty.websocket.tests;
|
package org.eclipse.jetty.websocket.tests;
|
||||||
|
|
||||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
import org.eclipse.jetty.websocket.common.CloseInfo;
|
import org.eclipse.jetty.websocket.common.CloseInfo;
|
||||||
import org.hamcrest.Matcher;
|
import org.hamcrest.Matcher;
|
||||||
import org.hamcrest.Matchers;
|
import org.hamcrest.Matchers;
|
||||||
|
|
||||||
public abstract class AbstractTrackingEndpoint<T>
|
public abstract class AbstractTrackingEndpoint<T>
|
||||||
{
|
{
|
||||||
public final Logger LOG;
|
public final Logger LOG;
|
||||||
|
|
||||||
public T session;
|
public T session;
|
||||||
|
|
||||||
public CountDownLatch openLatch = new CountDownLatch(1);
|
public CountDownLatch openLatch = new CountDownLatch(1);
|
||||||
public CountDownLatch closeLatch = new CountDownLatch(1);
|
public CountDownLatch closeLatch = new CountDownLatch(1);
|
||||||
public CountDownLatch errorLatch = new CountDownLatch(1);
|
public CountDownLatch errorLatch = new CountDownLatch(1);
|
||||||
public AtomicReference<CloseInfo> closeInfo = new AtomicReference<>();
|
public AtomicReference<CloseInfo> closeInfo = new AtomicReference<>();
|
||||||
public AtomicReference<Throwable> error = new AtomicReference<>();
|
public AtomicReference<Throwable> closeStack = new AtomicReference<>();
|
||||||
|
public AtomicReference<Throwable> error = new AtomicReference<>();
|
||||||
public AbstractTrackingEndpoint(String id)
|
|
||||||
{
|
public AbstractTrackingEndpoint(String id)
|
||||||
LOG = Log.getLogger(this.getClass().getName() + "." + id);
|
{
|
||||||
LOG.debug("init");
|
LOG = Log.getLogger(this.getClass().getName() + "." + id);
|
||||||
}
|
LOG.debug("init");
|
||||||
|
}
|
||||||
public void assertCloseInfo(String prefix, int expectedCloseStatusCode, Matcher<? super String> reasonMatcher) throws InterruptedException
|
|
||||||
{
|
public void assertCloseInfo(String prefix, int expectedCloseStatusCode, Matcher<? super String> reasonMatcher) throws InterruptedException
|
||||||
CloseInfo close = closeInfo.get();
|
{
|
||||||
assertThat(prefix + " close info", close, Matchers.notNullValue());
|
CloseInfo close = closeInfo.get();
|
||||||
assertThat(prefix + " received close code", close.getStatusCode(), Matchers.is(expectedCloseStatusCode));
|
assertThat(prefix + " close info", close, Matchers.notNullValue());
|
||||||
assertThat(prefix + " received close reason", close.getReason(), reasonMatcher);
|
assertThat(prefix + " received close code", close.getStatusCode(), Matchers.is(expectedCloseStatusCode));
|
||||||
}
|
assertThat(prefix + " received close reason", close.getReason(), reasonMatcher);
|
||||||
|
}
|
||||||
public void assertErrorEvent(String prefix, Matcher<Throwable> throwableMatcher, Matcher<? super String> messageMatcher)
|
|
||||||
{
|
public void assertErrorEvent(String prefix, Matcher<Throwable> throwableMatcher, Matcher<? super String> messageMatcher)
|
||||||
assertThat(prefix + " error event type", error.get(), throwableMatcher);
|
{
|
||||||
assertThat(prefix + " error event message", error.get().getMessage(), messageMatcher);
|
assertThat(prefix + " error event type", error.get(), throwableMatcher);
|
||||||
}
|
assertThat(prefix + " error event message", error.get().getMessage(), messageMatcher);
|
||||||
|
}
|
||||||
public void assertNoErrorEvents(String prefix)
|
|
||||||
{
|
public void assertNoErrorEvents(String prefix)
|
||||||
assertTrue(prefix + " error event should not have occurred", error.get() == null);
|
{
|
||||||
}
|
assertTrue(prefix + " error event should not have occurred", error.get() == null);
|
||||||
|
}
|
||||||
public void assertNotClosed(String prefix)
|
|
||||||
{
|
public void assertNotClosed(String prefix)
|
||||||
assertTrue(prefix + " close event should not have occurred: got " + closeInfo.get(), closeLatch.getCount() > 0);
|
{
|
||||||
}
|
assertTrue(prefix + " close event should not have occurred: got " + closeInfo.get(), closeLatch.getCount() > 0);
|
||||||
|
}
|
||||||
public void assertNotOpened(String prefix)
|
|
||||||
{
|
public void assertNotOpened(String prefix)
|
||||||
assertTrue(prefix + " open event should not have occurred", openLatch.getCount() > 0);
|
{
|
||||||
}
|
assertTrue(prefix + " open event should not have occurred", openLatch.getCount() > 0);
|
||||||
|
}
|
||||||
public void awaitCloseEvent(String prefix) throws InterruptedException
|
|
||||||
{
|
public void awaitCloseEvent(String prefix) throws InterruptedException
|
||||||
assertTrue(prefix + " onClose event", closeLatch.await(Defaults.CLOSE_EVENT_TIMEOUT_MS, TimeUnit.MILLISECONDS));
|
{
|
||||||
}
|
assertTrue(prefix + " onClose event", closeLatch.await(Defaults.CLOSE_EVENT_TIMEOUT_MS, TimeUnit.MILLISECONDS));
|
||||||
|
}
|
||||||
public void awaitOpenEvent(String prefix) throws InterruptedException
|
|
||||||
{
|
public void awaitOpenEvent(String prefix) throws InterruptedException
|
||||||
assertTrue(prefix + " onOpen event", openLatch.await(Defaults.OPEN_EVENT_TIMEOUT_MS, TimeUnit.MILLISECONDS));
|
{
|
||||||
}
|
assertTrue(prefix + " onOpen event", openLatch.await(Defaults.OPEN_EVENT_TIMEOUT_MS, TimeUnit.MILLISECONDS));
|
||||||
|
}
|
||||||
public void awaitErrorEvent(String prefix) throws InterruptedException
|
|
||||||
{
|
public void awaitErrorEvent(String prefix) throws InterruptedException
|
||||||
assertTrue(prefix + " onError event", errorLatch.await(Defaults.CLOSE_EVENT_TIMEOUT_MS, TimeUnit.MILLISECONDS));
|
{
|
||||||
}
|
assertTrue(prefix + " onError event", errorLatch.await(Defaults.CLOSE_EVENT_TIMEOUT_MS, TimeUnit.MILLISECONDS));
|
||||||
|
}
|
||||||
protected void onWSOpen(T session)
|
|
||||||
{
|
protected void onWSOpen(T session)
|
||||||
this.session = session;
|
{
|
||||||
if (LOG.isDebugEnabled())
|
this.session = session;
|
||||||
{
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("onWSOpen()");
|
{
|
||||||
}
|
LOG.debug("onWSOpen()");
|
||||||
this.openLatch.countDown();
|
}
|
||||||
}
|
this.openLatch.countDown();
|
||||||
|
}
|
||||||
protected void onWSClose(int statusCode, String reason)
|
|
||||||
{
|
protected void onWSClose(int statusCode, String reason)
|
||||||
if(LOG.isDebugEnabled())
|
{
|
||||||
{
|
if(LOG.isDebugEnabled())
|
||||||
LOG.debug("onWSClose({}, {})", statusCode, reason);
|
{
|
||||||
}
|
LOG.debug("onWSClose({}, {})", statusCode, reason);
|
||||||
CloseInfo close = new CloseInfo(statusCode, reason);
|
}
|
||||||
if (closeInfo.compareAndSet(null, close) == false)
|
CloseInfo close = new CloseInfo(statusCode, reason);
|
||||||
{
|
if (closeInfo.compareAndSet(null, close) == false)
|
||||||
LOG.warn("onClose should only happen once - Original Close: " + closeInfo.get());
|
{
|
||||||
LOG.warn("onClose should only happen once - Extra/Excess Close: " + close);
|
LOG.warn("onClose should only happen once - Original Close: " + closeInfo.get(), closeStack.get());
|
||||||
fail("onClose should only happen once!");
|
LOG.warn("onClose should only happen once - Extra/Excess Close: " + close, new Throwable("extra/excess"));
|
||||||
}
|
fail("onClose should only happen once!");
|
||||||
this.closeLatch.countDown();
|
}
|
||||||
}
|
closeStack.compareAndSet(null, new Throwable("original"));
|
||||||
|
this.closeLatch.countDown();
|
||||||
protected void onWSError(Throwable cause)
|
}
|
||||||
{
|
|
||||||
if(LOG.isDebugEnabled())
|
protected void onWSError(Throwable cause)
|
||||||
{
|
{
|
||||||
LOG.debug("onWSError()", cause);
|
if(LOG.isDebugEnabled())
|
||||||
}
|
{
|
||||||
assertThat("Error must have value", cause, notNullValue());
|
LOG.debug("onWSError()", cause);
|
||||||
if (error.compareAndSet(null, cause) == false)
|
}
|
||||||
{
|
assertThat("Error must have value", cause, notNullValue());
|
||||||
LOG.warn("onError should only happen once - Original Cause", error.get());
|
if (error.compareAndSet(null, cause) == false)
|
||||||
LOG.warn("onError should only happen once - Extra/Excess Cause", cause);
|
{
|
||||||
fail("onError should only happen once!");
|
LOG.warn("onError should only happen once - Original Cause", error.get());
|
||||||
}
|
LOG.warn("onError should only happen once - Extra/Excess Cause", cause);
|
||||||
this.errorLatch.countDown();
|
fail("onError should only happen once!");
|
||||||
}
|
}
|
||||||
}
|
this.errorLatch.countDown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.websocket.tests.client;
|
package org.eclipse.jetty.websocket.tests.client;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.anything;
|
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.hamcrest.Matchers.instanceOf;
|
import static org.hamcrest.Matchers.instanceOf;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
|
@ -26,7 +25,6 @@ import static org.hamcrest.Matchers.nullValue;
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.SocketTimeoutException;
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.channels.SelectableChannel;
|
import java.nio.channels.SelectableChannel;
|
||||||
|
@ -51,7 +49,7 @@ import org.eclipse.jetty.util.thread.Scheduler;
|
||||||
import org.eclipse.jetty.websocket.api.BatchMode;
|
import org.eclipse.jetty.websocket.api.BatchMode;
|
||||||
import org.eclipse.jetty.websocket.api.Session;
|
import org.eclipse.jetty.websocket.api.Session;
|
||||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketAdapter;
|
import org.eclipse.jetty.websocket.api.WebSocketTimeoutException;
|
||||||
import org.eclipse.jetty.websocket.client.WebSocketClient;
|
import org.eclipse.jetty.websocket.client.WebSocketClient;
|
||||||
import org.eclipse.jetty.websocket.common.OpCode;
|
import org.eclipse.jetty.websocket.common.OpCode;
|
||||||
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
||||||
|
@ -62,7 +60,6 @@ import org.eclipse.jetty.websocket.tests.UntrustedWSServer;
|
||||||
import org.eclipse.jetty.websocket.tests.UntrustedWSSession;
|
import org.eclipse.jetty.websocket.tests.UntrustedWSSession;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Ignore;
|
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.rules.TestName;
|
import org.junit.rules.TestName;
|
||||||
|
@ -70,52 +67,52 @@ import org.junit.rules.TestName;
|
||||||
public class ClientCloseTest
|
public class ClientCloseTest
|
||||||
{
|
{
|
||||||
private static final Logger LOG = Log.getLogger(ClientCloseTest.class);
|
private static final Logger LOG = Log.getLogger(ClientCloseTest.class);
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
public TestName testname = new TestName();
|
public TestName testname = new TestName();
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
public TestTracker tt = new TestTracker();
|
public TestTracker tt = new TestTracker();
|
||||||
|
|
||||||
private UntrustedWSServer server;
|
private UntrustedWSServer server;
|
||||||
private WebSocketClient client;
|
private WebSocketClient client;
|
||||||
|
|
||||||
private void confirmConnection(TrackingEndpoint clientSocket, Future<Session> clientFuture, UntrustedWSSession serverSession) throws Exception
|
private void confirmConnection(TrackingEndpoint clientSocket, Future<Session> clientFuture, UntrustedWSSession serverSession) throws Exception
|
||||||
{
|
{
|
||||||
// Wait for client connect on via future
|
// Wait for client connect on via future
|
||||||
Session clientSession = clientFuture.get(Defaults.CONNECT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
Session clientSession = clientFuture.get(Defaults.CONNECT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
||||||
clientSession.getRemote().setBatchMode(BatchMode.OFF);
|
clientSession.getRemote().setBatchMode(BatchMode.OFF);
|
||||||
|
|
||||||
// Wait for client connect via client websocket
|
// Wait for client connect via client websocket
|
||||||
assertThat("Client WebSocket is Open", clientSocket.openLatch.await(Defaults.OPEN_EVENT_TIMEOUT_MS, TimeUnit.MILLISECONDS), is(true));
|
assertThat("Client WebSocket is Open", clientSocket.openLatch.await(Defaults.OPEN_EVENT_TIMEOUT_MS, TimeUnit.MILLISECONDS), is(true));
|
||||||
|
|
||||||
UntrustedWSEndpoint serverEndpoint = serverSession.getUntrustedEndpoint();
|
UntrustedWSEndpoint serverEndpoint = serverSession.getUntrustedEndpoint();
|
||||||
|
|
||||||
// Send message from client to server
|
// Send message from client to server
|
||||||
final String echoMsg = "echo-test";
|
final String echoMsg = "echo-test";
|
||||||
Future<Void> testFut = clientSocket.getRemote().sendStringByFuture(echoMsg);
|
Future<Void> testFut = clientSocket.getRemote().sendStringByFuture(echoMsg);
|
||||||
|
|
||||||
// Wait for send future
|
// Wait for send future
|
||||||
testFut.get(30, TimeUnit.SECONDS);
|
testFut.get(30, TimeUnit.SECONDS);
|
||||||
|
|
||||||
// Read Frame on server side
|
// Read Frame on server side
|
||||||
WebSocketFrame frame = serverEndpoint.framesQueue.poll(10, TimeUnit.SECONDS);
|
WebSocketFrame frame = serverEndpoint.framesQueue.poll(10, TimeUnit.SECONDS);
|
||||||
assertThat("Server received frame", frame.getOpCode(), is(OpCode.TEXT));
|
assertThat("Server received frame", frame.getOpCode(), is(OpCode.TEXT));
|
||||||
assertThat("Server received frame payload", frame.getPayloadAsUTF8(), is(echoMsg));
|
assertThat("Server received frame payload", frame.getPayloadAsUTF8(), is(echoMsg));
|
||||||
|
|
||||||
// Server send echo reply
|
// Server send echo reply
|
||||||
serverEndpoint.getRemote().sendString(echoMsg);
|
serverEndpoint.getRemote().sendString(echoMsg);
|
||||||
|
|
||||||
// Wait for received echo
|
// Wait for received echo
|
||||||
String incomingMessage = clientSocket.messageQueue.poll(1, TimeUnit.SECONDS);
|
String incomingMessage = clientSocket.messageQueue.poll(1, TimeUnit.SECONDS);
|
||||||
|
|
||||||
// Verify received message
|
// Verify received message
|
||||||
assertThat("Received message", incomingMessage, is(echoMsg));
|
assertThat("Received message", incomingMessage, is(echoMsg));
|
||||||
|
|
||||||
// Verify that there are no errors
|
// Verify that there are no errors
|
||||||
assertThat("Error events", clientSocket.error.get(), nullValue());
|
assertThat("Error events", clientSocket.error.get(), nullValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TestClientTransportOverHTTP extends HttpClientTransportOverHTTP
|
public static class TestClientTransportOverHTTP extends HttpClientTransportOverHTTP
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
|
@ -133,16 +130,16 @@ public class ClientCloseTest
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TestEndPoint extends SocketChannelEndPoint
|
public static class TestEndPoint extends SocketChannelEndPoint
|
||||||
{
|
{
|
||||||
public AtomicBoolean congestedFlush = new AtomicBoolean(false);
|
public AtomicBoolean congestedFlush = new AtomicBoolean(false);
|
||||||
|
|
||||||
public TestEndPoint(SelectableChannel channel, ManagedSelector selector, SelectionKey key, Scheduler scheduler)
|
public TestEndPoint(SelectableChannel channel, ManagedSelector selector, SelectionKey key, Scheduler scheduler)
|
||||||
{
|
{
|
||||||
super((SocketChannel) channel, selector, key, scheduler);
|
super((SocketChannel) channel, selector, key, scheduler);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean flush(ByteBuffer... buffers) throws IOException
|
public boolean flush(ByteBuffer... buffers) throws IOException
|
||||||
{
|
{
|
||||||
|
@ -152,7 +149,7 @@ public class ClientCloseTest
|
||||||
return flushed;
|
return flushed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void startClient() throws Exception
|
public void startClient() throws Exception
|
||||||
{
|
{
|
||||||
|
@ -161,123 +158,113 @@ public class ClientCloseTest
|
||||||
client.addBean(httpClient);
|
client.addBean(httpClient);
|
||||||
client.start();
|
client.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void startServer() throws Exception
|
public void startServer() throws Exception
|
||||||
{
|
{
|
||||||
server = new UntrustedWSServer();
|
server = new UntrustedWSServer();
|
||||||
server.registerWebSocket("/noclose", (req, resp) -> new WebSocketAdapter()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void onWebSocketClose(int statusCode, String reason)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
getSession().disconnect();
|
|
||||||
}
|
|
||||||
catch (IOException ignore)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
server.start();
|
server.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
public void stopClient() throws Exception
|
public void stopClient() throws Exception
|
||||||
{
|
{
|
||||||
client.stop();
|
client.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
public void stopServer() throws Exception
|
public void stopServer() throws Exception
|
||||||
{
|
{
|
||||||
server.stop();
|
server.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Ignore("Not working yet")
|
|
||||||
public void testNetworkCongestion() throws Exception
|
public void testNetworkCongestion() throws Exception
|
||||||
{
|
{
|
||||||
// Set client timeout
|
// Set client timeout
|
||||||
final int timeout = 1000;
|
final int timeout = 1000;
|
||||||
client.setMaxIdleTimeout(timeout);
|
client.setMaxIdleTimeout(timeout);
|
||||||
|
|
||||||
URI wsUri = server.getUntrustedWsUri(this.getClass(), testname);
|
URI wsUri = server.getUntrustedWsUri(this.getClass(), testname);
|
||||||
CompletableFuture<UntrustedWSSession> serverSessionFut = new CompletableFuture<>();
|
CompletableFuture<UntrustedWSSession> serverSessionFut = new CompletableFuture<>();
|
||||||
server.registerOnOpenFuture(wsUri, serverSessionFut);
|
server.registerOnOpenFuture(wsUri, serverSessionFut);
|
||||||
|
|
||||||
// Client connects
|
// Client connects
|
||||||
TrackingEndpoint clientSocket = new TrackingEndpoint(testname.getMethodName());
|
TrackingEndpoint clientSocket = new TrackingEndpoint(testname.getMethodName());
|
||||||
Future<Session> clientConnectFuture = client.connect(clientSocket, wsUri);
|
Future<Session> clientConnectFuture = client.connect(clientSocket, wsUri);
|
||||||
|
|
||||||
// Server accepts connect
|
Session clientSession = clientConnectFuture.get(Defaults.CONNECT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
||||||
UntrustedWSSession serverSession = serverSessionFut.get(10, TimeUnit.SECONDS);
|
|
||||||
|
try
|
||||||
// client confirms connection via echo
|
|
||||||
confirmConnection(clientSocket, clientConnectFuture, serverSession);
|
|
||||||
|
|
||||||
// client sends BIG frames (until it cannot write anymore)
|
|
||||||
// server must not read (for test purpose, in order to congest connection)
|
|
||||||
// when write is congested, client enqueue close frame
|
|
||||||
// client initiate write, but write never completes
|
|
||||||
EndPoint endp = clientSocket.getJettyEndPoint();
|
|
||||||
assertThat("EndPoint is testable", endp, instanceOf(TestEndPoint.class));
|
|
||||||
TestEndPoint testendp = (TestEndPoint) endp;
|
|
||||||
|
|
||||||
char msg[] = new char[10240];
|
|
||||||
int writeCount = 0;
|
|
||||||
long writeSize = 0;
|
|
||||||
int i = 0;
|
|
||||||
while (!testendp.congestedFlush.get())
|
|
||||||
{
|
{
|
||||||
int z = i - ((i / 26) * 26);
|
|
||||||
char c = (char) ('a' + z);
|
// client sends frames big enough to break through network layer caching, until it cannot write anymore.
|
||||||
Arrays.fill(msg, c);
|
// server must not read (for test purpose, in order to congest connection)
|
||||||
clientSocket.getRemote().sendStringByFuture(String.valueOf(msg));
|
// when write is congested, client enqueue close frame
|
||||||
writeCount++;
|
// client initiate write, but write never completes
|
||||||
writeSize += msg.length;
|
EndPoint endp = clientSocket.getJettyEndPoint();
|
||||||
|
assertThat("EndPoint is testable", endp, instanceOf(TestEndPoint.class));
|
||||||
|
TestEndPoint testendp = (TestEndPoint) endp;
|
||||||
|
|
||||||
|
char msg[] = new char[10240];
|
||||||
|
int writeCount = 0;
|
||||||
|
long writeSize = 0;
|
||||||
|
int i = 0;
|
||||||
|
while (!testendp.congestedFlush.get())
|
||||||
|
{
|
||||||
|
int z = i - ((i / 26) * 26);
|
||||||
|
char c = (char) ('a' + z);
|
||||||
|
Arrays.fill(msg, c);
|
||||||
|
clientSocket.getRemote().sendStringByFuture(String.valueOf(msg));
|
||||||
|
writeCount++;
|
||||||
|
writeSize += msg.length;
|
||||||
|
}
|
||||||
|
LOG.info("Wrote {} frames totalling {} bytes of payload before congestion kicked in", writeCount, writeSize);
|
||||||
|
|
||||||
|
// Verify timeout error
|
||||||
|
clientSocket.awaitErrorEvent("Client");
|
||||||
|
clientSocket.assertErrorEvent("Client", instanceOf(WebSocketTimeoutException.class), containsString("Idle Timeout"));
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
clientSession.close();
|
||||||
}
|
}
|
||||||
LOG.info("Wrote {} frames totalling {} bytes of payload before congestion kicked in", writeCount, writeSize);
|
|
||||||
|
|
||||||
// Verify timeout error
|
|
||||||
clientSocket.assertErrorEvent("Client", instanceOf(SocketTimeoutException.class), anything());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(timeout = 5000L)
|
@Test(timeout = 5000L)
|
||||||
public void testStopLifecycle() throws Exception
|
public void testStopLifecycle() throws Exception
|
||||||
{
|
{
|
||||||
// Set client timeout
|
// Set client timeout
|
||||||
final int timeout = 1000;
|
final int timeout = 1000;
|
||||||
client.setMaxIdleTimeout(timeout);
|
client.setMaxIdleTimeout(timeout);
|
||||||
|
|
||||||
int clientCount = 3;
|
int clientCount = 3;
|
||||||
|
|
||||||
TrackingEndpoint clientSockets[] = new TrackingEndpoint[clientCount];
|
TrackingEndpoint clientSockets[] = new TrackingEndpoint[clientCount];
|
||||||
UntrustedWSSession serverSessions[] = new UntrustedWSSession[clientCount];
|
UntrustedWSSession serverSessions[] = new UntrustedWSSession[clientCount];
|
||||||
|
|
||||||
// Connect Multiple Clients
|
// Connect Multiple Clients
|
||||||
for (int i = 0; i < clientCount; i++)
|
for (int i = 0; i < clientCount; i++)
|
||||||
{
|
{
|
||||||
URI wsUri = server.getUntrustedWsUri(this.getClass(), testname).resolve(Integer.toString(i));
|
URI wsUri = server.getUntrustedWsUri(this.getClass(), testname).resolve(Integer.toString(i));
|
||||||
CompletableFuture<UntrustedWSSession> serverSessionFut = new CompletableFuture<>();
|
CompletableFuture<UntrustedWSSession> serverSessionFut = new CompletableFuture<>();
|
||||||
server.registerOnOpenFuture(wsUri, serverSessionFut);
|
server.registerOnOpenFuture(wsUri, serverSessionFut);
|
||||||
|
|
||||||
// Client Request Upgrade
|
// Client Request Upgrade
|
||||||
clientSockets[i] = new TrackingEndpoint(testname.getMethodName() + "[" + i + "]");
|
clientSockets[i] = new TrackingEndpoint(testname.getMethodName() + "[" + i + "]");
|
||||||
Future<Session> clientConnectFuture = client.connect(clientSockets[i], wsUri);
|
Future<Session> clientConnectFuture = client.connect(clientSockets[i], wsUri);
|
||||||
|
|
||||||
// Server accepts connection
|
// Server accepts connection
|
||||||
serverSessions[i] = serverSessionFut.get(10, TimeUnit.SECONDS);
|
serverSessions[i] = serverSessionFut.get(10, TimeUnit.SECONDS);
|
||||||
|
|
||||||
// client confirms connection via echo
|
// client confirms connection via echo
|
||||||
confirmConnection(clientSockets[i], clientConnectFuture, serverSessions[i]);
|
confirmConnection(clientSockets[i], clientConnectFuture, serverSessions[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// client lifecycle stop
|
// client lifecycle stop
|
||||||
// every open client should send a close frame
|
// every open client should send a close frame
|
||||||
client.stop();
|
client.stop();
|
||||||
|
|
||||||
// clients send close frames (code 1001, shutdown)
|
// clients send close frames (code 1001, shutdown)
|
||||||
for (int i = 0; i < clientCount; i++)
|
for (int i = 0; i < clientCount; i++)
|
||||||
{
|
{
|
||||||
|
@ -286,7 +273,7 @@ public class ClientCloseTest
|
||||||
serverEndpoint.awaitCloseEvent("Server");
|
serverEndpoint.awaitCloseEvent("Server");
|
||||||
serverEndpoint.assertCloseInfo("Server", StatusCode.SHUTDOWN, containsString("Shutdown"));
|
serverEndpoint.assertCloseInfo("Server", StatusCode.SHUTDOWN, containsString("Shutdown"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// clients disconnect
|
// clients disconnect
|
||||||
for (int i = 0; i < clientCount; i++)
|
for (int i = 0; i < clientCount; i++)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue