fix flaky test ClientCloseTest.testWriteException
Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
This commit is contained in:
parent
c33f3a75ed
commit
bb8e5557d2
|
@ -19,11 +19,11 @@
|
||||||
package org.eclipse.jetty.websocket.tests.client;
|
package org.eclipse.jetty.websocket.tests.client;
|
||||||
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
|
@ -36,6 +36,7 @@ import org.eclipse.jetty.server.handler.DefaultHandler;
|
||||||
import org.eclipse.jetty.server.handler.HandlerList;
|
import org.eclipse.jetty.server.handler.HandlerList;
|
||||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||||
import org.eclipse.jetty.servlet.ServletHolder;
|
import org.eclipse.jetty.servlet.ServletHolder;
|
||||||
|
import org.eclipse.jetty.util.BlockingArrayQueue;
|
||||||
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.api.CloseException;
|
import org.eclipse.jetty.websocket.api.CloseException;
|
||||||
|
@ -66,11 +67,13 @@ import static org.hamcrest.Matchers.instanceOf;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
import static org.hamcrest.Matchers.nullValue;
|
import static org.hamcrest.Matchers.nullValue;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively;
|
import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
public class ClientCloseTest
|
public class ClientCloseTest
|
||||||
{
|
{
|
||||||
private Server server;
|
private Server server;
|
||||||
private WebSocketClient client;
|
private WebSocketClient client;
|
||||||
|
private BlockingArrayQueue<ServerEndpoint> serverEndpoints = new BlockingArrayQueue<>();
|
||||||
|
|
||||||
private Session confirmConnection(CloseTrackingEndpoint clientSocket, Future<Session> clientFuture) throws Exception
|
private Session confirmConnection(CloseTrackingEndpoint clientSocket, Future<Session> clientFuture) throws Exception
|
||||||
{
|
{
|
||||||
|
@ -128,7 +131,12 @@ public class ClientCloseTest
|
||||||
{
|
{
|
||||||
factory.getPolicy().setIdleTimeout(10000);
|
factory.getPolicy().setIdleTimeout(10000);
|
||||||
factory.getPolicy().setMaxTextMessageSize(1024 * 1024 * 2);
|
factory.getPolicy().setMaxTextMessageSize(1024 * 1024 * 2);
|
||||||
factory.register(ServerEndpoint.class);
|
factory.setCreator((req,resp)->
|
||||||
|
{
|
||||||
|
ServerEndpoint endpoint = new ServerEndpoint();
|
||||||
|
serverEndpoints.offer(endpoint);
|
||||||
|
return endpoint;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
context.addServlet(holder, "/ws");
|
context.addServlet(holder, "/ws");
|
||||||
|
@ -353,6 +361,11 @@ public class ClientCloseTest
|
||||||
// client confirms connection via echo
|
// client confirms connection via echo
|
||||||
confirmConnection(clientSocket, clientConnectFuture);
|
confirmConnection(clientSocket, clientConnectFuture);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Block on the server so that the server does not detect a read failure
|
||||||
|
clientSocket.getSession().getRemote().sendString("block");
|
||||||
|
|
||||||
// setup client endpoint for write failure (test only)
|
// setup client endpoint for write failure (test only)
|
||||||
EndPoint endp = clientSocket.getEndPoint();
|
EndPoint endp = clientSocket.getEndPoint();
|
||||||
endp.shutdownOutput();
|
endp.shutdownOutput();
|
||||||
|
@ -366,16 +379,24 @@ public class ClientCloseTest
|
||||||
assertThat("OnError", clientSocket.error.get(), instanceOf(EofException.class));
|
assertThat("OnError", clientSocket.error.get(), instanceOf(EofException.class));
|
||||||
|
|
||||||
// client triggers close event on client ws-endpoint
|
// client triggers close event on client ws-endpoint
|
||||||
// assert - close code==1006 (abnormal) or code==1001 (shutdown)
|
// assert - close code==1006 (abnormal)
|
||||||
clientSocket.assertReceivedCloseEvent(timeout, anyOf(is(StatusCode.SHUTDOWN), is(StatusCode.ABNORMAL)));
|
clientSocket.assertReceivedCloseEvent(timeout, is(StatusCode.ABNORMAL), null);
|
||||||
|
|
||||||
clientSessionTracker.assertClosedProperly(client);
|
clientSessionTracker.assertClosedProperly(client);
|
||||||
|
|
||||||
|
assertThat(serverEndpoints.size(), is(1));
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
for (ServerEndpoint endpoint : serverEndpoints)
|
||||||
|
endpoint.block.countDown();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ServerEndpoint implements WebSocketFrameListener, WebSocketListener
|
public static class ServerEndpoint implements WebSocketFrameListener, WebSocketListener
|
||||||
{
|
{
|
||||||
private static final Logger LOG = Log.getLogger(ServerEndpoint.class);
|
private static final Logger LOG = Log.getLogger(ServerEndpoint.class);
|
||||||
private Session session;
|
private Session session;
|
||||||
|
CountDownLatch block = new CountDownLatch(1);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onWebSocketBinary(byte[] payload, int offset, int len)
|
public void onWebSocketBinary(byte[] payload, int offset, int len)
|
||||||
|
@ -395,15 +416,22 @@ public class ClientCloseTest
|
||||||
String bigmsg = new String(buf, UTF_8);
|
String bigmsg = new String(buf, UTF_8);
|
||||||
session.getRemote().sendString(bigmsg);
|
session.getRemote().sendString(bigmsg);
|
||||||
}
|
}
|
||||||
|
else if (message.equals("block"))
|
||||||
|
{
|
||||||
|
LOG.debug("blocking");
|
||||||
|
assertTrue(block.await(5, TimeUnit.MINUTES));
|
||||||
|
LOG.debug("unblocked");
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// simple echo
|
// simple echo
|
||||||
session.getRemote().sendString(message);
|
session.getRemote().sendString(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (IOException ignore)
|
catch (Throwable t)
|
||||||
{
|
{
|
||||||
LOG.debug(ignore);
|
LOG.debug(t);
|
||||||
|
throw new RuntimeException(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -422,9 +450,7 @@ public class ClientCloseTest
|
||||||
public void onWebSocketError(Throwable cause)
|
public void onWebSocketError(Throwable cause)
|
||||||
{
|
{
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
{
|
LOG.debug("onWebSocketError(): ", cause);
|
||||||
LOG.debug(cause);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -94,8 +94,8 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp
|
||||||
@Override
|
@Override
|
||||||
public void onCompleteFailure(Throwable failure)
|
public void onCompleteFailure(Throwable failure)
|
||||||
{
|
{
|
||||||
super.onCompleteFailure(failure);
|
|
||||||
AbstractWebSocketConnection.this.close(failure);
|
AbstractWebSocketConnection.this.close(failure);
|
||||||
|
super.onCompleteFailure(failure);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue