test/jdk/java/net/SocketOption/OptionsTest.java
changeset 55102 59567035d279
parent 55081 dd321e3596c0
child 55226 ce8bab2c4185
equal deleted inserted replaced
55101:c41783eb76eb 55102:59567035d279
    36 import java.util.*;
    36 import java.util.*;
    37 import jdk.test.lib.net.IPSupport;
    37 import jdk.test.lib.net.IPSupport;
    38 
    38 
    39 public class OptionsTest {
    39 public class OptionsTest {
    40 
    40 
    41     static class Test {
    41     static class Test<T> {
    42         Test(SocketOption<?> option, Object testValue) {
    42         final SocketOption<T> option;
       
    43         final T value;
       
    44         Test(SocketOption<T> option, T value) {
    43             this.option = option;
    45             this.option = option;
    44             this.testValue = testValue;
    46             this.value = value;
    45         }
    47         }
    46         static Test create (SocketOption<?> option, Object testValue) {
    48         static <T> Test<T> create(SocketOption<T> option, T value) {
    47             return new Test(option, testValue);
    49             return new Test<T>(option, value);
    48         }
    50         }
    49         Object option;
    51 
    50         Object testValue;
       
    51     }
    52     }
    52 
    53 
    53     // The tests set the option using the new API, read back the set value
    54     // The tests set the option using the new API, read back the set value
    54     // which could be diferent, and then use the legacy get API to check
    55     // which could be diferent, and then use the legacy get API to check
    55     // these values are the same
    56     // these values are the same
    56 
    57 
    57     static Test[] socketTests = new Test[] {
    58     static Test<?>[] socketTests = new Test<?>[] {
    58         Test.create(StandardSocketOptions.SO_KEEPALIVE, Boolean.TRUE),
    59         Test.create(StandardSocketOptions.SO_KEEPALIVE, Boolean.TRUE),
    59         Test.create(StandardSocketOptions.SO_SNDBUF, Integer.valueOf(10 * 100)),
    60         Test.create(StandardSocketOptions.SO_SNDBUF, Integer.valueOf(10 * 100)),
    60         Test.create(StandardSocketOptions.SO_RCVBUF, Integer.valueOf(8 * 100)),
    61         Test.create(StandardSocketOptions.SO_RCVBUF, Integer.valueOf(8 * 100)),
    61         Test.create(StandardSocketOptions.SO_REUSEADDR, Boolean.FALSE),
    62         Test.create(StandardSocketOptions.SO_REUSEADDR, Boolean.FALSE),
    62         Test.create(StandardSocketOptions.SO_REUSEPORT, Boolean.FALSE),
    63         Test.create(StandardSocketOptions.SO_REUSEPORT, Boolean.FALSE),
    64         Test.create(StandardSocketOptions.IP_TOS, Integer.valueOf(0)),  // lower-bound
    65         Test.create(StandardSocketOptions.IP_TOS, Integer.valueOf(0)),  // lower-bound
    65         Test.create(StandardSocketOptions.IP_TOS, Integer.valueOf(100)),
    66         Test.create(StandardSocketOptions.IP_TOS, Integer.valueOf(100)),
    66         Test.create(StandardSocketOptions.IP_TOS, Integer.valueOf(255))  //upper-bound
    67         Test.create(StandardSocketOptions.IP_TOS, Integer.valueOf(255))  //upper-bound
    67     };
    68     };
    68 
    69 
    69     static Test[] serverSocketTests = new Test[] {
    70     static Test<?>[] serverSocketTests = new Test<?>[] {
    70         Test.create(StandardSocketOptions.SO_RCVBUF, Integer.valueOf(8 * 100)),
    71         Test.create(StandardSocketOptions.SO_RCVBUF, Integer.valueOf(8 * 100)),
    71         Test.create(StandardSocketOptions.SO_REUSEADDR, Boolean.FALSE),
    72         Test.create(StandardSocketOptions.SO_REUSEADDR, Boolean.FALSE),
    72         Test.create(StandardSocketOptions.SO_REUSEPORT, Boolean.FALSE),
    73         Test.create(StandardSocketOptions.SO_REUSEPORT, Boolean.FALSE),
    73         Test.create(StandardSocketOptions.IP_TOS, Integer.valueOf(0)),  // lower-bound
    74         Test.create(StandardSocketOptions.IP_TOS, Integer.valueOf(0)),  // lower-bound
    74         Test.create(StandardSocketOptions.IP_TOS, Integer.valueOf(100)),
    75         Test.create(StandardSocketOptions.IP_TOS, Integer.valueOf(100)),
    75         Test.create(StandardSocketOptions.IP_TOS, Integer.valueOf(255))  //upper-bound
    76         Test.create(StandardSocketOptions.IP_TOS, Integer.valueOf(255))  //upper-bound
    76     };
    77     };
    77 
    78 
    78     static Test[] dgSocketTests = new Test[] {
    79     static Test<?>[] datagramSocketTests = new Test<?>[] {
    79         Test.create(StandardSocketOptions.SO_SNDBUF, Integer.valueOf(10 * 100)),
    80         Test.create(StandardSocketOptions.SO_SNDBUF, Integer.valueOf(10 * 100)),
    80         Test.create(StandardSocketOptions.SO_RCVBUF, Integer.valueOf(8 * 100)),
    81         Test.create(StandardSocketOptions.SO_RCVBUF, Integer.valueOf(8 * 100)),
    81         Test.create(StandardSocketOptions.SO_REUSEADDR, Boolean.FALSE),
    82         Test.create(StandardSocketOptions.SO_REUSEADDR, Boolean.FALSE),
    82         Test.create(StandardSocketOptions.SO_REUSEPORT, Boolean.FALSE),
    83         Test.create(StandardSocketOptions.SO_REUSEPORT, Boolean.FALSE),
    83         Test.create(StandardSocketOptions.IP_TOS, Integer.valueOf(0)),  // lower-bound
    84         Test.create(StandardSocketOptions.IP_TOS, Integer.valueOf(0)),  // lower-bound
    84         Test.create(StandardSocketOptions.IP_TOS, Integer.valueOf(100)),
    85         Test.create(StandardSocketOptions.IP_TOS, Integer.valueOf(100)),
    85         Test.create(StandardSocketOptions.IP_TOS, Integer.valueOf(255))  //upper-bound
    86         Test.create(StandardSocketOptions.IP_TOS, Integer.valueOf(255))  //upper-bound
    86     };
    87     };
    87 
    88 
    88     static Test[] mcSocketTests = new Test[] {
    89     static Test<?>[] multicastSocketTests = new Test<?>[] {
    89         Test.create(StandardSocketOptions.IP_MULTICAST_IF, getNetworkInterface()),
    90         Test.create(StandardSocketOptions.IP_MULTICAST_IF, getNetworkInterface()),
    90         Test.create(StandardSocketOptions.IP_MULTICAST_TTL, Integer.valueOf(0)),   // lower-bound
    91         Test.create(StandardSocketOptions.IP_MULTICAST_TTL, Integer.valueOf(0)),   // lower-bound
    91         Test.create(StandardSocketOptions.IP_MULTICAST_TTL, Integer.valueOf(10)),
    92         Test.create(StandardSocketOptions.IP_MULTICAST_TTL, Integer.valueOf(10)),
    92         Test.create(StandardSocketOptions.IP_MULTICAST_TTL, Integer.valueOf(255)), //upper-bound
    93         Test.create(StandardSocketOptions.IP_MULTICAST_TTL, Integer.valueOf(255)), //upper-bound
    93         Test.create(StandardSocketOptions.IP_MULTICAST_LOOP, Boolean.TRUE)
    94         Test.create(StandardSocketOptions.IP_MULTICAST_LOOP, Boolean.TRUE)
    95 
    96 
    96     static NetworkInterface getNetworkInterface() {
    97     static NetworkInterface getNetworkInterface() {
    97         try {
    98         try {
    98             Enumeration<NetworkInterface> nifs = NetworkInterface.getNetworkInterfaces();
    99             Enumeration<NetworkInterface> nifs = NetworkInterface.getNetworkInterfaces();
    99             while (nifs.hasMoreElements()) {
   100             while (nifs.hasMoreElements()) {
   100                 NetworkInterface ni = (NetworkInterface)nifs.nextElement();
   101                 NetworkInterface ni = nifs.nextElement();
   101                 if (ni.supportsMulticast()) {
   102                 if (ni.supportsMulticast()) {
   102                     return ni;
   103                     return ni;
   103                 }
   104                 }
   104             }
   105             }
   105         } catch (Exception e) {
   106         } catch (Exception e) {
   106         }
   107         }
   107         return null;
   108         return null;
   108     }
   109     }
   109 
   110 
       
   111     static boolean okayToTest(Socket s, SocketOption<?> option) {
       
   112         if (option == StandardSocketOptions.SO_REUSEPORT) {
       
   113             // skip SO_REUSEPORT if option is not supported
       
   114             return s.supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT);
       
   115         }
       
   116         if (option == StandardSocketOptions.IP_TOS && s.isConnected()) {
       
   117             // skip IP_TOS if connected
       
   118             return false;
       
   119         }
       
   120         return true;
       
   121     }
       
   122 
       
   123     static <T> void testEqual(SocketOption<T> option, T value1, T value2) {
       
   124         if (!value1.equals(value2)) {
       
   125             throw new RuntimeException("Test of " + option.name() + " failed: "
       
   126                     + value1 + " != " + value2);
       
   127         }
       
   128     }
       
   129 
       
   130     static <T> void test(Socket s, Test<T> test) throws Exception {
       
   131         SocketOption<T> option = test.option;
       
   132         s.setOption(option, test.value);
       
   133         T value1 = s.getOption(test.option);
       
   134         T value2 = (T) legacyGetOption(Socket.class, s, test.option);
       
   135         testEqual(option, value1, value2);
       
   136     }
       
   137 
       
   138     static <T> void test(ServerSocket ss, Test<T> test) throws Exception {
       
   139         SocketOption<T> option = test.option;
       
   140         ss.setOption(option, test.value);
       
   141         T value1 = ss.getOption(test.option);
       
   142         T value2 = (T) legacyGetOption(ServerSocket.class, ss, test.option);
       
   143         testEqual(option, value1, value2);
       
   144     }
       
   145 
       
   146     static <T> void test(DatagramSocket ds, Test<T> test) throws Exception {
       
   147         SocketOption<T> option = test.option;
       
   148         ds.setOption(option, test.value);
       
   149         T value1 = ds.getOption(test.option);
       
   150         T value2 = (T) legacyGetOption(ds.getClass(), ds, test.option);
       
   151         testEqual(option, value1, value2);
       
   152     }
       
   153 
       
   154     @SuppressWarnings("try")
   110     static void doSocketTests() throws Exception {
   155     static void doSocketTests() throws Exception {
   111         try (
   156         // unconnected socket
   112             ServerSocket srv = new ServerSocket(0, 50, InetAddress.getLoopbackAddress());
   157         try (Socket s = new Socket()) {
   113             Socket c = new Socket(InetAddress.getLoopbackAddress(), srv.getLocalPort());
   158             for (Test<?> test : socketTests) {
   114             Socket s = srv.accept();
   159                 if (okayToTest(s, test.option)) {
   115         ) {
   160                     test(s, test);
   116             Set<SocketOption<?>> options = c.supportedOptions();
   161                 }
   117             boolean reuseport = options.contains(StandardSocketOptions.SO_REUSEPORT);
   162             }
   118             for (int i=0; i<socketTests.length; i++) {
   163         }
   119                 Test test = socketTests[i];
   164 
       
   165         // connected socket
       
   166         try (ServerSocket ss = new ServerSocket()) {
       
   167             var loopback = InetAddress.getLoopbackAddress();
       
   168             ss.bind(new InetSocketAddress(loopback, 0));
       
   169             try (Socket s1 = new Socket()) {
       
   170                 s1.connect(ss.getLocalSocketAddress());
       
   171                 try (Socket s2 = ss.accept()) {
       
   172                     for (Test<?> test : socketTests) {
       
   173                         if (okayToTest(s1, test.option)) {
       
   174                             test(s1, test);
       
   175                         }
       
   176                     }
       
   177                 }
       
   178             }
       
   179         }
       
   180     }
       
   181 
       
   182     static void doServerSocketTests() throws Exception {
       
   183         try (ServerSocket ss = new ServerSocket(0)) {
       
   184             Set<SocketOption<?>> options = ss.supportedOptions();
       
   185             boolean reuseport = options.contains(StandardSocketOptions.SO_REUSEPORT);
       
   186             for (Test<?> test : serverSocketTests) {
   120                 if (!(test.option == StandardSocketOptions.SO_REUSEPORT && !reuseport)) {
   187                 if (!(test.option == StandardSocketOptions.SO_REUSEPORT && !reuseport)) {
   121                     c.setOption((SocketOption)test.option, test.testValue);
   188                     test(ss, test);
   122                     Object getval = c.getOption((SocketOption)test.option);
   189                 }
   123                     Object legacyget = legacyGetOption(Socket.class, c,test.option);
   190             }
   124                     if (!getval.equals(legacyget)) {
   191         }
   125                         Formatter f = new Formatter();
   192     }
   126                         f.format("S Err %d: %s/%s", i, getval, legacyget);
   193 
   127                         throw new RuntimeException(f.toString());
   194     static void doDatagramSocketTests() throws Exception {
   128                     }
   195         try (DatagramSocket ds = new DatagramSocket(0)) {
   129                 }
   196             Set<SocketOption<?>> options = ds.supportedOptions();
   130             }
   197             boolean reuseport = options.contains(StandardSocketOptions.SO_REUSEPORT);
   131         }
   198             for (Test<?> test : datagramSocketTests) {
   132     }
       
   133 
       
   134     static void doDgSocketTests() throws Exception {
       
   135         try (
       
   136             DatagramSocket c = new DatagramSocket(0);
       
   137         ) {
       
   138             Set<SocketOption<?>> options = c.supportedOptions();
       
   139             boolean reuseport = options.contains(StandardSocketOptions.SO_REUSEPORT);
       
   140             for (int i=0; i<dgSocketTests.length; i++) {
       
   141                 Test test = dgSocketTests[i];
       
   142                 if (!(test.option == StandardSocketOptions.SO_REUSEPORT && !reuseport)) {
   199                 if (!(test.option == StandardSocketOptions.SO_REUSEPORT && !reuseport)) {
   143                     c.setOption((SocketOption)test.option, test.testValue);
   200                     test(ds, test);
   144                     Object getval = c.getOption((SocketOption)test.option);
   201                 }
   145                     Object legacyget = legacyGetOption(DatagramSocket.class, c,test.option);
   202             }
   146                     if (!getval.equals(legacyget)) {
   203         }
   147                         Formatter f = new Formatter();
   204     }
   148                         f.format("DG Err %d: %s/%s", i, getval, legacyget);
   205 
   149                         throw new RuntimeException(f.toString());
   206     static void doMulticastSocketTests() throws Exception {
   150                     }
   207         try (MulticastSocket ms = new MulticastSocket(0)) {
   151                 }
   208             for (Test<?> test : multicastSocketTests) {
   152             }
   209                 test(ms, test);
   153         }
   210             }
   154     }
   211         }
   155 
   212     }
   156     static void doMcSocketTests() throws Exception {
   213 
   157         try (
   214     static Object legacyGetOption(Class<?> type, Object s, Object option) throws Exception {
   158             MulticastSocket c = new MulticastSocket(0);
       
   159         ) {
       
   160             for (int i=0; i<mcSocketTests.length; i++) {
       
   161                 Test test = mcSocketTests[i];
       
   162                 c.setOption((SocketOption)test.option, test.testValue);
       
   163                 Object getval = c.getOption((SocketOption)test.option);
       
   164                 Object legacyget = legacyGetOption(MulticastSocket.class, c,test.option);
       
   165                 if (!getval.equals(legacyget)) {
       
   166                     Formatter f = new Formatter();
       
   167                     f.format("MC Err %d: %s/%s", i, getval, legacyget);
       
   168                     throw new RuntimeException(f.toString());
       
   169                 }
       
   170             }
       
   171         }
       
   172     }
       
   173 
       
   174     static void doServerSocketTests() throws Exception {
       
   175         try (
       
   176             ServerSocket c = new ServerSocket(0);
       
   177         ) {
       
   178             Set<SocketOption<?>> options = c.supportedOptions();
       
   179             boolean reuseport = options.contains(StandardSocketOptions.SO_REUSEPORT);
       
   180             for (int i=0; i<serverSocketTests.length; i++) {
       
   181                 Test test = serverSocketTests[i];
       
   182                 if (!(test.option == StandardSocketOptions.SO_REUSEPORT && !reuseport)) {
       
   183                     c.setOption((SocketOption)test.option, test.testValue);
       
   184                     Object getval = c.getOption((SocketOption)test.option);
       
   185                     Object legacyget = legacyGetOption(
       
   186                         ServerSocket.class, c, test.option
       
   187                     );
       
   188                     if (!getval.equals(legacyget)) {
       
   189                         Formatter f = new Formatter();
       
   190                         f.format("SS Err %d: %s/%s", i, getval, legacyget);
       
   191                         throw new RuntimeException(f.toString());
       
   192                     }
       
   193                 }
       
   194             }
       
   195         }
       
   196     }
       
   197 
       
   198     static Object legacyGetOption(
       
   199         Class<?> type, Object s, Object option)
       
   200 
       
   201         throws Exception
       
   202     {
       
   203         if (type.equals(Socket.class)) {
   215         if (type.equals(Socket.class)) {
   204             Socket socket = (Socket)s;
   216             Socket socket = (Socket)s;
   205             Set<SocketOption<?>> options = socket.supportedOptions();
   217             Set<SocketOption<?>> options = socket.supportedOptions();
   206             boolean reuseport = options.contains(StandardSocketOptions.SO_REUSEPORT);
   218             boolean reuseport = options.contains(StandardSocketOptions.SO_REUSEPORT);
   207 
   219 
   289 
   301 
   290     public static void main(String args[]) throws Exception {
   302     public static void main(String args[]) throws Exception {
   291         IPSupport.throwSkippedExceptionIfNonOperational();
   303         IPSupport.throwSkippedExceptionIfNonOperational();
   292         doSocketTests();
   304         doSocketTests();
   293         doServerSocketTests();
   305         doServerSocketTests();
   294         doDgSocketTests();
   306         doDatagramSocketTests();
   295         doMcSocketTests();
   307         doMulticastSocketTests();
   296     }
   308     }
   297 
   309 
   298     // Reflectively access jdk.net.Sockets.getOption so that the test can run
   310     // Reflectively access jdk.net.Sockets.getOption so that the test can run
   299     // without the jdk.net module.
   311     // without the jdk.net module.
   300     static Object getServerSocketTrafficClass(ServerSocket ss) throws Exception {
   312     static Object getServerSocketTrafficClass(ServerSocket ss) throws Exception {