test/jdk/java/net/httpclient/SmallTimeout.java
changeset 48083 b1c1b4ef4be2
parent 47216 71c04702a3d5
child 49765 ee6f7a61f3a5
child 56082 1da51fab3032
equal deleted inserted replaced
48081:89829dd3cc54 48083:b1c1b4ef4be2
    38 
    38 
    39 /**
    39 /**
    40  * @test
    40  * @test
    41  * @bug 8178147
    41  * @bug 8178147
    42  * @summary Ensures that small timeouts do not cause hangs due to race conditions
    42  * @summary Ensures that small timeouts do not cause hangs due to race conditions
    43  * @run main/othervm SmallTimeout
    43  * @run main/othervm -Djdk.incubator.http.internal.common.DEBUG=true SmallTimeout
    44  */
    44  */
    45 
    45 
    46 // To enable logging use. Not enabled by default as it changes the dynamics
    46 // To enable logging use. Not enabled by default as it changes the dynamics
    47 // of the test.
    47 // of the test.
    48 // @run main/othervm -Djdk.httpclient.HttpClient.log=all,frames:all SmallTimeout
    48 // @run main/othervm -Djdk.httpclient.HttpClient.log=all,frames:all SmallTimeout
    50 public class SmallTimeout {
    50 public class SmallTimeout {
    51 
    51 
    52     static int[] TIMEOUTS = {2, 1, 3, 2, 100, 1};
    52     static int[] TIMEOUTS = {2, 1, 3, 2, 100, 1};
    53 
    53 
    54     // A queue for placing timed out requests so that their order can be checked.
    54     // A queue for placing timed out requests so that their order can be checked.
    55     static LinkedBlockingQueue<HttpRequest> queue = new LinkedBlockingQueue<>();
    55     static LinkedBlockingQueue<HttpResult> queue = new LinkedBlockingQueue<>();
       
    56 
       
    57     static final class HttpResult {
       
    58          final HttpRequest request;
       
    59          final Throwable   failed;
       
    60          HttpResult(HttpRequest request, Throwable   failed) {
       
    61              this.request = request;
       
    62              this.failed = failed;
       
    63          }
       
    64 
       
    65          static HttpResult of(HttpRequest request) {
       
    66              return new HttpResult(request, null);
       
    67          }
       
    68 
       
    69          static HttpResult of(HttpRequest request, Throwable t) {
       
    70              return new HttpResult(request, t);
       
    71          }
       
    72 
       
    73     }
    56 
    74 
    57     static volatile boolean error;
    75     static volatile boolean error;
    58 
    76 
    59     public static void main(String[] args) throws Exception {
    77     public static void main(String[] args) throws Exception {
    60         HttpClient client = HttpClient.newHttpClient();
    78         HttpClient client = HttpClient.newHttpClient();
    74 
    92 
    75                 final HttpRequest req = requests[i];
    93                 final HttpRequest req = requests[i];
    76                 CompletableFuture<HttpResponse<Object>> response = client
    94                 CompletableFuture<HttpResponse<Object>> response = client
    77                     .sendAsync(req, discard(null))
    95                     .sendAsync(req, discard(null))
    78                     .whenComplete((HttpResponse<Object> r, Throwable t) -> {
    96                     .whenComplete((HttpResponse<Object> r, Throwable t) -> {
       
    97                         Throwable cause = null;
    79                         if (r != null) {
    98                         if (r != null) {
    80                             out.println("Unexpected response: " + r);
    99                             out.println("Unexpected response: " + r);
       
   100                             cause = new RuntimeException("Unexpected response");
    81                             error = true;
   101                             error = true;
    82                         }
   102                         }
    83                         if (t != null) {
   103                         if (t != null) {
    84                             if (!(t.getCause() instanceof HttpTimeoutException)) {
   104                             if (!(t.getCause() instanceof HttpTimeoutException)) {
    85                                 out.println("Wrong exception type:" + t.toString());
   105                                 out.println("Wrong exception type:" + t.toString());
    86                                 Throwable c = t.getCause() == null ? t : t.getCause();
   106                                 Throwable c = t.getCause() == null ? t : t.getCause();
    87                                 c.printStackTrace();
   107                                 c.printStackTrace();
       
   108                                 cause = c;
    88                                 error = true;
   109                                 error = true;
    89                             } else {
   110                             } else {
    90                                 out.println("Caught expected timeout: " + t.getCause());
   111                                 out.println("Caught expected timeout: " + t.getCause());
    91                             }
   112                             }
    92                         }
   113                         }
    93                         if (t == null && r == null) {
   114                         if (t == null && r == null) {
    94                             out.println("Both response and throwable are null!");
   115                             out.println("Both response and throwable are null!");
       
   116                             cause = new RuntimeException("Both response and throwable are null!");
    95                             error = true;
   117                             error = true;
    96                         }
   118                         }
    97                         queue.add(req);
   119                         queue.add(HttpResult.of(req,cause));
    98                     });
   120                     });
    99             }
   121             }
   100             System.out.println("All requests submitted. Waiting ...");
   122             System.out.println("All requests submitted. Waiting ...");
   101 
   123 
   102             checkReturn(requests);
   124             checkReturn(requests);
   116                                          .GET()
   138                                          .GET()
   117                                          .build();
   139                                          .build();
   118 
   140 
   119                 final HttpRequest req = requests[i];
   141                 final HttpRequest req = requests[i];
   120                 executor.execute(() -> {
   142                 executor.execute(() -> {
       
   143                     Throwable cause = null;
   121                     try {
   144                     try {
   122                         client.send(req, discard(null));
   145                         client.send(req, discard(null));
   123                     } catch (HttpTimeoutException e) {
   146                     } catch (HttpTimeoutException e) {
   124                         out.println("Caught expected timeout: " + e);
   147                         out.println("Caught expected timeout: " + e);
   125                         queue.offer(req);
   148                     } catch (Throwable ee) {
   126                     } catch (IOException | InterruptedException ee) {
       
   127                         Throwable c = ee.getCause() == null ? ee : ee.getCause();
   149                         Throwable c = ee.getCause() == null ? ee : ee.getCause();
   128                         c.printStackTrace();
   150                         c.printStackTrace();
       
   151                         cause = c;
   129                         error = true;
   152                         error = true;
       
   153                     } finally {
       
   154                         queue.offer(HttpResult.of(req, cause));
   130                     }
   155                     }
   131                 });
   156                 });
   132             }
   157             }
   133             System.out.println("All requests submitted. Waiting ...");
   158             System.out.println("All requests submitted. Waiting ...");
   134 
   159 
   137             executor.shutdownNow();
   162             executor.shutdownNow();
   138 
   163 
   139             if (error)
   164             if (error)
   140                 throw new RuntimeException("Failed. Check output");
   165                 throw new RuntimeException("Failed. Check output");
   141 
   166 
   142         } finally {
       
   143             ((ExecutorService) client.executor()).shutdownNow();
       
   144         }
   167         }
   145     }
   168     }
   146 
   169 
   147     static void checkReturn(HttpRequest[] requests) throws InterruptedException {
   170     static void checkReturn(HttpRequest[] requests) throws InterruptedException {
   148         // wait for exceptions and check order
   171         // wait for exceptions and check order
       
   172         boolean ok = true;
   149         for (int j = 0; j < TIMEOUTS.length; j++) {
   173         for (int j = 0; j < TIMEOUTS.length; j++) {
   150             HttpRequest req = queue.take();
   174             HttpResult res = queue.take();
   151             out.println("Got request from queue " + req + ", order: " + getRequest(req, requests));
   175             HttpRequest req = res.request;
       
   176             out.println("Got request from queue " + req + ", order: " + getRequest(req, requests)
       
   177                          + (res.failed == null ? "" : " failed: " + res.failed));
       
   178             ok = ok && res.failed == null;
   152         }
   179         }
   153         out.println("Return ok");
   180         out.println("Return " + (ok ? "ok" : "nok"));
   154     }
   181     }
   155 
   182 
   156     /** Returns the index of the request in the array. */
   183     /** Returns the index of the request in the array. */
   157     static String getRequest(HttpRequest req, HttpRequest[] requests) {
   184     static String getRequest(HttpRequest req, HttpRequest[] requests) {
   158         for (int i=0; i<requests.length; i++) {
   185         for (int i=0; i<requests.length; i++) {