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 java.time.temporal.ChronoUnit.MILLIS; 8 9 import static org.junit.Assert.assertEquals; 10 import static org.junit.Assert.assertNotNull; 11 import static org.junit.Assert.assertNull; 12 import static org.junit.Assert.assertTrue; 13 14 import android.net.http.RequestFinishedInfo; 15 16 import java.time.Instant; 17 import java.util.LinkedList; 18 import java.util.NoSuchElementException; 19 import java.util.concurrent.Executor; 20 21 /** 22 * Classes which are useful for testing Cronet's metrics implementation and are needed in more than 23 * one test file. 24 */ 25 public class MetricsTestUtil { 26 /** 27 * Executor which runs tasks only when told to with runAllTasks(). 28 */ 29 public static class TestExecutor implements Executor { 30 private final LinkedList<Runnable> mTaskQueue = new LinkedList<Runnable>(); 31 32 @Override execute(Runnable task)33 public void execute(Runnable task) { 34 mTaskQueue.add(task); 35 } 36 runAllTasks()37 public void runAllTasks() { 38 try { 39 while (mTaskQueue.size() > 0) { 40 mTaskQueue.remove().run(); 41 } 42 } catch (NoSuchElementException e) { 43 throw new RuntimeException("Task was removed during iteration", e); 44 } 45 } 46 } 47 48 // Helper method to assert date1 is equals to or after date2. 49 // Truncate to MILLIS because CronetMetrics are in MILLIS. assertAfter(Instant date1, Instant date2)50 public static void assertAfter(Instant date1, Instant date2) { 51 Instant date1Ms = date1.truncatedTo(MILLIS); 52 Instant date2Ms = date2.truncatedTo(MILLIS); 53 assertTrue("date1: " + date1 + ", date2: " + date2Ms, 54 date1Ms.isAfter(date2Ms) || date1Ms.equals(date2Ms)); 55 } 56 57 /** 58 * Check existence of all the timing metrics that apply to most test requests, 59 * except those that come from net::LoadTimingInfo::ConnectTiming. 60 * Also check some timing differences, focusing on things we can't check with asserts in the 61 * CronetMetrics constructor. 62 * Don't check push times here. 63 */ checkTimingMetrics( RequestFinishedInfo.Metrics metrics, Instant startTime, Instant endTime)64 public static void checkTimingMetrics( 65 RequestFinishedInfo.Metrics metrics, Instant startTime, Instant endTime) { 66 assertNotNull(metrics.getRequestStart()); 67 assertAfter(metrics.getRequestStart(), startTime); 68 assertNotNull(metrics.getSendingStart()); 69 assertAfter(metrics.getSendingStart(), startTime); 70 assertNotNull(metrics.getSendingEnd()); 71 assertAfter(endTime, metrics.getSendingEnd()); 72 assertNotNull(metrics.getResponseStart()); 73 assertAfter(metrics.getResponseStart(), startTime); 74 assertNotNull(metrics.getRequestEnd()); 75 assertAfter(endTime, metrics.getRequestEnd()); 76 assertAfter(metrics.getRequestEnd(), metrics.getRequestStart()); 77 } 78 79 /** 80 * Check that the timing metrics which come from net::LoadTimingInfo::ConnectTiming exist, 81 * except SSL times in the case of non-https requests. 82 */ checkHasConnectTiming( RequestFinishedInfo.Metrics metrics, Instant startTime, Instant endTime, boolean isSsl)83 public static void checkHasConnectTiming( 84 RequestFinishedInfo.Metrics metrics, Instant startTime, Instant endTime, boolean isSsl) { 85 assertNotNull(metrics.getDnsStart()); 86 assertAfter(metrics.getDnsStart(), startTime); 87 assertNotNull(metrics.getDnsEnd()); 88 assertAfter(endTime, metrics.getDnsEnd()); 89 assertNotNull(metrics.getConnectStart()); 90 assertAfter(metrics.getConnectStart(), startTime); 91 assertNotNull(metrics.getConnectEnd()); 92 assertAfter(endTime, metrics.getConnectEnd()); 93 if (isSsl) { 94 assertNotNull(metrics.getSslStart()); 95 assertAfter(metrics.getSslStart(), startTime); 96 assertNotNull(metrics.getSslEnd()); 97 assertAfter(endTime, metrics.getSslEnd()); 98 } else { 99 assertNull(metrics.getSslStart()); 100 assertNull(metrics.getSslEnd()); 101 } 102 } 103 104 /** 105 * Check that the timing metrics from net::LoadTimingInfo::ConnectTiming don't exist. 106 */ checkNoConnectTiming(RequestFinishedInfo.Metrics metrics)107 public static void checkNoConnectTiming(RequestFinishedInfo.Metrics metrics) { 108 assertNull(metrics.getDnsStart()); 109 assertNull(metrics.getDnsEnd()); 110 assertNull(metrics.getSslStart()); 111 assertNull(metrics.getSslEnd()); 112 assertNull(metrics.getConnectStart()); 113 assertNull(metrics.getConnectEnd()); 114 } 115 116 /** 117 * Check that RequestFinishedInfo looks the way it should look for a normal successful request. 118 */ checkRequestFinishedInfo( RequestFinishedInfo info, String url, Instant startTime, Instant endTime)119 public static void checkRequestFinishedInfo( 120 RequestFinishedInfo info, String url, Instant startTime, Instant endTime) { 121 assertNotNull("RequestFinishedInfo.Listener must be called", info); 122 assertEquals(url, info.getUrl()); 123 assertNotNull(info.getResponseInfo()); 124 assertNull(info.getException()); 125 RequestFinishedInfo.Metrics metrics = info.getMetrics(); 126 assertNotNull("RequestFinishedInfo.getMetrics() must not be null", metrics); 127 // Check new timing metrics 128 checkTimingMetrics(metrics, startTime, endTime); 129 assertNull(metrics.getPushStart()); 130 assertNull(metrics.getPushEnd()); 131 // Check data use metrics 132 assertTrue(metrics.getSentByteCount() > 0); 133 assertTrue(metrics.getReceivedByteCount() > 0); 134 } 135 } 136