aboutsummaryrefslogtreecommitdiff
path: root/test/sample
diff options
context:
space:
mode:
authorrbackman <none@none>2011-04-12 09:04:57 +0200
committerrbackman <none@none>2011-04-12 09:04:57 +0200
commit55d22f8e969d044575e501cabdefc110672d0907 (patch)
treecbd95e221675bfc40022bbe68ea182610b678935 /test/sample
parent11f2076339062c9ccf20a08a3d27e406af4d11d9 (diff)
7026287: Asynchronous API sample
Summary: Implement a chat server using the new asynchronous networking API Reviewed-by: hosterda, alanb --HG-- extra : rebase_source : 61d8c30f3b16b9d1a6c3dc104ada01d0202acaf4
Diffstat (limited to 'test/sample')
-rw-r--r--test/sample/chatserver/ChatTest.java399
1 files changed, 399 insertions, 0 deletions
diff --git a/test/sample/chatserver/ChatTest.java b/test/sample/chatserver/ChatTest.java
new file mode 100644
index 000000000..05d6f44e8
--- /dev/null
+++ b/test/sample/chatserver/ChatTest.java
@@ -0,0 +1,399 @@
+/*
+ * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+/* @test
+ * @summary Test chat server chatserver test
+ *
+ * @library ../../../src/share/sample/nio/chatserver
+ * @build ChatTest ChatServer Client ClientReader DataReader MessageReader NameReader
+ * @run main ChatTest
+ */
+
+import java.io.*;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.CyclicBarrier;
+
+public class ChatTest {
+ public static int listeningPort = 0;
+
+ public static void main(String[] args) throws Throwable {
+ testStartStop();
+ testPortOpen();
+ testAsksForName();
+ testUseName();
+ testConnectDisconnectConnect();
+ testUsernameAndMessage();
+ testDontReceiveMessageInNameState();
+ }
+
+ private static ChatServer startServer() throws IOException {
+ ChatServer server = new ChatServer(0);
+ InetSocketAddress address = (InetSocketAddress) server.getSocketAddress();
+ listeningPort = address.getPort();
+ server.run();
+ return server;
+ }
+
+ public static void testStartStop() throws Exception {
+ ChatServer server = startServer();
+ server.shutdown();
+ }
+
+ public static void testPortOpen() throws Exception {
+ ChatServer server = startServer();
+ try {
+ Socket socket = new Socket("localhost", listeningPort);
+ if (!socket.isConnected()) {
+ throw new RuntimeException("Failed to connect to server: port not open");
+ }
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ public static void testAsksForName() throws Exception {
+ ChatServer server = startServer();
+ try {
+ Socket socket = new Socket("localhost", listeningPort);
+
+ Reader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+ String string = readAvailableString(reader);
+ if (!string.equals("Name: ")) {
+ throw new RuntimeException("Server doesn't send Name: ");
+ }
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ public static void testUseName() throws Throwable {
+ ChatServer server = startServer();
+ try {
+ performTestUseName();
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ public static void testConnectDisconnectConnect() throws Exception {
+ ChatServer server = startServer();
+ try {
+ performTestConnectDisconnectConnect();
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ public static void testUsernameAndMessage() throws Exception {
+ ChatServer server = startServer();
+ try {
+ performTestUsernameAndMessage();
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ public static void testDontReceiveMessageInNameState() throws Exception {
+ ChatServer server = startServer();
+ try {
+ performDontReceiveMessageInNameState();
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ private static void assertEqual(List<Exception> exception, Object value, Object expected) {
+ if (expected == value) {
+ return;
+ }
+ if (expected == null) {
+ exception.add(new RuntimeException("Expected null, but was: " + value));
+ return;
+ }
+ if (!expected.equals(value)) {
+ exception.add(new RuntimeException("Expected: " + expected + " but was: " + value));
+ return;
+ }
+ }
+
+ private static void performDontReceiveMessageInNameState() throws Exception {
+ final CyclicBarrier barrier1 = new CyclicBarrier(2);
+ final CyclicBarrier barrier2 = new CyclicBarrier(2);
+ final CyclicBarrier barrier3 = new CyclicBarrier(2);
+ final List<Exception> exceptions = Collections.synchronizedList(new ArrayList<Exception>());
+
+ ChatConnection chatConnection = new ChatConnection() {
+ @Override
+ public void run(Socket socket, BufferedReader reader, Writer writer) throws Exception {
+ String string = readAvailableString(reader);
+ assertEqual(exceptions, string, "Name: ");
+ writer.write("testClient1\n");
+ waitForJoin(reader, "testClient1");
+ barrier1.await();
+ writer.write("Ignore this!\n");
+ barrier2.await();
+ barrier3.await();
+ }
+ };
+
+ Thread client2 = new Thread(new ChatConnection() {
+ @Override
+ public void run(Socket socket, BufferedReader reader, Writer writer) throws Exception {
+ barrier1.await();
+ barrier2.await();
+ String string = readAvailableString(reader);
+ assertEqual(exceptions, string, "Name: ");
+ string = readAvailableString(reader, true);
+ assertEqual(exceptions, string, null);
+ writer.write("testClient2\n");
+ barrier3.await();
+ }
+ });
+
+ client2.start();
+ chatConnection.run();
+ if (!exceptions.isEmpty()) {
+ throw exceptions.get(0);
+ }
+
+ }
+
+ private static void waitForJoin(BufferedReader reader, String s) throws IOException {
+ String joined;
+ do {
+ joined = readAvailableString(reader);
+ } while (!(joined != null && joined.contains("Welcome " + s)));
+ }
+
+ private static void performTestUsernameAndMessage() throws Exception {
+ final CyclicBarrier barrier1 = new CyclicBarrier(2);
+ final CyclicBarrier barrier2 = new CyclicBarrier(2);
+ final CyclicBarrier barrier3 = new CyclicBarrier(2);
+ final List<Exception> exceptions = Collections.synchronizedList(new ArrayList<Exception>());
+
+ ChatConnection chatConnection = new ChatConnection() {
+ @Override
+ public void run(Socket socket, BufferedReader reader, Writer writer) throws Exception {
+ String string = readAvailableString(reader);
+ assertEqual(exceptions, string, "Name: ");
+ writer.write("testClient1\n");
+ waitForJoin(reader, "testClient1");
+ barrier1.await();
+ barrier2.await();
+ string = readAvailableString(reader);
+ assertEqual(exceptions, string, "testClient2: Hello world!\n");
+ barrier3.await();
+ }
+ };
+
+ Thread client2 = new Thread(new ChatConnection() {
+ @Override
+ public void run(Socket socket, BufferedReader reader, Writer writer) throws Exception {
+ String string = readAvailableString(reader);
+ assertEqual(exceptions, string, "Name: ");
+ barrier1.await();
+ writer.write("testClient2\nHello world!\n");
+ barrier2.await();
+ barrier3.await();
+ }
+ });
+
+ client2.start();
+ chatConnection.run();
+ if (!exceptions.isEmpty()) {
+ throw exceptions.get(0);
+ }
+ }
+
+ private static void performTestConnectDisconnectConnect() throws Exception {
+ final CyclicBarrier barrier1 = new CyclicBarrier(2);
+ final CyclicBarrier barrier2 = new CyclicBarrier(2);
+ final CyclicBarrier barrier3 = new CyclicBarrier(2);
+ final List<Exception> exceptions = new ArrayList<Exception>();
+
+ ChatConnection chatConnection = new ChatConnection() {
+ @Override
+ public void run(Socket socket, BufferedReader reader, Writer writer) throws Exception {
+ String string = readAvailableString(reader);
+ assertEqual(exceptions, string, "Name: ");
+ writer.write("testClient1\n");
+ }
+ };
+
+ ChatConnection chatConnection2 = new ChatConnection() {
+ @Override
+ public void run(Socket socket, BufferedReader reader, Writer writer) throws Exception {
+ readAvailableString(reader);
+ writer.write("testClient1\n");
+ waitForJoin(reader, "testClient1");
+ barrier1.await();
+ writer.write("Good morning!\n");
+ barrier2.await();
+ String string = readAvailableString(reader);
+ assertEqual(exceptions, string, "testClient2: Hello world!\n");
+ barrier3.await();
+ }
+ };
+
+ Thread client2 = new Thread(new ChatConnection() {
+ @Override
+ public void run(Socket socket, BufferedReader reader, Writer writer) throws Exception {
+ readAvailableString(reader);
+ writer.write("testClient2\n");
+ waitForJoin(reader, "testClient2");
+ barrier1.await();
+ writer.write("Hello world!\n");
+ barrier2.await();
+ String string = readAvailableString(reader);
+ assertEqual(exceptions, string, "testClient1: Good morning!\n");
+ barrier3.await();
+ }
+ });
+
+ client2.start();
+ chatConnection.run();
+ chatConnection2.run();
+ if (!exceptions.isEmpty()) {
+ throw exceptions.get(0);
+ }
+ }
+
+ private static void performTestUseName() throws Exception {
+ final CyclicBarrier barrier1 = new CyclicBarrier(2);
+ final CyclicBarrier barrier2 = new CyclicBarrier(2);
+ final CyclicBarrier barrier3 = new CyclicBarrier(2);
+ final List<Exception> exceptions = new ArrayList<Exception>();
+
+ ChatConnection chatConnection = new ChatConnection() {
+ @Override
+ public void run(Socket socket, BufferedReader reader, Writer writer) throws Exception {
+ String string = readAvailableString(reader);
+ if (!"Name: ".equals(string)) {
+ exceptions.add(new RuntimeException("Expected Name: "));
+ }
+ writer.write("testClient1\n");
+ waitForJoin(reader, "testClient1");
+ barrier1.await();
+ barrier2.await();
+ string = readAvailableString(reader);
+ if (!"testClient2: Hello world!\n".equals(string)) {
+ exceptions.add(new RuntimeException("testClient2: Hello world!\n"));
+ }
+ barrier3.await();
+ }
+ };
+
+ Thread client2 = new Thread(new ChatConnection() {
+ @Override
+ public void run(Socket socket, BufferedReader reader, Writer writer) throws Exception {
+ String string = readAvailableString(reader);
+ if (!"Name: ".equals(string)) {
+ exceptions.add(new RuntimeException("Expected Name: "));
+ }
+ writer.write("testClient2\n");
+ waitForJoin(reader, "testClient2");
+ barrier1.await();
+ writer.write("Hello world!\n");
+ barrier2.await();
+ barrier3.await();
+ }
+ });
+
+ client2.start();
+ chatConnection.run();
+ if (!exceptions.isEmpty()) {
+ throw exceptions.get(0);
+ }
+ }
+
+ private static String readAvailableString(Reader reader) throws IOException {
+ return readAvailableString(reader, false);
+ }
+
+ private static String readAvailableString(Reader reader, boolean now) throws IOException {
+ StringBuilder builder = new StringBuilder();
+ int bytes;
+ if (now && !reader.ready()) {
+ return null;
+ }
+ do {
+ char[] buf = new char[256];
+ bytes = reader.read(buf);
+ builder.append(buf, 0, bytes);
+ } while (bytes == 256);
+ return builder.toString();
+ }
+
+ private abstract static class ChatConnection implements Runnable {
+ public Exception exception;
+
+ @Override
+ public void run() {
+ try (Socket socket = new Socket("localhost", listeningPort);
+ BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+ Writer writer = new FlushingWriter(new OutputStreamWriter(socket.getOutputStream()))) {
+ socket.setTcpNoDelay(true);
+
+ run(socket, reader, writer);
+ } catch (Exception e) {
+ exception = e;
+ }
+ }
+
+ public abstract void run(Socket socket, BufferedReader reader, Writer writer) throws Exception;
+ }
+
+ private static class FlushingWriter extends Writer {
+ public final Writer delegate;
+
+ private FlushingWriter(Writer delegate) {
+ this.delegate = delegate;
+ }
+
+ @Override
+ public void write(char[] cbuf, int off, int len) throws IOException {
+ delegate.write(cbuf, off, len);
+ }
+
+ @Override
+ public void flush() throws IOException {
+ delegate.flush();
+ }
+
+ @Override
+ public void close() throws IOException {
+ delegate.close();
+ }
+
+ @Override
+ public void write(String str) throws IOException {
+ super.write(str);
+ flush();
+ }
+ }
+}