667 lines
27 KiB
Java
667 lines
27 KiB
Java
/*
|
|
* 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 static org.mockito.Mockito.eq;
|
|
import static org.mockito.Mockito.times;
|
|
import static org.mockito.Mockito.verify;
|
|
|
|
import android.app.blob.BlobStoreManager;
|
|
import android.content.Context;
|
|
import android.net.Uri;
|
|
import android.util.Log;
|
|
import androidx.test.core.app.ApplicationProvider;
|
|
import com.google.android.libraries.mobiledatadownload.downloader.FileDownloader;
|
|
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.BlobStoreBackend;
|
|
import com.google.android.libraries.mobiledatadownload.file.backends.BlobUri;
|
|
import com.google.android.libraries.mobiledatadownload.file.backends.JavaFileBackend;
|
|
import com.google.android.libraries.mobiledatadownload.file.transforms.CompressTransform;
|
|
import com.google.android.libraries.mobiledatadownload.monitor.DownloadProgressMonitor;
|
|
import com.google.android.libraries.mobiledatadownload.monitor.NetworkUsageMonitor;
|
|
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.base.Supplier;
|
|
import com.google.common.collect.ImmutableList;
|
|
import com.google.common.io.BaseEncoding;
|
|
import com.google.common.util.concurrent.ListeningExecutorService;
|
|
import com.google.common.util.concurrent.MoreExecutors;
|
|
import com.google.mobiledatadownload.ClientConfigProto.ClientFile;
|
|
import com.google.mobiledatadownload.ClientConfigProto.ClientFileGroup;
|
|
import com.google.mobiledatadownload.DownloadConfigProto.DataFileGroup;
|
|
import com.google.mobiledatadownload.DownloadConfigProto.DownloadConditions.DeviceNetworkPolicy;
|
|
import com.google.mobiledatadownload.LogProto.MddLogData;
|
|
import com.google.testing.junit.testparameterinjector.TestParameter;
|
|
import com.google.testing.junit.testparameterinjector.TestParameterInjector;
|
|
import java.io.OutputStream;
|
|
import java.security.MessageDigest;
|
|
import java.util.Calendar;
|
|
import java.util.List;
|
|
import java.util.concurrent.Executors;
|
|
import java.util.concurrent.ScheduledExecutorService;
|
|
import org.junit.After;
|
|
import org.junit.Before;
|
|
import org.junit.Rule;
|
|
import org.junit.Test;
|
|
import org.junit.runner.RunWith;
|
|
import org.mockito.ArgumentCaptor;
|
|
import org.mockito.Mock;
|
|
import org.mockito.junit.MockitoJUnit;
|
|
import org.mockito.junit.MockitoRule;
|
|
|
|
@RunWith(TestParameterInjector.class)
|
|
public class DownloadFileGroupAndroidSharingIntegrationTest {
|
|
|
|
private static final String TAG = "DownloadFileGroupIntegrationTest";
|
|
private static final int MAX_DOWNLOAD_FILE_GROUP_WAIT_TIME_SECS = 300;
|
|
|
|
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 ScheduledExecutorService DOWNLOAD_EXECUTOR =
|
|
Executors.newScheduledThreadPool(2);
|
|
|
|
private static final String FILE_GROUP_TO_SHARE_1 = "test-group-1";
|
|
private static final String FILE_GROUP_TO_SHARE_2 = "test-group-2";
|
|
|
|
private static final String FILE_ID_1 = "test-file-to-share-1";
|
|
private static final String FILE_CHECKSUM_1 = "fcc96b272633cdf6c4bbd2d77512cca51bfb1dbd"; // SHA_1
|
|
static final String FILE_ANDROID_SHARING_CHECKSUM_1 =
|
|
"225017b5d5ec35732940af813b1ab7be5191e4c52659953e75a1a36a1398c48d"; // SHA_256
|
|
static final int FILE_SIZE_1 = 57;
|
|
static final String FILE_URL_1 = "https://www.gstatic.com/icing/idd/sample_group/step1.txt";
|
|
|
|
private static final String FILE_ID_2 = "test-file-to-share-2";
|
|
private static final String FILE_CHECKSUM_2 = "22d565c9511c5752baab8a3bbf7b955bd2ca66fd"; // SHA_1
|
|
static final String FILE_ANDROID_SHARING_CHECKSUM_2 =
|
|
"98863d56d683f6f1fdf17b38873a481f47a3216e05314750f9b384220af418ab"; // SHA_256
|
|
static final int FILE_SIZE_2 = 13;
|
|
static final String FILE_URL_2 = "https://www.gstatic.com/icing/idd/sample_group/step2.txt";
|
|
|
|
private static final Context context = ApplicationProvider.getApplicationContext();
|
|
|
|
@Mock private TaskScheduler mockTaskScheduler;
|
|
@Mock private NetworkUsageMonitor mockNetworkUsageMonitor;
|
|
@Mock private DownloadProgressMonitor mockDownloadProgressMonitor;
|
|
@Mock private Logger mockLogger;
|
|
|
|
private SynchronousFileStorage fileStorage;
|
|
private BlobStoreBackend blobStoreBackend;
|
|
private BlobStoreManager blobStoreManager;
|
|
private MobileDataDownload mobileDataDownload;
|
|
private ListeningExecutorService controlExecutor;
|
|
|
|
private final TestFlags flags = new TestFlags();
|
|
|
|
@Rule public final MockitoRule mocks = MockitoJUnit.rule();
|
|
|
|
// TODO(b/226405643): Some tests seem to fail due to BlobStore not clearing out files across runs.
|
|
// Investigate why this is happening and enable single-threaded tests.
|
|
@TestParameter({"MULTI_THREADED"})
|
|
ExecutorType controlExecutorType;
|
|
|
|
@Before
|
|
public void setUp() throws Exception {
|
|
|
|
flags.mddAndroidSharingSampleInterval = Optional.of(1);
|
|
|
|
flags.mddDefaultSampleInterval = Optional.of(1);
|
|
|
|
blobStoreBackend = new BlobStoreBackend(context);
|
|
blobStoreManager = (BlobStoreManager) context.getSystemService(Context.BLOB_STORE_SERVICE);
|
|
|
|
fileStorage =
|
|
new SynchronousFileStorage(
|
|
/* backends= */ ImmutableList.of(
|
|
AndroidFileBackend.builder(context).build(),
|
|
blobStoreBackend,
|
|
new JavaFileBackend()),
|
|
/* transforms= */ ImmutableList.of(new CompressTransform()),
|
|
/* monitors= */ ImmutableList.of(mockNetworkUsageMonitor, mockDownloadProgressMonitor));
|
|
|
|
controlExecutor = controlExecutorType.executor();
|
|
}
|
|
|
|
@After
|
|
public void tearDown() throws Exception {
|
|
mobileDataDownload.clear().get();
|
|
}
|
|
|
|
private static String computeDigest(byte[] byteContent, String algorithm) throws Exception {
|
|
MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
|
|
if (messageDigest == null) {
|
|
return "";
|
|
}
|
|
return BaseEncoding.base16().lowerCase().encode(messageDigest.digest(byteContent));
|
|
}
|
|
|
|
@Test
|
|
public void oneAndroidSharedFile_blobStoreBackendNotRegistered_fileDownloadedAndStoredLocally()
|
|
throws Exception {
|
|
fileStorage =
|
|
new SynchronousFileStorage(
|
|
/* backends= */ ImmutableList.of(
|
|
AndroidFileBackend.builder(context).build(), new JavaFileBackend()),
|
|
/* transforms= */ ImmutableList.of(new CompressTransform()),
|
|
/* monitors= */ ImmutableList.of(mockNetworkUsageMonitor, mockDownloadProgressMonitor));
|
|
|
|
mobileDataDownload = builderForTest().setFileStorage(fileStorage).build();
|
|
|
|
Uri androidUri =
|
|
BlobUri.builder(context).setBlobParameters(FILE_ANDROID_SHARING_CHECKSUM_1).build();
|
|
|
|
// A file group with one android-shared file and one non-androidShared file
|
|
DataFileGroup groupWithFileToShare =
|
|
TestFileGroupPopulator.createDataFileGroup(
|
|
FILE_GROUP_TO_SHARE_1,
|
|
context.getPackageName(),
|
|
new String[] {FILE_ID_1, FILE_ID},
|
|
new int[] {FILE_SIZE_1, FILE_SIZE},
|
|
new String[] {FILE_CHECKSUM_1, FILE_CHECKSUM},
|
|
new String[] {FILE_ANDROID_SHARING_CHECKSUM_1, ""},
|
|
new String[] {FILE_URL_1, FILE_URL},
|
|
DeviceNetworkPolicy.DOWNLOAD_ON_ANY_NETWORK);
|
|
|
|
assertThat(
|
|
mobileDataDownload
|
|
.addFileGroup(
|
|
AddFileGroupRequest.newBuilder().setDataFileGroup(groupWithFileToShare).build())
|
|
.get())
|
|
.isTrue();
|
|
|
|
mobileDataDownload
|
|
.downloadFileGroup(
|
|
DownloadFileGroupRequest.newBuilder()
|
|
.setGroupName(FILE_GROUP_TO_SHARE_1)
|
|
.setListenerOptional(
|
|
Optional.of(
|
|
new DownloadListener() {
|
|
@Override
|
|
public void onProgress(long currentSize) {
|
|
Log.i(TAG, "onProgress " + currentSize);
|
|
}
|
|
|
|
@Override
|
|
public void onComplete(ClientFileGroup clientFileGroup) {
|
|
Log.i(TAG, "onComplete " + clientFileGroup.getGroupName());
|
|
}
|
|
}))
|
|
.build())
|
|
.get(MAX_DOWNLOAD_FILE_GROUP_WAIT_TIME_SECS, SECONDS);
|
|
|
|
ClientFileGroup clientFileGroup =
|
|
mobileDataDownload
|
|
.getFileGroup(
|
|
GetFileGroupRequest.newBuilder().setGroupName(FILE_GROUP_TO_SHARE_1).build())
|
|
.get();
|
|
|
|
assertThat(clientFileGroup).isNotNull();
|
|
assertThat(clientFileGroup.getGroupName()).isEqualTo(FILE_GROUP_TO_SHARE_1);
|
|
assertThat(clientFileGroup.getFileCount()).isEqualTo(2);
|
|
|
|
ClientFile clientFile = clientFileGroup.getFileList().get(0);
|
|
assertThat(clientFile.getFileId()).isEqualTo(FILE_ID_1);
|
|
Uri uri = Uri.parse(clientFile.getFileUri());
|
|
assertThat(uri).isNotEqualTo(androidUri);
|
|
assertThat(fileStorage.fileSize(uri)).isEqualTo(FILE_SIZE_1);
|
|
|
|
clientFile = clientFileGroup.getFileList().get(1);
|
|
assertThat(clientFile.getFileId()).isEqualTo(FILE_ID);
|
|
uri = Uri.parse(clientFile.getFileUri());
|
|
assertThat(fileStorage.fileSize(uri)).isEqualTo(FILE_SIZE);
|
|
|
|
ArgumentCaptor<MddLogData> logDataCaptor = ArgumentCaptor.forClass(MddLogData.class);
|
|
// 1073 is the tag number for MddClientEvent.Code.EVENT_CODE_UNSPECIFIED.
|
|
verify(mockLogger, times(2)).log(logDataCaptor.capture(), /* eventCode= */ eq(1073));
|
|
|
|
List<MddLogData> logData = logDataCaptor.getAllValues();
|
|
Void log1 = null;
|
|
Void log2 = null;
|
|
assertThat(logData).hasSize(2);
|
|
|
|
Void androidSharingLog = null;
|
|
assertThat(log1).isEqualTo(androidSharingLog);
|
|
assertThat(log2).isEqualTo(androidSharingLog);
|
|
}
|
|
|
|
@Test
|
|
public void oneAndroidSharedFile_twoFileGroups_downloadedOnlyOnce() throws Exception {
|
|
mobileDataDownload = builderForTest().build();
|
|
|
|
Uri androidUri =
|
|
BlobUri.builder(context).setBlobParameters(FILE_ANDROID_SHARING_CHECKSUM_1).build();
|
|
assertThat(fileStorage.exists(androidUri)).isFalse();
|
|
|
|
// groupWithFileToShare1 and groupWithFileToShare2 contain the same file configured to be
|
|
// shared.
|
|
DataFileGroup groupWithFileToShare1 =
|
|
TestFileGroupPopulator.createDataFileGroup(
|
|
FILE_GROUP_TO_SHARE_1,
|
|
context.getPackageName(),
|
|
new String[] {FILE_ID_1},
|
|
new int[] {FILE_SIZE_1},
|
|
new String[] {FILE_CHECKSUM_1},
|
|
new String[] {FILE_ANDROID_SHARING_CHECKSUM_1},
|
|
new String[] {FILE_URL_1},
|
|
DeviceNetworkPolicy.DOWNLOAD_ON_ANY_NETWORK);
|
|
|
|
long oneDayLaterInSeconds =
|
|
Calendar.getInstance().getTimeInMillis() / 1000 + 86400; // in one day
|
|
groupWithFileToShare1 =
|
|
groupWithFileToShare1.toBuilder().setExpirationDate(oneDayLaterInSeconds).build();
|
|
|
|
DataFileGroup groupWithFileToShare2 =
|
|
TestFileGroupPopulator.createDataFileGroup(
|
|
FILE_GROUP_TO_SHARE_2,
|
|
context.getPackageName(),
|
|
new String[] {FILE_ID_1},
|
|
new int[] {FILE_SIZE_1},
|
|
new String[] {FILE_CHECKSUM_1},
|
|
new String[] {FILE_ANDROID_SHARING_CHECKSUM_1},
|
|
new String[] {FILE_URL_1},
|
|
DeviceNetworkPolicy.DOWNLOAD_ON_ANY_NETWORK);
|
|
|
|
long twoDaysLaterInSeconds =
|
|
Calendar.getInstance().getTimeInMillis() / 1000 + 172800; // in two days
|
|
groupWithFileToShare2 =
|
|
groupWithFileToShare2.toBuilder().setExpirationDate(twoDaysLaterInSeconds).build();
|
|
|
|
assertThat(
|
|
mobileDataDownload
|
|
.addFileGroup(
|
|
AddFileGroupRequest.newBuilder()
|
|
.setDataFileGroup(groupWithFileToShare1)
|
|
.build())
|
|
.get())
|
|
.isTrue();
|
|
|
|
assertThat(
|
|
mobileDataDownload
|
|
.addFileGroup(
|
|
AddFileGroupRequest.newBuilder()
|
|
.setDataFileGroup(groupWithFileToShare2)
|
|
.build())
|
|
.get())
|
|
.isTrue();
|
|
|
|
mobileDataDownload
|
|
.downloadFileGroup(
|
|
DownloadFileGroupRequest.newBuilder()
|
|
.setGroupName(FILE_GROUP_TO_SHARE_1)
|
|
.setListenerOptional(
|
|
Optional.of(
|
|
new DownloadListener() {
|
|
@Override
|
|
public void onProgress(long currentSize) {
|
|
Log.i(TAG, "onProgress " + currentSize);
|
|
}
|
|
|
|
@Override
|
|
public void onComplete(ClientFileGroup clientFileGroup) {
|
|
Log.i(TAG, "onComplete " + clientFileGroup.getGroupName());
|
|
}
|
|
}))
|
|
.build())
|
|
.get(MAX_DOWNLOAD_FILE_GROUP_WAIT_TIME_SECS, SECONDS);
|
|
|
|
ClientFileGroup clientFileGroup =
|
|
mobileDataDownload
|
|
.getFileGroup(
|
|
GetFileGroupRequest.newBuilder().setGroupName(FILE_GROUP_TO_SHARE_1).build())
|
|
.get();
|
|
|
|
assertThat(clientFileGroup).isNotNull();
|
|
assertThat(clientFileGroup.getGroupName()).isEqualTo(FILE_GROUP_TO_SHARE_1);
|
|
assertThat(clientFileGroup.getFileCount()).isEqualTo(1);
|
|
|
|
ClientFile clientFile = clientFileGroup.getFileList().get(0);
|
|
assertThat(clientFile.getFileId()).isEqualTo(FILE_ID_1);
|
|
Uri uri = Uri.parse(clientFile.getFileUri());
|
|
|
|
// The file is now available in the android shared storage.
|
|
assertThat(uri).isEqualTo(androidUri);
|
|
assertThat(fileStorage.exists(uri)).isTrue();
|
|
assertThat(blobStoreManager.getLeasedBlobs()).hasSize(1);
|
|
|
|
mobileDataDownload
|
|
.downloadFileGroup(
|
|
DownloadFileGroupRequest.newBuilder()
|
|
.setGroupName(FILE_GROUP_TO_SHARE_2)
|
|
.setListenerOptional(
|
|
Optional.of(
|
|
new DownloadListener() {
|
|
@Override
|
|
public void onProgress(long currentSize) {
|
|
Log.i(TAG, "onProgress " + currentSize);
|
|
}
|
|
|
|
@Override
|
|
public void onComplete(ClientFileGroup clientFileGroup) {
|
|
Log.i(TAG, "onComplete " + clientFileGroup.getGroupName());
|
|
}
|
|
}))
|
|
.build())
|
|
.get(MAX_DOWNLOAD_FILE_GROUP_WAIT_TIME_SECS, SECONDS);
|
|
|
|
String debugString = mobileDataDownload.getDebugInfoAsString();
|
|
Log.i(TAG, "MDD Lib dump:");
|
|
for (String line : debugString.split("\n", -1)) {
|
|
Log.i(TAG, line);
|
|
}
|
|
|
|
clientFileGroup =
|
|
mobileDataDownload
|
|
.getFileGroup(
|
|
GetFileGroupRequest.newBuilder().setGroupName(FILE_GROUP_TO_SHARE_2).build())
|
|
.get();
|
|
|
|
assertThat(clientFileGroup).isNotNull();
|
|
assertThat(clientFileGroup.getGroupName()).isEqualTo(FILE_GROUP_TO_SHARE_2);
|
|
assertThat(clientFileGroup.getFileCount()).isEqualTo(1);
|
|
|
|
clientFile = clientFileGroup.getFileList().get(0);
|
|
assertThat(clientFile.getFileId()).isEqualTo(FILE_ID_1);
|
|
uri = Uri.parse(clientFile.getFileUri());
|
|
|
|
// The file is still available in the android shared storage.
|
|
assertThat(uri).isEqualTo(androidUri);
|
|
assertThat(fileStorage.exists(uri)).isTrue();
|
|
assertThat(blobStoreManager.getLeasedBlobs()).hasSize(1);
|
|
|
|
ArgumentCaptor<MddLogData> logDataCaptor = ArgumentCaptor.forClass(MddLogData.class);
|
|
// 1073 is the tag number for MddClientEvent.Code.EVENT_CODE_UNSPECIFIED.
|
|
verify(mockLogger, times(2)).log(logDataCaptor.capture(), /* eventCode= */ eq(1073));
|
|
|
|
List<MddLogData> logData = logDataCaptor.getAllValues();
|
|
assertThat(logData).hasSize(2);
|
|
|
|
Void log1 = null;
|
|
Void log2 = null;
|
|
}
|
|
|
|
@Test
|
|
public void fileAvailableInSharedStorage_neverDownloaded() throws Exception {
|
|
mobileDataDownload = builderForTest().build();
|
|
|
|
byte[] content = "fileAvailableInSharedStorage_neverDownloaded".getBytes();
|
|
String androidChecksum = computeDigest(content, "SHA-256");
|
|
String checksum = computeDigest(content, "SHA-1");
|
|
Uri androidUri = BlobUri.builder(context).setBlobParameters(androidChecksum).build();
|
|
|
|
assertThat(blobStoreBackend.exists(androidUri)).isFalse();
|
|
|
|
// Write file in the shared storage
|
|
try (OutputStream out = blobStoreBackend.openForWrite(androidUri)) {
|
|
assertThat(out).isNotNull();
|
|
out.write(content);
|
|
}
|
|
assertThat(blobStoreBackend.exists(androidUri)).isTrue();
|
|
assertThat(blobStoreManager.getLeasedBlobs()).isEmpty();
|
|
|
|
// A file group with one android-shared file and one non-androidShared file
|
|
DataFileGroup groupWithFileToShare1 =
|
|
TestFileGroupPopulator.createDataFileGroup(
|
|
FILE_GROUP_TO_SHARE_1,
|
|
context.getPackageName(),
|
|
new String[] {FILE_ID_1, FILE_ID},
|
|
new int[] {content.length, FILE_SIZE},
|
|
new String[] {checksum, FILE_CHECKSUM},
|
|
new String[] {androidChecksum, ""},
|
|
new String[] {"https://random-url", FILE_URL},
|
|
DeviceNetworkPolicy.DOWNLOAD_ON_ANY_NETWORK);
|
|
|
|
assertThat(
|
|
mobileDataDownload
|
|
.addFileGroup(
|
|
AddFileGroupRequest.newBuilder()
|
|
.setDataFileGroup(groupWithFileToShare1)
|
|
.build())
|
|
.get())
|
|
.isTrue();
|
|
|
|
mobileDataDownload
|
|
.downloadFileGroup(
|
|
DownloadFileGroupRequest.newBuilder()
|
|
.setGroupName(FILE_GROUP_TO_SHARE_1)
|
|
.setListenerOptional(
|
|
Optional.of(
|
|
new DownloadListener() {
|
|
@Override
|
|
public void onProgress(long currentSize) {
|
|
Log.i(TAG, "onProgress " + currentSize);
|
|
}
|
|
|
|
@Override
|
|
public void onComplete(ClientFileGroup clientFileGroup) {
|
|
Log.i(TAG, "onComplete " + clientFileGroup.getGroupName());
|
|
}
|
|
}))
|
|
.build())
|
|
.get(MAX_DOWNLOAD_FILE_GROUP_WAIT_TIME_SECS, SECONDS);
|
|
|
|
ClientFileGroup clientFileGroup =
|
|
mobileDataDownload
|
|
.getFileGroup(
|
|
GetFileGroupRequest.newBuilder().setGroupName(FILE_GROUP_TO_SHARE_1).build())
|
|
.get();
|
|
|
|
assertThat(clientFileGroup).isNotNull();
|
|
assertThat(clientFileGroup.getGroupName()).isEqualTo(FILE_GROUP_TO_SHARE_1);
|
|
assertThat(clientFileGroup.getFileCount()).isEqualTo(2);
|
|
|
|
ClientFile clientFile = clientFileGroup.getFileList().get(0);
|
|
assertThat(clientFile.getFileId()).isEqualTo(FILE_ID_1);
|
|
Uri uri = Uri.parse(clientFile.getFileUri());
|
|
|
|
// The file is available in the android shared storage.
|
|
assertThat(uri).isEqualTo(androidUri);
|
|
assertThat(fileStorage.exists(androidUri)).isTrue();
|
|
assertThat(blobStoreManager.getLeasedBlobs()).hasSize(1);
|
|
|
|
clientFile = clientFileGroup.getFileList().get(1);
|
|
assertThat(clientFile.getFileId()).isEqualTo(FILE_ID);
|
|
uri = Uri.parse(clientFile.getFileUri());
|
|
assertThat(fileStorage.fileSize(uri)).isEqualTo(FILE_SIZE);
|
|
|
|
ArgumentCaptor<MddLogData> logDataCaptor = ArgumentCaptor.forClass(MddLogData.class);
|
|
// 1073 is the tag number for MddClientEvent.Code.EVENT_CODE_UNSPECIFIED.
|
|
verify(mockLogger).log(logDataCaptor.capture(), /* eventCode= */ eq(1073));
|
|
|
|
List<MddLogData> logData = logDataCaptor.getAllValues();
|
|
assertThat(logData).hasSize(1);
|
|
|
|
Void log1 = null;
|
|
}
|
|
|
|
@Test
|
|
public void fileDownloadedForFirstFileGroup_thenSharedForSecondFileGroup() throws Exception {
|
|
mobileDataDownload = builderForTest().build();
|
|
|
|
Uri androidUri =
|
|
BlobUri.builder(context).setBlobParameters(FILE_ANDROID_SHARING_CHECKSUM_2).build();
|
|
assertThat(blobStoreBackend.exists(androidUri)).isFalse();
|
|
|
|
// Create non-android-shared file group.
|
|
DataFileGroup groupWithFileToShare1 =
|
|
TestFileGroupPopulator.createDataFileGroup(
|
|
FILE_GROUP_TO_SHARE_1,
|
|
context.getPackageName(),
|
|
new String[] {FILE_ID_2},
|
|
new int[] {FILE_SIZE_2},
|
|
new String[] {FILE_CHECKSUM_2},
|
|
new String[] {FILE_URL_2},
|
|
DeviceNetworkPolicy.DOWNLOAD_ON_ANY_NETWORK);
|
|
|
|
long laterTimeSecs = Calendar.getInstance().getTimeInMillis() / 1000 + 86400; // in one day
|
|
groupWithFileToShare1 =
|
|
groupWithFileToShare1.toBuilder().setExpirationDate(laterTimeSecs).build();
|
|
|
|
assertThat(
|
|
mobileDataDownload
|
|
.addFileGroup(
|
|
AddFileGroupRequest.newBuilder()
|
|
.setDataFileGroup(groupWithFileToShare1)
|
|
.build())
|
|
.get())
|
|
.isTrue();
|
|
|
|
// groupWithFileToShare2 has the same file as the previous file group but it has been configured
|
|
// to be share.
|
|
DataFileGroup groupWithFileToShare2 =
|
|
TestFileGroupPopulator.createDataFileGroup(
|
|
FILE_GROUP_TO_SHARE_2,
|
|
context.getPackageName(),
|
|
new String[] {FILE_ID_2},
|
|
new int[] {FILE_SIZE_2},
|
|
new String[] {FILE_CHECKSUM_2},
|
|
new String[] {FILE_ANDROID_SHARING_CHECKSUM_2},
|
|
new String[] {FILE_URL_2},
|
|
DeviceNetworkPolicy.DOWNLOAD_ON_ANY_NETWORK);
|
|
|
|
assertThat(
|
|
mobileDataDownload
|
|
.addFileGroup(
|
|
AddFileGroupRequest.newBuilder()
|
|
.setDataFileGroup(groupWithFileToShare2)
|
|
.build())
|
|
.get())
|
|
.isTrue();
|
|
|
|
mobileDataDownload
|
|
.downloadFileGroup(
|
|
DownloadFileGroupRequest.newBuilder()
|
|
.setGroupName(FILE_GROUP_TO_SHARE_1)
|
|
.setListenerOptional(
|
|
Optional.of(
|
|
new DownloadListener() {
|
|
@Override
|
|
public void onProgress(long currentSize) {
|
|
Log.i(TAG, "onProgress " + currentSize);
|
|
}
|
|
|
|
@Override
|
|
public void onComplete(ClientFileGroup clientFileGroup) {
|
|
Log.i(TAG, "onComplete " + clientFileGroup.getGroupName());
|
|
}
|
|
}))
|
|
.build())
|
|
.get(MAX_DOWNLOAD_FILE_GROUP_WAIT_TIME_SECS, SECONDS);
|
|
|
|
ClientFileGroup clientFileGroup =
|
|
mobileDataDownload
|
|
.getFileGroup(
|
|
GetFileGroupRequest.newBuilder().setGroupName(FILE_GROUP_TO_SHARE_1).build())
|
|
.get();
|
|
|
|
assertThat(clientFileGroup).isNotNull();
|
|
assertThat(clientFileGroup.getGroupName()).isEqualTo(FILE_GROUP_TO_SHARE_1);
|
|
assertThat(clientFileGroup.getFileCount()).isEqualTo(1);
|
|
|
|
ClientFile clientFile = clientFileGroup.getFileList().get(0);
|
|
assertThat(clientFile.getFileId()).isEqualTo(FILE_ID_2);
|
|
|
|
// File stored locally
|
|
Uri localUri = Uri.parse(clientFile.getFileUri());
|
|
assertThat(localUri).isNotEqualTo(androidUri);
|
|
assertThat(blobStoreManager.getLeasedBlobs()).isEmpty();
|
|
|
|
mobileDataDownload
|
|
.downloadFileGroup(
|
|
DownloadFileGroupRequest.newBuilder()
|
|
.setGroupName(FILE_GROUP_TO_SHARE_2)
|
|
.setListenerOptional(
|
|
Optional.of(
|
|
new DownloadListener() {
|
|
@Override
|
|
public void onProgress(long currentSize) {
|
|
Log.i(TAG, "onProgress " + currentSize);
|
|
}
|
|
|
|
@Override
|
|
public void onComplete(ClientFileGroup clientFileGroup) {
|
|
Log.i(TAG, "onComplete " + clientFileGroup.getGroupName());
|
|
}
|
|
}))
|
|
.build())
|
|
.get(MAX_DOWNLOAD_FILE_GROUP_WAIT_TIME_SECS, SECONDS);
|
|
|
|
String debugString = mobileDataDownload.getDebugInfoAsString();
|
|
Log.i(TAG, "MDD Lib dump:");
|
|
for (String line : debugString.split("\n", -1)) {
|
|
Log.i(TAG, line);
|
|
}
|
|
|
|
clientFileGroup =
|
|
mobileDataDownload
|
|
.getFileGroup(
|
|
GetFileGroupRequest.newBuilder().setGroupName(FILE_GROUP_TO_SHARE_2).build())
|
|
.get();
|
|
|
|
assertThat(clientFileGroup).isNotNull();
|
|
assertThat(clientFileGroup.getGroupName()).isEqualTo(FILE_GROUP_TO_SHARE_2);
|
|
assertThat(clientFileGroup.getFileCount()).isEqualTo(1);
|
|
|
|
clientFile = clientFileGroup.getFileList().get(0);
|
|
assertThat(clientFile.getFileId()).isEqualTo(FILE_ID_2);
|
|
Uri uri = Uri.parse(clientFile.getFileUri());
|
|
|
|
// The file is now available in the shared storage.
|
|
assertThat(uri).isNotEqualTo(localUri);
|
|
assertThat(uri).isEqualTo(androidUri);
|
|
assertThat(fileStorage.exists(uri)).isTrue();
|
|
assertThat(blobStoreManager.getLeasedBlobs()).hasSize(1);
|
|
|
|
ArgumentCaptor<MddLogData> logDataCaptor = ArgumentCaptor.forClass(MddLogData.class);
|
|
// 1073 is the tag number for MddClientEvent.Code.EVENT_CODE_UNSPECIFIED.
|
|
verify(mockLogger).log(logDataCaptor.capture(), /* eventCode= */ eq(1073));
|
|
|
|
List<MddLogData> logData = logDataCaptor.getAllValues();
|
|
assertThat(logData).hasSize(1);
|
|
|
|
Void log1 = null;
|
|
}
|
|
|
|
private MobileDataDownloadBuilder builderForTest() {
|
|
Supplier<FileDownloader> fileDownloaderSupplier =
|
|
() ->
|
|
new TestFileDownloader(
|
|
TEST_DATA_RELATIVE_PATH,
|
|
fileStorage,
|
|
MoreExecutors.listeningDecorator(DOWNLOAD_EXECUTOR));
|
|
|
|
return MobileDataDownloadBuilder.newBuilder()
|
|
.setContext(context)
|
|
.setControlExecutor(controlExecutor)
|
|
.setFileDownloaderSupplier(fileDownloaderSupplier)
|
|
.setTaskScheduler(Optional.of(mockTaskScheduler))
|
|
.setDeltaDecoderOptional(Optional.absent())
|
|
.setFileStorage(fileStorage)
|
|
.setNetworkUsageMonitor(mockNetworkUsageMonitor)
|
|
.setDownloadMonitorOptional(Optional.of(mockDownloadProgressMonitor))
|
|
.setLoggerOptional(Optional.of(mockLogger))
|
|
.setFlagsOptional(Optional.of(flags));
|
|
}
|
|
}
|