blob: 327653b4f1186fe2f1f5112a46d313654bf312db [file] [log] [blame]
/*
* Copyright (C) 2018 The Android Open Source Project
*
* 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.android.tradefed.util;
import com.android.tradefed.build.BuildRetrievalError;
import com.google.cloud.storage.Blob;
import com.google.cloud.storage.Bucket;
import com.google.cloud.storage.Storage.BlobListOption;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Paths;
/** {@link GCSFileDownloader} functional test. */
@RunWith(JUnit4.class)
public class GCSFileDownloaderFuncTest {
private static final String BUCKET_NAME = "tradefed_function_test";
private static final String FILE_NAME1 = "a_host_config.xml";
private static final String FILE_NAME2 = "file2.txt";
private static final String FILE_NAME3 = "file3.txt";
private static final String FILE_NAME4 = "file4.txt";
private static final String FOLDER_NAME1 = "folder1";
private static final String FOLDER_NAME2 = "folder2";
private static final String FILE_CONTENT = "Hello World!";
private GCSFileDownloader mDownloader;
private Bucket mBucket;
private String mRemoteRoot;
private File mLocalRoot;
private static void createFile(String content, Bucket bucket, String... pathSegs) {
String path = String.join("/", pathSegs);
bucket.create(path, content.getBytes());
}
@Before
public void setUp() throws IOException {
File tempFile =
FileUtil.createTempFile(GCSFileDownloaderFuncTest.class.getSimpleName(), "");
mRemoteRoot = tempFile.getName();
FileUtil.deleteFile(tempFile);
mDownloader =
new GCSFileDownloader() {
@Override
File createTempFile(String remoteFilePath, File rootDir)
throws BuildRetrievalError {
try {
File tmpFile =
FileUtil.createTempFileForRemote(remoteFilePath, mLocalRoot);
tmpFile.delete();
return tmpFile;
} catch (IOException e) {
throw new BuildRetrievalError(e.getMessage(), e);
}
}
};
mBucket = mDownloader.getStorage().get(BUCKET_NAME);
createFile(FILE_CONTENT, mBucket, mRemoteRoot, FILE_NAME1);
createFile(FILE_NAME2, mBucket, mRemoteRoot, FOLDER_NAME1, FILE_NAME2);
createFile(FILE_NAME3, mBucket, mRemoteRoot, FOLDER_NAME1, FILE_NAME3);
createFile(FILE_NAME4, mBucket, mRemoteRoot, FOLDER_NAME1, FOLDER_NAME2, FILE_NAME4);
mLocalRoot = FileUtil.createTempDir(GCSFileDownloaderFuncTest.class.getSimpleName());
}
@After
public void tearDown() {
FileUtil.recursiveDelete(mLocalRoot);
for (Blob blob : mBucket.list(BlobListOption.prefix(mRemoteRoot)).iterateAll()) {
blob.delete();
}
}
@Test
public void testDownloadFile_streamOutput() throws Exception {
InputStream inputStream =
mDownloader.downloadFile(BUCKET_NAME, mRemoteRoot + "/" + FILE_NAME1);
String content = StreamUtil.getStringFromStream(inputStream);
Assert.assertEquals(FILE_CONTENT, content);
}
@Test
public void testDownloadFile_streamOutput_notExist() throws Exception {
try {
mDownloader.downloadFile(BUCKET_NAME, mRemoteRoot + "/" + "non_exist_file");
Assert.fail("Should throw IOExcepiton.");
} catch (IOException e) {
// Expect IOException
}
}
@Test
public void testDownloadFile() throws Exception {
File localFile =
mDownloader.downloadFile(
String.format("gs://%s/%s/%s", BUCKET_NAME, mRemoteRoot, FILE_NAME1));
String content = FileUtil.readStringFromFile(localFile);
Assert.assertEquals(FILE_CONTENT, content);
}
@Test
public void testDownloadFile_nonExist() throws Exception {
try {
mDownloader.downloadFile(
String.format("gs://%s/%s/%s", BUCKET_NAME, mRemoteRoot, "non_exist_file"));
Assert.fail("Should throw BuildRetrievalError.");
} catch (BuildRetrievalError e) {
// Expect BuildRetrievalError
}
}
@Test
public void testDownloadFile_folder() throws Exception {
File localFile =
mDownloader.downloadFile(
String.format("gs://%s/%s/%s/", BUCKET_NAME, mRemoteRoot, FOLDER_NAME1));
checkDownloadedFolder(localFile);
}
@Test
public void testDownloadFile_folderNotsanitize() throws Exception {
File localFile =
mDownloader.downloadFile(
String.format("gs://%s/%s/%s", BUCKET_NAME, mRemoteRoot, FOLDER_NAME1));
checkDownloadedFolder(localFile);
}
private void checkDownloadedFolder(File localFile) throws Exception {
Assert.assertTrue(localFile.isDirectory());
Assert.assertEquals(3, localFile.list().length);
for (String filename : localFile.list()) {
if (filename.equals(FILE_NAME2)) {
Assert.assertEquals(
FILE_NAME2,
FileUtil.readStringFromFile(
new File(localFile.getAbsolutePath(), filename)));
} else if (filename.equals(FILE_NAME3)) {
Assert.assertEquals(
FILE_NAME3,
FileUtil.readStringFromFile(
new File(localFile.getAbsolutePath(), filename)));
} else if (filename.equals(FOLDER_NAME2)) {
File subFolder = new File(localFile.getAbsolutePath(), filename);
Assert.assertTrue(subFolder.isDirectory());
Assert.assertEquals(1, subFolder.list().length);
Assert.assertEquals(
FILE_NAME4,
FileUtil.readStringFromFile(
new File(subFolder.getAbsolutePath(), subFolder.list()[0])));
} else {
Assert.assertTrue(String.format("Unknonwn file %s", filename), false);
}
}
}
@Test
public void testDownloadFile_folder_nonExist() throws Exception {
try {
mDownloader.downloadFile(
String.format("gs://%s/%s/%s/", BUCKET_NAME, "mRemoteRoot", "nonExistFolder"));
Assert.fail("Should throw BuildRetrievalError.");
} catch (BuildRetrievalError e) {
// Expect BuildRetrievalError
}
}
@Test
public void testCheckFreshness() throws Exception {
String remotePath = String.format("gs://%s/%s/%s", BUCKET_NAME, mRemoteRoot, FILE_NAME1);
File localFile = mDownloader.downloadFile(remotePath);
Assert.assertTrue(mDownloader.isFresh(localFile, remotePath));
}
@Test
public void testCheckFreshness_notFresh() throws Exception {
String remotePath = String.format("gs://%s/%s/%s", BUCKET_NAME, mRemoteRoot, FILE_NAME1);
File localFile = mDownloader.downloadFile(remotePath);
// Change the remote file.
createFile("New content.", mBucket, mRemoteRoot, FILE_NAME1);
Assert.assertFalse(mDownloader.isFresh(localFile, remotePath));
}
@Test
public void testCheckFreshness_folder() throws Exception {
String remotePath = String.format("gs://%s/%s/%s", BUCKET_NAME, mRemoteRoot, FOLDER_NAME1);
File localFolder = mDownloader.downloadFile(remotePath);
Assert.assertTrue(mDownloader.isFresh(localFolder, remotePath));
}
@Test
public void testCheckFreshness_folder_addFile() throws Exception {
String remotePath = String.format("gs://%s/%s/%s", BUCKET_NAME, mRemoteRoot, FOLDER_NAME1);
File localFolder = mDownloader.downloadFile(remotePath);
createFile("A new file", mBucket, mRemoteRoot, FOLDER_NAME1, FOLDER_NAME2, "new_file.txt");
Assert.assertFalse(mDownloader.isFresh(localFolder, remotePath));
}
@Test
public void testCheckFreshness_folder_removeFile() throws Exception {
String remotePath = String.format("gs://%s/%s/%s", BUCKET_NAME, mRemoteRoot, FOLDER_NAME1);
File localFolder = mDownloader.downloadFile(remotePath);
mBucket.get(Paths.get(mRemoteRoot, FOLDER_NAME1, FILE_NAME3).toString()).delete();
Assert.assertFalse(mDownloader.isFresh(localFolder, remotePath));
}
@Test
public void testCheckFreshness_folder_changeFile() throws Exception {
String remotePath = String.format("gs://%s/%s/%s", BUCKET_NAME, mRemoteRoot, FOLDER_NAME1);
File localFolder = mDownloader.downloadFile(remotePath);
createFile("New content", mBucket, mRemoteRoot, FOLDER_NAME1, FILE_NAME3);
Assert.assertFalse(mDownloader.isFresh(localFolder, remotePath));
}
}