Support the file/folder use case
GCS allows a file and folder to have the same name so we
need to handle it to avoid NPE at download.
Test: unit/func tests
Bug: 153581184
Change-Id: I47af276fc31df69c03c6296dad155b010c6f50f9
diff --git a/src/com/android/tradefed/util/GCSFileDownloader.java b/src/com/android/tradefed/util/GCSFileDownloader.java
index 303d3b7..08c4990 100644
--- a/src/com/android/tradefed/util/GCSFileDownloader.java
+++ b/src/com/android/tradefed/util/GCSFileDownloader.java
@@ -190,11 +190,16 @@
}
for (String subRemoteFolder : subRemoteFolders) {
String subFolderName = Paths.get(subRemoteFolder).getFileName().toString();
- if (!recursiveCheckFolderFreshness(
- bucketName, subRemoteFolder, new File(localFolder, subFolderName))) {
+ File subFolder = new File(localFolder, subFolderName);
+ if (new File(localFolder, subFolderName).exists()
+ && !new File(localFolder, subFolderName).isDirectory()) {
+ CLog.w("%s exists as a non-directory.", subFolder);
+ subFolder = new File(localFolder, subFolderName + "_folder");
+ }
+ if (!recursiveCheckFolderFreshness(bucketName, subRemoteFolder, subFolder)) {
return false;
}
- subFilenames.remove(subFolderName);
+ subFilenames.remove(subFolder.getName());
}
return subFilenames.isEmpty();
}
@@ -310,6 +315,14 @@
if (!localFolder.exists()) {
FileUtil.mkdirsRWX(localFolder);
}
+ if (!localFolder.isDirectory()) {
+ String error =
+ String.format(
+ "%s is not a folder. (gs://%s/%s)",
+ localFolder, bucketName, remoteFolderName);
+ CLog.e(error);
+ throw new IOException(error);
+ }
Set<String> subFilenames = new HashSet<>(Arrays.asList(localFolder.list()));
List<String> subRemoteFolders = new ArrayList<>();
List<StorageObject> subRemoteFiles = new ArrayList<>();
@@ -322,9 +335,14 @@
}
for (String subRemoteFolder : subRemoteFolders) {
String subFolderName = Paths.get(subRemoteFolder).getFileName().toString();
- recursiveDownloadFolder(
- bucketName, subRemoteFolder, new File(localFolder, subFolderName));
- subFilenames.remove(subFolderName);
+ File subFolder = new File(localFolder, subFolderName);
+ if (new File(localFolder, subFolderName).exists()
+ && !new File(localFolder, subFolderName).isDirectory()) {
+ CLog.w("%s exists as a non-directory.", subFolder);
+ subFolder = new File(localFolder, subFolderName + "_folder");
+ }
+ recursiveDownloadFolder(bucketName, subRemoteFolder, subFolder);
+ subFilenames.remove(subFolder.getName());
}
for (String subFilename : subFilenames) {
FileUtil.recursiveDelete(new File(localFolder, subFilename));
diff --git a/tests/src/com/android/tradefed/util/GCSFileDownloaderFuncTest.java b/tests/src/com/android/tradefed/util/GCSFileDownloaderFuncTest.java
index c0c5d05..8d97efb 100644
--- a/tests/src/com/android/tradefed/util/GCSFileDownloaderFuncTest.java
+++ b/tests/src/com/android/tradefed/util/GCSFileDownloaderFuncTest.java
@@ -102,6 +102,8 @@
createFile(mStorage, FILE_CONTENT, BUCKET_NAME, mRemoteRoot, FILE_NAME1);
createFile(mStorage, FILE_NAME2, BUCKET_NAME, mRemoteRoot, FOLDER_NAME1, FILE_NAME2);
createFile(mStorage, FILE_NAME3, BUCKET_NAME, mRemoteRoot, FOLDER_NAME1, FILE_NAME3);
+ // Create a special case condition where folder name is also a file name.
+ createFile(mStorage, FILE_NAME3, BUCKET_NAME, mRemoteRoot, FOLDER_NAME1, FOLDER_NAME2);
createFile(
mStorage,
FILE_NAME4,
@@ -230,7 +232,7 @@
private void checkDownloadedFolder(File localFile) throws Exception {
Assert.assertTrue(localFile.isDirectory());
- Assert.assertEquals(3, localFile.list().length);
+ Assert.assertEquals(4, localFile.list().length);
for (String filename : localFile.list()) {
if (filename.equals(FILE_NAME2)) {
Assert.assertEquals(
@@ -242,7 +244,7 @@
FILE_NAME3,
FileUtil.readStringFromFile(
new File(localFile.getAbsolutePath(), filename)));
- } else if (filename.equals(FOLDER_NAME2)) {
+ } else if (filename.equals(FOLDER_NAME2 + "_folder")) {
File subFolder = new File(localFile.getAbsolutePath(), filename);
Assert.assertTrue(subFolder.isDirectory());
Assert.assertEquals(1, subFolder.list().length);
@@ -250,6 +252,9 @@
FILE_NAME4,
FileUtil.readStringFromFile(
new File(subFolder.getAbsolutePath(), subFolder.list()[0])));
+ } else if (filename.equals(FOLDER_NAME2)) {
+ File fileWithFolderName = new File(localFile.getAbsolutePath(), filename);
+ Assert.assertTrue(fileWithFolderName.isFile());
} else {
Assert.assertTrue(String.format("Unknonwn file %s", filename), false);
}