1 /*
   2  * Copyright (c) 2000, 2017, 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 socketchannel vector IO (use -Dseed=X to set PRNG seed)
  26  * @library .. /test/lib
  27  * @build jdk.test.lib.RandomFactory
  28  * @run main VectorIO
  29  * @key randomness
  30  */
  31 
  32 import java.io.*;
  33 import java.net.*;
  34 import java.nio.*;
  35 import java.nio.channels.*;
  36 import java.util.*;
  37 import jdk.test.lib.RandomFactory;
  38 
  39 public class VectorIO {
  40 
  41     private static Random generator = RandomFactory.getRandom();
  42 
  43     static int testSize;
  44 
  45     public static void main(String[] args) throws Exception {
  46         testSize = 1;
  47         runTest();
  48         for(int i=15; i<18; i++) {
  49             testSize = i;
  50             runTest();
  51         }
  52     }
  53 
  54     static void runTest() throws Exception {
  55         System.err.println("Length " + testSize);
  56         Server sv = new Server(testSize);
  57         sv.start();
  58         bufferTest(sv.port());
  59         if (sv.finish(8000) == 0)
  60             throw new Exception("Failed: Length = " + testSize);
  61     }
  62 
  63     static void bufferTest(int port) throws Exception {
  64         ByteBuffer[] bufs = new ByteBuffer[testSize];
  65         long total = 0L;
  66         for(int i=0; i<testSize; i++) {
  67             String source = "buffer" + i;
  68             if (generator.nextBoolean())
  69                 bufs[i] = ByteBuffer.allocateDirect(source.length());
  70             else
  71                 bufs[i] = ByteBuffer.allocate(source.length());
  72 
  73             bufs[i].put(source.getBytes("8859_1"));
  74             bufs[i].flip();
  75             total += bufs[i].remaining();
  76         }
  77 
  78         // Get a connection to the server
  79         InetAddress lh = InetAddress.getLocalHost();
  80         InetSocketAddress isa = new InetSocketAddress(lh, port);
  81         SocketChannel sc = SocketChannel.open();
  82         sc.connect(isa);
  83         sc.configureBlocking(generator.nextBoolean());
  84 
  85         // Write the data out
  86         long rem = total;
  87         while (rem > 0L) {
  88             long bytesWritten = sc.write(bufs);
  89             if (bytesWritten == 0) {
  90                 if (sc.isBlocking()) {
  91                     throw new RuntimeException("write did not block");
  92                 } else {
  93                     System.err.println("Non-blocking write() wrote zero bytes");
  94                 }
  95                 Thread.sleep(50);
  96             } else {
  97                 rem -= bytesWritten;
  98             }
  99         }
 100 
 101         // Clean up
 102         sc.close();
 103     }
 104 
 105     static class Server
 106         extends TestThread
 107     {
 108         final int testSize;
 109         final ServerSocketChannel ssc;
 110 
 111         Server(int testSize) throws IOException {
 112             super("Server " + testSize);
 113             this.testSize = testSize;
 114             this.ssc = ServerSocketChannel.open().bind(new InetSocketAddress(0));
 115         }
 116 
 117         int port() {
 118             return ssc.socket().getLocalPort();
 119         }
 120 
 121         void go() throws Exception {
 122             bufferTest();
 123         }
 124 
 125         void bufferTest() throws Exception {
 126             long total = 0L;
 127             ByteBuffer[] bufs = new ByteBuffer[testSize];
 128             for(int i=0; i<testSize; i++) {
 129                 String source = "buffer" + i;
 130                 if (generator.nextBoolean())
 131                     bufs[i] = ByteBuffer.allocateDirect(source.length());
 132                 else
 133                     bufs[i] = ByteBuffer.allocate(source.length());
 134                 total += bufs[i].capacity();
 135             }
 136 
 137             // Get a connection from client
 138             SocketChannel sc = null;
 139 
 140             try {
 141 
 142                 ssc.configureBlocking(false);
 143 
 144                 for (;;) {
 145                     sc = ssc.accept();
 146                     if (sc != null) {
 147                         System.err.println("accept() succeeded");
 148                         break;
 149                     }
 150                     Thread.sleep(50);
 151                 }
 152 
 153                 sc.configureBlocking(generator.nextBoolean());
 154 
 155                 // Read data into multiple buffers
 156                 long avail = total;
 157                 while (avail > 0) {
 158                     long bytesRead = sc.read(bufs);
 159                     if (bytesRead < 0)
 160                         break;
 161                     if (bytesRead == 0) {
 162                         if (sc.isBlocking()) {
 163                             throw new RuntimeException("read did not block");
 164                         } else {
 165                             System.err.println
 166                                 ("Non-blocking read() read zero bytes");
 167                         }
 168                         Thread.sleep(50);
 169                     }
 170                     avail -= bytesRead;
 171                 }
 172 
 173                 // Check results
 174                 for(int i=0; i<testSize; i++) {
 175                     String expected = "buffer" + i;
 176                     bufs[i].flip();
 177                     int size = bufs[i].capacity();
 178                     byte[] data = new byte[size];
 179                     for(int j=0; j<size; j++)
 180                         data[j] = bufs[i].get();
 181                     String message = new String(data, "8859_1");
 182                     if (!message.equals(expected))
 183                         throw new Exception("Wrong data: Got "
 184                                             + message + ", expected "
 185                                             + expected);
 186                 }
 187 
 188             } finally {
 189                 // Clean up
 190                 ssc.close();
 191                 if (sc != null)
 192                     sc.close();
 193             }
 194 
 195         }
 196 
 197     }
 198 
 199 }