aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuang Zhu <guangzhu@google.com>2017-01-03 17:59:55 -0800
committerGuang Zhu <guangzhu@google.com>2017-01-05 10:14:33 -0800
commit91fdf44e35897eceaa614d78300d5b370a2795aa (patch)
treea788f4957a36838b212c8b94f498a4499e96ded8
parent0c7950f1f51ff8ad502da252c549f56130319c1a (diff)
downloadtradefederation-91fdf44e35897eceaa614d78300d5b370a2795aa.tar.gz
add new zip extraction util methods to cover file permissions
- the new util methods are meant to provide same interface as before (modulus using a different ZipFile class) - existing uses of the util methods are migrated Bug: 33942619 Test: new & existing unit tests Change-Id: I9b53cd822ef282e90832cc18c47d4672a6a375d5
-rw-r--r--src/com/android/tradefed/device/NativeDevice.java9
-rw-r--r--src/com/android/tradefed/result/CodeCoverageReporter.java7
-rw-r--r--src/com/android/tradefed/targetprep/CdmaDeviceFlasher.java7
-rw-r--r--src/com/android/tradefed/targetprep/FastbootDeviceFlasher.java7
-rw-r--r--src/com/android/tradefed/testtype/JackCodeCoverageTest.java8
-rw-r--r--src/com/android/tradefed/util/Bugreport.java15
-rw-r--r--src/com/android/tradefed/util/FileUtil.java34
-rw-r--r--src/com/android/tradefed/util/ZipUtil2.java121
-rw-r--r--tests/res/util/permission-test.zipbin0 -> 460 bytes
-rw-r--r--tests/src/com/android/tradefed/UnitTests.java2
-rw-r--r--tests/src/com/android/tradefed/build/LocalDeviceBuildProviderTest.java11
-rw-r--r--tests/src/com/android/tradefed/device/TestDeviceTest.java12
-rw-r--r--tests/src/com/android/tradefed/util/FileUtilTest.java39
-rw-r--r--tests/src/com/android/tradefed/util/ZipUtil2Test.java127
14 files changed, 365 insertions, 34 deletions
diff --git a/src/com/android/tradefed/device/NativeDevice.java b/src/com/android/tradefed/device/NativeDevice.java
index d5bda74d7..8f82fb837 100644
--- a/src/com/android/tradefed/device/NativeDevice.java
+++ b/src/com/android/tradefed/device/NativeDevice.java
@@ -52,9 +52,11 @@ import com.android.tradefed.util.PsParser;
import com.android.tradefed.util.RunUtil;
import com.android.tradefed.util.SizeLimitedOutputStream;
import com.android.tradefed.util.StreamUtil;
-import com.android.tradefed.util.ZipUtil;
+import com.android.tradefed.util.ZipUtil2;
import com.android.tradefed.util.sl4a.Sl4aClient;
+import org.apache.commons.compress.archivers.zip.ZipFile;
+
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FilenameFilter;
@@ -75,7 +77,6 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import java.util.zip.ZipFile;
import javax.annotation.concurrent.GuardedBy;
@@ -1924,10 +1925,10 @@ public class NativeDevice implements IManagedTestDevice {
}
zip = new ZipFile(bugreportzFile);
// We get the main_entry.txt that contains the bugreport name.
- mainEntry = ZipUtil.extractFileFromZip(zip, "main_entry.txt");
+ mainEntry = ZipUtil2.extractFileFromZip(zip, "main_entry.txt");
String bugreportName = FileUtil.readStringFromFile(mainEntry).trim();
CLog.d("bugreport name: '%s'", bugreportName);
- File bugreport = ZipUtil.extractFileFromZip(zip, bugreportName);
+ File bugreport = ZipUtil2.extractFileFromZip(zip, bugreportName);
return new FileInputStreamSource(bugreport, true);
} catch (IOException e) {
CLog.e("Error while unzipping bugreportz");
diff --git a/src/com/android/tradefed/result/CodeCoverageReporter.java b/src/com/android/tradefed/result/CodeCoverageReporter.java
index 59e84f6cb..05abe8c0c 100644
--- a/src/com/android/tradefed/result/CodeCoverageReporter.java
+++ b/src/com/android/tradefed/result/CodeCoverageReporter.java
@@ -27,17 +27,18 @@ import com.android.tradefed.util.CommandStatus;
import com.android.tradefed.util.FileUtil;
import com.android.tradefed.util.IRunUtil;
import com.android.tradefed.util.RunUtil;
-import com.android.tradefed.util.ZipUtil;
+import com.android.tradefed.util.ZipUtil2;
import junit.framework.Assert;
import junit.framework.AssertionFailedError;
+import org.apache.commons.compress.archivers.zip.ZipFile;
+
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-import java.util.zip.ZipFile;
/**
* A {@link ITestInvocationListener} that will generate code coverage reports.
@@ -193,7 +194,7 @@ public class CodeCoverageReporter implements ITestInvocationListener {
try {
mLocalTmpDir = FileUtil.createTempDir("emma-meta");
ZipFile zipFile = new ZipFile(coverageZipFile);
- ZipUtil.extractZip(zipFile, mLocalTmpDir);
+ ZipUtil2.extractZip(zipFile, mLocalTmpDir);
File coverageMetaFile;
if (mCoverageMetaFilePath == null) {
coverageMetaFile = FileUtil.findFile(mLocalTmpDir, "coverage.em");
diff --git a/src/com/android/tradefed/targetprep/CdmaDeviceFlasher.java b/src/com/android/tradefed/targetprep/CdmaDeviceFlasher.java
index db2d14663..85da73ea6 100644
--- a/src/com/android/tradefed/targetprep/CdmaDeviceFlasher.java
+++ b/src/com/android/tradefed/targetprep/CdmaDeviceFlasher.java
@@ -23,11 +23,12 @@ import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.util.FileUtil;
import com.android.tradefed.util.IRunUtil;
import com.android.tradefed.util.RunUtil;
-import com.android.tradefed.util.ZipUtil;
+import com.android.tradefed.util.ZipUtil2;
+
+import org.apache.commons.compress.archivers.zip.ZipFile;
import java.io.File;
import java.io.IOException;
-import java.util.zip.ZipFile;
/**
* A class that flashes an image on a physical Android device with a CDMA radio.
@@ -141,7 +142,7 @@ public class CdmaDeviceFlasher extends FastbootDeviceFlasher {
protected File extractSystemZip(IDeviceBuildInfo deviceBuild) throws IOException {
File updateDir = FileUtil.createTempDir(LOG_TAG);
ZipFile updater = new ZipFile(deviceBuild.getDeviceImageFile().getAbsolutePath());
- ZipUtil.extractZip(updater, updateDir);
+ ZipUtil2.extractZip(updater, updateDir);
return updateDir;
}
diff --git a/src/com/android/tradefed/targetprep/FastbootDeviceFlasher.java b/src/com/android/tradefed/targetprep/FastbootDeviceFlasher.java
index b0c20c396..f45b6676c 100644
--- a/src/com/android/tradefed/targetprep/FastbootDeviceFlasher.java
+++ b/src/com/android/tradefed/targetprep/FastbootDeviceFlasher.java
@@ -26,7 +26,9 @@ import com.android.tradefed.util.CommandStatus;
import com.android.tradefed.util.FileUtil;
import com.android.tradefed.util.IRunUtil;
import com.android.tradefed.util.RunUtil;
-import com.android.tradefed.util.ZipUtil;
+import com.android.tradefed.util.ZipUtil2;
+
+import org.apache.commons.compress.archivers.zip.ZipFile;
import java.io.File;
import java.io.IOException;
@@ -35,7 +37,6 @@ import java.util.Collection;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import java.util.zip.ZipFile;
/**
* A class that relies on fastboot to flash an image on physical Android hardware.
@@ -485,7 +486,7 @@ public class FastbootDeviceFlasher implements IDeviceFlasher {
File userdataImg = null;
try {
try {
- userdataImg = ZipUtil.extractFileFromZip(
+ userdataImg = ZipUtil2.extractFileFromZip(
new ZipFile(deviceBuild.getDeviceImageFile()), "userdata.img");
} catch (IOException ioe) {
throw new TargetSetupError("failed to extract userdata.img from image file", ioe,
diff --git a/src/com/android/tradefed/testtype/JackCodeCoverageTest.java b/src/com/android/tradefed/testtype/JackCodeCoverageTest.java
index 6f8b6866f..e3d3d93ad 100644
--- a/src/com/android/tradefed/testtype/JackCodeCoverageTest.java
+++ b/src/com/android/tradefed/testtype/JackCodeCoverageTest.java
@@ -21,19 +21,19 @@ import static com.android.tradefed.testtype.JackCodeCoverageReportFormat.XML;
import com.android.tradefed.config.Option;
import com.android.tradefed.config.OptionClass;
-import com.android.tradefed.testtype.IRemoteTest;
import com.android.tradefed.util.CommandResult;
import com.android.tradefed.util.CommandStatus;
import com.android.tradefed.util.FileUtil;
import com.android.tradefed.util.RunUtil;
-import com.android.tradefed.util.ZipUtil;
+import com.android.tradefed.util.ZipUtil2;
+
import com.google.common.collect.Lists;
import java.io.File;
import java.io.IOException;
-import java.nio.file.Files;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
+import java.nio.file.Files;
import java.nio.file.PathMatcher;
import java.security.CodeSource;
import java.util.ArrayList;
@@ -127,7 +127,7 @@ public class JackCodeCoverageTest extends CodeCoverageTestBase<JackCodeCoverageR
// Extract the metadata files if we haven't already
if (mMetadataCache == null) {
File metadataZip = getBuild().getFile(getMetadataZipArtifact());
- mMetadataCache = ZipUtil.extractZipToTemp(metadataZip, "metadata");
+ mMetadataCache = ZipUtil2.extractZipToTemp(metadataZip, "metadata");
}
// Convert the filter strings to PathMatchers
diff --git a/src/com/android/tradefed/util/Bugreport.java b/src/com/android/tradefed/util/Bugreport.java
index 214b0d867..666ad1e57 100644
--- a/src/com/android/tradefed/util/Bugreport.java
+++ b/src/com/android/tradefed/util/Bugreport.java
@@ -21,14 +21,15 @@ import com.android.tradefed.result.FileInputStreamSource;
import com.android.tradefed.result.InputStreamSource;
import com.android.tradefed.result.LogDataType;
+import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
+import org.apache.commons.compress.archivers.zip.ZipFile;
+
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
/**
* Object holding the bugreport files references, compatible of flat bugreport and zipped bugreport
@@ -80,14 +81,14 @@ public class Bugreport implements Closeable {
try {
zip = new ZipFile(mBugreport);
// We get the main_entry.txt that contains the bugreport name.
- mainEntry = ZipUtil.extractFileFromZip(zip, "main_entry.txt");
+ mainEntry = ZipUtil2.extractFileFromZip(zip, "main_entry.txt");
if (mainEntry == null) {
CLog.w("main_entry.txt was not found inside the bugreport");
return null;
}
String bugreportName = FileUtil.readStringFromFile(mainEntry).trim();
CLog.d("bugreport name: '%s'", bugreportName);
- return ZipUtil.extractFileFromZip(zip, bugreportName);
+ return ZipUtil2.extractFileFromZip(zip, bugreportName);
} catch (IOException e) {
CLog.e("Error while unzipping bugreportz");
CLog.e(e);
@@ -113,14 +114,14 @@ public class Bugreport implements Closeable {
ZipFile zipBugreport = null;
try {
zipBugreport = new ZipFile(mBugreport);
- for (ZipEntry entry : Collections.list(zipBugreport.entries())) {
+ for (ZipArchiveEntry entry : Collections.list(zipBugreport.getEntries())) {
list.add(entry.getName());
}
} catch (IOException e) {
CLog.e("Error reading the list of files in the bugreport");
CLog.e(e);
} finally {
- ZipUtil.closeZip(zipBugreport);
+ ZipUtil2.closeZip(zipBugreport);
}
return list;
}
@@ -148,7 +149,7 @@ public class Bugreport implements Closeable {
File bugreport = null;
try {
zip = new ZipFile(mBugreport);
- bugreport = ZipUtil.extractFileFromZip(zip, name);
+ bugreport = ZipUtil2.extractFileFromZip(zip, name);
return bugreport;
} catch (IOException e) {
CLog.e("Error while unzipping bugreportz");
diff --git a/src/com/android/tradefed/util/FileUtil.java b/src/com/android/tradefed/util/FileUtil.java
index 02fa70151..e64aef409 100644
--- a/src/com/android/tradefed/util/FileUtil.java
+++ b/src/com/android/tradefed/util/FileUtil.java
@@ -31,10 +31,14 @@ import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.nio.file.attribute.PosixFilePermission;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import java.util.zip.ZipFile;
@@ -60,6 +64,20 @@ public class FileUtil {
private static String CHMOD = "chmod";
+ /** A map of {@link PosixFilePermission} to its corresponding Unix file mode */
+ private static final Map<PosixFilePermission, Integer> PERM_MODE_MAP = new HashMap<>();
+ static {
+ PERM_MODE_MAP.put(PosixFilePermission.OWNER_READ, 0b100000000);
+ PERM_MODE_MAP.put(PosixFilePermission.OWNER_WRITE, 0b010000000);
+ PERM_MODE_MAP.put(PosixFilePermission.OWNER_EXECUTE, 0b001000000);
+ PERM_MODE_MAP.put(PosixFilePermission.GROUP_READ, 0b000100000);
+ PERM_MODE_MAP.put(PosixFilePermission.GROUP_WRITE, 0b000010000);
+ PERM_MODE_MAP.put(PosixFilePermission.GROUP_EXECUTE, 0b000001000);
+ PERM_MODE_MAP.put(PosixFilePermission.OTHERS_READ, 0b000000100);
+ PERM_MODE_MAP.put(PosixFilePermission.OTHERS_WRITE, 0b000000010);
+ PERM_MODE_MAP.put(PosixFilePermission.OTHERS_EXECUTE, 0b000000001);
+ }
+
public static int FILESYSTEM_FILENAME_MAX_LENGTH = 255;
/**
@@ -912,4 +930,20 @@ public class FileUtil {
FileInputStream inputSource = new FileInputStream(file);
return StreamUtil.calculateMd5(inputSource);
}
+
+ /**
+ * Converts an integer representing unix mode to a set of {@link PosixFilePermission}s
+ * @param mode
+ * @return
+ */
+ public static Set<PosixFilePermission> unixModeToPosix(int mode) {
+ Set<PosixFilePermission> result = EnumSet.noneOf(PosixFilePermission.class);
+ for (PosixFilePermission pfp : EnumSet.allOf(PosixFilePermission.class)) {
+ int m = PERM_MODE_MAP.get(pfp);
+ if ((m & mode) == m) {
+ result.add(pfp);
+ }
+ }
+ return result;
+ }
}
diff --git a/src/com/android/tradefed/util/ZipUtil2.java b/src/com/android/tradefed/util/ZipUtil2.java
new file mode 100644
index 000000000..547790373
--- /dev/null
+++ b/src/com/android/tradefed/util/ZipUtil2.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2016 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.log.LogUtil.CLog;
+
+import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
+import org.apache.commons.compress.archivers.zip.ZipFile;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.util.Enumeration;
+
+/**
+ * A helper class for zip extraction that takes POSIX file permissions into account
+ */
+public class ZipUtil2 {
+
+ /**
+ * A util method to apply unix mode from {@link ZipArchiveEntry} to the created local file
+ * system entry if necessary
+ * @param entry the entry inside zipfile (potentially contains mode info)
+ * @param localFile the extracted local file entry
+ * @throws IOException
+ */
+ private static void applyUnixModeIfNecessary(ZipArchiveEntry entry, File localFile)
+ throws IOException {
+ if (entry.getPlatform() == ZipArchiveEntry.PLATFORM_UNIX) {
+ Files.setPosixFilePermissions(localFile.toPath(),
+ FileUtil.unixModeToPosix(entry.getUnixMode()));
+ } else {
+ CLog.i("Entry does not contain Unix mode info: %s", entry.getName());
+ }
+ }
+
+ /**
+ * Utility method to extract entire contents of zip file into given directory
+ *
+ * @param zipFile the {@link ZipFile} to extract
+ * @param destDir the local dir to extract file to
+ * @throws IOException if failed to extract file
+ */
+ public static void extractZip(ZipFile zipFile, File destDir) throws IOException {
+ Enumeration<? extends ZipArchiveEntry> entries = zipFile.getEntries();
+ while (entries.hasMoreElements()) {
+ ZipArchiveEntry entry = entries.nextElement();
+ File childFile = new File(destDir, entry.getName());
+ childFile.getParentFile().mkdirs();
+ if (entry.isDirectory()) {
+ childFile.mkdirs();
+ applyUnixModeIfNecessary(entry, childFile);
+ continue;
+ } else {
+ FileUtil.writeToFile(zipFile.getInputStream(entry), childFile);
+ applyUnixModeIfNecessary(entry, childFile);
+ }
+ }
+ }
+
+ /**
+ * Utility method to extract one specific file from zip file into a tmp file
+ *
+ * @param zipFile the {@link ZipFile} to extract
+ * @param filePath the filePath of to extract
+ * @throws IOException if failed to extract file
+ * @return the {@link File} or null if not found
+ */
+ public static File extractFileFromZip(ZipFile zipFile, String filePath) throws IOException {
+ ZipArchiveEntry entry = zipFile.getEntry(filePath);
+ if (entry == null) {
+ return null;
+ }
+ File createdFile = FileUtil.createTempFile("extracted",
+ FileUtil.getExtension(filePath));
+ FileUtil.writeToFile(zipFile.getInputStream(entry), createdFile);
+ applyUnixModeIfNecessary(entry, createdFile);
+ return createdFile;
+ }
+
+ /**
+ * Extract a zip file to a temp directory prepended with a string
+ *
+ * @param zipFile the zip file to extract
+ * @param nameHint a prefix for the temp directory
+ * @return a {@link File} pointing to the temp directory
+ */
+ public static File extractZipToTemp(File zipFile, String nameHint) throws IOException {
+ File localRootDir = FileUtil.createTempDir(nameHint);
+ extractZip(new ZipFile(zipFile), localRootDir);
+ return localRootDir;
+ }
+
+ /**
+ * Close an open {@link ZipFile}, ignoring any exceptions.
+ *
+ * @param zipFile the file to close
+ */
+ public static void closeZip(ZipFile zipFile) {
+ if (zipFile != null) {
+ try {
+ zipFile.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ }
+}
diff --git a/tests/res/util/permission-test.zip b/tests/res/util/permission-test.zip
new file mode 100644
index 000000000..5397ea500
--- /dev/null
+++ b/tests/res/util/permission-test.zip
Binary files differ
diff --git a/tests/src/com/android/tradefed/UnitTests.java b/tests/src/com/android/tradefed/UnitTests.java
index d838c99fc..bbfbe197d 100644
--- a/tests/src/com/android/tradefed/UnitTests.java
+++ b/tests/src/com/android/tradefed/UnitTests.java
@@ -168,6 +168,7 @@ import com.android.tradefed.util.TarUtilTest;
import com.android.tradefed.util.TestLoaderTest;
import com.android.tradefed.util.TimeUtilTest;
import com.android.tradefed.util.TimeValTest;
+import com.android.tradefed.util.ZipUtil2Test;
import com.android.tradefed.util.ZipUtilTest;
import com.android.tradefed.util.keystore.JSONFileKeyStoreClientTest;
import com.android.tradefed.util.net.HttpHelperTest;
@@ -371,6 +372,7 @@ import org.junit.runners.Suite.SuiteClasses;
TimeValTest.class,
XmlRpcHelperTest.class,
ZipUtilTest.class,
+ ZipUtil2Test.class,
// util subdirs
AndroidManifestWriterTest.class,
diff --git a/tests/src/com/android/tradefed/build/LocalDeviceBuildProviderTest.java b/tests/src/com/android/tradefed/build/LocalDeviceBuildProviderTest.java
index 3987553d3..fd5710bf4 100644
--- a/tests/src/com/android/tradefed/build/LocalDeviceBuildProviderTest.java
+++ b/tests/src/com/android/tradefed/build/LocalDeviceBuildProviderTest.java
@@ -15,17 +15,20 @@
*/
package com.android.tradefed.build;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
import com.android.tradefed.util.FileUtil;
-import com.android.tradefed.util.ZipUtil;
+import com.android.tradefed.util.ZipUtil2;
+import org.apache.commons.compress.archivers.zip.ZipFile;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.File;
-import java.util.zip.ZipFile;
/**
@@ -118,7 +121,7 @@ public class LocalDeviceBuildProviderTest {
File buildImageZip = mLocalDeviceBuildProvider.createBuildImageZip();
try {
assertNotNull(buildImageZip);
- ZipUtil.extractZip(new ZipFile(buildImageZip), mTmpDir);
+ ZipUtil2.extractZip(new ZipFile(buildImageZip), mTmpDir);
File extractedFile1 = new File(mTmpDir, mAndroidInfo.getName());
File extractedFile2 = new File(mTmpDir, mBootImg.getName());
File extractedFile3 = new File(mTmpDir, mSystemImg.getName());
diff --git a/tests/src/com/android/tradefed/device/TestDeviceTest.java b/tests/src/com/android/tradefed/device/TestDeviceTest.java
index e490a1670..4e10a9d0f 100644
--- a/tests/src/com/android/tradefed/device/TestDeviceTest.java
+++ b/tests/src/com/android/tradefed/device/TestDeviceTest.java
@@ -35,13 +35,17 @@ import com.android.tradefed.util.CommandStatus;
import com.android.tradefed.util.FileUtil;
import com.android.tradefed.util.IRunUtil;
import com.android.tradefed.util.RunUtil;
-import com.android.tradefed.util.ZipUtil;
+import com.android.tradefed.util.ZipUtil2;
import com.google.common.util.concurrent.SettableFuture;
import junit.framework.Assert;
import junit.framework.TestCase;
+import org.easymock.EasyMock;
+import org.easymock.IAnswer;
+import org.easymock.IExpectationSetters;
+
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
@@ -55,10 +59,6 @@ import java.util.Set;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
-import org.easymock.EasyMock;
-import org.easymock.IAnswer;
-import org.easymock.IExpectationSetters;
-
/**
* Unit tests for {@link TestDevice}.
*/
@@ -2769,7 +2769,7 @@ public class TestDeviceTest extends TestCase {
File imageZipFile = FileUtil.createTempFile("rawImage", ".zip");
try {
FileUtil.writeToFile(imageZip, imageZipFile);
- File dir = ZipUtil.extractZipToTemp(imageZipFile, "test-raw-image");
+ File dir = ZipUtil2.extractZipToTemp(imageZipFile, "test-raw-image");
return new File(dir, "rawImageScreenshot.raw");
} finally {
FileUtil.deleteFile(imageZipFile);
diff --git a/tests/src/com/android/tradefed/util/FileUtilTest.java b/tests/src/com/android/tradefed/util/FileUtilTest.java
index 35fa968ae..f4de5497c 100644
--- a/tests/src/com/android/tradefed/util/FileUtilTest.java
+++ b/tests/src/com/android/tradefed/util/FileUtilTest.java
@@ -23,6 +23,8 @@ import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
+import java.nio.file.attribute.PosixFilePermission;
+import java.util.Set;
/**
* Unit tests for {@link FileUtil}
@@ -288,4 +290,41 @@ public class FileUtilTest extends TestCase {
FileUtil.deleteFile(testFile);
}
}
+
+ /**
+ * Test {@link FileUtil#unixModeToPosix(int)} returns expected results;
+ */
+ public void testUnixModeToPosix() {
+ Set<PosixFilePermission> perms = null;
+ // can't test all 8 * 8 * 8, so just a select few
+ perms = FileUtil.unixModeToPosix(0777);
+ assertTrue("failed unix mode conversion: 0777",
+ perms.remove(PosixFilePermission.OWNER_READ) &&
+ perms.remove(PosixFilePermission.OWNER_WRITE) &&
+ perms.remove(PosixFilePermission.OWNER_EXECUTE) &&
+ perms.remove(PosixFilePermission.GROUP_READ) &&
+ perms.remove(PosixFilePermission.GROUP_WRITE) &&
+ perms.remove(PosixFilePermission.GROUP_EXECUTE) &&
+ perms.remove(PosixFilePermission.OTHERS_READ) &&
+ perms.remove(PosixFilePermission.OTHERS_WRITE) &&
+ perms.remove(PosixFilePermission.OTHERS_EXECUTE) &&
+ perms.isEmpty());
+ perms = FileUtil.unixModeToPosix(0644);
+ assertTrue("failed unix mode conversion: 0644",
+ perms.remove(PosixFilePermission.OWNER_READ) &&
+ perms.remove(PosixFilePermission.OWNER_WRITE) &&
+ perms.remove(PosixFilePermission.GROUP_READ) &&
+ perms.remove(PosixFilePermission.OTHERS_READ) &&
+ perms.isEmpty());
+ perms = FileUtil.unixModeToPosix(0755);
+ assertTrue("failed unix mode conversion: 0755",
+ perms.remove(PosixFilePermission.OWNER_READ) &&
+ perms.remove(PosixFilePermission.OWNER_WRITE) &&
+ perms.remove(PosixFilePermission.OWNER_EXECUTE) &&
+ perms.remove(PosixFilePermission.GROUP_READ) &&
+ perms.remove(PosixFilePermission.GROUP_EXECUTE) &&
+ perms.remove(PosixFilePermission.OTHERS_READ) &&
+ perms.remove(PosixFilePermission.OTHERS_EXECUTE) &&
+ perms.isEmpty());
+ }
}
diff --git a/tests/src/com/android/tradefed/util/ZipUtil2Test.java b/tests/src/com/android/tradefed/util/ZipUtil2Test.java
new file mode 100644
index 000000000..b91aae45b
--- /dev/null
+++ b/tests/src/com/android/tradefed/util/ZipUtil2Test.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2017 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 org.apache.commons.compress.archivers.zip.ZipFile;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.attribute.PosixFilePermission;
+import java.nio.file.attribute.PosixFilePermissions;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Unit tests for {@link ZipUtil2}
+ */
+public class ZipUtil2Test {
+
+ private Set<File> mTempFiles = new HashSet<File>();
+
+ /**
+ * Cleans up temp test files
+ * @throws Exception
+ */
+ @After
+ public void tempFileCleanUp() throws Exception {
+ for (File file : mTempFiles) {
+ FileUtil.recursiveDelete(file);
+ }
+ }
+
+ /**
+ * Utility method to assert that provided file has expected permission per standard Unix
+ * notation, e.g. file should have permission "rwxrwxrwx"
+ * @param file
+ */
+ private void verifyFilePermission(File file, String permString) throws IOException {
+ Set<PosixFilePermission> actual = Files.getPosixFilePermissions(file.toPath());
+ Set<PosixFilePermission> expected = PosixFilePermissions.fromString(permString);
+ Assert.assertEquals(expected, actual);
+ }
+
+ /**
+ * Utility method to assert that provided file has expected permission per its file name, i.e.
+ * a file (literally) named "rwxrwxrwx" should have the expected permission bits
+ * @param file
+ */
+ private void verifyFilePermission(File file) throws IOException {
+ verifyFilePermission(file, file.getName());
+ }
+
+ @Test
+ public void testExtractFileFromZip() throws Exception {
+ final File zip = getTestDataFile("permission-test");
+ final String fileName = "rwxr-x--x";
+ ZipFile zipFile = null;
+ try {
+ zipFile = new ZipFile(zip);
+ File extracted = ZipUtil2.extractFileFromZip(zipFile, fileName);
+ mTempFiles.add(extracted);
+ verifyFilePermission(extracted, fileName);
+ } finally {
+ ZipFile.closeQuietly(zipFile);
+ }
+ }
+
+ @Test
+ public void testExtractZip() throws Exception {
+ final File zip = getTestDataFile("permission-test");
+ final File destDir = createTempDir("ZipUtil2Test");
+ ZipFile zipFile = null;
+ try {
+ zipFile = new ZipFile(zip);
+ ZipUtil2.extractZip(zipFile, destDir);
+ // now loop over files to verify
+ for (File file : destDir.listFiles()) {
+ // the pmierssion-test.zip file has no hierarchy inside
+ verifyFilePermission(file);
+ }
+ } finally {
+ ZipFile.closeQuietly(zipFile);
+ }
+ }
+
+ private File getTestDataFile(String name) throws IOException {
+ final InputStream inputStream =
+ getClass().getResourceAsStream(String.format("/util/%s.zip", name));
+ final File zipFile = createTempFile(name, ".zip");
+ FileUtil.writeToFile(inputStream, zipFile);
+ return zipFile;
+ }
+
+ // Helpers
+ private File createTempDir(String prefix) throws IOException {
+ return createTempDir(prefix, null);
+ }
+
+ private File createTempDir(String prefix, File parentDir) throws IOException {
+ File tempDir = FileUtil.createTempDir(prefix, parentDir);
+ mTempFiles.add(tempDir);
+ return tempDir;
+ }
+
+ private File createTempFile(String prefix, String suffix) throws IOException {
+ File tempFile = FileUtil.createTempFile(prefix, suffix);
+ mTempFiles.add(tempFile);
+ return tempFile;
+ }
+}