1 /* 2 * Copyright (C) 2023 The Android Open Source Project 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 17 package com.android.adservices.download; 18 19 import static com.android.adservices.service.stats.AdServicesStatsLog.MOBILE_DATA_DOWNLOAD_DOWNLOAD_RESULT_REPORTED; 20 import static com.android.adservices.service.stats.AdServicesStatsLog.MOBILE_DATA_DOWNLOAD_FILE_GROUP_STATUS_REPORTED; 21 import static com.android.adservices.service.stats.AdServicesStatsLog.MOBILE_DATA_DOWNLOAD_FILE_GROUP_STORAGE_STATS_REPORTED; 22 import static com.android.dx.mockito.inline.extended.ExtendedMockito.staticMockMarker; 23 24 import static com.google.mobiledatadownload.LogEnumsProto.MddDownloadResult.Code.SUCCESS; 25 import static com.google.mobiledatadownload.LogEnumsProto.MddDownloadResult.Code.SUCCESS_VALUE; 26 import static com.google.mobiledatadownload.LogEnumsProto.MddFileGroupDownloadStatus.Code.COMPLETE; 27 import static com.google.mobiledatadownload.LogEnumsProto.MddFileGroupDownloadStatus.Code.COMPLETE_VALUE; 28 29 import static org.mockito.ArgumentMatchers.any; 30 import static org.mockito.ArgumentMatchers.anyInt; 31 import static org.mockito.ArgumentMatchers.anyLong; 32 import static org.mockito.ArgumentMatchers.eq; 33 import static org.mockito.Mockito.verifyNoMoreInteractions; 34 import static org.mockito.Mockito.when; 35 36 import androidx.test.filters.SmallTest; 37 38 import com.android.adservices.service.stats.AdServicesStatsLog; 39 import com.android.dx.mockito.inline.extended.ExtendedMockito; 40 41 import com.google.mobiledatadownload.LogProto.DataDownloadFileGroupStats; 42 import com.google.mobiledatadownload.LogProto.MddDownloadResultLog; 43 import com.google.mobiledatadownload.LogProto.MddFileGroupStatus; 44 import com.google.mobiledatadownload.LogProto.MddLogData; 45 import com.google.mobiledatadownload.LogProto.MddStorageStats; 46 import com.google.protobuf.MessageLite; 47 48 import org.junit.After; 49 import org.junit.Before; 50 import org.junit.Test; 51 import org.mockito.Mock; 52 import org.mockito.MockitoSession; 53 import org.mockito.Spy; 54 55 @SmallTest 56 public class MddLoggerTest { 57 58 // Enum code defined in log_enums.proto. 59 private static final int EVENT_CODE_UNSPECIFIED = 0; 60 private static final int DATA_DOWNLOAD_FILE_GROUP_STATUS = 1044; 61 private static final int DATA_DOWNLOAD_RESULT_LOG = 1068; 62 private static final int DATA_DOWNLOAD_STORAGE_STATS = 1055; 63 private static final long SAMPLE_INTERVAL = 1; 64 private static final long TEST_TIMESTAMP = 1L; 65 private static final int TEST_DAYS = 3; 66 private static final long TEST_BYTE_USED = 5; 67 68 private MockitoSession mMockitoSession; 69 private MddLogger mMddLogger = new MddLogger(); 70 private MessageLite mMessageLite; 71 72 @Mock private MessageLite mMockLog; 73 @Spy private MddDownloadResultLog mMockMddDownloadResultLog; 74 @Spy private MddFileGroupStatus mMockMddFileGroupStatus; 75 @Spy private DataDownloadFileGroupStats mSpyDataDownloadFileGroupStats; 76 @Spy private MddStorageStats mMockMddStorageStats; 77 78 @Before setup()79 public void setup() { 80 mMockitoSession = 81 ExtendedMockito.mockitoSession() 82 .spyStatic(AdServicesStatsLog.class) 83 .initMocks(this) 84 .startMocking(); 85 } 86 87 @After teardown()88 public void teardown() { 89 if (mMockitoSession != null) { 90 mMockitoSession.finishMocking(); 91 } 92 } 93 94 @Test mddLoggerTest_unspecified()95 public void mddLoggerTest_unspecified() { 96 mMddLogger.log(mMockLog, EVENT_CODE_UNSPECIFIED); 97 // Unspecified event does not trigger MDD logging. 98 ExtendedMockito.verifyZeroInteractions(staticMockMarker(AdServicesStatsLog.class)); 99 } 100 101 @Test mddLoggerTest_logFileGroupStatusComplete()102 public void mddLoggerTest_logFileGroupStatusComplete() { 103 // This test will not log any test data. 104 ExtendedMockito.doNothing() 105 .when( 106 () -> 107 AdServicesStatsLog.write( 108 anyInt(), 109 anyInt(), 110 anyLong(), 111 anyLong(), 112 any(byte[].class), 113 anyInt())); 114 115 // Create a MessageLite using mock or default value. 116 mMessageLite = 117 MddLogData.newBuilder() 118 .setSamplingInterval(SAMPLE_INTERVAL) 119 .setDataDownloadFileGroupStats(mSpyDataDownloadFileGroupStats) 120 .setMddFileGroupStatus(mMockMddFileGroupStatus) 121 .build(); 122 123 when(mMockMddFileGroupStatus.getFileGroupDownloadStatus()).thenReturn(COMPLETE); 124 when(mMockMddFileGroupStatus.getGroupAddedTimestampInSeconds()).thenReturn(TEST_TIMESTAMP); 125 when(mMockMddFileGroupStatus.getGroupDownloadedTimestampInSeconds()) 126 .thenReturn(TEST_TIMESTAMP); 127 when(mMockMddFileGroupStatus.getDaysSinceLastLog()).thenReturn(TEST_DAYS); 128 129 mMddLogger.log(mMessageLite, DATA_DOWNLOAD_FILE_GROUP_STATUS); 130 131 // Verify AdServicesStatsLog code and mocked value. 132 ExtendedMockito.verify( 133 () -> 134 AdServicesStatsLog.write( 135 eq(MOBILE_DATA_DOWNLOAD_FILE_GROUP_STATUS_REPORTED), 136 /* file_group_download_status default value */ eq(COMPLETE_VALUE), 137 /* group_added_timestamp default value */ eq(TEST_TIMESTAMP), 138 /* group_downloaded_timestamp default value */ eq(TEST_TIMESTAMP), 139 /* file_group_stats */ any(byte[].class), 140 /* days_since_last_log default value */ eq(TEST_DAYS))); 141 142 verifyNoMoreInteractions(staticMockMarker(AdServicesStatsLog.class)); 143 } 144 145 @Test mddLoggerTest_logDownloadResultSuccess()146 public void mddLoggerTest_logDownloadResultSuccess() { 147 // This test will not log any test data. 148 ExtendedMockito.doNothing() 149 .when(() -> AdServicesStatsLog.write(anyInt(), anyInt(), any(byte[].class))); 150 151 // Create a MessageLite using mock or default value. 152 mMessageLite = 153 MddLogData.newBuilder() 154 .setSamplingInterval(SAMPLE_INTERVAL) 155 .setDataDownloadFileGroupStats(mSpyDataDownloadFileGroupStats) 156 .setMddDownloadResultLog(mMockMddDownloadResultLog) 157 .build(); 158 159 when(mMockMddDownloadResultLog.getResult()).thenReturn(SUCCESS); 160 when(mMockMddDownloadResultLog.getDataDownloadFileGroupStats()) 161 .thenReturn(mSpyDataDownloadFileGroupStats); 162 163 mMddLogger.log(mMessageLite, DATA_DOWNLOAD_RESULT_LOG); 164 165 // Verify AdServicesStatsLog code and mocked value. 166 ExtendedMockito.verify( 167 () -> 168 AdServicesStatsLog.write( 169 eq(MOBILE_DATA_DOWNLOAD_DOWNLOAD_RESULT_REPORTED), 170 /* download_result */ eq(SUCCESS_VALUE), 171 /* file_group_stats */ any(byte[].class))); 172 173 verifyNoMoreInteractions(staticMockMarker(AdServicesStatsLog.class)); 174 } 175 176 @Test mddLoggerTest_logStorageStats()177 public void mddLoggerTest_logStorageStats() { 178 // This test will not log any test data. 179 ExtendedMockito.doNothing() 180 .when( 181 () -> 182 AdServicesStatsLog.write( 183 anyInt(), any(byte[].class), anyLong(), anyLong())); 184 185 // Create a MessageLite using mock or default value. 186 mMessageLite = 187 MddLogData.newBuilder() 188 .setSamplingInterval(SAMPLE_INTERVAL) 189 .setMddStorageStats(mMockMddStorageStats) 190 .build(); 191 192 when(mMockMddStorageStats.getTotalMddBytesUsed()).thenReturn(TEST_BYTE_USED); 193 when(mMockMddStorageStats.getTotalMddDirectoryBytesUsed()).thenReturn(TEST_BYTE_USED); 194 195 mMddLogger.log(mMessageLite, DATA_DOWNLOAD_STORAGE_STATS); 196 197 // Verify AdServicesStatsLog code and mocked value. 198 ExtendedMockito.verify( 199 () -> 200 AdServicesStatsLog.write( 201 eq(MOBILE_DATA_DOWNLOAD_FILE_GROUP_STORAGE_STATS_REPORTED), 202 /* storage status */ any(byte[].class), 203 /* total mdd bytes used */ eq(TEST_BYTE_USED), 204 /* total directory bytes used */ eq(TEST_BYTE_USED))); 205 206 verifyNoMoreInteractions(staticMockMarker(AdServicesStatsLog.class)); 207 } 208 } 209