• 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.truth.Truth.assertThat;
19 import static junit.framework.TestCase.assertTrue;
20 import static org.junit.Assert.assertFalse;
21 import static org.mockito.ArgumentMatchers.any;
22 import static org.mockito.Mockito.times;
23 import static org.mockito.Mockito.verify;
24 import static org.mockito.Mockito.when;
25 
26 import com.google.mobiledatadownload.internal.MetadataProto.DataFile;
27 import com.google.mobiledatadownload.internal.MetadataProto.DataFileGroupBookkeeping;
28 import com.google.mobiledatadownload.internal.MetadataProto.DataFileGroupInternal;
29 import com.google.mobiledatadownload.internal.MetadataProto.GroupKey;
30 import com.google.android.libraries.mobiledatadownload.internal.FileGroupManager;
31 import com.google.android.libraries.mobiledatadownload.internal.FileGroupManager.GroupDownloadStatus;
32 import com.google.android.libraries.mobiledatadownload.internal.FileGroupsMetadata;
33 import com.google.android.libraries.mobiledatadownload.internal.MddTestUtil;
34 import com.google.android.libraries.mobiledatadownload.internal.collect.GroupKeyAndGroup;
35 import com.google.android.libraries.mobiledatadownload.internal.util.FileGroupUtil;
36 import com.google.common.util.concurrent.AsyncCallable;
37 import com.google.common.util.concurrent.Futures;
38 import com.google.common.util.concurrent.MoreExecutors;
39 import com.google.mobiledatadownload.LogEnumsProto.MddFileGroupDownloadStatus;
40 import com.google.mobiledatadownload.LogProto.DataDownloadFileGroupStats;
41 import com.google.mobiledatadownload.LogProto.MddFileGroupStatus;
42 import java.util.ArrayList;
43 import java.util.List;
44 import org.junit.Before;
45 import org.junit.Rule;
46 import org.junit.Test;
47 import org.junit.runner.RunWith;
48 import org.mockito.ArgumentCaptor;
49 import org.mockito.Captor;
50 import org.mockito.Mock;
51 import org.mockito.junit.MockitoJUnit;
52 import org.mockito.junit.MockitoRule;
53 import org.robolectric.RobolectricTestRunner;
54 
55 @RunWith(RobolectricTestRunner.class)
56 public class FileGroupStatsLoggerTest {
57 
58   private static final String TEST_GROUP = "test-group";
59   private static final String TEST_GROUP_2 = "test-group-2";
60 
61   private static final String TEST_PACKAGE = "test-package";
62 
63   // This one has account
64   private static final GroupKey TEST_KEY =
65       GroupKey.newBuilder()
66           .setGroupName(TEST_GROUP)
67           .setOwnerPackage(TEST_PACKAGE)
68           .setAccount("some_account")
69           .build();
70 
71   // This one does not have account
72   private static final GroupKey TEST_KEY_2 =
73       GroupKey.newBuilder().setGroupName(TEST_GROUP_2).setOwnerPackage(TEST_PACKAGE).build();
74 
75   @Mock FileGroupManager mockFileGroupManager;
76   @Mock FileGroupsMetadata mockFileGroupsMetadata;
77   @Mock EventLogger mockEventLogger;
78 
79   private FileGroupStatsLogger fileGroupStatsLogger;
80 
81   @Rule public final MockitoRule mocks = MockitoJUnit.rule();
82 
83   @Captor
84   ArgumentCaptor<AsyncCallable<List<EventLogger.FileGroupStatusWithDetails>>>
85       fileGroupStatusAndDetailsListCaptor;
86 
87   @Before
setUp()88   public void setUp() throws Exception {
89 
90     fileGroupStatsLogger =
91         new FileGroupStatsLogger(
92             mockFileGroupManager,
93             mockFileGroupsMetadata,
94             mockEventLogger,
95             MoreExecutors.directExecutor());
96   }
97 
98   @Test
fileGroupStatsLogging()99   public void fileGroupStatsLogging() throws Exception {
100     int daysSinceLastLog = 10;
101 
102     List<GroupKeyAndGroup> groups = new ArrayList<>();
103 
104     // Add a downloaded group with version number 10.
105     DataFileGroupInternal fileGroupDownloaded =
106         MddTestUtil.createDataFileGroupInternal(TEST_GROUP, 2).toBuilder()
107             .setFileGroupVersionNumber(10)
108             .setBuildId(10)
109             .setVariantId("test-variant")
110             .build();
111     fileGroupDownloaded =
112         FileGroupUtil.setGroupNewFilesReceivedTimestamp(fileGroupDownloaded, 5000);
113     fileGroupDownloaded = FileGroupUtil.setDownloadedTimestampInMillis(fileGroupDownloaded, 10000);
114 
115     groups.add(
116         GroupKeyAndGroup.create(
117             TEST_KEY.toBuilder().setDownloaded(true).build(), fileGroupDownloaded));
118 
119     // Add a pending download group for the same group name with version number 11.
120     DataFileGroupInternal fileGroupPending =
121         MddTestUtil.createDataFileGroupInternal(TEST_GROUP, 3).toBuilder()
122             .setFileGroupVersionNumber(11)
123             .setStaleLifetimeSecs(0)
124             .setExpirationDateSecs(0)
125             .setBookkeeping(DataFileGroupBookkeeping.newBuilder().setStaleExpirationDate(0).build())
126             .setBuildId(11)
127             .setVariantId("test-variant")
128             .build();
129     fileGroupPending = FileGroupUtil.setGroupNewFilesReceivedTimestamp(fileGroupPending, 15000);
130     groups.add(GroupKeyAndGroup.create(TEST_KEY, fileGroupPending));
131     when(mockFileGroupManager.getFileGroupDownloadStatus(fileGroupPending))
132         .thenReturn(Futures.immediateFuture(GroupDownloadStatus.PENDING));
133 
134     // Add a failed group to metadata with version 5.
135     DataFileGroupInternal fileGroupFailed =
136         MddTestUtil.createDataFileGroupInternal(TEST_GROUP_2, 3).toBuilder()
137             .setFileGroupVersionNumber(5)
138             .setStaleLifetimeSecs(0)
139             .setExpirationDateSecs(0)
140             .setBookkeeping(DataFileGroupBookkeeping.newBuilder().setStaleExpirationDate(0).build())
141             .build();
142     fileGroupFailed = FileGroupUtil.setGroupNewFilesReceivedTimestamp(fileGroupFailed, 12000);
143     groups.add(GroupKeyAndGroup.create(TEST_KEY_2, fileGroupFailed));
144     when(mockFileGroupManager.getFileGroupDownloadStatus(fileGroupFailed))
145         .thenReturn(Futures.immediateFuture(GroupDownloadStatus.FAILED));
146 
147     when(mockFileGroupsMetadata.getAllFreshGroups()).thenReturn(Futures.immediateFuture(groups));
148 
149     when(mockEventLogger.logMddFileGroupStats(any())).thenReturn(Futures.immediateVoidFuture());
150     fileGroupStatsLogger.log(daysSinceLastLog).get();
151 
152     verify(mockEventLogger, times(1))
153         .logMddFileGroupStats(fileGroupStatusAndDetailsListCaptor.capture());
154 
155     List<EventLogger.FileGroupStatusWithDetails> allFileGroupStatusAndDetailsList =
156         fileGroupStatusAndDetailsListCaptor.getValue().call().get();
157     MddFileGroupStatus status1 = allFileGroupStatusAndDetailsList.get(0).fileGroupStatus();
158     MddFileGroupStatus status2 = allFileGroupStatusAndDetailsList.get(1).fileGroupStatus();
159     MddFileGroupStatus status3 = allFileGroupStatusAndDetailsList.get(2).fileGroupStatus();
160 
161     DataDownloadFileGroupStats details1 =
162         allFileGroupStatusAndDetailsList.get(0).fileGroupDetails();
163     DataDownloadFileGroupStats details2 =
164         allFileGroupStatusAndDetailsList.get(1).fileGroupDetails();
165     DataDownloadFileGroupStats details3 =
166         allFileGroupStatusAndDetailsList.get(2).fileGroupDetails();
167 
168     // Check that the downloaded group status is logged.
169     assertThat(details1.getFileGroupName()).isEqualTo(TEST_GROUP);
170     assertThat(details1.getOwnerPackage()).isEqualTo(TEST_PACKAGE);
171     assertThat(details1.getFileGroupVersionNumber()).isEqualTo(10);
172     assertThat(details1.getBuildId()).isEqualTo(10);
173     assertThat(details1.getVariantId()).isEqualTo("test-variant");
174     assertThat(details1.getFileCount()).isEqualTo(2);
175     assertThat(details1.getInlineFileCount()).isEqualTo(0);
176     assertTrue(details1.getHasAccount());
177     assertThat(status1.getFileGroupDownloadStatus())
178         .isEqualTo(MddFileGroupDownloadStatus.Code.COMPLETE);
179     assertThat(status1.getGroupAddedTimestampInSeconds()).isEqualTo(5);
180     assertThat(status1.getGroupDownloadedTimestampInSeconds()).isEqualTo(10);
181     assertThat(status1.getDaysSinceLastLog()).isEqualTo(daysSinceLastLog);
182 
183     // Check that the pending group status is logged.
184     assertThat(details2.getFileGroupName()).isEqualTo(TEST_GROUP);
185     assertThat(details2.getFileGroupVersionNumber()).isEqualTo(11);
186     assertThat(details2.getBuildId()).isEqualTo(11);
187     assertThat(details2.getVariantId()).isEqualTo("test-variant");
188     assertThat(details2.getOwnerPackage()).isEqualTo(TEST_PACKAGE);
189     assertThat(details2.getFileCount()).isEqualTo(3);
190     assertThat(details2.getInlineFileCount()).isEqualTo(0);
191     assertTrue(details2.getHasAccount());
192     assertThat(status2.getFileGroupDownloadStatus())
193         .isEqualTo(MddFileGroupDownloadStatus.Code.PENDING);
194     assertThat(status2.getGroupAddedTimestampInSeconds()).isEqualTo(15);
195     assertThat(status2.getGroupDownloadedTimestampInSeconds()).isEqualTo(-1);
196     assertThat(status2.getDaysSinceLastLog()).isEqualTo(daysSinceLastLog);
197 
198     // Check that the failed group status is logged.
199     assertThat(details3.getFileGroupName()).isEqualTo(TEST_GROUP_2);
200     assertThat(details3.getFileGroupVersionNumber()).isEqualTo(5);
201     assertThat(details3.getOwnerPackage()).isEqualTo(TEST_PACKAGE);
202     assertThat(details3.getFileCount()).isEqualTo(3);
203     assertThat(details3.getInlineFileCount()).isEqualTo(0);
204     assertFalse(details3.getHasAccount());
205     assertThat(status3.getFileGroupDownloadStatus())
206         .isEqualTo(MddFileGroupDownloadStatus.Code.FAILED);
207     assertThat(status3.getGroupAddedTimestampInSeconds()).isEqualTo(12);
208     assertThat(status3.getGroupDownloadedTimestampInSeconds()).isEqualTo(-1);
209     assertThat(status3.getDaysSinceLastLog()).isEqualTo(daysSinceLastLog);
210   }
211 
212   @Test
fileGroupStatsLogging_withInlineFiles()213   public void fileGroupStatsLogging_withInlineFiles() throws Exception {
214     int daysSinceLastLog = 10;
215 
216     List<GroupKeyAndGroup> groups = new ArrayList<>();
217 
218     DataFile inlineFile1 =
219         DataFile.newBuilder()
220             .setFileId("inline-file")
221             .setUrlToDownload("inlinefile:sha1:checksum")
222             .setChecksum("checksum")
223             .setByteSize(10)
224             .build();
225     DataFile inlineFile2 =
226         DataFile.newBuilder()
227             .setFileId("inline-file-2")
228             .setUrlToDownload("inlinefile:sha1:checksum2")
229             .setChecksum("checksum2")
230             .setByteSize(11)
231             .build();
232 
233     // Add a downloaded group with version number 10 and inline file
234     DataFileGroupInternal fileGroupDownloaded =
235         MddTestUtil.createDataFileGroupInternal(TEST_GROUP, 2).toBuilder()
236             .setFileGroupVersionNumber(10)
237             .setBuildId(10)
238             .setVariantId("test-variant")
239             .addFile(inlineFile1)
240             .addFile(inlineFile2)
241             .build();
242     fileGroupDownloaded =
243         FileGroupUtil.setGroupNewFilesReceivedTimestamp(fileGroupDownloaded, 5000);
244     fileGroupDownloaded = FileGroupUtil.setDownloadedTimestampInMillis(fileGroupDownloaded, 10000);
245 
246     groups.add(
247         GroupKeyAndGroup.create(
248             TEST_KEY.toBuilder().setDownloaded(true).build(), fileGroupDownloaded));
249 
250     // Add a pending download group for the same group name with version number 11 and inline file.
251     DataFileGroupInternal fileGroupPending =
252         MddTestUtil.createDataFileGroupInternal(TEST_GROUP, 3).toBuilder()
253             .setFileGroupVersionNumber(11)
254             .setStaleLifetimeSecs(0)
255             .setExpirationDateSecs(0)
256             .setBookkeeping(DataFileGroupBookkeeping.newBuilder().setStaleExpirationDate(0).build())
257             .setBuildId(11)
258             .setVariantId("test-variant")
259             .addFile(inlineFile1)
260             .build();
261     fileGroupPending = FileGroupUtil.setGroupNewFilesReceivedTimestamp(fileGroupPending, 15000);
262     groups.add(GroupKeyAndGroup.create(TEST_KEY, fileGroupPending));
263     when(mockFileGroupManager.getFileGroupDownloadStatus(fileGroupPending))
264         .thenReturn(Futures.immediateFuture(GroupDownloadStatus.PENDING));
265 
266     // Add a failed group to metadata with version 5 with no inline files.
267     DataFileGroupInternal fileGroupFailed =
268         MddTestUtil.createDataFileGroupInternal(TEST_GROUP_2, 3).toBuilder()
269             .setFileGroupVersionNumber(5)
270             .setStaleLifetimeSecs(0)
271             .setExpirationDateSecs(0)
272             .setBookkeeping(DataFileGroupBookkeeping.newBuilder().setStaleExpirationDate(0).build())
273             .build();
274     fileGroupFailed = FileGroupUtil.setGroupNewFilesReceivedTimestamp(fileGroupFailed, 12000);
275     groups.add(GroupKeyAndGroup.create(TEST_KEY_2, fileGroupFailed));
276     when(mockFileGroupManager.getFileGroupDownloadStatus(fileGroupFailed))
277         .thenReturn(Futures.immediateFuture(GroupDownloadStatus.FAILED));
278 
279     when(mockFileGroupsMetadata.getAllFreshGroups()).thenReturn(Futures.immediateFuture(groups));
280     when(mockEventLogger.logMddFileGroupStats(any())).thenReturn(Futures.immediateVoidFuture());
281 
282     fileGroupStatsLogger.log(daysSinceLastLog).get();
283 
284     verify(mockEventLogger, times(1))
285         .logMddFileGroupStats(fileGroupStatusAndDetailsListCaptor.capture());
286 
287     List<EventLogger.FileGroupStatusWithDetails> allFileGroupStatusAndDetailsList =
288         fileGroupStatusAndDetailsListCaptor.getValue().call().get();
289     MddFileGroupStatus status1 = allFileGroupStatusAndDetailsList.get(0).fileGroupStatus();
290     MddFileGroupStatus status2 = allFileGroupStatusAndDetailsList.get(1).fileGroupStatus();
291     MddFileGroupStatus status3 = allFileGroupStatusAndDetailsList.get(2).fileGroupStatus();
292 
293     DataDownloadFileGroupStats details1 =
294         allFileGroupStatusAndDetailsList.get(0).fileGroupDetails();
295     DataDownloadFileGroupStats details2 =
296         allFileGroupStatusAndDetailsList.get(1).fileGroupDetails();
297     DataDownloadFileGroupStats details3 =
298         allFileGroupStatusAndDetailsList.get(2).fileGroupDetails();
299 
300     // Check that the downloaded group status is logged.
301     assertThat(details1.getFileGroupName()).isEqualTo(TEST_GROUP);
302     assertThat(details1.getOwnerPackage()).isEqualTo(TEST_PACKAGE);
303     assertThat(details1.getFileGroupVersionNumber()).isEqualTo(10);
304     assertThat(details1.getBuildId()).isEqualTo(10);
305     assertThat(details1.getVariantId()).isEqualTo("test-variant");
306     assertThat(details1.getFileCount()).isEqualTo(4);
307     assertThat(details1.getInlineFileCount()).isEqualTo(2);
308     assertTrue(details1.getHasAccount());
309     assertThat(status1.getFileGroupDownloadStatus())
310         .isEqualTo(MddFileGroupDownloadStatus.Code.COMPLETE);
311     assertThat(status1.getGroupAddedTimestampInSeconds()).isEqualTo(5);
312     assertThat(status1.getGroupDownloadedTimestampInSeconds()).isEqualTo(10);
313     assertThat(status1.getDaysSinceLastLog()).isEqualTo(daysSinceLastLog);
314 
315     // Check that the pending group status is logged.
316     assertThat(details2.getFileGroupName()).isEqualTo(TEST_GROUP);
317     assertThat(details2.getFileGroupVersionNumber()).isEqualTo(11);
318     assertThat(details2.getBuildId()).isEqualTo(11);
319     assertThat(details2.getVariantId()).isEqualTo("test-variant");
320     assertThat(details2.getOwnerPackage()).isEqualTo(TEST_PACKAGE);
321     assertThat(details2.getFileCount()).isEqualTo(4);
322     assertThat(details2.getInlineFileCount()).isEqualTo(1);
323     assertTrue(details2.getHasAccount());
324     assertThat(status2.getFileGroupDownloadStatus())
325         .isEqualTo(MddFileGroupDownloadStatus.Code.PENDING);
326     assertThat(status2.getGroupAddedTimestampInSeconds()).isEqualTo(15);
327     assertThat(status2.getGroupDownloadedTimestampInSeconds()).isEqualTo(-1);
328     assertThat(status2.getDaysSinceLastLog()).isEqualTo(daysSinceLastLog);
329 
330     // Check that the failed group status is logged.
331     assertThat(details3.getFileGroupName()).isEqualTo(TEST_GROUP_2);
332     assertThat(details3.getFileGroupVersionNumber()).isEqualTo(5);
333     assertThat(details3.getOwnerPackage()).isEqualTo(TEST_PACKAGE);
334     assertThat(details3.getFileCount()).isEqualTo(3);
335     assertThat(details3.getInlineFileCount()).isEqualTo(0);
336     assertFalse(details3.getHasAccount());
337     assertThat(status3.getFileGroupDownloadStatus())
338         .isEqualTo(MddFileGroupDownloadStatus.Code.FAILED);
339     assertThat(status3.getGroupAddedTimestampInSeconds()).isEqualTo(12);
340     assertThat(status3.getGroupDownloadedTimestampInSeconds()).isEqualTo(-1);
341     assertThat(status3.getDaysSinceLastLog()).isEqualTo(daysSinceLastLog);
342   }
343 }
344