summaryrefslogtreecommitdiff
path: root/javatests/com/google/android/libraries/mobiledatadownload/MobileDataDownloadIsolatedStructuresIntegrationTest.java
blob: cbfe3153bd3b8b621483bdbdd453021e14941c24 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
/*
 * Copyright 2022 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.google.android.libraries.mobiledatadownload;

import static com.google.android.libraries.mobiledatadownload.TestFileGroupPopulator.FILE_CHECKSUM;
import static com.google.android.libraries.mobiledatadownload.TestFileGroupPopulator.FILE_ID;
import static com.google.android.libraries.mobiledatadownload.TestFileGroupPopulator.FILE_SIZE;
import static com.google.android.libraries.mobiledatadownload.TestFileGroupPopulator.FILE_URL;
import static com.google.android.libraries.mobiledatadownload.testing.MddTestDependencies.ExecutorType;
import static com.google.common.truth.Truth.assertThat;
import static java.util.concurrent.TimeUnit.SECONDS;

import android.accounts.Account;
import android.content.Context;
import androidx.test.core.app.ApplicationProvider;
import com.google.android.libraries.mobiledatadownload.account.AccountUtil;
import com.google.android.libraries.mobiledatadownload.file.SynchronousFileStorage;
import com.google.android.libraries.mobiledatadownload.file.backends.AndroidFileBackend;
import com.google.android.libraries.mobiledatadownload.file.backends.JavaFileBackend;
import com.google.android.libraries.mobiledatadownload.monitor.NetworkUsageMonitor;
import com.google.android.libraries.mobiledatadownload.testing.FakeTimeSource;
import com.google.android.libraries.mobiledatadownload.testing.MddTestDependencies;
import com.google.android.libraries.mobiledatadownload.testing.TestFileDownloader;
import com.google.android.libraries.mobiledatadownload.testing.TestFlags;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.ListeningScheduledExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.mobiledatadownload.ClientConfigProto.ClientFileGroup;
import com.google.mobiledatadownload.DownloadConfigProto.DataFile;
import com.google.mobiledatadownload.DownloadConfigProto.DataFileGroup;
import com.google.mobiledatadownload.DownloadConfigProto.DownloadConditions;
import com.google.mobiledatadownload.DownloadConfigProto.DownloadConditions.DeviceNetworkPolicy;
import com.google.testing.junit.testparameterinjector.TestParameter;
import com.google.testing.junit.testparameterinjector.TestParameterInjector;
import java.util.concurrent.Executors;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;

/**
 * Integration Tests that relate to interactions with MDD's Isolated Structures feature
 *
 * <p>Tests should be included here if they test MDD's behavior regarding reading/writing isolated
 * structure groups.
 */
@RunWith(TestParameterInjector.class)
public class MobileDataDownloadIsolatedStructuresIntegrationTest {

  private static final String TAG = "MDDIsolatedStructuresIntegrationTest";
  private static final int MAX_MDD_API_WAIT_TIME_SECS = 5;

  private static final String GROUP_NAME_1 = "test-group-1";
  private static final String GROUP_NAME_2 = "test-group-2";

  private static final String VARIANT_1 = "test-variant-1";
  private static final String VARIANT_2 = "test-variant-2";

  private static final Account ACCOUNT_1 = AccountUtil.create("account-name-1", "account-type");
  private static final Account ACCOUNT_2 = AccountUtil.create("account-name-2", "account-type");

  private static final String TEST_DATA_RELATIVE_PATH =
      "third_party/java_src/android_libs/mobiledatadownload/javatests/com/google/android/libraries/mobiledatadownload/testdata/";

  private static final ListeningScheduledExecutorService DOWNLOAD_EXECUTOR =
      MoreExecutors.listeningDecorator(Executors.newScheduledThreadPool(2));

  private static final Context context = ApplicationProvider.getApplicationContext();

  private final NetworkUsageMonitor networkUsageMonitor =
      new NetworkUsageMonitor(context, new FakeTimeSource());

  private final SynchronousFileStorage fileStorage =
      new SynchronousFileStorage(
          ImmutableList.of(AndroidFileBackend.builder(context).build(), new JavaFileBackend()),
          ImmutableList.of(),
          ImmutableList.of(networkUsageMonitor));

  private final TestFlags flags = new TestFlags();

  private ListeningExecutorService controlExecutor;

  @Mock private Logger mockLogger;
  @Mock private TaskScheduler mockTaskScheduler;

  @Rule(order = 1)
  public final MockitoRule mocks = MockitoJUnit.rule();

  @TestParameter ExecutorType controlExecutorType;

  @Before
  public void setUp() throws Exception {

    controlExecutor = controlExecutorType.executor();
  }

