• 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 import static org.junit.Assert.assertFalse;
20 import static org.junit.Assert.assertTrue;
21 import static org.mockito.Mockito.verify;
22 import static org.mockito.Mockito.verifyNoInteractions;
23 
24 import android.content.Context;
25 import androidx.test.core.app.ApplicationProvider;
26 import com.google.android.libraries.mobiledatadownload.Logger;
27 import com.google.android.libraries.mobiledatadownload.testing.FakeTimeSource;
28 import com.google.android.libraries.mobiledatadownload.testing.MddTestDependencies;
29 import com.google.android.libraries.mobiledatadownload.testing.TestFlags;
30 import com.google.common.base.Optional;
31 import com.google.mobiledatadownload.LogEnumsProto.MddClientEvent;
32 import com.google.mobiledatadownload.LogEnumsProto.MddDownloadResult;
33 import com.google.mobiledatadownload.LogProto.AndroidClientInfo;
34 import com.google.mobiledatadownload.LogProto.DataDownloadFileGroupStats;
35 import com.google.mobiledatadownload.LogProto.MddDeviceInfo;
36 import com.google.mobiledatadownload.LogProto.MddDownloadResultLog;
37 import com.google.mobiledatadownload.LogProto.MddLogData;
38 import com.google.mobiledatadownload.LogProto.StableSamplingInfo;
39 import java.security.SecureRandom;
40 import java.util.Random;
41 import org.junit.Before;
42 import org.junit.Rule;
43 import org.junit.Test;
44 import org.junit.runner.RunWith;
45 import org.mockito.Mock;
46 import org.mockito.junit.MockitoJUnit;
47 import org.mockito.junit.MockitoRule;
48 import org.robolectric.RobolectricTestRunner;
49 
50 @RunWith(RobolectricTestRunner.class)
51 public class MddEventLoggerTest {
52 
53   @Rule public final MockitoRule mocks = MockitoJUnit.rule();
54 
55   private static final int SOME_MODULE_VERSION = 42;
56   private static final int SAMPLING_ALWAYS = 1;
57   private static final int SAMPLING_NEVER = 0;
58 
59   @Mock private Logger mockLogger;
60   private MddEventLogger mddEventLogger;
61 
62   private final Context context = ApplicationProvider.getApplicationContext();
63   private final TestFlags flags = new TestFlags();
64 
65   @Before
setUp()66   public void setUp() throws Exception {
67     mddEventLogger =
68         new MddEventLogger(
69             context,
70             mockLogger,
71             SOME_MODULE_VERSION,
72             new LogSampler(flags, new SecureRandom()),
73             flags);
74     mddEventLogger.setLoggingStateStore(
75         MddTestDependencies.LoggingStateStoreImpl.SHARED_PREFERENCES.loggingStateStore(
76             context, Optional.absent(), new FakeTimeSource(), directExecutor(), new Random(0)));
77   }
78 
newLogDataBuilderWithClientInfo()79   private MddLogData.Builder newLogDataBuilderWithClientInfo() {
80     return MddLogData.newBuilder()
81         .setAndroidClientInfo(
82             AndroidClientInfo.newBuilder()
83                 .setModuleVersion(SOME_MODULE_VERSION)
84                 .setHostPackageName(context.getPackageName()));
85   }
86 
87   @Test
testSampleInterval_zero_none()88   public void testSampleInterval_zero_none() {
89     assertFalse(LogUtil.shouldSampleInterval(0));
90   }
91 
92   @Test
testSampleInterval_negative_none()93   public void testSampleInterval_negative_none() {
94     assertFalse(LogUtil.shouldSampleInterval(-1));
95   }
96 
97   @Test
testSampleInterval_always()98   public void testSampleInterval_always() {
99     assertTrue(LogUtil.shouldSampleInterval(1));
100   }
101 
102   @Test
testLogMddEvents_noLog()103   public void testLogMddEvents_noLog() {
104     overrideDefaultSampleInterval(SAMPLING_NEVER);
105 
106     mddEventLogger.logEventSampled(
107         MddClientEvent.Code.EVENT_CODE_UNSPECIFIED,
108         "fileGroup",
109         /* fileGroupVersionNumber= */ 0,
110         /* buildId= */ 0,
111         /* variantId= */ "");
112     verifyNoInteractions(mockLogger);
113   }
114 
115   @Test
testLogMddEvents()116   public void testLogMddEvents() {
117     overrideDefaultSampleInterval(SAMPLING_ALWAYS);
118     mddEventLogger.logEventSampled(
119         MddClientEvent.Code.EVENT_CODE_UNSPECIFIED,
120         "fileGroup",
121         /* fileGroupVersionNumber= */ 1,
122         /* buildId= */ 123,
123         /* variantId= */ "testVariant");
124 
125     MddLogData expectedData =
126         newLogDataBuilderWithClientInfo()
127             .setSamplingInterval(SAMPLING_ALWAYS)
128             .setDataDownloadFileGroupStats(
129                 DataDownloadFileGroupStats.newBuilder()
130                     .setFileGroupName("fileGroup")
131                     .setFileGroupVersionNumber(1)
132                     .setBuildId(123)
133                     .setVariantId("testVariant"))
134             .setDeviceInfo(MddDeviceInfo.newBuilder().setDeviceStorageLow(false))
135             .setStableSamplingInfo(getStableSamplingInfo())
136             .build();
137 
138     verify(mockLogger).log(expectedData, MddClientEvent.Code.EVENT_CODE_UNSPECIFIED_VALUE);
139   }
140 
141   @Test
testLogExpirationHandlerRemoveUnaccountedFilesSampled()142   public void testLogExpirationHandlerRemoveUnaccountedFilesSampled() {
143     final int unaccountedFileCount = 5;
144     overrideDefaultSampleInterval(SAMPLING_ALWAYS);
145     mddEventLogger.logMddDataDownloadFileExpirationEvent(0, unaccountedFileCount);
146 
147     MddLogData expectedData =
148         newLogDataBuilderWithClientInfo()
149             .setSamplingInterval(SAMPLING_ALWAYS)
150             .setDeviceInfo(MddDeviceInfo.newBuilder().setDeviceStorageLow(false))
151             .setStableSamplingInfo(getStableSamplingInfo())
152             .build();
153 
154     verify(mockLogger).log(expectedData, MddClientEvent.Code.EVENT_CODE_UNSPECIFIED_VALUE);
155   }
156 
157   @Test
testLogMddNetworkSavingsSampled()158   public void testLogMddNetworkSavingsSampled() {
159     overrideDefaultSampleInterval(SAMPLING_ALWAYS);
160     DataDownloadFileGroupStats icingDataDownloadFileGroupStats =
161         DataDownloadFileGroupStats.newBuilder()
162             .setFileGroupName("fileGroup")
163             .setFileGroupVersionNumber(1)
164             .build();
165     mddEventLogger.logMddNetworkSavings(
166         icingDataDownloadFileGroupStats, 0, 200L, 100L, "file-id", 1);
167     MddLogData expectedData =
168         newLogDataBuilderWithClientInfo()
169             .setSamplingInterval(SAMPLING_ALWAYS)
170             .setDeviceInfo(MddDeviceInfo.newBuilder().setDeviceStorageLow(false))
171             .setStableSamplingInfo(getStableSamplingInfo())
172             .build();
173 
174     verify(mockLogger).log(expectedData, MddClientEvent.Code.EVENT_CODE_UNSPECIFIED_VALUE);
175   }
176 
177   @Test
testLogMddDownloadResult()178   public void testLogMddDownloadResult() {
179     overrideDefaultSampleInterval(SAMPLING_ALWAYS);
180     DataDownloadFileGroupStats icingDataDownloadFileGroupStats =
181         DataDownloadFileGroupStats.newBuilder()
182             .setFileGroupName("fileGroup")
183             .setFileGroupVersionNumber(1)
184             .build();
185     mddEventLogger.logMddDownloadResult(
186         MddDownloadResult.Code.LOW_DISK_ERROR, icingDataDownloadFileGroupStats);
187 
188     MddLogData expectedData =
189         newLogDataBuilderWithClientInfo()
190             .setSamplingInterval(SAMPLING_ALWAYS)
191             .setMddDownloadResultLog(
192                 MddDownloadResultLog.newBuilder()
193                     .setResult(MddDownloadResult.Code.LOW_DISK_ERROR)
194                     .setDataDownloadFileGroupStats(icingDataDownloadFileGroupStats))
195             .setDeviceInfo(MddDeviceInfo.newBuilder().setDeviceStorageLow(false))
196             .setStableSamplingInfo(getStableSamplingInfo())
197             .build();
198 
199     verify(mockLogger).log(expectedData, MddClientEvent.Code.DATA_DOWNLOAD_RESULT_LOG_VALUE);
200   }
201 
202   @Test
testLogMddUsageEvent()203   public void testLogMddUsageEvent() {
204     overrideDefaultSampleInterval(SAMPLING_ALWAYS);
205 
206     DataDownloadFileGroupStats icingDataDownloadFileGroupStats =
207         DataDownloadFileGroupStats.newBuilder()
208             .setFileGroupName("fileGroup")
209             .setFileGroupVersionNumber(1)
210             .setBuildId(123)
211             .setVariantId("variant-id")
212             .build();
213 
214     Void usageEventLog = null;
215 
216     mddEventLogger.logMddUsageEvent(icingDataDownloadFileGroupStats, usageEventLog);
217 
218     MddLogData expectedData =
219         newLogDataBuilderWithClientInfo()
220             .setDataDownloadFileGroupStats(icingDataDownloadFileGroupStats)
221             .setSamplingInterval(SAMPLING_ALWAYS)
222             .setDeviceInfo(MddDeviceInfo.newBuilder().setDeviceStorageLow(false))
223             .setStableSamplingInfo(getStableSamplingInfo())
224             .build();
225 
226     verify(mockLogger).log(expectedData, MddClientEvent.Code.EVENT_CODE_UNSPECIFIED_VALUE);
227   }
228 
229   @Test
testlogMddLibApiResultLog()230   public void testlogMddLibApiResultLog() {
231     overrideApiLoggingSampleInterval(SAMPLING_ALWAYS);
232 
233     DataDownloadFileGroupStats icingDataDownloadFileGroupStats =
234         DataDownloadFileGroupStats.newBuilder()
235             .setFileGroupName("fileGroup")
236             .setFileGroupVersionNumber(1)
237             .build();
238 
239     Void mddLibApiResultLog = null;
240     mddEventLogger.logMddLibApiResultLog(mddLibApiResultLog);
241 
242     MddLogData expectedData =
243         newLogDataBuilderWithClientInfo()
244             .setSamplingInterval(SAMPLING_ALWAYS)
245             .setDeviceInfo(MddDeviceInfo.newBuilder().setDeviceStorageLow(false))
246             .setStableSamplingInfo(getStableSamplingInfo())
247             .build();
248 
249     verify(mockLogger).log(expectedData, MddClientEvent.Code.EVENT_CODE_UNSPECIFIED_VALUE);
250   }
251 
overrideDefaultSampleInterval(int sampleInterval)252   private void overrideDefaultSampleInterval(int sampleInterval) {
253     flags.mddDefaultSampleInterval = Optional.of(sampleInterval);
254   }
255 
overrideApiLoggingSampleInterval(int sampleInterval)256   private void overrideApiLoggingSampleInterval(int sampleInterval) {
257     flags.apiLoggingSampleInterval = Optional.of(sampleInterval);
258   }
259 
getStableSamplingInfo()260   private StableSamplingInfo getStableSamplingInfo() {
261     if (flags.enableRngBasedDeviceStableSampling()) {
262       return StableSamplingInfo.newBuilder()
263           .setStableSamplingUsed(true)
264           .setStableSamplingFirstEnabledTimestampMs(0)
265           .setPartOfAlwaysLoggingGroup(false)
266           .setInvalidSamplingRateUsed(false)
267           .build();
268     }
269 
270     return StableSamplingInfo.newBuilder().setStableSamplingUsed(false).build();
271   }
272 }
273