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