1 /*
   2  * Copyright (c) 2018, 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  * @bug 8195160
  26  * @summary Unit test for server-socket channels
  27  * @requires (os.family == "linux")
  28  * @library .. /test/lib /test/jdk/java/nio/channels
  29  * @build RsocketTest
  30  * @run main/othervm Basic
  31  */
  32 
  33 import java.io.IOException;
  34 import java.io.PrintStream;
  35 import java.net.InetAddress;
  36 import java.net.InetSocketAddress;
  37 import java.net.StandardProtocolFamily;
  38 import java.nio.ByteBuffer;
  39 import java.nio.channels.ServerSocketChannel;
  40 import java.nio.channels.SocketChannel;
  41 import java.util.Random;
  42 import jdk.net.RdmaSockets;
  43 
  44 import jtreg.SkippedException;
  45 
  46 public class Basic {
  47 
  48     static PrintStream log = System.err;
  49 
  50     static class Server
  51         extends TestThread
  52     {
  53         ServerSocketChannel ssc;
  54         boolean block;
  55 
  56         Server(ServerSocketChannel ssc, boolean block) {
  57             super("Server", Basic.log);
  58             this.ssc = ssc;
  59             this.block = block;
  60         }
  61 
  62         void go() throws Exception {
  63             log.println("Server: Listening "
  64                         + (block ? "(blocking)" : "(non-blocking)"));
  65             if (!block)
  66                 ssc.configureBlocking(false);
  67             log.println("  " + ssc);
  68             SocketChannel sc = null;
  69             for (;;) {
  70                 sc = ssc.accept();
  71                 if (sc != null) {
  72                     break;
  73                 }
  74                 log.println("Server: Sleeping...");
  75                 Thread.sleep(50);
  76             }
  77             log.println("Server: Accepted " + sc);
  78             ByteBuffer bb = ByteBuffer.allocateDirect(100);
  79             if (sc.read(bb) != 1)
  80                 throw new Exception("Read failed");
  81             bb.flip();
  82             byte b = bb.get();
  83             log.println("Server: Read " + b + ", writing " + (b + 1));
  84             bb.clear();
  85             bb.put((byte)43);
  86             bb.flip();
  87             if (sc.write(bb) != 1)
  88                 throw new Exception("Write failed");
  89             sc.close();
  90             ssc.close();
  91             log.println("Server: Finished");
  92         }
  93 
  94     }
  95 
  96     static class Client
  97         extends TestThread
  98     {
  99         int port;
 100         boolean dally;
 101 
 102         Client(int port, boolean block) {
 103             super("Client", Basic.log);
 104             this.port = port;
 105             this.dally = !block;
 106         }
 107 
 108         public void go() throws Exception {
 109             if (dally)
 110                 Thread.sleep(200);
 111             InetSocketAddress isa
 112                 = new InetSocketAddress(InetAddress.getLocalHost(), port);
 113             log.println("Client: Connecting to " + isa);
 114             SocketChannel sc = RdmaSockets.openSocketChannel(
 115                 StandardProtocolFamily.INET);
 116             sc.connect(isa);
 117             log.println("Client: Connected");
 118             ByteBuffer bb = ByteBuffer.allocateDirect(512);
 119             bb.put((byte)42).flip();
 120             log.println("Client: Writing " + bb.get(0));
 121             if (sc.write(bb) != 1)
 122                 throw new Exception("Write failed");
 123             bb.clear();
 124             if (sc.read(bb) != 1)
 125                 throw new Exception("Read failed");
 126             bb.flip();
 127             if (bb.get() != 43)
 128                 throw new Exception("Read " + bb.get(bb.position() - 1));
 129             log.println("Client: Read " + bb.get(0));
 130             sc.close();
 131             log.println("Client: Finished");
 132         }
 133 
 134     }
 135 
 136     static void test(boolean block) throws Exception {
 137         ServerSocketChannel ssc = RdmaSockets.openServerSocketChannel(
 138             StandardProtocolFamily.INET);
 139         ssc.socket().setReuseAddress(true);
 140         InetAddress lh = InetAddress.getLocalHost();
 141         int port;
 142         Random r = new Random();
 143         for (;;) {
 144             port = r.nextInt((1 << 16) - 1024) + 1024;
 145             InetSocketAddress isa = new InetSocketAddress(lh, port);
 146             try {
 147                 ssc.socket().bind(isa);
 148             } catch (IOException x) {
 149                 continue;
 150             }
 151             break;
 152         }
 153 
 154         Server server = new Server(ssc, block);
 155         Client client = new Client(port, block);
 156         server.start();
 157         client.start();
 158         if ((server.finish(0) & client.finish(0)) == 0)
 159             throw new Exception("Failure");
 160         log.println();
 161     }
 162 
 163     public static void main(String[] args) throws Exception {
 164         if (!RsocketTest.isRsocketAvailable())
 165             throw new SkippedException("rsocket is not available");
 166 
 167         log.println();
 168         test(true);
 169         test(false);
 170     }
 171 
 172 }