• 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;
17 
18 import static com.google.android.libraries.mobiledatadownload.TestFileGroupPopulator.FILE_CHECKSUM;
19 import static com.google.android.libraries.mobiledatadownload.TestFileGroupPopulator.FILE_ID;
20 import static com.google.android.libraries.mobiledatadownload.TestFileGroupPopulator.FILE_SIZE;
21 import static com.google.android.libraries.mobiledatadownload.TestFileGroupPopulator.FILE_URL;
22 import static com.google.android.libraries.mobiledatadownload.testing.MddTestDependencies.ExecutorType;
23 import static com.google.common.truth.Truth.assertThat;
24 import static java.util.concurrent.TimeUnit.SECONDS;
25 
26 import android.accounts.Account;
27 import android.content.Context;
28 import androidx.test.core.app.ApplicationProvider;
29 import com.google.android.libraries.mobiledatadownload.account.AccountUtil;
30 import com.google.android.libraries.mobiledatadownload.file.SynchronousFileStorage;
31 import com.google.android.libraries.mobiledatadownload.file.backends.AndroidFileBackend;
32 import com.google.android.libraries.mobiledatadownload.file.backends.JavaFileBackend;
33 import com.google.android.libraries.mobiledatadownload.monitor.NetworkUsageMonitor;
34 import com.google.android.libraries.mobiledatadownload.testing.FakeTimeSource;
35 import com.google.android.libraries.mobiledatadownload.testing.MddTestDependencies;
36 import com.google.android.libraries.mobiledatadownload.testing.TestFileDownloader;
37 import com.google.android.libraries.mobiledatadownload.testing.TestFlags;
38 import com.google.common.base.Optional;
39 import com.google.common.collect.ImmutableList;
40 import com.google.common.util.concurrent.ListeningExecutorService;
41 import com.google.common.util.concurrent.ListeningScheduledExecutorService;
42 import com.google.common.util.concurrent.MoreExecutors;
43 import com.google.mobiledatadownload.ClientConfigProto.ClientFileGroup;
44 import com.google.mobiledatadownload.DownloadConfigProto.DataFile;
45 import com.google.mobiledatadownload.DownloadConfigProto.DataFileGroup;
46 import com.google.mobiledatadownload.DownloadConfigProto.DownloadConditions;
47 import com.google.mobiledatadownload.DownloadConfigProto.DownloadConditions.DeviceNetworkPolicy;
48 import com.google.testing.junit.testparameterinjector.TestParameter;
49 import com.google.testing.junit.testparameterinjector.TestParameterInjector;
50 import java.util.concurrent.Executors;
51 import org.junit.Before;
52 import org.junit.Rule;
53 import org.junit.Test;
54 import org.junit.runner.RunWith;
55 import org.mockito.Mock;
56 import org.mockito.junit.MockitoJUnit;
57 import org.mockito.junit.MockitoRule;
58 
59 /**
60  * Integration Tests that relate to interactions with MDD's Isolated Structures feature
61  *
62  * <p>Tests should be included here if they test MDD's behavior regarding reading/writing isolated
63  * structure groups.
64  */
65 @RunWith(TestParameterInjector.class)
66 public class MobileDataDownloadIsolatedStructuresIntegrationTest {
67 
68   private static final String TAG = "MDDIsolatedStructuresIntegrationTest";
69   private static final int MAX_MDD_API_WAIT_TIME_SECS = 5;
70 
71   private static final String GROUP_NAME_1 = "test-group-1";
72   private static final String GROUP_NAME_2 = "test-group-2";
73 
74   private static final String VARIANT_1 = "test-variant-1";
75   private static final String VARIANT_2 = "test-variant-2";
76 
77   private static final Account ACCOUNT_1 = AccountUtil.create("account-name-1", "account-type");
78   private static final Account ACCOUNT_2 = AccountUtil.create("account-name-2", "account-type");
79 
80   private static final String TEST_DATA_RELATIVE_PATH =
81       "third_party/java_src/android_libs/mobiledatadownload/javatests/com/google/android/libraries/mobiledatadownload/testdata/";
82 
83   private static final ListeningScheduledExecutorService DOWNLOAD_EXECUTOR =
84       MoreExecutors.listeningDecorator(Executors.newScheduledThreadPool(2));
85 
86   private static final Context context = ApplicationProvider.getApplicationContext();
87 
88   private final NetworkUsageMonitor networkUsageMonitor =
89       new NetworkUsageMonitor(context, new FakeTimeSource());
90 
91   private final SynchronousFileStorage fileStorage =
92       new SynchronousFileStorage(
93           ImmutableList.of(AndroidFileBackend.builder(context).build(), new JavaFileBackend()),
94           ImmutableList.of(),
95           ImmutableList.of(networkUsageMonitor));
96 
97   private final TestFlags flags = new TestFlags();
98 
99   private ListeningExecutorService controlExecutor;
100 
101   @Mock private Logger mockLogger;
102   @Mock private TaskScheduler mockTaskScheduler;
103 
104   @Rule(order = 1)
105   public final MockitoRule mocks = MockitoJUnit.rule();
106 
107   @TestParameter ExecutorType controlExecutorType;
108 
109   @Before
setUp()110   public void setUp() throws Exception {
111 
112     controlExecutor = controlExecutorType.executor();
113   }
114 
115   @Test
addFileGroup_whenImmediatelyComplete_createsCorrectIsolatedRoot( @estParameter boolean sameGroupName, @TestParameter boolean sameAccount, @TestParameter boolean sameVariantId)116   public void addFileGroup_whenImmediatelyComplete_createsCorrectIsolatedRoot(
117       @TestParameter boolean sameGroupName,
118       @TestParameter boolean sameAccount,
119       @TestParameter boolean sameVariantId)
120       throws Exception {
121     Optional<String> instanceId = Optional.of(MddTestDependencies.randomInstanceId());
122 
123     String groupName1 = GROUP_NAME_1;
124     String variantId1 = VARIANT_1;
125     Account account1 = ACCOUNT_1;
126 
127     // Define group2 properties based on test parameters
128     String groupName2 = sameGroupName ? GROUP_NAME_1 : GROUP_NAME_2;
129     String variantId2 = sameVariantId ? VARIANT_1 : VARIANT_2;
130     Account account2 = sameAccount ? ACCOUNT_1 : ACCOUNT_2;
131 
132     DataFileGroup symlinkGroup1 = buildSymlinkGroup(groupName1, variantId1);
133     DataFileGroup symlinkGroup2 = buildSymlinkGroup(groupName2, variantId2);
134 
135     MobileDataDownload mobileDataDownload =
136         builderForTest()
137             .setInstanceIdOptional(instanceId)
138             .setFileDownloaderSupplier(
139                 () ->
140                     new TestFileDownloader(
141                         TEST_DATA_RELATIVE_PATH,
142                         fileStorage,
143                         MoreExecutors.listeningDecorator(DOWNLOAD_EXECUTOR)))
144             .build();
145 
146     // Add group1 and download it
147     mobileDataDownload
148         .addFileGroup(
149             AddFileGroupRequest.newBuilder()
150                 .setDataFileGroup(symlinkGroup1)
151                 .setVariantIdOptional(Optional.of(variantId1))
152                 .setAccountOptional(Optional.of(account1))
153                 .build())
154         .get(MAX_MDD_API_WAIT_TIME_SECS, SECONDS);
155     ClientFileGroup downloadedSymlinkGroup1 =
156         mobileDataDownload
157             .downloadFileGroup(
158                 DownloadFileGroupRequest.newBuilder()
159                     .setGroupName(groupName1)
160                     .setVariantIdOptional(Optional.of(variantId1))
161                     .setAccountOptional(Optional.of(account1))
162                     .build())
163             .get(MAX_MDD_API_WAIT_TIME_SECS, SECONDS);
164 
165     // Add group2 and get it since it should be immediately downloaded.
166     mobileDataDownload
167         .addFileGroup(
168             AddFileGroupRequest.newBuilder()
169                 .setDataFileGroup(symlinkGroup2)
170                 .setVariantIdOptional(Optional.of(variantId2))
171                 .setAccountOptional(Optional.of(account2))
172                 .build())
173         .get(MAX_MDD_API_WAIT_TIME_SECS, SECONDS);
174     ClientFileGroup downloadedSymlinkGroup2 =
175         mobileDataDownload
176             .getFileGroup(
177                 GetFileGroupRequest.newBuilder()
178                     .setGroupName(groupName2)
179                     .setVariantIdOptional(Optional.of(variantId2))
180                     .setAccountOptional(Optional.of(account2))
181                     .build())
182             .get(MAX_MDD_API_WAIT_TIME_SECS, SECONDS);
183 
184     String isolatedFileUriGroup1 = downloadedSymlinkGroup1.getFile(0).getFileUri();
185     String isolatedFileUriGroup2 = downloadedSymlinkGroup2.getFile(0).getFileUri();
186     assertThat(isolatedFileUriGroup1).contains(groupName1 + "_");
187     assertThat(isolatedFileUriGroup2).contains(groupName2 + "_");
188 
189     // assert that uris are the same if all test parameters are true and different if otherwise.
190     assertThat(isolatedFileUriGroup1.equalsIgnoreCase(isolatedFileUriGroup2))
191         .isEqualTo(sameGroupName && sameVariantId && sameAccount);
192   }
193 
buildSymlinkGroup(String groupName, String variantId)194   private static DataFileGroup buildSymlinkGroup(String groupName, String variantId) {
195     return DataFileGroup.newBuilder()
196         .setOwnerPackage(context.getPackageName())
197         .setGroupName(groupName)
198         .setDownloadConditions(
199             DownloadConditions.newBuilder()
200                 .setDeviceNetworkPolicy(DeviceNetworkPolicy.DOWNLOAD_ON_ANY_NETWORK)
201                 .build())
202         .addFile(
203             DataFile.newBuilder()
204                 .setFileId(FILE_ID)
205                 .setByteSize(FILE_SIZE)
206                 .setChecksum(FILE_CHECKSUM)
207                 .setUrlToDownload(FILE_URL)
208                 .setRelativeFilePath("my-file.tmp")
209                 .build())
210         .setPreserveFilenamesAndIsolateFiles(true)
211         .setVariantId(variantId)
212         .setBuildId(9999)
213         .build();
214   }
215 
builderForTest()216   private MobileDataDownloadBuilder builderForTest() {
217     return MobileDataDownloadBuilder.newBuilder()
218         .setContext(context)
219         .setControlExecutor(controlExecutor)
220         .setTaskScheduler(Optional.of(mockTaskScheduler))
221         .setLoggerOptional(Optional.of(mockLogger))
222         .setDeltaDecoderOptional(Optional.absent())
223         .setFileStorage(fileStorage)
224         .setNetworkUsageMonitor(networkUsageMonitor)
225         .setFlagsOptional(Optional.of(flags));
226   }
227 }
228