1 /*
   2  * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /* @test
  25  * @summary Test socket-channel connection-state transitions
  26  * @library ..
  27  */
  28 
  29 import java.io.*;
  30 import java.net.*;
  31 import java.nio.*;
  32 import java.nio.channels.*;
  33 
  34 
  35 public class ConnectState {
  36 
  37     static PrintStream log = System.err;
  38 
  39     static String REMOTE_HOST = TestUtil.HOST;
  40     static int REMOTE_PORT = 7;                         // echo
  41     static InetSocketAddress remote;
  42 
  43     final static int ST_UNCONNECTED = 0;
  44     final static int ST_PENDING = 1;
  45     final static int ST_CONNECTED = 2;
  46     final static int ST_CLOSED = 3;
  47 
  48     static abstract class Test {
  49 
  50         abstract String go(SocketChannel sc) throws Exception;
  51 
  52         static void check(boolean test, String desc) throws Exception {
  53             if (!test)
  54                 throw new Exception("Incorrect state: " + desc);
  55         }
  56 
  57         static void check(SocketChannel sc, int state) throws Exception {
  58             switch (state) {
  59             case ST_UNCONNECTED:
  60                 check(!sc.isConnected(), "!isConnected");
  61                 check(!sc.isConnectionPending(), "!isConnectionPending");
  62                 check(sc.isOpen(), "isOpen");
  63                 break;
  64             case ST_PENDING:
  65                 check(!sc.isConnected(), "!isConnected");
  66                 check(sc.isConnectionPending(), "isConnectionPending");
  67                 check(sc.isOpen(), "isOpen");
  68                 break;
  69             case ST_CONNECTED:
  70                 check(sc.isConnected(), "isConnected");
  71                 check(!sc.isConnectionPending(), "!isConnectionPending");
  72                 check(sc.isOpen(), "isOpen");
  73                 break;
  74             case ST_CLOSED:
  75                 check(sc.isConnected(), "isConnected");
  76                 check(!sc.isConnectionPending(), "!isConnectionPending");
  77                 check(sc.isOpen(), "isOpen");
  78                 break;
  79             }
  80         }
  81 
  82         Test(String name, Class exception, int state) throws Exception {
  83             SocketChannel sc = SocketChannel.open();
  84             String note = null;
  85             try {
  86                 try {
  87                     note = go(sc);
  88                 } catch (Exception x) {
  89                     if (exception != null) {
  90                         if (exception.isInstance(x)) {
  91                             log.println(name + ": As expected: "
  92                                         + x);
  93                             check(sc, state);
  94                             return;
  95                         } else {
  96                             throw new Exception(name
  97                                                 + ": Incorrect exception",
  98                                                 x);
  99                         }
 100                     } else {
 101                         throw new Exception(name
 102                                             + ": Unexpected exception",
 103                                             x);
 104                     }
 105                 }
 106                 if (exception != null)
 107                     throw new Exception(name
 108                                         + ": Expected exception not thrown: "
 109                                         + exception);
 110                 check(sc, state);
 111                 log.println(name + ": Returned normally"
 112                             + ((note != null) ? ": " + note : ""));
 113             } finally {
 114                 if (sc.isOpen())
 115                     sc.close();
 116             }
 117         }
 118 
 119     }
 120 
 121     static void tests() throws Exception {
 122         log.println(remote);
 123 
 124         new Test("Read unconnected", NotYetConnectedException.class,
 125                  ST_UNCONNECTED) {
 126                 String go(SocketChannel sc) throws Exception {
 127                     ByteBuffer b = ByteBuffer.allocateDirect(1024);
 128                     sc.read(b);
 129                     return null;
 130                 }};
 131 
 132         new Test("Write unconnected", NotYetConnectedException.class,
 133                  ST_UNCONNECTED) {
 134                 String go(SocketChannel sc) throws Exception {
 135                     ByteBuffer b = ByteBuffer.allocateDirect(1024);
 136                     sc.write(b);
 137                     return null;
 138                 }};
 139 
 140         new Test("Simple connect", null, ST_CONNECTED) {
 141                 String go(SocketChannel sc) throws Exception {
 142                     sc.connect(remote);
 143                     return null;
 144                 }};
 145 
 146         new Test("Simple connect & finish", null, ST_CONNECTED) {
 147                 String go(SocketChannel sc) throws Exception {
 148                     sc.connect(remote);
 149                     if (!sc.finishConnect())
 150                         throw new Exception("finishConnect returned false");
 151                     return null;
 152                 }};
 153 
 154         new Test("Double connect",
 155                  AlreadyConnectedException.class, ST_CONNECTED) {
 156                 String go(SocketChannel sc) throws Exception {
 157                     sc.connect(remote);
 158                     sc.connect(remote);
 159                     return null;
 160                 }};
 161 
 162         new Test("Finish w/o start",
 163                  NoConnectionPendingException.class, ST_UNCONNECTED) {
 164                 String go(SocketChannel sc) throws Exception {
 165                     sc.finishConnect();
 166                     return null;
 167                 }};
 168 
 169         new Test("NB simple connect", null, ST_CONNECTED) {
 170                 String go(SocketChannel sc) throws Exception {
 171                     sc.configureBlocking(false);
 172                     sc.connect(remote);
 173                     int n = 0;
 174                     while (!sc.finishConnect()) {
 175                         Thread.sleep(10);
 176                         n++;
 177                     }
 178                     sc.finishConnect();         // Check redundant invocation
 179                     return ("Tries to finish = " + n);
 180                 }};
 181 
 182         new Test("NB double connect",
 183                  ConnectionPendingException.class, ST_PENDING) {
 184                 String go(SocketChannel sc) throws Exception {
 185                     sc.configureBlocking(false);
 186                     sc.connect(remote);
 187                     sc.connect(remote);
 188                     return null;
 189                 }};
 190 
 191         new Test("NB finish w/o start",
 192                  NoConnectionPendingException.class, ST_UNCONNECTED) {
 193                 String go(SocketChannel sc) throws Exception {
 194                     sc.configureBlocking(false);
 195                     sc.finishConnect();
 196                     return null;
 197                 }};
 198 
 199         new Test("NB connect, B finish", null, ST_CONNECTED) {
 200                 String go(SocketChannel sc) throws Exception {
 201                     sc.configureBlocking(false);
 202                     sc.connect(remote);
 203                     sc.configureBlocking(true);
 204                     sc.finishConnect();
 205                     return null;
 206                 }};
 207 
 208     }
 209 
 210     public static void main(String[] args) throws Exception {
 211         remote = new InetSocketAddress(InetAddress.getByName(REMOTE_HOST),
 212                                        REMOTE_PORT);
 213         tests();
 214     }
 215 
 216 }