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 SocketOption
  27  * @requires (os.family == "linux")
  28  * @requires !vm.graal.enabled
  29  * @library .. /test/lib
  30  * @build RsocketTest
  31  * @run main/othervm OptionsTest
  32  */
  33 
  34 import java.net.StandardProtocolFamily;
  35 import java.net.ServerSocket;
  36 import java.net.Socket;
  37 import java.net.SocketOption;
  38 import java.net.StandardSocketOptions;
  39 import java.util.Formatter;
  40 import java.util.Set;
  41 import jdk.net.RdmaSockets;
  42 import jdk.net.RdmaSocketOptions;
  43 
  44 import jtreg.SkippedException;
  45 
  46 public class OptionsTest {
  47 
  48     static class Test {
  49         Test(SocketOption<?> option, Object testValue) {
  50             this.option = option;
  51             this.testValue = testValue;
  52         }
  53         static Test create (SocketOption<?> option, Object testValue) {
  54             return new Test(option, testValue);
  55         }
  56         Object option;
  57         Object testValue;
  58     }
  59 
  60     // The tests set the option using the new API, read back the set value
  61     // which could be diferent, and then use the legacy get API to check
  62     // these values are the same
  63 
  64     static Test[] socketTests = new Test[] {
  65         Test.create(StandardSocketOptions.SO_SNDBUF, Integer.valueOf(10 * 100)),
  66         Test.create(StandardSocketOptions.SO_RCVBUF, Integer.valueOf(8 * 100)),
  67         Test.create(StandardSocketOptions.SO_REUSEADDR, Boolean.FALSE),
  68     };
  69 
  70     static Test[] serverSocketTests = new Test[] {
  71         Test.create(StandardSocketOptions.SO_RCVBUF, Integer.valueOf(8 * 100)),
  72         Test.create(StandardSocketOptions.SO_REUSEADDR, Boolean.FALSE),
  73     };
  74 
  75     static Test[] rdmaSocketOptionTests = new Test[] {
  76         Test.create(RdmaSocketOptions.RDMA_SQSIZE, Integer.valueOf(8 * 100)),
  77         Test.create(RdmaSocketOptions.RDMA_RQSIZE, Integer.valueOf(10 * 100)),
  78         Test.create(RdmaSocketOptions.RDMA_INLINE, Integer.valueOf(20 * 100)),
  79     };
  80 
  81     static void doSocketTests() throws Exception {
  82         try {
  83             Socket c = RdmaSockets.openSocket(StandardProtocolFamily.INET);
  84 
  85             for (int i = 0; i < socketTests.length; i++) {
  86                 Test test = socketTests[i];
  87                 c.setOption((SocketOption)test.option, test.testValue);
  88                 Object getval = c.getOption((SocketOption)test.option);
  89                 Object legacyget = legacyGetOption(Socket.class, c, test.option);
  90                 if (!getval.equals(legacyget)) {
  91                     Formatter f = new Formatter();
  92                     f.format("S Err %d: %s/%s", i, getval, legacyget);
  93                     throw new RuntimeException(f.toString());
  94                 }
  95             }
  96 
  97             for (int i = 0; i < rdmaSocketOptionTests.length; i++) {
  98                 Test test = rdmaSocketOptionTests[i];
  99                 c.setOption((SocketOption)test.option, test.testValue);
 100                 Object getval = c.getOption((SocketOption)test.option);
 101                 if (((Integer)getval).intValue() !=
 102                         ((Integer)test.testValue).intValue())
 103                     throw new RuntimeException("Test Failed");
 104             }
 105         } catch (Exception e) {
 106             e.printStackTrace();
 107             throw new RuntimeException("Test Failed");
 108         }
 109     }
 110 
 111     static void doServerSocketTests() throws Exception {
 112         try {
 113             ServerSocket srv = RdmaSockets.openServerSocket(
 114                 StandardProtocolFamily.INET);
 115             for (int i = 0; i < serverSocketTests.length; i++) {
 116                 Test test = serverSocketTests[i];
 117                 srv.setOption((SocketOption)test.option, test.testValue);
 118                 Object getval = srv.getOption((SocketOption)test.option);
 119                 Object legacyget = legacyGetOption(
 120                     ServerSocket.class, srv, test.option
 121                 );
 122                 if (!getval.equals(legacyget)) {
 123                     Formatter f = new Formatter();
 124                     f.format("SS Err %d: %s/%s", i, getval, legacyget);
 125                     throw new RuntimeException(f.toString());
 126                 }
 127             }
 128 
 129             for (int i = 0; i < rdmaSocketOptionTests.length; i++) {
 130                 Test test = rdmaSocketOptionTests[i];
 131                 srv.setOption((SocketOption)test.option, test.testValue);
 132                 Object getval = srv.getOption((SocketOption)test.option);
 133                 if (((Integer)getval).intValue() != 
 134                         ((Integer)test.testValue).intValue())
 135                     throw new RuntimeException("Test Failed");
 136             }
 137         } catch (Exception e) {
 138             e.printStackTrace();
 139             throw new RuntimeException("Test Failed");
 140         }
 141     }
 142 
 143     static Object legacyGetOption(
 144         Class<?> type, Object s, Object option)
 145 
 146         throws Exception
 147     {
 148         if (type.equals(Socket.class)) {
 149             Socket socket = (Socket)s;
 150             Set<SocketOption<?>> options = socket.supportedOptions();
 151 
 152             if (option.equals(StandardSocketOptions.SO_SNDBUF)) {
 153                 return Integer.valueOf(socket.getSendBufferSize());
 154             } else if (option.equals(StandardSocketOptions.SO_RCVBUF)) {
 155                 return Integer.valueOf(socket.getReceiveBufferSize());
 156             } else if (option.equals(StandardSocketOptions.SO_REUSEADDR)) {
 157                 return Boolean.valueOf(socket.getReuseAddress());
 158             } else if (option.equals(StandardSocketOptions.TCP_NODELAY)) {
 159                 return Boolean.valueOf(socket.getTcpNoDelay());
 160             } else {
 161                 throw new RuntimeException("unexecpted socket option");
 162             }
 163         } else if  (type.equals(ServerSocket.class)) {
 164             ServerSocket socket = (ServerSocket)s;
 165             Set<SocketOption<?>> options = socket.supportedOptions();
 166 
 167             if (option.equals(StandardSocketOptions.SO_RCVBUF)) {
 168                 return Integer.valueOf(socket.getReceiveBufferSize());
 169             } else if (option.equals(StandardSocketOptions.SO_REUSEADDR)) {
 170                 return Boolean.valueOf(socket.getReuseAddress());
 171             } else {
 172                 throw new RuntimeException("unexecpted socket option");
 173             }
 174         }
 175         throw new RuntimeException("unexecpted socket type");
 176     }
 177 
 178     public static void main(String args[]) throws Exception {
 179         if (!RsocketTest.isRsocketAvailable())
 180             throw new SkippedException("rsocket is not available");
 181 
 182         doSocketTests();
 183         doServerSocketTests();
 184     }
 185 }