Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/sample/chatserver/ChatTest.java
38833 views
/*1* Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/222324/* @test25* @summary Test chat server chatserver test26*27* @library /src/share/sample/nio/chatserver28* @build ChatTest ChatServer Client ClientReader DataReader MessageReader NameReader29* @run testng ChatTest30*/3132import java.io.*;33import java.net.InetSocketAddress;34import java.net.Socket;35import java.util.ArrayList;36import java.util.Collections;37import java.util.List;38import java.util.concurrent.CyclicBarrier;3940import org.testng.annotations.Test;4142public class ChatTest {43public static int listeningPort = 0;4445@Test46public static void doTest() throws Throwable {47testStartStop();48testPortOpen();49testAsksForName();50testUseName();51testConnectDisconnectConnect();52testUsernameAndMessage();53testDontReceiveMessageInNameState();54}5556private static ChatServer startServer() throws IOException {57ChatServer server = new ChatServer(0);58InetSocketAddress address = (InetSocketAddress) server.getSocketAddress();59listeningPort = address.getPort();60server.run();61return server;62}6364public static void testStartStop() throws Exception {65ChatServer server = startServer();66server.shutdown();67}6869public static void testPortOpen() throws Exception {70ChatServer server = startServer();71try {72Socket socket = new Socket("localhost", listeningPort);73if (!socket.isConnected()) {74throw new RuntimeException("Failed to connect to server: port not open");75}76} finally {77server.shutdown();78}79}8081public static void testAsksForName() throws Exception {82ChatServer server = startServer();83try {84Socket socket = new Socket("localhost", listeningPort);8586Reader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));87String string = readAvailableString(reader);88if (!string.equals("Name: ")) {89throw new RuntimeException("Server doesn't send Name: ");90}91} finally {92server.shutdown();93}94}9596public static void testUseName() throws Throwable {97ChatServer server = startServer();98try {99performTestUseName();100} finally {101server.shutdown();102}103}104105public static void testConnectDisconnectConnect() throws Exception {106ChatServer server = startServer();107try {108performTestConnectDisconnectConnect();109} finally {110server.shutdown();111}112}113114public static void testUsernameAndMessage() throws Exception {115ChatServer server = startServer();116try {117performTestUsernameAndMessage();118} finally {119server.shutdown();120}121}122123public static void testDontReceiveMessageInNameState() throws Exception {124ChatServer server = startServer();125try {126performDontReceiveMessageInNameState();127} finally {128server.shutdown();129}130}131132private static void assertEqual(List<Exception> exception, Object value, Object expected) {133if (expected == value) {134return;135}136if (expected == null) {137exception.add(new RuntimeException("Expected null, but was: " + value));138return;139}140if (!expected.equals(value)) {141exception.add(new RuntimeException("Expected: " + expected + " but was: " + value));142return;143}144}145146private static void performDontReceiveMessageInNameState() throws Exception {147final CyclicBarrier barrier1 = new CyclicBarrier(2);148final CyclicBarrier barrier2 = new CyclicBarrier(2);149final CyclicBarrier barrier3 = new CyclicBarrier(2);150final List<Exception> exceptions = Collections.synchronizedList(new ArrayList<Exception>());151152ChatConnection chatConnection = new ChatConnection() {153@Override154public void run(Socket socket, BufferedReader reader, Writer writer) throws Exception {155String string = readAvailableString(reader);156assertEqual(exceptions, string, "Name: ");157writer.write("testClient1\n");158waitForJoin(reader, "testClient1");159barrier1.await();160writer.write("Ignore this!\n");161barrier2.await();162barrier3.await();163}164};165166Thread client2 = new Thread(new ChatConnection() {167@Override168public void run(Socket socket, BufferedReader reader, Writer writer) throws Exception {169barrier1.await();170barrier2.await();171String string = readAvailableString(reader);172assertEqual(exceptions, string, "Name: ");173string = readAvailableString(reader, true);174assertEqual(exceptions, string, null);175writer.write("testClient2\n");176barrier3.await();177}178});179180client2.start();181chatConnection.run();182if (!exceptions.isEmpty()) {183throw exceptions.get(0);184}185186}187188private static void waitForJoin(BufferedReader reader, String s) throws IOException {189String joined;190do {191joined = readAvailableString(reader);192} while (!(joined != null && joined.contains("Welcome " + s)));193}194195private static void performTestUsernameAndMessage() throws Exception {196final CyclicBarrier barrier1 = new CyclicBarrier(2);197final CyclicBarrier barrier2 = new CyclicBarrier(2);198final CyclicBarrier barrier3 = new CyclicBarrier(2);199final List<Exception> exceptions = Collections.synchronizedList(new ArrayList<Exception>());200201ChatConnection chatConnection = new ChatConnection() {202@Override203public void run(Socket socket, BufferedReader reader, Writer writer) throws Exception {204String string = readAvailableString(reader);205assertEqual(exceptions, string, "Name: ");206writer.write("testClient1\n");207waitForJoin(reader, "testClient1");208barrier1.await();209barrier2.await();210string = readAvailableString(reader);211assertEqual(exceptions, string, "testClient2: Hello world!\n");212barrier3.await();213}214};215216Thread client2 = new Thread(new ChatConnection() {217@Override218public void run(Socket socket, BufferedReader reader, Writer writer) throws Exception {219String string = readAvailableString(reader);220assertEqual(exceptions, string, "Name: ");221barrier1.await();222writer.write("testClient2\nHello world!\n");223barrier2.await();224barrier3.await();225}226});227228client2.start();229chatConnection.run();230if (!exceptions.isEmpty()) {231throw exceptions.get(0);232}233}234235private static void performTestConnectDisconnectConnect() throws Exception {236final CyclicBarrier barrier1 = new CyclicBarrier(2);237final CyclicBarrier barrier2 = new CyclicBarrier(2);238final CyclicBarrier barrier3 = new CyclicBarrier(2);239final List<Exception> exceptions = new ArrayList<Exception>();240241ChatConnection chatConnection = new ChatConnection() {242@Override243public void run(Socket socket, BufferedReader reader, Writer writer) throws Exception {244String string = readAvailableString(reader);245assertEqual(exceptions, string, "Name: ");246writer.write("testClient1\n");247}248};249250ChatConnection chatConnection2 = new ChatConnection() {251@Override252public void run(Socket socket, BufferedReader reader, Writer writer) throws Exception {253readAvailableString(reader);254writer.write("testClient1\n");255waitForJoin(reader, "testClient1");256barrier1.await();257writer.write("Good morning!\n");258barrier2.await();259String string = readAvailableString(reader);260assertEqual(exceptions, string, "testClient2: Hello world!\n");261barrier3.await();262}263};264265Thread client2 = new Thread(new ChatConnection() {266@Override267public void run(Socket socket, BufferedReader reader, Writer writer) throws Exception {268readAvailableString(reader);269writer.write("testClient2\n");270waitForJoin(reader, "testClient2");271barrier1.await();272writer.write("Hello world!\n");273barrier2.await();274String string = readAvailableString(reader);275assertEqual(exceptions, string, "testClient1: Good morning!\n");276barrier3.await();277}278});279280client2.start();281chatConnection.run();282chatConnection2.run();283if (!exceptions.isEmpty()) {284throw exceptions.get(0);285}286}287288private static void performTestUseName() throws Exception {289final CyclicBarrier barrier1 = new CyclicBarrier(2);290final CyclicBarrier barrier2 = new CyclicBarrier(2);291final CyclicBarrier barrier3 = new CyclicBarrier(2);292final List<Exception> exceptions = new ArrayList<Exception>();293294ChatConnection chatConnection = new ChatConnection() {295@Override296public void run(Socket socket, BufferedReader reader, Writer writer) throws Exception {297String string = readAvailableString(reader);298if (!"Name: ".equals(string)) {299exceptions.add(new RuntimeException("Expected Name: "));300}301writer.write("testClient1\n");302waitForJoin(reader, "testClient1");303barrier1.await();304barrier2.await();305string = readAvailableString(reader);306if (!"testClient2: Hello world!\n".equals(string)) {307exceptions.add(new RuntimeException("testClient2: Hello world!\n"));308}309barrier3.await();310}311};312313Thread client2 = new Thread(new ChatConnection() {314@Override315public void run(Socket socket, BufferedReader reader, Writer writer) throws Exception {316String string = readAvailableString(reader);317if (!"Name: ".equals(string)) {318exceptions.add(new RuntimeException("Expected Name: "));319}320writer.write("testClient2\n");321waitForJoin(reader, "testClient2");322barrier1.await();323writer.write("Hello world!\n");324barrier2.await();325barrier3.await();326}327});328329client2.start();330chatConnection.run();331if (!exceptions.isEmpty()) {332throw exceptions.get(0);333}334}335336private static String readAvailableString(Reader reader) throws IOException {337return readAvailableString(reader, false);338}339340private static String readAvailableString(Reader reader, boolean now) throws IOException {341StringBuilder builder = new StringBuilder();342int bytes;343if (now && !reader.ready()) {344return null;345}346do {347char[] buf = new char[256];348bytes = reader.read(buf);349builder.append(buf, 0, bytes);350} while (bytes == 256);351return builder.toString();352}353354private abstract static class ChatConnection implements Runnable {355public Exception exception;356357@Override358public void run() {359try (Socket socket = new Socket("localhost", listeningPort);360BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));361Writer writer = new FlushingWriter(new OutputStreamWriter(socket.getOutputStream()))) {362socket.setTcpNoDelay(true);363364run(socket, reader, writer);365} catch (Exception e) {366exception = e;367}368}369370public abstract void run(Socket socket, BufferedReader reader, Writer writer) throws Exception;371}372373private static class FlushingWriter extends Writer {374public final Writer delegate;375376private FlushingWriter(Writer delegate) {377this.delegate = delegate;378}379380@Override381public void write(char[] cbuf, int off, int len) throws IOException {382delegate.write(cbuf, off, len);383}384385@Override386public void flush() throws IOException {387delegate.flush();388}389390@Override391public void close() throws IOException {392delegate.close();393}394395@Override396public void write(String str) throws IOException {397super.write(str);398flush();399}400}401}402403404