Enabling more websocket tests

This commit is contained in:
Joakim Erdfelt 2017-06-21 07:56:48 -07:00
parent 21b1ecef7b
commit 31705767f0
3 changed files with 213 additions and 224 deletions

View File

@ -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"));
} }
} }

View File

@ -43,6 +43,7 @@ public abstract class AbstractTrackingEndpoint<T>
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> closeStack = new AtomicReference<>();
public AtomicReference<Throwable> error = new AtomicReference<>(); public AtomicReference<Throwable> error = new AtomicReference<>();
public AbstractTrackingEndpoint(String id) public AbstractTrackingEndpoint(String id)
@ -114,10 +115,11 @@ public abstract class AbstractTrackingEndpoint<T>
CloseInfo close = new CloseInfo(statusCode, reason); CloseInfo close = new CloseInfo(statusCode, reason);
if (closeInfo.compareAndSet(null, close) == false) if (closeInfo.compareAndSet(null, close) == false)
{ {
LOG.warn("onClose should only happen once - Original Close: " + closeInfo.get()); LOG.warn("onClose should only happen once - Original Close: " + closeInfo.get(), closeStack.get());
LOG.warn("onClose should only happen once - Extra/Excess Close: " + close); LOG.warn("onClose should only happen once - Extra/Excess Close: " + close, new Throwable("extra/excess"));
fail("onClose should only happen once!"); fail("onClose should only happen once!");
} }
closeStack.compareAndSet(null, new Throwable("original"));
this.closeLatch.countDown(); this.closeLatch.countDown();
} }

View File

@ -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;
@ -166,20 +163,6 @@ public class ClientCloseTest
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();
} }
@ -196,7 +179,6 @@ public class ClientCloseTest
} }
@Test @Test
@Ignore("Not working yet")
public void testNetworkCongestion() throws Exception public void testNetworkCongestion() throws Exception
{ {
// Set client timeout // Set client timeout
@ -211,37 +193,42 @@ public class ClientCloseTest
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);
// client confirms connection via echo try
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);
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 // client sends frames big enough to break through network layer caching, until it cannot write anymore.
clientSocket.assertErrorEvent("Client", instanceOf(SocketTimeoutException.class), anything()); // 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);
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();
}
} }
@Test(timeout = 5000L) @Test(timeout = 5000L)