  @Test
  public void addFileGroup_whenImmediatelyComplete_createsCorrectIsolatedRoot(
      @TestParameter boolean sameGroupName,
      @TestParameter boolean sameAccount,
      @TestParameter boolean sameVariantId)
      throws Exception {
    Optional<String> instanceId = Optional.of(MddTestDependencies.randomInstanceId());

    String groupName1 = GROUP_NAME_1;
    String variantId1 = VARIANT_1;
    Account account1 = ACCOUNT_1;

    // Define group2 properties based on test parameters
    String groupName2 = sameGroupName ? GROUP_NAME_1 : GROUP_NAME_2;
    String variantId2 = sameVariantId ? VARIANT_1 : VARIANT_2;
    Account account2 = sameAccount ? ACCOUNT_1 : ACCOUNT_2;

    DataFileGroup symlinkGroup1 = buildSymlinkGroup(groupName1, variantId1);
    DataFileGroup symlinkGroup2 = buildSymlinkGroup(groupName2, variantId2);

    MobileDataDownload mobileDataDownload =
        builderForTest()
            .setInstanceIdOptional(instanceId)
            .setFileDownloaderSupplier(
                () ->
                    new TestFileDownloader(
                        TEST_DATA_RELATIVE_PATH,
                        fileStorage,
                        MoreExecutors.listeningDecorator(DOWNLOAD_EXECUTOR)))
            .build();

    // Add group1 and download it
    mobileDataDownload
        .addFileGroup(
            AddFileGroupRequest.newBuilder()
                .setDataFileGroup(symlinkGroup1)
                .setVariantIdOptional(Optional.of(variantId1))
                .setAccountOptional(Optional.of(account1))
                .build())
        .get(MAX_MDD_API_WAIT_TIME_SECS, SECONDS);
    ClientFileGroup downloadedSymlinkGroup1 =
        mobileDataDownload
            .downloadFileGroup(
                DownloadFileGroupRequest.newBuilder()
                    .setGroupName(groupName1)
                    .setVariantIdOptional(Optional.of(variantId1))
                    .setAccountOptional(Optional.of(account1))
                    .build())
            .get(MAX_MDD_API_WAIT_TIME_SECS, SECONDS);

    // Add group2 and get it since it should be immediately downloaded.
    mobileDataDownload
        .addFileGroup(
            AddFileGroupRequest.newBuilder()
                .setDataFileGroup(symlinkGroup2)
                .setVariantIdOptional(Optional.of(variantId2))
                .setAccountOptional(Optional.of(account2))
                .build())
        .get(MAX_MDD_API_WAIT_TIME_SECS, SECONDS);
    ClientFileGroup downloadedSymlinkGroup2 =
        mobileDataDownload
            .getFileGroup(
                GetFileGroupRequest.newBuilder()
                    .setGroupName(groupName2)
                    .setVariantIdOptional(Optional.of(variantId2))
                    .setAccountOptional(Optional.of(account2))
                    .build())
            .get(MAX_MDD_API_WAIT_TIME_SECS, SECONDS);

    String isolatedFileUriGroup1 = downloadedSymlinkGroup1.getFile(0).getFileUri();
    String isolatedFileUriGroup2 = downloadedSymlinkGroup2.getFile(0).getFileUri();
    assertThat(isolatedFileUriGroup1).contains(groupName1 + "_");
    assertThat(isolatedFileUriGroup2).contains(groupName2 + "_");

    // assert that uris are the same if all test parameters are true and different if otherwise.
    assertThat(isolatedFileUriGroup1.equalsIgnoreCase(isolatedFileUriGroup2))
        .isEqualTo(sameGroupName && sameVariantId && sameAccount);
  }

  private static DataFileGroup buildSymlinkGroup(String groupName, String variantId) {
    return DataFileGroup.newBuilder()
        .setOwnerPackage(context.getPackageName())
        .setGroupName(groupName)
        .setDownloadConditions(
            DownloadConditions.newBuilder()
                .setDeviceNetworkPolicy(DeviceNetworkPolicy.DOWNLOAD_ON_ANY_NETWORK)
                .build())
        .addFile(
            DataFile.newBuilder()
                .setFileId(FILE_ID)
                .setByteSize(FILE_SIZE)
                .setChecksum(FILE_CHECKSUM)
                .setUrlToDownload(FILE_URL)
                .setRelativeFilePath("my-file.tmp")
                .build())
        .setPreserveFilenamesAndIsolateFiles(true)
        .setVariantId(variantId)
        .setBuildId(9999)
        .build();
  }

  private MobileDataDownloadBuilder builderForTest() {
    return MobileDataDownloadBuilder.newBuilder()
        .setContext(context)
        .setControlExecutor(controlExecutor)
        .setTaskScheduler(Optional.of(mockTaskScheduler))
        .setLoggerOptional(Optional.of(mockLogger))
        .setDeltaDecoderOptional(Optional.absent())
        .setFileStorage(fileStorage)
        .setNetworkUsageMonitor(networkUsageMonitor)
        .setFlagsOptional(Optional.of(flags));
  }
}