aboutsummaryrefslogtreecommitdiff
path: root/websocket/src/test/java/fi
diff options
context:
space:
mode:
Diffstat (limited to 'websocket/src/test/java/fi')
-rw-r--r--websocket/src/test/java/fi/iki/elonen/NanoWebSocketServerTest.java41
-rw-r--r--websocket/src/test/java/fi/iki/elonen/WebSocketResponseHandlerTest.java181
-rw-r--r--websocket/src/test/java/fi/iki/elonen/samples/echo/EchoWebSocketsTest.java102
-rw-r--r--websocket/src/test/java/fi/iki/elonen/samples/echo/SimpleEchoSocket.java104
4 files changed, 321 insertions, 107 deletions
diff --git a/websocket/src/test/java/fi/iki/elonen/NanoWebSocketServerTest.java b/websocket/src/test/java/fi/iki/elonen/NanoWebSocketServerTest.java
deleted file mode 100644
index 7cd06b7..0000000
--- a/websocket/src/test/java/fi/iki/elonen/NanoWebSocketServerTest.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package fi.iki.elonen;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.runners.MockitoJUnitRunner;
-
-import java.util.Map;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.when;
-
-@RunWith(MockitoJUnitRunner.class)
-public class NanoWebSocketServerTest {
- @Mock
- private NanoHTTPD.IHTTPSession session;
-
- private NanoWebSocketServer server;
-
- @Before
- public void setUp() {
- server = new NanoWebSocketServer(9090);
- }
-
- @Test(expected = Error.class)
- public void testMissingResponseFactoryThrowsErrorOnServe() {
- server.openWebSocket(session);
- }
-
- @Test
- public void testMissingResponseFactoryThrowsErrorWithCorrectMessageOnServe() {
- NanoWebSocketServer server = new NanoWebSocketServer(9090);
- try {
- server.openWebSocket(session);
- } catch (Error e) {
- assertEquals(NanoWebSocketServer.MISSING_FACTORY_MESSAGE, e.getMessage());
- }
- }
-} \ No newline at end of file
diff --git a/websocket/src/test/java/fi/iki/elonen/WebSocketResponseHandlerTest.java b/websocket/src/test/java/fi/iki/elonen/WebSocketResponseHandlerTest.java
index 04a497b..8c083ee 100644
--- a/websocket/src/test/java/fi/iki/elonen/WebSocketResponseHandlerTest.java
+++ b/websocket/src/test/java/fi/iki/elonen/WebSocketResponseHandlerTest.java
@@ -1,120 +1,169 @@
package fi.iki.elonen;
+/*
+ * #%L
+ * NanoHttpd-Websocket
+ * %%
+ * Copyright (C) 2012 - 2015 nanohttpd
+ * %%
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the nanohttpd nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * #L%
+ */
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertNull;
+import static org.mockito.Mockito.when;
+
+import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
-
-import fi.iki.elonen.NanoHTTPD.IHTTPSession;
-import fi.iki.elonen.NanoHTTPD.Response;
import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
import org.mockito.Mock;
+import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
-import static junit.framework.Assert.*;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.atLeast;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
+import fi.iki.elonen.NanoHTTPD.IHTTPSession;
+import fi.iki.elonen.NanoHTTPD.Response;
+import fi.iki.elonen.NanoWSD.WebSocketFrame;
+import fi.iki.elonen.NanoWSD.WebSocketFrame.CloseCode;
@RunWith(MockitoJUnitRunner.class)
public class WebSocketResponseHandlerTest {
@Mock
private IHTTPSession session;
- @Mock
- private WebSocket webSocket;
- @Mock
- private IWebSocketFactory webSocketFactory;
- @Mock
- private Response response;
- @Captor
- private ArgumentCaptor<String> headerNameCaptor;
- @Captor
- private ArgumentCaptor<String> headerCaptor;
+
+ private NanoWSD nanoWebSocketServer;
private Map<String, String> headers;
- private WebSocketResponseHandler responseHandler;
+ private static class MockedWSD extends NanoWSD {
+
+ public MockedWSD(int port) {
+ super(port);
+ }
+
+ public MockedWSD(String hostname, int port) {
+ super(hostname, port);
+ }
+
+ @Override
+ protected WebSocket openWebSocket(IHTTPSession handshake) {
+ return new WebSocket(handshake) { // Dummy websocket inner class.
+
+ @Override
+ protected void onPong(WebSocketFrame pong) {
+ }
+
+ @Override
+ protected void onOpen() {
+ }
+
+ @Override
+ protected void onMessage(WebSocketFrame message) {
+ }
+
+ @Override
+ protected void onException(IOException exception) {
+ }
+
+ @Override
+ protected void onClose(CloseCode code, String reason, boolean initiatedByRemote) {
+ }
+ };
+ }
+ }
@Before
public void setUp() {
- headers = new HashMap<String, String>();
- headers.put("upgrade", "websocket");
- headers.put("connection", "Upgrade");
- headers.put("sec-websocket-key", "x3JJHMbDL1EzLkh9GBhXDw==");
- headers.put("sec-websocket-protocol", "chat, superchat");
- headers.put("sec-websocket-version", "13");
-
- when(session.getHeaders()).thenReturn(headers);
- when(webSocketFactory.openWebSocket(any(IHTTPSession.class))).thenReturn(webSocket);
- when(webSocket.getHandshakeResponse()).thenReturn(response);
-
- responseHandler = new WebSocketResponseHandler(webSocketFactory);
+ this.nanoWebSocketServer = Mockito.mock(MockedWSD.class, Mockito.CALLS_REAL_METHODS);
+
+ this.headers = new HashMap<String, String>();
+ this.headers.put("upgrade", "websocket");
+ this.headers.put("connection", "Upgrade");
+ this.headers.put("sec-websocket-key", "x3JJHMbDL1EzLkh9GBhXDw==");
+ this.headers.put("sec-websocket-protocol", "chat, superchat");
+ this.headers.put("sec-websocket-version", "13");
+
+ when(this.session.getHeaders()).thenReturn(this.headers);
}
@Test
- public void testHandshakeReturnsResponseWithExpectedHeaders() {
- Response handshakeResponse = responseHandler.serve(session);
+ public void testConnectionHeaderHandlesKeepAlive_FixingFirefoxConnectIssue() {
+ this.headers.put("connection", "keep-alive, Upgrade");
+ Response handshakeResponse = this.nanoWebSocketServer.serve(this.session);
- verify(webSocket).getHandshakeResponse();
assertNotNull(handshakeResponse);
- assertSame(response, handshakeResponse);
-
- verify(response, atLeast(1)).addHeader(headerNameCaptor.capture(), headerCaptor.capture());
- assertHeader(0, "sec-websocket-accept", "HSmrc0sMlYUkAGmm5OPpG2HaGWk=");
- assertHeader(1, "sec-websocket-protocol", "chat");
}
@Test
- public void testWrongWebsocketVersionReturnsErrorResponse() {
- headers.put("sec-websocket-version", "12");
-
- Response handshakeResponse = responseHandler.serve(session);
+ public void testHandshakeReturnsResponseWithExpectedHeaders() {
+ Response handshakeResponse = this.nanoWebSocketServer.serve(this.session);
assertNotNull(handshakeResponse);
- assertEquals(Response.Status.BAD_REQUEST, handshakeResponse.getStatus());
+
+ assertEquals(handshakeResponse.getHeader(NanoWSD.HEADER_WEBSOCKET_ACCEPT), "HSmrc0sMlYUkAGmm5OPpG2HaGWk=");
+ assertEquals(handshakeResponse.getHeader(NanoWSD.HEADER_WEBSOCKET_PROTOCOL), "chat");
}
@Test
public void testMissingKeyReturnsErrorResponse() {
- headers.remove("sec-websocket-key");
+ this.headers.remove("sec-websocket-key");
- Response handshakeResponse = responseHandler.serve(session);
+ Response handshakeResponse = this.nanoWebSocketServer.serve(this.session);
assertNotNull(handshakeResponse);
assertEquals(Response.Status.BAD_REQUEST, handshakeResponse.getStatus());
}
@Test
- public void testWrongUpgradeHeaderReturnsNullResponse() {
- headers.put("upgrade", "not a websocket");
- Response handshakeResponse = responseHandler.serve(session);
- assertNull(handshakeResponse);
+ public void testWrongConnectionHeaderReturnsNullResponse() {
+ this.headers.put("connection", "Junk");
+ Response handshakeResponse = this.nanoWebSocketServer.serve(this.session);
+ assertNull(handshakeResponse.getHeader(NanoWSD.HEADER_UPGRADE));
}
@Test
- public void testWrongConnectionHeaderReturnsNullResponse() {
- headers.put("connection", "Junk");
- Response handshakeResponse = responseHandler.serve(session);
- assertNull(handshakeResponse);
+ public void testWrongUpgradeHeaderReturnsNullResponse() {
+ this.headers.put("upgrade", "not a websocket");
+ Response handshakeResponse = this.nanoWebSocketServer.serve(this.session);
+ assertNull(handshakeResponse.getHeader(NanoWSD.HEADER_UPGRADE));
}
@Test
- public void testConnectionHeaderHandlesKeepAlive_FixingFirefoxConnectIssue() {
- headers.put("connection", "keep-alive, Upgrade");
- Response handshakeResponse = responseHandler.serve(session);
+ public void testWrongWebsocketVersionReturnsErrorResponse() {
+ this.headers.put("sec-websocket-version", "12");
- verify(webSocket).getHandshakeResponse();
- assertNotNull(handshakeResponse);
- assertSame(response, handshakeResponse);
- }
+ Response handshakeResponse = this.nanoWebSocketServer.serve(this.session);
- private void assertHeader(int index, String name, String value) {
- assertEquals(name, headerNameCaptor.getAllValues().get(index));
- assertEquals(value, headerCaptor.getAllValues().get(index));
+ assertNotNull(handshakeResponse);
+ assertEquals(Response.Status.BAD_REQUEST, handshakeResponse.getStatus());
}
}
diff --git a/websocket/src/test/java/fi/iki/elonen/samples/echo/EchoWebSocketsTest.java b/websocket/src/test/java/fi/iki/elonen/samples/echo/EchoWebSocketsTest.java
new file mode 100644
index 0000000..d8b96ab
--- /dev/null
+++ b/websocket/src/test/java/fi/iki/elonen/samples/echo/EchoWebSocketsTest.java
@@ -0,0 +1,102 @@
+package fi.iki.elonen.samples.echo;
+
+/*
+ * #%L
+ * NanoHttpd-Websocket
+ * %%
+ * Copyright (C) 2012 - 2015 nanohttpd
+ * %%
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the nanohttpd nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * #L%
+ */
+
+import java.net.URI;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
+import org.eclipse.jetty.websocket.client.WebSocketClient;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import fi.iki.elonen.NanoWSD;
+
+public class EchoWebSocketsTest {
+
+ private static NanoWSD server;
+
+ @BeforeClass
+ public static void setUp() throws Exception {
+ EchoWebSocketsTest.server = new DebugWebSocketServer(9191, true);
+ EchoWebSocketsTest.server.start();
+ }
+
+ @AfterClass
+ public static void tearDown() throws Exception {
+ EchoWebSocketsTest.server.stop();
+ }
+
+ @Test
+ public void testWebsocketClient() throws Exception {
+ String destUri = "ws://localhost:9191";
+
+ WebSocketClient client = new WebSocketClient();
+ SimpleEchoSocket socket = new SimpleEchoSocket();
+ socket.getToSendMessages().add("Hello");
+ socket.getToSendMessages().add("Thanks for the conversation.");
+ socket.getToSendMessages().add(createString(31000));
+ socket.getToSendMessages().add(createString(65400));
+ try {
+ client.start();
+ URI echoUri = new URI(destUri);
+ ClientUpgradeRequest request = new ClientUpgradeRequest();
+ client.connect(socket, echoUri, request);
+ System.out.printf("Connecting to : %s%n", echoUri);
+ socket.awaitClose(5, TimeUnit.SECONDS);
+ } catch (Throwable t) {
+ t.printStackTrace();
+ } finally {
+ try {
+ client.stop();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ Assert.assertEquals(4, socket.getReceivedMessages().size());
+ Assert.assertEquals("Hello", socket.getReceivedMessages().get(0));
+ Assert.assertEquals("Thanks for the conversation.", socket.getReceivedMessages().get(1));
+
+ }
+
+ private String createString(int i) {
+ StringBuilder builder = new StringBuilder();
+ while (builder.length() < i) {
+ builder.append("A very long text.");
+ }
+ return builder.toString();
+ }
+}
diff --git a/websocket/src/test/java/fi/iki/elonen/samples/echo/SimpleEchoSocket.java b/websocket/src/test/java/fi/iki/elonen/samples/echo/SimpleEchoSocket.java
new file mode 100644
index 0000000..45524d2
--- /dev/null
+++ b/websocket/src/test/java/fi/iki/elonen/samples/echo/SimpleEchoSocket.java
@@ -0,0 +1,104 @@
+package fi.iki.elonen.samples.echo;
+
+/*
+ * #%L
+ * NanoHttpd-Websocket
+ * %%
+ * Copyright (C) 2012 - 2015 nanohttpd
+ * %%
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the nanohttpd nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * #L%
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.jetty.websocket.api.Session;
+import org.eclipse.jetty.websocket.api.StatusCode;
+import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
+import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
+import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
+import org.eclipse.jetty.websocket.api.annotations.WebSocket;
+
+/**
+ * Basic Echo Client Socket
+ */
+@WebSocket(maxTextMessageSize = 64 * 1024)
+public class SimpleEchoSocket {
+
+ private final List<String> receivedMessages = new ArrayList<String>();
+
+ private final List<String> toSendMessages = new ArrayList<String>();
+
+ private final CountDownLatch closeLatch;
+
+ public SimpleEchoSocket() {
+ this.closeLatch = new CountDownLatch(1);
+ }
+
+ public boolean awaitClose(int duration, TimeUnit unit) throws InterruptedException {
+ return this.closeLatch.await(duration, unit);
+ }
+
+ public List<String> getReceivedMessages() {
+ return this.receivedMessages;
+ }
+
+ public List<String> getToSendMessages() {
+ return this.toSendMessages;
+ }
+
+ @OnWebSocketClose
+ public void onClose(int statusCode, String reason) {
+ System.out.printf("Connection closed: %d - %s%n", statusCode, reason);
+ this.closeLatch.countDown();
+ }
+
+ @OnWebSocketConnect
+ public void onConnect(Session session) {
+ System.out.printf("Got connect: %s%n", session);
+ try {
+ Future<Void> fut;
+
+ for (String message : this.toSendMessages) {
+ fut = session.getRemote().sendStringByFuture(message);
+ fut.get(5, TimeUnit.SECONDS);
+ }
+ session.close(StatusCode.NORMAL, "I'm done");
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+ }
+
+ @OnWebSocketMessage
+ public void onMessage(String msg) {
+ System.out.printf("Got msg: %s%n", msg);
+ this.receivedMessages.add(msg);
+ }
+}