Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/java/nio/channels/SocketChannel/ConnectState.java
38828 views
/*1* Copyright (c) 2001, 2012, 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*/2223/* @test24* @summary Test socket-channel connection-state transitions25* @library ..26*/2728import java.io.*;29import java.net.*;30import java.nio.*;31import java.nio.channels.*;32import java.util.Arrays;33import java.util.Collection;34import java.util.Collections;35import java.util.HashSet;363738public class ConnectState {3940static PrintStream log = System.err;4142static InetSocketAddress remote;4344final static int ST_UNCONNECTED = 0;45final static int ST_PENDING = 1;46final static int ST_CONNECTED = 2;47final static int ST_CLOSED = 3;48final static int ST_PENDING_OR_CONNECTED = 4;49// NO exceptions expected50final static Collection<Class<?>> NONE = Collections.emptySet();5152// make a set of expected exception.53static Collection<Class<?>> expectedExceptions(Class<?>... expected) {54final Collection<Class<?>> exceptions;55if (expected.length == 0) {56exceptions = NONE;57} else if (expected.length == 1) {58assert expected[0] != null;59exceptions = Collections.<Class<?>>singleton(expected[0]);60} else {61exceptions = new HashSet<>(Arrays.asList(expected));62}63return exceptions;64}6566static abstract class Test {6768abstract String go(SocketChannel sc) throws Exception;6970static void check(boolean test, String desc) throws Exception {71if (!test)72throw new Exception("Incorrect state: " + desc);73}7475static void check(SocketChannel sc, int state) throws Exception {76switch (state) {77case ST_UNCONNECTED:78check(!sc.isConnected(), "!isConnected");79check(!sc.isConnectionPending(), "!isConnectionPending");80check(sc.isOpen(), "isOpen");81break;82case ST_PENDING:83check(!sc.isConnected(), "!isConnected");84check(sc.isConnectionPending(), "isConnectionPending");85check(sc.isOpen(), "isOpen");86break;87case ST_CONNECTED:88check(sc.isConnected(), "isConnected");89check(!sc.isConnectionPending(), "!isConnectionPending");90check(sc.isOpen(), "isOpen");91break;92case ST_CLOSED:93check(sc.isConnected(), "isConnected");94check(!sc.isConnectionPending(), "!isConnectionPending");95check(sc.isOpen(), "isOpen");96break;97case ST_PENDING_OR_CONNECTED:98check(sc.isConnected() || sc.isConnectionPending(),99"isConnected || isConnectionPending");100check(sc.isOpen(), "isOpen");101break;102}103}104105Test(String name, Class<?> exception, int state) throws Exception {106this(name, expectedExceptions(exception), state);107}108109// On some architecture we may need to accept several exceptions.110// For instance on Solaris, when using a server colocated on the111// machine we cannot guarantee that we will get a112// ConnectionPendingException when connecting twice on the same113// non-blocking socket. We may instead get a an114// AlreadyConnectedException, which is also valid: it simply means115// that the first connection has been immediately accepted.116Test(String name, Collection<Class<?>> exceptions, int state)117throws Exception {118SocketChannel sc = SocketChannel.open();119String note;120try {121try {122note = go(sc);123} catch (Exception x) {124Class<?> expectedExceptionClass = null;125for (Class<?> exception : exceptions) {126if (exception.isInstance(x)) {127log.println(name + ": As expected: "128+ x);129expectedExceptionClass = exception;130check(sc, state);131break;132}133}134if (expectedExceptionClass == null135&& !exceptions.isEmpty()) {136// we had an exception, but it's not of the set of137// exceptions we expected.138throw new Exception(name139+ ": Incorrect exception",140x);141} else if (exceptions.isEmpty()) {142// we didn't expect any exception143throw new Exception(name144+ ": Unexpected exception",145x);146}147// if we reach here, we have our expected exception148assert expectedExceptionClass != null;149return;150}151if (!exceptions.isEmpty()) {152throw new Exception(name153+ ": Expected exception not thrown: "154+ exceptions.iterator().next());155}156check(sc, state);157log.println(name + ": Returned normally"158+ ((note != null) ? ": " + note : ""));159} finally {160if (sc.isOpen())161sc.close();162}163}164165}166167static void tests() throws Exception {168log.println(remote);169170new Test("Read unconnected", NotYetConnectedException.class,171ST_UNCONNECTED) {172@Override173String go(SocketChannel sc) throws Exception {174ByteBuffer b = ByteBuffer.allocateDirect(1024);175sc.read(b);176return null;177}};178179new Test("Write unconnected", NotYetConnectedException.class,180ST_UNCONNECTED) {181@Override182String go(SocketChannel sc) throws Exception {183ByteBuffer b = ByteBuffer.allocateDirect(1024);184sc.write(b);185return null;186}};187188new Test("Simple connect", NONE, ST_CONNECTED) {189@Override190String go(SocketChannel sc) throws Exception {191sc.connect(remote);192return null;193}};194195new Test("Simple connect & finish", NONE, ST_CONNECTED) {196@Override197String go(SocketChannel sc) throws Exception {198sc.connect(remote);199if (!sc.finishConnect())200throw new Exception("finishConnect returned false");201return null;202}};203204new Test("Double connect",205AlreadyConnectedException.class, ST_CONNECTED) {206@Override207String go(SocketChannel sc) throws Exception {208sc.connect(remote);209sc.connect(remote);210return null;211}};212213new Test("Finish w/o start",214NoConnectionPendingException.class, ST_UNCONNECTED) {215@Override216String go(SocketChannel sc) throws Exception {217sc.finishConnect();218return null;219}};220221// Note: using our local EchoServer rather than echo on a distant222// host - we see that Tries to finish = 0 (instead of ~ 18).223new Test("NB simple connect", NONE, ST_CONNECTED) {224@Override225String go(SocketChannel sc) throws Exception {226sc.configureBlocking(false);227sc.connect(remote);228int n = 0;229while (!sc.finishConnect()) {230Thread.sleep(10);231n++;232}233sc.finishConnect(); // Check redundant invocation234return ("Tries to finish = " + n);235}};236237// Note: using our local EchoServer rather than echo on a distant238// host - we cannot guarantee that this test will get a239// a ConnectionPendingException: it may get an240// AlreadyConnectedException, so we should allow for both.241new Test("NB double connect",242expectedExceptions(ConnectionPendingException.class,243AlreadyConnectedException.class),244ST_PENDING_OR_CONNECTED) {245@Override246String go(SocketChannel sc) throws Exception {247sc.configureBlocking(false);248sc.connect(remote);249sc.connect(remote);250return null;251}};252253new Test("NB finish w/o start",254NoConnectionPendingException.class, ST_UNCONNECTED) {255@Override256String go(SocketChannel sc) throws Exception {257sc.configureBlocking(false);258sc.finishConnect();259return null;260}};261262new Test("NB connect, B finish", NONE, ST_CONNECTED) {263@Override264String go(SocketChannel sc) throws Exception {265sc.configureBlocking(false);266sc.connect(remote);267sc.configureBlocking(true);268sc.finishConnect();269return null;270}};271272}273274public static void main(String[] args) throws Exception {275try (TestServers.EchoServer echoServer276= TestServers.EchoServer.startNewServer(500)) {277remote = new InetSocketAddress(echoServer.getAddress(),278echoServer.getPort());279tests();280}281}282283}284285286