test/jdk/java/net/httpclient/websocket/WebSocketBuilderTest.java
changeset 49765 ee6f7a61f3a5
child 56451 9585061fdb04
equal deleted inserted replaced
49707:f7fd051519ac 49765:ee6f7a61f3a5
       
     1 /*
       
     2  * Copyright (c) 2016, 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 /*
       
    25  * @test
       
    26  * @bug 8159053
       
    27  * @run testng/othervm WebSocketBuilderTest
       
    28  */
       
    29 
       
    30 import org.testng.annotations.DataProvider;
       
    31 import org.testng.annotations.Test;
       
    32 
       
    33 import java.net.URI;
       
    34 import java.net.http.HttpClient;
       
    35 import java.net.http.WebSocket;
       
    36 import java.time.Duration;
       
    37 import java.util.List;
       
    38 import java.util.concurrent.CompletionStage;
       
    39 import java.util.function.Function;
       
    40 import java.util.stream.Collectors;
       
    41 import java.util.stream.Stream;
       
    42 
       
    43 import static org.testng.Assert.assertThrows;
       
    44 
       
    45 /*
       
    46  * In some places in this test a new String is created out of a string literal.
       
    47  * The idea is to make sure the code under test relies on something better than
       
    48  * the reference equality ( == ) for string equality checks.
       
    49  */
       
    50 public final class WebSocketBuilderTest {
       
    51 
       
    52     private final static URI VALID_URI = URI.create("ws://websocket.example.com");
       
    53 
       
    54     @Test
       
    55     public void nullArguments() {
       
    56         HttpClient c = HttpClient.newHttpClient();
       
    57 
       
    58         assertThrows(NullPointerException.class,
       
    59                      () -> c.newWebSocketBuilder()
       
    60                              .buildAsync(null, listener()));
       
    61         assertThrows(NullPointerException.class,
       
    62                      () -> c.newWebSocketBuilder()
       
    63                              .buildAsync(VALID_URI, null));
       
    64         assertThrows(NullPointerException.class,
       
    65                      () -> c.newWebSocketBuilder()
       
    66                              .buildAsync(null, null));
       
    67         assertThrows(NullPointerException.class,
       
    68                      () -> c.newWebSocketBuilder()
       
    69                              .header(null, "value"));
       
    70         assertThrows(NullPointerException.class,
       
    71                      () -> c.newWebSocketBuilder()
       
    72                              .header("name", null));
       
    73         assertThrows(NullPointerException.class,
       
    74                      () -> c.newWebSocketBuilder()
       
    75                              .header(null, null));
       
    76         assertThrows(NullPointerException.class,
       
    77                      () -> c.newWebSocketBuilder()
       
    78                              .subprotocols(null));
       
    79         assertThrows(NullPointerException.class,
       
    80                      () -> c.newWebSocketBuilder()
       
    81                              .subprotocols(null, "sub2.example.com"));
       
    82         assertThrows(NullPointerException.class,
       
    83                      () -> c.newWebSocketBuilder()
       
    84                              .subprotocols("sub1.example.com", (String) null));
       
    85         assertThrows(NullPointerException.class,
       
    86                      () -> c.newWebSocketBuilder()
       
    87                              .subprotocols("sub1.example.com", (String[]) null));
       
    88         assertThrows(NullPointerException.class,
       
    89                      () -> c.newWebSocketBuilder()
       
    90                              .subprotocols("sub1.example.com", "sub2.example.com", null));
       
    91         assertThrows(NullPointerException.class,
       
    92                      () -> c.newWebSocketBuilder()
       
    93                              .subprotocols("sub1.example.com", null, "sub3.example.com"));
       
    94         assertThrows(NullPointerException.class,
       
    95                      () -> c.newWebSocketBuilder()
       
    96                              .connectTimeout(null));
       
    97     }
       
    98 
       
    99     @Test(dataProvider = "badURIs")
       
   100     void illegalURI(URI uri) {
       
   101         WebSocket.Builder b = HttpClient.newHttpClient().newWebSocketBuilder();
       
   102         assertFails(IllegalArgumentException.class,
       
   103                     b.buildAsync(uri, listener()));
       
   104     }
       
   105 
       
   106     @Test
       
   107     public void illegalHeaders() {
       
   108         List<String> headers =
       
   109                 List.of("Sec-WebSocket-Accept",
       
   110                         "Sec-WebSocket-Extensions",
       
   111                         "Sec-WebSocket-Key",
       
   112                         "Sec-WebSocket-Protocol",
       
   113                         "Sec-WebSocket-Version")
       
   114                         .stream()
       
   115                         .flatMap(s -> Stream.of(s, new String(s))) // a string and a copy of it
       
   116                         .collect(Collectors.toList());
       
   117 
       
   118         Function<String, CompletionStage<?>> f =
       
   119                 header -> HttpClient.newHttpClient()
       
   120                         .newWebSocketBuilder()
       
   121                         .header(header, "value")
       
   122                         .buildAsync(VALID_URI, listener());
       
   123 
       
   124         headers.forEach(h -> assertFails(IllegalArgumentException.class, f.apply(h)));
       
   125     }
       
   126 
       
   127     // TODO: test for bad syntax headers
       
   128     // TODO: test for overwrites (subprotocols) and additions (headers)
       
   129 
       
   130     @Test(dataProvider = "badSubprotocols")
       
   131     public void illegalSubprotocolsSyntax(String s) {
       
   132         WebSocket.Builder b = HttpClient.newHttpClient()
       
   133                 .newWebSocketBuilder()
       
   134                 .subprotocols(s);
       
   135         assertFails(IllegalArgumentException.class,
       
   136                     b.buildAsync(VALID_URI, listener()));
       
   137     }
       
   138 
       
   139     @Test(dataProvider = "duplicatingSubprotocols")
       
   140     public void illegalSubprotocolsDuplicates(String mostPreferred,
       
   141                                               String[] lesserPreferred) {
       
   142         WebSocket.Builder b = HttpClient.newHttpClient()
       
   143                 .newWebSocketBuilder()
       
   144                 .subprotocols(mostPreferred, lesserPreferred);
       
   145         assertFails(IllegalArgumentException.class,
       
   146                     b.buildAsync(VALID_URI, listener()));
       
   147     }
       
   148 
       
   149     @Test(dataProvider = "badConnectTimeouts")
       
   150     public void illegalConnectTimeout(Duration d) {
       
   151         WebSocket.Builder b = HttpClient.newHttpClient()
       
   152                 .newWebSocketBuilder()
       
   153                 .connectTimeout(d);
       
   154         assertFails(IllegalArgumentException.class,
       
   155                     b.buildAsync(VALID_URI, listener()));
       
   156     }
       
   157 
       
   158     @DataProvider
       
   159     public Object[][] badURIs() {
       
   160         return new Object[][]{
       
   161                 {URI.create("http://example.com")},
       
   162                 {URI.create("ftp://example.com")},
       
   163                 {URI.create("wss://websocket.example.com/hello#fragment")},
       
   164                 {URI.create("ws://websocket.example.com/hello#fragment")},
       
   165         };
       
   166     }
       
   167 
       
   168     @DataProvider
       
   169     public Object[][] badConnectTimeouts() {
       
   170         return new Object[][]{
       
   171                 {Duration.ofDays(0)},
       
   172                 {Duration.ofDays(-1)},
       
   173                 {Duration.ofHours(0)},
       
   174                 {Duration.ofHours(-1)},
       
   175                 {Duration.ofMinutes(0)},
       
   176                 {Duration.ofMinutes(-1)},
       
   177                 {Duration.ofSeconds(0)},
       
   178                 {Duration.ofSeconds(-1)},
       
   179                 {Duration.ofMillis(0)},
       
   180                 {Duration.ofMillis(-1)},
       
   181                 {Duration.ofNanos(0)},
       
   182                 {Duration.ofNanos(-1)},
       
   183                 {Duration.ZERO},
       
   184         };
       
   185     }
       
   186 
       
   187     // https://tools.ietf.org/html/rfc7230#section-3.2.6
       
   188     // https://tools.ietf.org/html/rfc20
       
   189     @DataProvider
       
   190     public static Object[][] badSubprotocols() {
       
   191         return new Object[][]{
       
   192                 {""},
       
   193                 {new String("")},
       
   194                 {"round-brackets("},
       
   195                 {"round-brackets)"},
       
   196                 {"comma,"},
       
   197                 {"slash/"},
       
   198                 {"colon:"},
       
   199                 {"semicolon;"},
       
   200                 {"angle-brackets<"},
       
   201                 {"angle-brackets>"},
       
   202                 {"equals="},
       
   203                 {"question-mark?"},
       
   204                 {"at@"},
       
   205                 {"brackets["},
       
   206                 {"backslash\\"},
       
   207                 {"brackets]"},
       
   208                 {"curly-brackets{"},
       
   209                 {"curly-brackets}"},
       
   210                 {"space "},
       
   211                 {"non-printable-character " + Character.toString((char) 31)},
       
   212                 {"non-printable-character " + Character.toString((char) 127)},
       
   213         };
       
   214     }
       
   215 
       
   216     @DataProvider
       
   217     public static Object[][] duplicatingSubprotocols() {
       
   218         return new Object[][]{
       
   219                 {"a.b.c", new String[]{"a.b.c"}},
       
   220                 {"a.b.c", new String[]{"x.y.z", "p.q.r", "x.y.z"}},
       
   221                 {"a.b.c", new String[]{new String("a.b.c")}},
       
   222         };
       
   223     }
       
   224 
       
   225     private static WebSocket.Listener listener() {
       
   226         return new WebSocket.Listener() { };
       
   227     }
       
   228 
       
   229     /* shortcut */
       
   230     public static void assertFails(Class<? extends Throwable> clazz,
       
   231                                    CompletionStage<?> stage) {
       
   232         Support.assertCompletesExceptionally(clazz, stage);
       
   233     }
       
   234 }