test/jdk/java/net/httpclient/websocket/Exceptionally.java
branchhttp-client-branch
changeset 56045 5c6e3b76d2ad
parent 56024 de352132c7e8
child 56046 75d9bc7febf5
equal deleted inserted replaced
56044:a8423a38386e 56045:5c6e3b76d2ad
    30 import jdk.incubator.http.WebSocket;
    30 import jdk.incubator.http.WebSocket;
    31 import org.testng.annotations.Test;
    31 import org.testng.annotations.Test;
    32 
    32 
    33 import java.io.IOException;
    33 import java.io.IOException;
    34 import java.nio.ByteBuffer;
    34 import java.nio.ByteBuffer;
       
    35 import java.nio.CharBuffer;
       
    36 import java.nio.channels.SocketChannel;
       
    37 import java.nio.charset.StandardCharsets;
    35 import java.util.concurrent.CompletableFuture;
    38 import java.util.concurrent.CompletableFuture;
    36 import java.util.concurrent.CompletionException;
    39 import java.util.concurrent.CompletionException;
       
    40 import java.util.concurrent.TimeUnit;
       
    41 import java.util.concurrent.TimeoutException;
    37 
    42 
    38 import static jdk.incubator.http.HttpClient.newHttpClient;
    43 import static jdk.incubator.http.HttpClient.newHttpClient;
    39 import static jdk.incubator.http.WebSocket.NORMAL_CLOSURE;
    44 import static jdk.incubator.http.WebSocket.NORMAL_CLOSURE;
    40 import static org.testng.Assert.assertThrows;
    45 import static org.testng.Assert.assertThrows;
    41 
    46 
    42 public class Exceptionally {
    47 public class Exceptionally {
    43 
    48 
    44     static final Class<NullPointerException> NPE = NullPointerException.class;
    49     private static final Class<NullPointerException> NPE
       
    50             = NullPointerException.class;
       
    51     private static final Class<IllegalArgumentException> IAE
       
    52             = IllegalArgumentException.class;
    45 
    53 
    46     @Test
    54     @Test
    47     public void testNull() throws IOException {
    55     public void testNull() throws IOException {
    48         try (DummyWebSocketServer server = new DummyWebSocketServer()) {
    56         try (DummyWebSocketServer server = new DummyWebSocketServer()) {
    49             server.open();
    57             server.open();
    50             WebSocket ws = newHttpClient()
    58             WebSocket ws = newHttpClient()
    51                     .newWebSocketBuilder()
    59                     .newWebSocketBuilder()
    52                     .buildAsync(server.getURI(), new WebSocket.Listener() { })
    60                     .buildAsync(server.getURI(), new WebSocket.Listener() { })
    53                     .join();
    61                     .join();
    54 
    62 
       
    63             assertThrows(NPE, () -> ws.sendText(null, false));
       
    64             assertThrows(NPE, () -> ws.sendText(null, true));
       
    65             assertThrows(NPE, () -> ws.sendBinary(null, false));
       
    66             assertThrows(NPE, () -> ws.sendBinary(null, true));
    55             assertThrows(NPE, () -> ws.sendPing(null));
    67             assertThrows(NPE, () -> ws.sendPing(null));
    56             assertThrows(NPE, () -> ws.sendPong(null));
    68             assertThrows(NPE, () -> ws.sendPong(null));
    57             assertThrows(NPE, () -> ws.sendClose(NORMAL_CLOSURE, null));
    69             assertThrows(NPE, () -> ws.sendClose(NORMAL_CLOSURE, null));
    58 
    70         }
    59             // ... add more NPE scenarios
       
    60         }
       
    61     }
       
    62 
       
    63     private static String stringWithNBytes(int n) {
       
    64         StringBuilder sb = new StringBuilder(n);
       
    65         for (int i = 0; i < n; i++)
       
    66             sb.append("A");
       
    67         return sb.toString();
       
    68     }
    71     }
    69 
    72 
    70     @Test
    73     @Test
    71     public void testIllegalArgument() throws IOException {
    74     public void testIllegalArgument() throws IOException {
    72         try (DummyWebSocketServer server = new DummyWebSocketServer()) {
    75         try (DummyWebSocketServer server = new DummyWebSocketServer()) {
    77                     .join();
    80                     .join();
    78 
    81 
    79             assertIAE(ws.sendPing(ByteBuffer.allocate(126)));
    82             assertIAE(ws.sendPing(ByteBuffer.allocate(126)));
    80             assertIAE(ws.sendPing(ByteBuffer.allocate(127)));
    83             assertIAE(ws.sendPing(ByteBuffer.allocate(127)));
    81             assertIAE(ws.sendPing(ByteBuffer.allocate(128)));
    84             assertIAE(ws.sendPing(ByteBuffer.allocate(128)));
    82             assertIAE(ws.sendPing(ByteBuffer.allocate(150)));
    85             assertIAE(ws.sendPing(ByteBuffer.allocate(129)));
       
    86             assertIAE(ws.sendPing(ByteBuffer.allocate(256)));
    83 
    87 
    84             assertIAE(ws.sendPong(ByteBuffer.allocate(126)));
    88             assertIAE(ws.sendPong(ByteBuffer.allocate(126)));
    85             assertIAE(ws.sendPong(ByteBuffer.allocate(127)));
    89             assertIAE(ws.sendPong(ByteBuffer.allocate(127)));
    86             assertIAE(ws.sendPong(ByteBuffer.allocate(128)));
    90             assertIAE(ws.sendPong(ByteBuffer.allocate(128)));
    87             assertIAE(ws.sendPong(ByteBuffer.allocate(150)));
    91             assertIAE(ws.sendPong(ByteBuffer.allocate(129)));
       
    92             assertIAE(ws.sendPong(ByteBuffer.allocate(256)));
       
    93 
       
    94             assertIAE(ws.sendText(incompleteString(), true));
       
    95             assertIAE(ws.sendText(incompleteString(), false));
       
    96             assertIAE(ws.sendText(malformedString(), true));
       
    97             assertIAE(ws.sendText(malformedString(), false));
    88 
    98 
    89             assertIAE(ws.sendClose(NORMAL_CLOSURE, stringWithNBytes(124)));
    99             assertIAE(ws.sendClose(NORMAL_CLOSURE, stringWithNBytes(124)));
    90             assertIAE(ws.sendClose(NORMAL_CLOSURE, stringWithNBytes(150)));
   100             assertIAE(ws.sendClose(NORMAL_CLOSURE, stringWithNBytes(125)));
    91             assertIAE(ws.sendClose(NORMAL_CLOSURE - 1, "a reason"));
   101             assertIAE(ws.sendClose(NORMAL_CLOSURE, stringWithNBytes(128)));
    92 
   102             assertIAE(ws.sendClose(NORMAL_CLOSURE, stringWithNBytes(256)));
    93             // ... add more CF complete exceptionally scenarios
   103             assertIAE(ws.sendClose(NORMAL_CLOSURE, stringWithNBytes(257)));
    94         }
   104             assertIAE(ws.sendClose(NORMAL_CLOSURE, stringWith2NBytes((123 / 2) + 1)));
    95     }
   105             assertIAE(ws.sendClose(NORMAL_CLOSURE, malformedString()));
    96 
   106             assertIAE(ws.sendClose(NORMAL_CLOSURE, incompleteString()));
    97     @Test
   107 
    98     public void testIllegalState() throws IOException {
   108             assertIAE(ws.sendClose(-2, "a reason"));
       
   109             assertIAE(ws.sendClose(-1, "a reason"));
       
   110             assertIAE(ws.sendClose(0, "a reason"));
       
   111             assertIAE(ws.sendClose(1, "a reason"));
       
   112             assertIAE(ws.sendClose(500, "a reason"));
       
   113             assertIAE(ws.sendClose(998, "a reason"));
       
   114             assertIAE(ws.sendClose(999, "a reason"));
       
   115             assertIAE(ws.sendClose(1002, "a reason"));
       
   116             assertIAE(ws.sendClose(1003, "a reason"));
       
   117             assertIAE(ws.sendClose(1006, "a reason"));
       
   118             assertIAE(ws.sendClose(1007, "a reason"));
       
   119             assertIAE(ws.sendClose(1009, "a reason"));
       
   120             assertIAE(ws.sendClose(1010, "a reason"));
       
   121             assertIAE(ws.sendClose(1012, "a reason"));
       
   122             assertIAE(ws.sendClose(1013, "a reason"));
       
   123             assertIAE(ws.sendClose(1015, "a reason"));
       
   124             assertIAE(ws.sendClose(5000, "a reason"));
       
   125             assertIAE(ws.sendClose(32768, "a reason"));
       
   126             assertIAE(ws.sendClose(65535, "a reason"));
       
   127             assertIAE(ws.sendClose(65536, "a reason"));
       
   128             assertIAE(ws.sendClose(Integer.MAX_VALUE, "a reason"));
       
   129             assertIAE(ws.sendClose(Integer.MIN_VALUE, "a reason"));
       
   130 
       
   131             assertThrows(IAE, () -> ws.request(Integer.MIN_VALUE));
       
   132             assertThrows(IAE, () -> ws.request(-1));
       
   133             assertThrows(IAE, () -> ws.request(0));
       
   134         }
       
   135     }
       
   136 
       
   137     @Test
       
   138     public void testIllegalStateOutstanding1() throws Exception {
       
   139         try (DummyWebSocketServer server = notReadingServer()) {
       
   140             server.open();
       
   141             WebSocket ws = newHttpClient()
       
   142                     .newWebSocketBuilder()
       
   143                     .buildAsync(server.getURI(), new WebSocket.Listener() { })
       
   144                     .join();
       
   145 
       
   146             ByteBuffer data = ByteBuffer.allocate(65536);
       
   147             for (int i = 0; ; i++) {
       
   148                 System.out.println("cycle #" + i);
       
   149                 try {
       
   150                     ws.sendBinary(data, true).get(10, TimeUnit.SECONDS);
       
   151                     data.clear();
       
   152                 } catch (TimeoutException e) {
       
   153                     break;
       
   154                 }
       
   155             }
       
   156             assertISE(ws.sendBinary(ByteBuffer.allocate(0), true));
       
   157             assertISE(ws.sendText("", true));
       
   158         }
       
   159     }
       
   160 
       
   161     @Test
       
   162     public void testIllegalStateOutstanding2() throws Exception {
       
   163         try (DummyWebSocketServer server = notReadingServer()) {
       
   164             server.open();
       
   165             WebSocket ws = newHttpClient()
       
   166                     .newWebSocketBuilder()
       
   167                     .buildAsync(server.getURI(), new WebSocket.Listener() { })
       
   168                     .join();
       
   169 
       
   170             CharBuffer data = CharBuffer.allocate(65536);
       
   171             for (int i = 0; ; i++) {
       
   172                 System.out.println("cycle #" + i);
       
   173                 try {
       
   174                     ws.sendText(data, true).get(10, TimeUnit.SECONDS);
       
   175                     data.clear();
       
   176                 } catch (TimeoutException e) {
       
   177                     break;
       
   178                 }
       
   179             }
       
   180             assertISE(ws.sendText("", true));
       
   181             assertISE(ws.sendBinary(ByteBuffer.allocate(0), true));
       
   182         }
       
   183     }
       
   184 
       
   185     private static DummyWebSocketServer notReadingServer() {
       
   186         return new DummyWebSocketServer() {
       
   187             @Override
       
   188             protected void serve(SocketChannel channel) throws IOException {
       
   189                 try {
       
   190                     Thread.sleep(Long.MAX_VALUE);
       
   191                 } catch (InterruptedException e) {
       
   192                     throw new IOException(e);
       
   193                 }
       
   194             }
       
   195         };
       
   196     }
       
   197 
       
   198     @Test
       
   199     public void testIllegalStateIntermixed1() throws IOException {
       
   200         try (DummyWebSocketServer server = new DummyWebSocketServer()) {
       
   201             server.open();
       
   202             WebSocket ws = newHttpClient()
       
   203                     .newWebSocketBuilder()
       
   204                     .buildAsync(server.getURI(), new WebSocket.Listener() { })
       
   205                     .join();
       
   206 
       
   207             ws.sendBinary(ByteBuffer.allocate(16), false).join();
       
   208             assertISE(ws.sendText("text", false));
       
   209             assertISE(ws.sendText("text", true));
       
   210         }
       
   211     }
       
   212 
       
   213     @Test
       
   214     public void testIllegalStateIntermixed2() throws IOException {
       
   215         try (DummyWebSocketServer server = new DummyWebSocketServer()) {
       
   216             server.open();
       
   217             WebSocket ws = newHttpClient()
       
   218                     .newWebSocketBuilder()
       
   219                     .buildAsync(server.getURI(), new WebSocket.Listener() { })
       
   220                     .join();
       
   221 
       
   222             ws.sendText("text", false).join();
       
   223             assertISE(ws.sendBinary(ByteBuffer.allocate(16), false));
       
   224             assertISE(ws.sendBinary(ByteBuffer.allocate(16), true));
       
   225         }
       
   226     }
       
   227 
       
   228     private static String malformedString() {
       
   229         return new String(new char[]{0xDC00, 0xD800});
       
   230     }
       
   231 
       
   232     private static String incompleteString() {
       
   233         return new String(new char[]{0xD800});
       
   234     }
       
   235 
       
   236     private static String stringWithNBytes(int n) {
       
   237         StringBuilder sb = new StringBuilder(n);
       
   238         for (int i = 0; i < n; i++) {
       
   239             sb.append("A");
       
   240         }
       
   241         return sb.toString();
       
   242     }
       
   243 
       
   244     private static String stringWith2NBytes(int n) {
       
   245         // Russian alphabet repeated cyclically
       
   246         char FIRST = '\u0410';
       
   247         char LAST = '\u042F';
       
   248         StringBuilder sb = new StringBuilder(n);
       
   249         char c = FIRST;
       
   250         for (int i = 0; i < n; i++) {
       
   251             if (++c > LAST) {
       
   252                 c = FIRST;
       
   253             }
       
   254             sb.append(c);
       
   255         }
       
   256         String s = sb.toString();
       
   257         assert s.length() == n && s.getBytes(StandardCharsets.UTF_8).length == 2 * n;
       
   258         return s;
       
   259     }
       
   260 
       
   261     @Test
       
   262     public void testIllegalStateSendClose() throws IOException {
    99         try (DummyWebSocketServer server = new DummyWebSocketServer()) {
   263         try (DummyWebSocketServer server = new DummyWebSocketServer()) {
   100             server.open();
   264             server.open();
   101             WebSocket ws = newHttpClient()
   265             WebSocket ws = newHttpClient()
   102                     .newWebSocketBuilder()
   266                     .newWebSocketBuilder()
   103                     .buildAsync(server.getURI(), new WebSocket.Listener() { })
   267                     .buildAsync(server.getURI(), new WebSocket.Listener() { })
   104                     .join();
   268                     .join();
   105 
   269 
   106             ws.sendClose(NORMAL_CLOSURE, "normal close").join();
   270             ws.sendClose(NORMAL_CLOSURE, "normal close").join();
       
   271 
       
   272             assertISE(ws.sendText("", true));
       
   273             assertISE(ws.sendText("", false));
       
   274             assertISE(ws.sendText("abc", true));
       
   275             assertISE(ws.sendText("abc", false));
       
   276             assertISE(ws.sendBinary(ByteBuffer.allocate(0), true));
       
   277             assertISE(ws.sendBinary(ByteBuffer.allocate(0), false));
       
   278             assertISE(ws.sendBinary(ByteBuffer.allocate(1), true));
       
   279             assertISE(ws.sendBinary(ByteBuffer.allocate(1), false));
   107 
   280 
   108             assertISE(ws.sendPing(ByteBuffer.allocate(125)));
   281             assertISE(ws.sendPing(ByteBuffer.allocate(125)));
   109             assertISE(ws.sendPing(ByteBuffer.allocate(124)));
   282             assertISE(ws.sendPing(ByteBuffer.allocate(124)));
   110             assertISE(ws.sendPing(ByteBuffer.allocate(  1)));
   283             assertISE(ws.sendPing(ByteBuffer.allocate(1)));
   111             assertISE(ws.sendPing(ByteBuffer.allocate(  0)));
   284             assertISE(ws.sendPing(ByteBuffer.allocate(0)));
   112 
   285 
   113             assertISE(ws.sendPong(ByteBuffer.allocate(125)));
   286             assertISE(ws.sendPong(ByteBuffer.allocate(125)));
   114             assertISE(ws.sendPong(ByteBuffer.allocate(124)));
   287             assertISE(ws.sendPong(ByteBuffer.allocate(124)));
   115             assertISE(ws.sendPong(ByteBuffer.allocate(  1)));
   288             assertISE(ws.sendPong(ByteBuffer.allocate(1)));
   116             assertISE(ws.sendPong(ByteBuffer.allocate(  0)));
   289             assertISE(ws.sendPong(ByteBuffer.allocate(0)));
   117 
   290         }
   118             // ... add more CF complete exceptionally scenarios
   291     }
   119         }
   292 
   120     }
   293     private static void assertIAE(CompletableFuture<?> stage) {
   121 
   294         assertExceptionally(IAE, stage);
   122     private void assertIAE(CompletableFuture<?> stage) {
   295     }
   123         assertExceptionally(IllegalArgumentException.class, stage);
   296 
   124     }
   297     private static void assertISE(CompletableFuture<?> stage) {
   125 
       
   126     private void assertISE(CompletableFuture<?> stage) {
       
   127         assertExceptionally(IllegalStateException.class, stage);
   298         assertExceptionally(IllegalStateException.class, stage);
   128     }
   299     }
   129 
   300 
   130     private void assertExceptionally(Class<? extends Throwable> clazz,
   301     private static void assertExceptionally(Class<? extends Throwable> clazz,
   131                                      CompletableFuture<?> stage) {
   302                                             CompletableFuture<?> stage) {
   132         stage.handle((result, error) -> {
   303         stage.handle((result, error) -> {
   133             if (error instanceof CompletionException) {
   304             if (error instanceof CompletionException) {
   134                 Throwable cause = error.getCause();
   305                 Throwable cause = error.getCause();
   135                 if (cause == null) {
   306                 if (cause == null) {
   136                     throw new AssertionError("Unexpected null cause: " + error);
   307                     throw new AssertionError("Unexpected null cause: " + error);
   141             }
   312             }
   142             return null;
   313             return null;
   143         }).join();
   314         }).join();
   144     }
   315     }
   145 
   316 
   146     private void assertException(Class<? extends Throwable> clazz, Throwable t) {
   317     private static void assertException(Class<? extends Throwable> clazz,
       
   318                                         Throwable t) {
   147         if (t == null) {
   319         if (t == null) {
   148             throw new AssertionError("Expected " + clazz + ", caught nothing");
   320             throw new AssertionError("Expected " + clazz + ", caught nothing");
   149         }
   321         }
   150         if (!clazz.isInstance(t)) {
   322         if (!clazz.isInstance(t)) {
   151             throw new AssertionError("Expected " + clazz + ", caught " + t);
   323             throw new AssertionError("Expected " + clazz + ", caught " + t);
   152         }
   324         }
   153     }
   325     }
   154 
       
   155     // ... more API assertions ???
       
   156 }
   326 }