• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2023 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.telemetry;
6 
7 import static com.google.common.truth.TruthJUnit.assume;
8 
9 import static org.mockito.Mockito.never;
10 import static org.mockito.Mockito.spy;
11 import static org.mockito.Mockito.times;
12 import static org.mockito.Mockito.verify;
13 
14 import android.os.Build;
15 import android.os.ConditionVariable;
16 
17 import androidx.test.ext.junit.runners.AndroidJUnit4;
18 
19 import org.junit.Before;
20 import org.junit.Rule;
21 import org.junit.Test;
22 import org.junit.runner.RunWith;
23 import org.mockito.Mock;
24 import org.mockito.junit.MockitoJUnit;
25 import org.mockito.junit.MockitoRule;
26 
27 import org.chromium.base.test.util.Batch;
28 import org.chromium.net.impl.CronetLogger.CronetEngineBuilderInfo;
29 import org.chromium.net.impl.CronetLogger.CronetSource;
30 import org.chromium.net.impl.CronetLogger.CronetTrafficInfo;
31 import org.chromium.net.impl.CronetLogger.CronetVersion;
32 
33 @RunWith(AndroidJUnit4.class)
34 @Batch(Batch.UNIT_TESTS)
35 public final class CronetLoggerImplTest {
CronetLoggerImplTest()36     public CronetLoggerImplTest() {
37         // CronetLoggerImpl only supports R+
38         assume().that(Build.VERSION.SDK_INT).isAtLeast(Build.VERSION_CODES.R);
39         // TODO(crbug.com/1503671): Chromium Mockito doesn't work on Android 14. Remove this line
40         // once Mockito is fixed.
41         assume().that(Build.VERSION.SDK_INT).isLessThan(Build.VERSION_CODES.UPSIDE_DOWN_CAKE);
42     }
43 
44     @Rule public final MockitoRule mockito = MockitoJUnit.rule();
45 
46     private static final int CRONET_ENGINE_ID = 1;
47     private static final CronetSource SOURCE = CronetSource.CRONET_SOURCE_STATICALLY_LINKED;
48 
49     private CronetLoggerImpl mCronetLoggerImpl;
50 
51     @Mock CronetEngineBuilderInfo mBuilderInfo;
52     @Mock CronetVersion mVersion;
53     @Mock CronetTrafficInfo mTrafficInfo;
54 
55     @Before
setUp()56     public void setUp() {
57         mCronetLoggerImpl = spy(new CronetLoggerImpl(1));
58     }
59 
60     @Test
testLogCronetEngineCreated_validInputs_shouldExecuteWrite()61     public void testLogCronetEngineCreated_validInputs_shouldExecuteWrite() {
62         mCronetLoggerImpl.logCronetEngineCreation(CRONET_ENGINE_ID, mBuilderInfo, mVersion, SOURCE);
63 
64         verify(mCronetLoggerImpl, times(1))
65                 .writeCronetEngineCreation(CRONET_ENGINE_ID, mBuilderInfo, mVersion, SOURCE);
66     }
67 
68     @Test
testLogCronetEngineCreated_invalidInputs_shouldNotExecuteWrite()69     public void testLogCronetEngineCreated_invalidInputs_shouldNotExecuteWrite() {
70         mCronetLoggerImpl.logCronetEngineCreation(CRONET_ENGINE_ID, null, mVersion, SOURCE);
71 
72         verify(mCronetLoggerImpl, never())
73                 .writeCronetEngineCreation(CRONET_ENGINE_ID, null, mVersion, SOURCE);
74     }
75 
76     @Test
testLogCronetTrafficInfo_validInputs_shouldExecuteWrite()77     public void testLogCronetTrafficInfo_validInputs_shouldExecuteWrite() {
78         mCronetLoggerImpl.logCronetTrafficInfo(CRONET_ENGINE_ID, mTrafficInfo);
79 
80         verify(mCronetLoggerImpl, times(1))
81                 .writeCronetTrafficReported(CRONET_ENGINE_ID, mTrafficInfo, 0);
82     }
83 
84     @Test
testLogCronetTrafficInfo_invalidInputs_shouldNotExecuteWrite()85     public void testLogCronetTrafficInfo_invalidInputs_shouldNotExecuteWrite() {
86         mCronetLoggerImpl.logCronetTrafficInfo(CRONET_ENGINE_ID, null);
87 
88         verify(mCronetLoggerImpl, never()).writeCronetTrafficReported(CRONET_ENGINE_ID, null, 0);
89     }
90 
91     // TODO(b/309098875): the internal repo these tests were originally written in had the following
92     // tests:
93     // - logCronetTrafficInfo_samplesRateLimited_shouldBeZero
94     // - logCronetTrafficInfo_samplesRateLimited_shouldBe2
95     // - logCronetTrafficInfo_simultaneousLogs_shouldExecuteWriteOnce
96     // Problem is these tests used the Roboelectric ShadowSystemClock, which we can't easily use
97     // here. We should find a way to work around that. In the mean time, these tests are omitted.
98 
99     @Test
testLogCronetTrafficInfo_twoSamplesPerSecond_shouldLogTwice()100     public void testLogCronetTrafficInfo_twoSamplesPerSecond_shouldLogTwice() {
101         mCronetLoggerImpl = spy(new CronetLoggerImpl(2));
102 
103         mCronetLoggerImpl.logCronetTrafficInfo(CRONET_ENGINE_ID, mTrafficInfo);
104         mCronetLoggerImpl.logCronetTrafficInfo(CRONET_ENGINE_ID, mTrafficInfo);
105         mCronetLoggerImpl.logCronetTrafficInfo(CRONET_ENGINE_ID, mTrafficInfo);
106 
107         verify(mCronetLoggerImpl, times(2))
108                 .writeCronetTrafficReported(CRONET_ENGINE_ID, mTrafficInfo, 0);
109     }
110 
111     static class LogThread extends Thread {
112         final CronetLoggerImpl mLogger;
113         final ConditionVariable mRunBlocker;
114         final CronetTrafficInfo mTrafficInfo;
115 
LogThread( CronetLoggerImpl logger, ConditionVariable runBlocker, CronetTrafficInfo trafficInfo)116         public LogThread(
117                 CronetLoggerImpl logger,
118                 ConditionVariable runBlocker,
119                 CronetTrafficInfo trafficInfo) {
120             this.mLogger = logger;
121             this.mRunBlocker = runBlocker;
122             this.mTrafficInfo = trafficInfo;
123         }
124 
125         @Override
run()126         public void run() {
127             mRunBlocker.block();
128             mLogger.logCronetTrafficInfo(CRONET_ENGINE_ID, mTrafficInfo);
129         }
130     }
131 }
132