• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 package org.chromium.net;
6 
7 import static org.junit.Assert.assertEquals;
8 import static org.junit.Assert.assertNotNull;
9 import static org.junit.Assert.assertNull;
10 import static org.junit.Assert.assertTrue;
11 import static org.junit.Assert.fail;
12 
13 import static org.chromium.base.CollectionUtil.newHashSet;
14 import static org.chromium.net.CronetTestRule.getContext;
15 
16 import android.net.http.ExperimentalHttpEngine;
17 import android.net.http.ExperimentalUrlRequest;
18 import android.net.http.NetworkException;
19 import android.net.http.RequestFinishedInfo;
20 import android.net.http.UrlRequest;
21 import android.net.http.UrlResponseInfo;
22 import android.os.ConditionVariable;
23 
24 import androidx.test.ext.junit.runners.AndroidJUnit4;
25 import androidx.test.filters.SmallTest;
26 
27 import org.junit.After;
28 import org.junit.Before;
29 import org.junit.Rule;
30 import org.junit.Test;
31 import org.junit.runner.RunWith;
32 
33 import org.chromium.net.CronetTestRule.CronetTestFramework;
34 import org.chromium.net.CronetTestRule.OnlyRunNativeCronet;
35 import org.chromium.net.CronetTestRule.RequiresMinApi;
36 import org.chromium.net.MetricsTestUtil.TestExecutor;
37 import org.chromium.net.impl.CronetMetrics;
38 
39 import java.time.Instant;
40 import java.util.ArrayList;
41 import java.util.Date;
42 import java.util.HashSet;
43 import java.util.List;
44 import java.util.concurrent.Executor;
45 import java.util.concurrent.RejectedExecutionException;
46 import java.util.concurrent.atomic.AtomicBoolean;
47 
48 /**
49  * Test RequestFinishedInfo.Listener and the metrics information it provides.
50  */
51 @RunWith(AndroidJUnit4.class)
52 public class RequestFinishedInfoTest {
53     @Rule
54     public final CronetTestRule mTestRule = new CronetTestRule();
55 
56     CronetTestFramework mTestFramework;
57 
58     private String mUrl;
59 
60     // A subclass of TestRequestFinishedListener to additionally assert that UrlRequest.Callback's
61     // terminal callbacks have been invoked at the time of onRequestFinished().
62     // See crbug.com/710877.
63     private static class AssertCallbackDoneRequestFinishedListener
64             extends TestRequestFinishedListener {
65         private final TestUrlRequestCallback mCallback;
AssertCallbackDoneRequestFinishedListener(TestUrlRequestCallback callback)66         public AssertCallbackDoneRequestFinishedListener(TestUrlRequestCallback callback) {
67             // Use same executor as request callback to verify stable call order.
68             super(callback.getExecutor());
69             mCallback = callback;
70         }
71 
72         @Override
onRequestFinished(RequestFinishedInfo requestInfo)73         public void onRequestFinished(RequestFinishedInfo requestInfo) {
74             assertTrue(mCallback.isDone());
75             super.onRequestFinished(requestInfo);
76         }
77     };
78 
79     @Before
setUp()80     public void setUp() throws Exception {
81         assertTrue(NativeTestServer.startNativeTestServer(getContext()));
82         mUrl = NativeTestServer.getSuccessURL();
83         mTestFramework = mTestRule.startCronetTestFramework();
84     }
85 
86     @After
tearDown()87     public void tearDown() throws Exception {
88         mTestFramework.mCronetEngine.shutdown();
89         NativeTestServer.shutdownNativeTestServer();
90     }
91 
92     static class DirectExecutor implements Executor {
93         private ConditionVariable mBlock = new ConditionVariable();
94 
95         @Override
execute(Runnable task)96         public void execute(Runnable task) {
97             task.run();
98             mBlock.open();
99         }
100 
blockUntilDone()101         public void blockUntilDone() {
102             mBlock.block();
103         }
104     }
105 
106     static class ThreadExecutor implements Executor {
107         private List<Thread> mThreads = new ArrayList<Thread>();
108 
109         @Override
execute(Runnable task)110         public void execute(Runnable task) {
111             Thread newThread = new Thread(task);
112             mThreads.add(newThread);
113             newThread.start();
114         }
115 
joinAll()116         public void joinAll() throws InterruptedException {
117             for (Thread thread : mThreads) {
118                 thread.join();
119             }
120         }
121     }
122 
123     @Test
124     @SmallTest
125     @OnlyRunNativeCronet
126     @SuppressWarnings("deprecation")
testRequestFinishedListener()127     public void testRequestFinishedListener() throws Exception {
128         TestRequestFinishedListener requestFinishedListener = new TestRequestFinishedListener();
129         mTestFramework.mCronetEngine.addRequestFinishedListener(requestFinishedListener);
130         TestUrlRequestCallback callback = new TestUrlRequestCallback();
131         ExperimentalUrlRequest.Builder urlRequestBuilder =
132                 (ExperimentalUrlRequest.Builder) mTestFramework.mCronetEngine.newUrlRequestBuilder(
133                         mUrl, callback, callback.getExecutor());
134         Instant startTime = Instant.now();
135         urlRequestBuilder.addRequestAnnotation("request annotation")
136                 .addRequestAnnotation(this)
137                 .build()
138                 .start();
139         callback.blockForDone();
140         requestFinishedListener.blockUntilDone();
141         Instant endTime = Instant.now();
142 
143         RequestFinishedInfo requestInfo = requestFinishedListener.getRequestInfo();
144         MetricsTestUtil.checkRequestFinishedInfo(requestInfo, mUrl, startTime, endTime);
145         assertEquals(RequestFinishedInfo.SUCCEEDED, requestInfo.getFinishedReason());
146         MetricsTestUtil.checkHasConnectTiming(requestInfo.getMetrics(), startTime, endTime, false);
147         assertEquals(newHashSet("request annotation", this), // Use sets for unordered comparison.
148                 new HashSet<Object>(requestInfo.getAnnotations()));
149     }
150 
151     @Test
152     @SmallTest
153     @OnlyRunNativeCronet
154     @SuppressWarnings("deprecation")
testRequestFinishedListenerDirectExecutor()155     public void testRequestFinishedListenerDirectExecutor() throws Exception {
156         DirectExecutor testExecutor = new DirectExecutor();
157         TestRequestFinishedListener requestFinishedListener =
158                 new TestRequestFinishedListener(testExecutor);
159         mTestFramework.mCronetEngine.addRequestFinishedListener(requestFinishedListener);
160         TestUrlRequestCallback callback = new TestUrlRequestCallback();
161         ExperimentalUrlRequest.Builder urlRequestBuilder =
162                 (ExperimentalUrlRequest.Builder) mTestFramework.mCronetEngine.newUrlRequestBuilder(
163                         mUrl, callback, callback.getExecutor());
164         Instant startTime = Instant.now();
165         urlRequestBuilder.addRequestAnnotation("request annotation")
166                 .addRequestAnnotation(this)
167                 .build()
168                 .start();
169         callback.blockForDone();
170         // Block on the executor, not the listener, since blocking on the listener doesn't work when
171         // it's created with a non-default executor.
172         testExecutor.blockUntilDone();
173         Instant endTime = Instant.now();
174 
175         RequestFinishedInfo requestInfo = requestFinishedListener.getRequestInfo();
176         MetricsTestUtil.checkRequestFinishedInfo(requestInfo, mUrl, startTime, endTime);
177         assertEquals(RequestFinishedInfo.SUCCEEDED, requestInfo.getFinishedReason());
178         MetricsTestUtil.checkHasConnectTiming(requestInfo.getMetrics(), startTime, endTime, false);
179         assertEquals(newHashSet("request annotation", this), // Use sets for unordered comparison.
180                 new HashSet<Object>(requestInfo.getAnnotations()));
181     }
182 
183     @Test
184     @SmallTest
185     @OnlyRunNativeCronet
186     @SuppressWarnings("deprecation")
testRequestFinishedListenerDifferentThreads()187     public void testRequestFinishedListenerDifferentThreads() throws Exception {
188         TestRequestFinishedListener firstListener = new TestRequestFinishedListener();
189         TestRequestFinishedListener secondListener = new TestRequestFinishedListener();
190         mTestFramework.mCronetEngine.addRequestFinishedListener(firstListener);
191         mTestFramework.mCronetEngine.addRequestFinishedListener(secondListener);
192         TestUrlRequestCallback callback = new TestUrlRequestCallback();
193         ExperimentalUrlRequest.Builder urlRequestBuilder =
194                 (ExperimentalUrlRequest.Builder) mTestFramework.mCronetEngine.newUrlRequestBuilder(
195                         mUrl, callback, callback.getExecutor());
196         Instant startTime = Instant.now();
197         urlRequestBuilder.addRequestAnnotation("request annotation")
198                 .addRequestAnnotation(this)
199                 .build()
200                 .start();
201         callback.blockForDone();
202         firstListener.blockUntilDone();
203         secondListener.blockUntilDone();
204         Instant endTime = Instant.now();
205 
206         RequestFinishedInfo firstRequestInfo = firstListener.getRequestInfo();
207         RequestFinishedInfo secondRequestInfo = secondListener.getRequestInfo();
208 
209         MetricsTestUtil.checkRequestFinishedInfo(firstRequestInfo, mUrl, startTime, endTime);
210         assertEquals(RequestFinishedInfo.SUCCEEDED, firstRequestInfo.getFinishedReason());
211         MetricsTestUtil.checkHasConnectTiming(
212                 firstRequestInfo.getMetrics(), startTime, endTime, false);
213 
214         MetricsTestUtil.checkRequestFinishedInfo(secondRequestInfo, mUrl, startTime, endTime);
215         assertEquals(RequestFinishedInfo.SUCCEEDED, secondRequestInfo.getFinishedReason());
216         MetricsTestUtil.checkHasConnectTiming(
217                 secondRequestInfo.getMetrics(), startTime, endTime, false);
218 
219         assertEquals(newHashSet("request annotation", this), // Use sets for unordered comparison.
220                 new HashSet<Object>(firstRequestInfo.getAnnotations()));
221         assertEquals(newHashSet("request annotation", this),
222                 new HashSet<Object>(secondRequestInfo.getAnnotations()));
223     }
224 
225     @Test
226     @SmallTest
227     @OnlyRunNativeCronet
228     @SuppressWarnings("deprecation")
testRequestFinishedListenerFailedRequest()229     public void testRequestFinishedListenerFailedRequest() throws Exception {
230         String connectionRefusedUrl = "http://127.0.0.1:3";
231         TestRequestFinishedListener requestFinishedListener = new TestRequestFinishedListener();
232         mTestFramework.mCronetEngine.addRequestFinishedListener(requestFinishedListener);
233         TestUrlRequestCallback callback = new TestUrlRequestCallback();
234         UrlRequest.Builder urlRequestBuilder = mTestFramework.mCronetEngine.newUrlRequestBuilder(
235                 connectionRefusedUrl, callback, callback.getExecutor());
236         Instant startTime = Instant.now();
237         urlRequestBuilder.build().start();
238         callback.blockForDone();
239         assertTrue(callback.mOnErrorCalled);
240         requestFinishedListener.blockUntilDone();
241         Instant endTime = Instant.now();
242 
243         RequestFinishedInfo requestInfo = requestFinishedListener.getRequestInfo();
244         assertNotNull("RequestFinishedInfo.Listener must be called", requestInfo);
245         assertEquals(connectionRefusedUrl, requestInfo.getUrl());
246         assertTrue(requestInfo.getAnnotations().isEmpty());
247         assertEquals(RequestFinishedInfo.FAILED, requestInfo.getFinishedReason());
248         assertNotNull(requestInfo.getException());
249         assertEquals(NetworkException.ERROR_CONNECTION_REFUSED,
250                 ((NetworkException) requestInfo.getException()).getErrorCode());
251         RequestFinishedInfo.Metrics metrics = requestInfo.getMetrics();
252         assertNotNull("RequestFinishedInfo.getMetrics() must not be null", metrics);
253 
254         // Check the timing metrics
255         assertNotNull(metrics.getRequestStart());
256         MetricsTestUtil.assertAfter(metrics.getRequestStart(), startTime);
257         MetricsTestUtil.checkNoConnectTiming(metrics);
258         assertNull(metrics.getSendingStart());
259         assertNull(metrics.getSendingEnd());
260         assertNull(metrics.getResponseStart());
261         assertNotNull(metrics.getRequestEnd());
262         MetricsTestUtil.assertAfter(endTime, metrics.getRequestEnd());
263         MetricsTestUtil.assertAfter(metrics.getRequestEnd(), metrics.getRequestStart());
264         assertTrue(metrics.getSentByteCount() == 0);
265         assertTrue(metrics.getReceivedByteCount() == 0);
266     }
267 
268     @Test
269     @SmallTest
270     @OnlyRunNativeCronet
271     @SuppressWarnings("deprecation")
testRequestFinishedListenerRemoved()272     public void testRequestFinishedListenerRemoved() throws Exception {
273         TestExecutor testExecutor = new TestExecutor();
274         TestRequestFinishedListener requestFinishedListener =
275                 new TestRequestFinishedListener(testExecutor);
276         mTestFramework.mCronetEngine.addRequestFinishedListener(requestFinishedListener);
277         TestUrlRequestCallback callback = new TestUrlRequestCallback();
278         UrlRequest.Builder urlRequestBuilder = mTestFramework.mCronetEngine.newUrlRequestBuilder(
279                 mUrl, callback, callback.getExecutor());
280         UrlRequest request = urlRequestBuilder.build();
281         mTestFramework.mCronetEngine.removeRequestFinishedListener(requestFinishedListener);
282         request.start();
283         callback.blockForDone();
284         testExecutor.runAllTasks();
285 
286         assertNull("RequestFinishedInfo.Listener must not be called",
287                 requestFinishedListener.getRequestInfo());
288     }
289 
290     @Test
291     @SmallTest
292     @OnlyRunNativeCronet
testRequestFinishedListenerCanceledRequest()293     public void testRequestFinishedListenerCanceledRequest() throws Exception {
294         TestRequestFinishedListener requestFinishedListener = new TestRequestFinishedListener();
295         mTestFramework.mCronetEngine.addRequestFinishedListener(requestFinishedListener);
296         TestUrlRequestCallback callback = new TestUrlRequestCallback() {
297             @Override
298             public void onResponseStarted(UrlRequest request, UrlResponseInfo info) {
299                 super.onResponseStarted(request, info);
300                 request.cancel();
301             }
302         };
303         ExperimentalUrlRequest.Builder urlRequestBuilder =
304                 (ExperimentalUrlRequest.Builder) mTestFramework.mCronetEngine.newUrlRequestBuilder(
305                         mUrl, callback, callback.getExecutor());
306         Instant startTime = Instant.now();
307         urlRequestBuilder.addRequestAnnotation("request annotation")
308                 .addRequestAnnotation(this)
309                 .build()
310                 .start();
311         callback.blockForDone();
312         requestFinishedListener.blockUntilDone();
313         Instant endTime = Instant.now();
314 
315         RequestFinishedInfo requestInfo = requestFinishedListener.getRequestInfo();
316         MetricsTestUtil.checkRequestFinishedInfo(requestInfo, mUrl, startTime, endTime);
317         assertEquals(RequestFinishedInfo.CANCELED, requestInfo.getFinishedReason());
318         MetricsTestUtil.checkHasConnectTiming(requestInfo.getMetrics(), startTime, endTime, false);
319 
320         assertEquals(newHashSet("request annotation", this), // Use sets for unordered comparison.
321                 new HashSet<Object>(requestInfo.getAnnotations()));
322     }
323 
324     private static class RejectAllTasksExecutor implements Executor {
325         @Override
execute(Runnable task)326         public void execute(Runnable task) {
327             throw new RejectedExecutionException();
328         }
329     }
330 
331     // Checks that CronetURLRequestAdapter::DestroyOnNetworkThread() doesn't crash when metrics
332     // collection is enabled and the URLRequest hasn't been created. See http://crbug.com/675629.
333     @Test
334     @SmallTest
335     @OnlyRunNativeCronet
testExceptionInRequestStart()336     public void testExceptionInRequestStart() throws Exception {
337         // The listener in this test shouldn't get any tasks.
338         Executor executor = new RejectAllTasksExecutor();
339         TestRequestFinishedListener requestFinishedListener =
340                 new TestRequestFinishedListener(executor);
341         mTestFramework.mCronetEngine.addRequestFinishedListener(requestFinishedListener);
342         TestUrlRequestCallback callback = new TestUrlRequestCallback();
343         UrlRequest.Builder urlRequestBuilder =
344                 mTestFramework.mCronetEngine.newUrlRequestBuilder(
345                         mUrl, callback, callback.getExecutor());
346         // Empty headers are invalid and will cause start() to throw an exception.
347         UrlRequest request = urlRequestBuilder.addHeader("", "").build();
348         try {
349             request.start();
350             fail("UrlRequest.start() should throw IllegalArgumentException");
351         } catch (IllegalArgumentException e) {
352             assertEquals("Invalid header =", e.getMessage());
353         }
354     }
355 
356     @Test
357     @SmallTest
testMetricsGetters()358     public void testMetricsGetters() throws Exception {
359         long requestStart = 1;
360         long dnsStart = 2;
361         long dnsEnd = -1;
362         long connectStart = 4;
363         long connectEnd = 5;
364         long sslStart = 6;
365         long sslEnd = 7;
366         long sendingStart = 8;
367         long sendingEnd = 9;
368         long pushStart = 10;
369         long pushEnd = 11;
370         long responseStart = 12;
371         long requestEnd = 13;
372         boolean socketReused = true;
373         long sentByteCount = 14;
374         long receivedByteCount = 15;
375         // Make sure nothing gets reordered inside the Metrics class
376         RequestFinishedInfo.Metrics metrics = new CronetMetrics(requestStart, dnsStart, dnsEnd,
377                 connectStart, connectEnd, sslStart, sslEnd, sendingStart, sendingEnd, pushStart,
378                 pushEnd, responseStart, requestEnd, socketReused, sentByteCount, receivedByteCount);
379         assertEquals(Instant.ofEpochMilli(requestStart), metrics.getRequestStart());
380         // -1 timestamp should translate to null
381         assertNull(metrics.getDnsEnd());
382         assertEquals(Instant.ofEpochMilli(dnsStart), metrics.getDnsStart());
383         assertEquals(Instant.ofEpochMilli(connectStart), metrics.getConnectStart());
384         assertEquals(Instant.ofEpochMilli(connectEnd), metrics.getConnectEnd());
385         assertEquals(Instant.ofEpochMilli(sslStart), metrics.getSslStart());
386         assertEquals(Instant.ofEpochMilli(sslEnd), metrics.getSslEnd());
387         assertEquals(Instant.ofEpochMilli(pushStart), metrics.getPushStart());
388         assertEquals(Instant.ofEpochMilli(pushEnd), metrics.getPushEnd());
389         assertEquals(Instant.ofEpochMilli(responseStart), metrics.getResponseStart());
390         assertEquals(Instant.ofEpochMilli(requestEnd), metrics.getRequestEnd());
391         assertEquals(socketReused, metrics.getSocketReused());
392         assertEquals(sentByteCount, (long) metrics.getSentByteCount());
393         assertEquals(receivedByteCount, (long) metrics.getReceivedByteCount());
394     }
395 
396     @Test
397     @SmallTest
398     @OnlyRunNativeCronet
399     @SuppressWarnings("deprecation")
testOrderSuccessfulRequest()400     public void testOrderSuccessfulRequest() throws Exception {
401         final TestUrlRequestCallback callback = new TestUrlRequestCallback();
402         TestRequestFinishedListener requestFinishedListener =
403                 new AssertCallbackDoneRequestFinishedListener(callback);
404         mTestFramework.mCronetEngine.addRequestFinishedListener(requestFinishedListener);
405         ExperimentalUrlRequest.Builder urlRequestBuilder =
406                 (ExperimentalUrlRequest.Builder) mTestFramework.mCronetEngine.newUrlRequestBuilder(
407                         mUrl, callback, callback.getExecutor());
408         Instant startTime = Instant.now();
409         urlRequestBuilder.addRequestAnnotation("request annotation")
410                 .addRequestAnnotation(this)
411                 .build()
412                 .start();
413         callback.blockForDone();
414         requestFinishedListener.blockUntilDone();
415         Instant endTime = Instant.now();
416 
417         RequestFinishedInfo requestInfo = requestFinishedListener.getRequestInfo();
418         MetricsTestUtil.checkRequestFinishedInfo(requestInfo, mUrl, startTime, endTime);
419         assertEquals(RequestFinishedInfo.SUCCEEDED, requestInfo.getFinishedReason());
420         MetricsTestUtil.checkHasConnectTiming(requestInfo.getMetrics(), startTime, endTime, false);
421         assertEquals(newHashSet("request annotation", this), // Use sets for unordered comparison.
422                 new HashSet<Object>(requestInfo.getAnnotations()));
423     }
424 
425     @Test
426     @SmallTest
427     @OnlyRunNativeCronet
428     @RequiresMinApi(11)
testUpdateAnnotationOnSucceeded()429     public void testUpdateAnnotationOnSucceeded() throws Exception {
430         // The annotation that is updated in onSucceeded() callback.
431         AtomicBoolean requestAnnotation = new AtomicBoolean(false);
432         final TestUrlRequestCallback callback = new TestUrlRequestCallback() {
433             @Override
434             public void onSucceeded(UrlRequest request, UrlResponseInfo info) {
435                 // Add processing information to request annotation.
436                 requestAnnotation.set(true);
437                 super.onSucceeded(request, info);
438             }
439         };
440         TestRequestFinishedListener requestFinishedListener =
441                 new AssertCallbackDoneRequestFinishedListener(callback);
442         ExperimentalUrlRequest.Builder urlRequestBuilder =
443                 (ExperimentalUrlRequest.Builder) mTestFramework.mCronetEngine.newUrlRequestBuilder(
444                         mUrl, callback, callback.getExecutor());
445         Instant startTime = Instant.now();
446         urlRequestBuilder.addRequestAnnotation(requestAnnotation)
447                 .setRequestFinishedListener(requestFinishedListener)
448                 .build()
449                 .start();
450         callback.blockForDone();
451         requestFinishedListener.blockUntilDone();
452         Instant endTime = Instant.now();
453         RequestFinishedInfo requestInfo = requestFinishedListener.getRequestInfo();
454         MetricsTestUtil.checkRequestFinishedInfo(requestInfo, mUrl, startTime, endTime);
455         assertEquals(RequestFinishedInfo.SUCCEEDED, requestInfo.getFinishedReason());
456         MetricsTestUtil.checkHasConnectTiming(requestInfo.getMetrics(), startTime, endTime, false);
457         // Check that annotation got updated in onSucceeded() callback.
458         assertEquals(requestAnnotation, requestInfo.getAnnotations().iterator().next());
459         assertTrue(requestAnnotation.get());
460     }
461 
462     @Test
463     @SmallTest
464     @OnlyRunNativeCronet
465     // Tests a failed request where the error originates from Java.
testOrderFailedRequestJava()466     public void testOrderFailedRequestJava() throws Exception {
467         final TestUrlRequestCallback callback = new TestUrlRequestCallback() {
468             @Override
469             public void onResponseStarted(UrlRequest request, UrlResponseInfo info) {
470                 throw new RuntimeException("make this request fail");
471             }
472         };
473         TestRequestFinishedListener requestFinishedListener =
474                 new AssertCallbackDoneRequestFinishedListener(callback);
475         mTestFramework.mCronetEngine.addRequestFinishedListener(requestFinishedListener);
476         UrlRequest.Builder urlRequestBuilder = mTestFramework.mCronetEngine.newUrlRequestBuilder(
477                 mUrl, callback, callback.getExecutor());
478         urlRequestBuilder.build().start();
479         callback.blockForDone();
480         assertTrue(callback.mOnErrorCalled);
481         requestFinishedListener.blockUntilDone();
482         RequestFinishedInfo requestInfo = requestFinishedListener.getRequestInfo();
483         assertNotNull("RequestFinishedInfo.Listener must be called", requestInfo);
484         assertEquals(mUrl, requestInfo.getUrl());
485         assertTrue(requestInfo.getAnnotations().isEmpty());
486         assertEquals(RequestFinishedInfo.FAILED, requestInfo.getFinishedReason());
487         assertNotNull(requestInfo.getException());
488         assertEquals("Exception received from UrlRequest.Callback",
489                 requestInfo.getException().getMessage());
490         RequestFinishedInfo.Metrics metrics = requestInfo.getMetrics();
491         assertNotNull("RequestFinishedInfo.getMetrics() must not be null", metrics);
492     }
493 
494     @Test
495     @SmallTest
496     @OnlyRunNativeCronet
497     // Tests a failed request where the error originates from native code.
testOrderFailedRequestNative()498     public void testOrderFailedRequestNative() throws Exception {
499         String connectionRefusedUrl = "http://127.0.0.1:3";
500         final TestUrlRequestCallback callback = new TestUrlRequestCallback();
501         TestRequestFinishedListener requestFinishedListener =
502                 new AssertCallbackDoneRequestFinishedListener(callback);
503         mTestFramework.mCronetEngine.addRequestFinishedListener(requestFinishedListener);
504         UrlRequest.Builder urlRequestBuilder = mTestFramework.mCronetEngine.newUrlRequestBuilder(
505                 connectionRefusedUrl, callback, callback.getExecutor());
506         urlRequestBuilder.build().start();
507         callback.blockForDone();
508         assertTrue(callback.mOnErrorCalled);
509         requestFinishedListener.blockUntilDone();
510         RequestFinishedInfo requestInfo = requestFinishedListener.getRequestInfo();
511         assertNotNull("RequestFinishedInfo.Listener must be called", requestInfo);
512         assertEquals(connectionRefusedUrl, requestInfo.getUrl());
513         assertTrue(requestInfo.getAnnotations().isEmpty());
514         assertEquals(RequestFinishedInfo.FAILED, requestInfo.getFinishedReason());
515         assertNotNull(requestInfo.getException());
516         assertEquals(NetworkException.ERROR_CONNECTION_REFUSED,
517                 ((NetworkException) requestInfo.getException()).getErrorCode());
518         RequestFinishedInfo.Metrics metrics = requestInfo.getMetrics();
519         assertNotNull("RequestFinishedInfo.getMetrics() must not be null", metrics);
520     }
521 
522     @Test
523     @SmallTest
524     @OnlyRunNativeCronet
testOrderCanceledRequest()525     public void testOrderCanceledRequest() throws Exception {
526         final TestUrlRequestCallback callback = new TestUrlRequestCallback() {
527             @Override
528             public void onResponseStarted(UrlRequest request, UrlResponseInfo info) {
529                 super.onResponseStarted(request, info);
530                 request.cancel();
531             }
532         };
533 
534         TestRequestFinishedListener requestFinishedListener =
535                 new AssertCallbackDoneRequestFinishedListener(callback);
536         mTestFramework.mCronetEngine.addRequestFinishedListener(requestFinishedListener);
537         ExperimentalUrlRequest.Builder urlRequestBuilder =
538                 (ExperimentalUrlRequest.Builder) mTestFramework.mCronetEngine.newUrlRequestBuilder(
539                         mUrl, callback, callback.getExecutor());
540         Instant startTime = Instant.now();
541         urlRequestBuilder.addRequestAnnotation("request annotation")
542                 .addRequestAnnotation(this)
543                 .build()
544                 .start();
545         callback.blockForDone();
546         requestFinishedListener.blockUntilDone();
547         Instant endTime = Instant.now();
548 
549         RequestFinishedInfo requestInfo = requestFinishedListener.getRequestInfo();
550         MetricsTestUtil.checkRequestFinishedInfo(requestInfo, mUrl, startTime, endTime);
551         assertEquals(RequestFinishedInfo.CANCELED, requestInfo.getFinishedReason());
552         MetricsTestUtil.checkHasConnectTiming(requestInfo.getMetrics(), startTime, endTime, false);
553 
554         assertEquals(newHashSet("request annotation", this), // Use sets for unordered comparison.
555                 new HashSet<Object>(requestInfo.getAnnotations()));
556     }
557 }
558