• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2022 Google LLC
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.google.android.libraries.mobiledatadownload.internal.logging;
17 
18 import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
19 
20 import static org.junit.Assert.assertFalse;
21 import static org.junit.Assert.assertTrue;
22 import static org.mockito.Mockito.verify;
23 import static org.mockito.Mockito.verifyNoInteractions;
24 
25 import android.content.Context;
26 
27 import androidx.test.core.app.ApplicationProvider;
28 
29 import com.google.android.libraries.mobiledatadownload.Logger;
30 import com.google.android.libraries.mobiledatadownload.testing.FakeTimeSource;
31 import com.google.android.libraries.mobiledatadownload.testing.MddTestDependencies;
32 import com.google.android.libraries.mobiledatadownload.testing.TestFlags;
33 import com.google.common.base.Optional;
34 import com.google.mobiledatadownload.LogEnumsProto.MddClientEvent;
35 import com.google.mobiledatadownload.LogEnumsProto.MddDownloadResult;
36 import com.google.mobiledatadownload.LogProto.AndroidClientInfo;
37 import com.google.mobiledatadownload.LogProto.DataDownloadFileGroupStats;
38 import com.google.mobiledatadownload.LogProto.MddDeviceInfo;
39 import com.google.mobiledatadownload.LogProto.MddDownloadResultLog;
40 import com.google.mobiledatadownload.LogProto.MddLogData;
41 import com.google.mobiledatadownload.LogProto.StableSamplingInfo;
42 
43 import org.junit.Before;
44 import org.junit.Rule;
45 import org.junit.Test;
46 import org.junit.runner.RunWith;
47 import org.mockito.Mock;
48 import org.mockito.junit.MockitoJUnit;
49 import org.mockito.junit.MockitoRule;
50 import org.robolectric.RobolectricTestRunner;
51 
52 import java.security.SecureRandom;
53 import java.util.Random;
54 
55 @RunWith(RobolectricTestRunner.class)
56 public class MddEventLoggerTest {
57 
58     @Rule
59     public final MockitoRule mocks = MockitoJUnit.rule();
60 
61     private static final int SOME_MODULE_VERSION = 42;
62     private static final int SAMPLING_ALWAYS = 1;
63     private static final int SAMPLING_NEVER = 0;
64 
65     @Mock
66     private Logger mockLogger;
67     private MddEventLogger mddEventLogger;
68 
69     private final Context context = ApplicationProvider.getApplicationContext();
70     private final TestFlags flags = new TestFlags();
71 
72     @Before
setUp()73     public void setUp() throws Exception {
74         mddEventLogger =
75                 new MddEventLogger(
76                         context,
77                         mockLogger,
78                         SOME_MODULE_VERSION,
79                         new LogSampler(flags, new SecureRandom()),
80                         flags);
81         mddEventLogger.setLoggingStateStore(
82                 MddTestDependencies.LoggingStateStoreImpl.SHARED_PREFERENCES.loggingStateStore(
83                         context, Optional.absent(), new FakeTimeSource(), directExecutor(),
84                         new Random(0)));
85     }
86 
newLogDataBuilderWithClientInfo()87     private MddLogData.Builder newLogDataBuilderWithClientInfo() {
88         return MddLogData.newBuilder()
89                 .setAndroidClientInfo(
90                         AndroidClientInfo.newBuilder()
91                                 .setModuleVersion(SOME_MODULE_VERSION)
92                                 .setHostPackageName(context.getPackageName()));
93     }
94 
95     @Test
testSampleInterval_zero_none()96     public void testSampleInterval_zero_none() {
97         assertFalse(LogUtil.shouldSampleInterval(0));
98     }
99 
100     @Test
testSampleInterval_negative_none()101     public void testSampleInterval_negative_none() {
102         assertFalse(LogUtil.shouldSampleInterval(-1));
103     }
104 
105     @Test
testSampleInterval_always()106     public void testSampleInterval_always() {
107         assertTrue(LogUtil.shouldSampleInterval(1));
108     }
109 
110     @Test
testLogMddEvents_noLog()111     public void testLogMddEvents_noLog() {
112         overrideDefaultSampleInterval(SAMPLING_NEVER);
113 
114         mddEventLogger.logEventSampled(
115                 MddClientEvent.Code.EVENT_CODE_UNSPECIFIED,
116                 "fileGroup",
117                 /* fileGroupVersionNumber= */ 0,
118                 /* buildId= */ 0,
119                 /* variantId= */ "");
120         verifyNoInteractions(mockLogger);
121     }
122 
123     @Test
testLogMddEvents()124     public void testLogMddEvents() {
125         overrideDefaultSampleInterval(SAMPLING_ALWAYS);
126         mddEventLogger.logEventSampled(
127                 MddClientEvent.Code.EVENT_CODE_UNSPECIFIED,
128                 "fileGroup",
129                 /* fileGroupVersionNumber= */ 1,
130                 /* buildId= */ 123,
131                 /* variantId= */ "testVariant");
132 
133         MddLogData expectedData =
134                 newLogDataBuilderWithClientInfo()
135                         .setSamplingInterval(SAMPLING_ALWAYS)
136                         .setDataDownloadFileGroupStats(
137                                 DataDownloadFileGroupStats.newBuilder()
138                                         .setFileGroupName("fileGroup")
139                                         .setFileGroupVersionNumber(1)
140                                         .setBuildId(123)
141                                         .setVariantId("testVariant"))
142                         .setDeviceInfo(MddDeviceInfo.newBuilder().setDeviceStorageLow(false))
143                         .setStableSamplingInfo(getStableSamplingInfo())
144                         .build();
145 
146         verify(mockLogger).log(expectedData, MddClientEvent.Code.EVENT_CODE_UNSPECIFIED_VALUE);
147     }
148 
149     @Test
testLogExpirationHandlerRemoveUnaccountedFilesSampled()150     public void testLogExpirationHandlerRemoveUnaccountedFilesSampled() {
151         final int unaccountedFileCount = 5;
152         overrideDefaultSampleInterval(SAMPLING_ALWAYS);
153         mddEventLogger.logMddDataDownloadFileExpirationEvent(0, unaccountedFileCount);
154 
155         MddLogData expectedData =
156                 newLogDataBuilderWithClientInfo()
157                         .setSamplingInterval(SAMPLING_ALWAYS)
158                         .setDeviceInfo(MddDeviceInfo.newBuilder().setDeviceStorageLow(false))
159                         .setStableSamplingInfo(getStableSamplingInfo())
160                         .build();
161 
162         verify(mockLogger).log(expectedData, MddClientEvent.Code.EVENT_CODE_UNSPECIFIED_VALUE);
163     }
164 
165     @Test
testLogMddNetworkSavingsSampled()166     public void testLogMddNetworkSavingsSampled() {
167         overrideDefaultSampleInterval(SAMPLING_ALWAYS);
168         DataDownloadFileGroupStats icingDataDownloadFileGroupStats =
169                 DataDownloadFileGroupStats.newBuilder()
170                         .setFileGroupName("fileGroup")
171                         .setFileGroupVersionNumber(1)
172                         .build();
173         mddEventLogger.logMddNetworkSavings(
174                 icingDataDownloadFileGroupStats, 0, 200L, 100L, "file-id", 1);
175         MddLogData expectedData =
176                 newLogDataBuilderWithClientInfo()
177                         .setSamplingInterval(SAMPLING_ALWAYS)
178                         .setDeviceInfo(MddDeviceInfo.newBuilder().setDeviceStorageLow(false))
179                         .setStableSamplingInfo(getStableSamplingInfo())
180                         .build();
181 
182         verify(mockLogger).log(expectedData, MddClientEvent.Code.EVENT_CODE_UNSPECIFIED_VALUE);
183     }
184 
185     @Test
testLogMddDownloadResult()186     public void testLogMddDownloadResult() {
187         overrideDefaultSampleInterval(SAMPLING_ALWAYS);
188         DataDownloadFileGroupStats icingDataDownloadFileGroupStats =
189                 DataDownloadFileGroupStats.newBuilder()
190                         .setFileGroupName("fileGroup")
191                         .setFileGroupVersionNumber(1)
192                         .build();
193         mddEventLogger.logMddDownloadResult(
194                 MddDownloadResult.Code.LOW_DISK_ERROR, icingDataDownloadFileGroupStats);
195 
196         MddLogData expectedData =
197                 newLogDataBuilderWithClientInfo()
198                         .setSamplingInterval(SAMPLING_ALWAYS)
199                         .setMddDownloadResultLog(
200                                 MddDownloadResultLog.newBuilder()
201                                         .setResult(MddDownloadResult.Code.LOW_DISK_ERROR)
202                                         .setDataDownloadFileGroupStats(
203                                                 icingDataDownloadFileGroupStats))
204                         .setDeviceInfo(MddDeviceInfo.newBuilder().setDeviceStorageLow(false))
205                         .setStableSamplingInfo(getStableSamplingInfo())
206                         .build();
207 
208         verify(mockLogger).log(expectedData, MddClientEvent.Code.DATA_DOWNLOAD_RESULT_LOG_VALUE);
209     }
210 
211     @Test
testLogMddUsageEvent()212     public void testLogMddUsageEvent() {
213         overrideDefaultSampleInterval(SAMPLING_ALWAYS);
214 
215         DataDownloadFileGroupStats icingDataDownloadFileGroupStats =
216                 DataDownloadFileGroupStats.newBuilder()
217                         .setFileGroupName("fileGroup")
218                         .setFileGroupVersionNumber(1)
219                         .setBuildId(123)
220                         .setVariantId("variant-id")
221                         .build();
222 
223         Void usageEventLog = null;
224 
225         mddEventLogger.logMddUsageEvent(icingDataDownloadFileGroupStats, usageEventLog);
226 
227         MddLogData expectedData =
228                 newLogDataBuilderWithClientInfo()
229                         .setDataDownloadFileGroupStats(icingDataDownloadFileGroupStats)
230                         .setSamplingInterval(SAMPLING_ALWAYS)
231                         .setDeviceInfo(MddDeviceInfo.newBuilder().setDeviceStorageLow(false))
232                         .setStableSamplingInfo(getStableSamplingInfo())
233                         .build();
234 
235         verify(mockLogger).log(expectedData, MddClientEvent.Code.EVENT_CODE_UNSPECIFIED_VALUE);
236     }
237 
238     @Test
testlogMddLibApiResultLog()239     public void testlogMddLibApiResultLog() {
240         overrideApiLoggingSampleInterval(SAMPLING_ALWAYS);
241 
242         DataDownloadFileGroupStats icingDataDownloadFileGroupStats =
243                 DataDownloadFileGroupStats.newBuilder()
244                         .setFileGroupName("fileGroup")
245                         .setFileGroupVersionNumber(1)
246                         .build();
247 
248         Void mddLibApiResultLog = null;
249         mddEventLogger.logMddLibApiResultLog(mddLibApiResultLog);
250 
251         MddLogData expectedData =
252                 newLogDataBuilderWithClientInfo()
253                         .setSamplingInterval(SAMPLING_ALWAYS)
254                         .setDeviceInfo(MddDeviceInfo.newBuilder().setDeviceStorageLow(false))
255                         .setStableSamplingInfo(getStableSamplingInfo())
256                         .build();
257 
258         verify(mockLogger).log(expectedData, MddClientEvent.Code.EVENT_CODE_UNSPECIFIED_VALUE);
259     }
260 
overrideDefaultSampleInterval(int sampleInterval)261     private void overrideDefaultSampleInterval(int sampleInterval) {
262         flags.mddDefaultSampleInterval = Optional.of(sampleInterval);
263     }
264 
overrideApiLoggingSampleInterval(int sampleInterval)265     private void overrideApiLoggingSampleInterval(int sampleInterval) {
266         flags.apiLoggingSampleInterval = Optional.of(sampleInterval);
267     }
268 
getStableSamplingInfo()269     private StableSamplingInfo getStableSamplingInfo() {
270         if (flags.enableRngBasedDeviceStableSampling()) {
271             return StableSamplingInfo.newBuilder()
272                     .setStableSamplingUsed(true)
273                     .setStableSamplingFirstEnabledTimestampMs(0)
274                     .setPartOfAlwaysLoggingGroup(false)
275                     .setInvalidSamplingRateUsed(false)
276                     .build();
277         }
278 
279         return StableSamplingInfo.newBuilder().setStableSamplingUsed(false).build();
280     }
281 }
282