Merge "Fix DatagramChannelMulticastTest#test_joinAnySource_IPv6"
diff --git a/luni/src/main/java/android/system/OsConstants.java b/luni/src/main/java/android/system/OsConstants.java
index 20a4a47..2e6fc1b 100644
--- a/luni/src/main/java/android/system/OsConstants.java
+++ b/luni/src/main/java/android/system/OsConstants.java
@@ -357,6 +357,7 @@
public static final int MS_ASYNC = placeholder();
public static final int MS_INVALIDATE = placeholder();
public static final int MS_SYNC = placeholder();
+ /** @hide */ public static final int NETLINK_NETFILTER = placeholder();
/** @hide */ public static final int NETLINK_ROUTE = placeholder();
public static final int NI_DGRAM = placeholder();
public static final int NI_NAMEREQD = placeholder();
diff --git a/luni/src/test/java/libcore/java/security/ProviderTest.java b/luni/src/test/java/libcore/java/security/ProviderTest.java
index 422fa6a..dab862a 100644
--- a/luni/src/test/java/libcore/java/security/ProviderTest.java
+++ b/luni/src/test/java/libcore/java/security/ProviderTest.java
@@ -286,8 +286,21 @@
return p.getService(typeAndAlg[0], typeAndAlg[1]);
}
+ /**
+ * Identifiers provided by Bouncy Castle that we exclude from consideration
+ * when checking that all Bouncy Castle identifiers are also covered by Conscrypt.
+ * Each block of excluded identifiers is preceded by the justification specific
+ * to those IDs.
+ */
private static final Set<String> BC_OVERRIDE_EXCEPTIONS = new HashSet<>();
static {
+ // A typo caused Bouncy Castle to accept these incorrect OIDs for AES, and they
+ // maintain these aliases for backwards compatibility. We don't want to continue
+ // this in Conscrypt.
+ BC_OVERRIDE_EXCEPTIONS.add("Alg.Alias.AlgorithmParameters.2.16.840.1.101.3.4.2");
+ BC_OVERRIDE_EXCEPTIONS.add("Alg.Alias.AlgorithmParameters.2.16.840.1.101.3.4.22");
+ BC_OVERRIDE_EXCEPTIONS.add("Alg.Alias.AlgorithmParameters.2.16.840.1.101.3.4.42");
+
// BC uses the same class to implement AlgorithmParameters.DES and
// AlgorithmParameters.DESEDE. Conscrypt doesn't support DES, so it doesn't
// include an implementation of AlgorithmParameters.DES, and this isn't a problem.
diff --git a/tzdata/update2/src/main/libcore/tzdata/update2/TimeZoneDistroInstaller.java b/tzdata/update2/src/main/libcore/tzdata/update2/TimeZoneDistroInstaller.java
index f21f3d7..f2bf1d7 100644
--- a/tzdata/update2/src/main/libcore/tzdata/update2/TimeZoneDistroInstaller.java
+++ b/tzdata/update2/src/main/libcore/tzdata/update2/TimeZoneDistroInstaller.java
@@ -34,15 +34,15 @@
* testing. This class is not thread-safe: callers are expected to handle mutual exclusion.
*/
public class TimeZoneDistroInstaller {
- /** {@link #stageInstallWithErrorCode(byte[])} result code: Success. */
+ /** {@link #stageInstallWithErrorCode(TimeZoneDistro)} result code: Success. */
public final static int INSTALL_SUCCESS = 0;
- /** {@link #stageInstallWithErrorCode(byte[])} result code: Distro corrupt. */
+ /** {@link #stageInstallWithErrorCode(TimeZoneDistro)} result code: Distro corrupt. */
public final static int INSTALL_FAIL_BAD_DISTRO_STRUCTURE = 1;
- /** {@link #stageInstallWithErrorCode(byte[])} result code: Distro version incompatible. */
+ /** {@link #stageInstallWithErrorCode(TimeZoneDistro)} result code: Distro version incompatible. */
public final static int INSTALL_FAIL_BAD_DISTRO_FORMAT_VERSION = 2;
- /** {@link #stageInstallWithErrorCode(byte[])} result code: Distro rules too old for device. */
+ /** {@link #stageInstallWithErrorCode(TimeZoneDistro)} result code: Distro rules too old for device. */
public final static int INSTALL_FAIL_RULES_TOO_OLD = 3;
- /** {@link #stageInstallWithErrorCode(byte[])} result code: Distro content failed validation. */
+ /** {@link #stageInstallWithErrorCode(TimeZoneDistro)} result code: Distro content failed validation. */
public final static int INSTALL_FAIL_VALIDATION_ERROR = 4;
// This constant must match one in system/core/tzdatacheck.cpp.
@@ -102,8 +102,8 @@
* If the distro content is invalid this method returns {@code false}.
* If the installation completed successfully this method returns {@code true}.
*/
- public boolean install(byte[] content) throws IOException {
- int result = stageInstallWithErrorCode(content);
+ public boolean install(TimeZoneDistro distro) throws IOException {
+ int result = stageInstallWithErrorCode(distro);
return result == INSTALL_SUCCESS;
}
@@ -113,7 +113,7 @@
* <p>Errors during unpacking or staging will throw an {@link IOException}.
* Returns {@link #INSTALL_SUCCESS} or an error code.
*/
- public int stageInstallWithErrorCode(byte[] content) throws IOException {
+ public int stageInstallWithErrorCode(TimeZoneDistro distro) throws IOException {
if (oldStagedDataDir.exists()) {
FileUtils.deleteRecursive(oldStagedDataDir);
}
@@ -123,7 +123,7 @@
Slog.i(logTag, "Unpacking / verifying time zone update");
try {
- unpackDistro(content, workingDir);
+ unpackDistro(distro, workingDir);
DistroVersion distroVersion;
try {
@@ -317,9 +317,8 @@
}
}
- private void unpackDistro(byte[] content, File targetDir) throws IOException {
+ private void unpackDistro(TimeZoneDistro distro, File targetDir) throws IOException {
Slog.i(logTag, "Unpacking update content to: " + targetDir);
- TimeZoneDistro distro = new TimeZoneDistro(content);
distro.extractTo(targetDir);
}
diff --git a/tzdata/update2/src/test/libcore/tzdata/update2/TimeZoneDistroInstallerTest.java b/tzdata/update2/src/test/libcore/tzdata/update2/TimeZoneDistroInstallerTest.java
index f3bec40..06dad3e 100644
--- a/tzdata/update2/src/test/libcore/tzdata/update2/TimeZoneDistroInstallerTest.java
+++ b/tzdata/update2/src/test/libcore/tzdata/update2/TimeZoneDistroInstallerTest.java
@@ -21,20 +21,23 @@
import com.android.timezone.distro.TimeZoneDistro;
import com.android.timezone.distro.tools.TimeZoneDistroBuilder;
-import junit.framework.AssertionFailedError;
import junit.framework.TestCase;
-import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
-import java.io.InputStream;
+import java.nio.file.FileVisitResult;
+import java.nio.file.FileVisitor;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
+import java.util.List;
import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import libcore.io.IoUtils;
-import libcore.io.Streams;
import libcore.tzdata.testing.ZoneInfoTestHelper;
import static org.junit.Assert.assertArrayEquals;
@@ -58,9 +61,9 @@
@Override
public void setUp() throws Exception {
super.setUp();
- tempDir = createDirectory("tempDir");
- testInstallDir = createDirectory("testInstall");
- testSystemTzDataDir = createDirectory("testSystemTzData");
+ tempDir = createUniqueDirectory(null, "tempDir");
+ testInstallDir = createSubDirectory(tempDir, "testInstall");
+ testSystemTzDataDir = createSubDirectory(tempDir, "testSystemTzData");
// Create a file to represent the tzdata file in the /system partition of the device.
File testSystemTzDataFile = new File(testSystemTzDataDir, "tzdata");
@@ -71,21 +74,25 @@
"TimeZoneDistroInstallerTest", testSystemTzDataFile, testInstallDir);
}
- private static File createDirectory(String prefix) throws Exception {
- File dir = File.createTempFile(prefix, "");
+ /**
+ * Creates a unique temporary directory. rootDir can be null, in which case the directory will
+ * be created beneath the directory pointed to by the java.io.tmpdir system property.
+ */
+ private static File createUniqueDirectory(File rootDir, String prefix) throws Exception {
+ File dir = File.createTempFile(prefix, "", rootDir);
assertTrue(dir.delete());
assertTrue(dir.mkdir());
return dir;
}
+ private static File createSubDirectory(File parent, String subDirName) {
+ File dir = new File(parent, subDirName);
+ assertTrue(dir.mkdir());
+ return dir;
+ }
+
@Override
public void tearDown() throws Exception {
- if (testSystemTzDataDir.exists()) {
- FileUtils.deleteRecursive(testInstallDir);
- }
- if (testInstallDir.exists()) {
- FileUtils.deleteRecursive(testInstallDir);
- }
if (tempDir.exists()) {
FileUtils.deleteRecursive(tempDir);
}
@@ -97,10 +104,10 @@
File doesNotExist = new File(testSystemTzDataDir, "doesNotExist");
TimeZoneDistroInstaller brokenSystemInstaller = new TimeZoneDistroInstaller(
"TimeZoneDistroInstallerTest", doesNotExist, testInstallDir);
- TimeZoneDistro tzData = createValidTimeZoneDistro(NEW_RULES_VERSION, 1);
+ TimeZoneDistro distro = createValidTimeZoneDistro(NEW_RULES_VERSION, 1);
try {
- brokenSystemInstaller.stageInstallWithErrorCode(tzData.getBytes());
+ brokenSystemInstaller.stageInstallWithErrorCode(distro);
fail();
} catch (IOException expected) {}
@@ -114,7 +121,7 @@
assertEquals(
TimeZoneDistroInstaller.INSTALL_SUCCESS,
- installer.stageInstallWithErrorCode(distro.getBytes()));
+ installer.stageInstallWithErrorCode(distro));
assertInstallDistroStaged(distro);
assertNoInstalledDistro();
}
@@ -127,7 +134,7 @@
TimeZoneDistro distro = createValidTimeZoneDistro(SYSTEM_RULES_VERSION, 1);
assertEquals(
TimeZoneDistroInstaller.INSTALL_SUCCESS,
- installer.stageInstallWithErrorCode(distro.getBytes()));
+ installer.stageInstallWithErrorCode(distro));
assertInstallDistroStaged(distro);
assertNoInstalledDistro();
}
@@ -140,7 +147,7 @@
TimeZoneDistro distro = createValidTimeZoneDistro(OLDER_RULES_VERSION, 1);
assertEquals(
TimeZoneDistroInstaller.INSTALL_FAIL_RULES_TOO_OLD,
- installer.stageInstallWithErrorCode(distro.getBytes()));
+ installer.stageInstallWithErrorCode(distro));
assertNoDistroOperationStaged();
assertNoInstalledDistro();
}
@@ -153,19 +160,19 @@
TimeZoneDistro distro1 = createValidTimeZoneDistro(NEW_RULES_VERSION, 1);
assertEquals(
TimeZoneDistroInstaller.INSTALL_SUCCESS,
- installer.stageInstallWithErrorCode(distro1.getBytes()));
+ installer.stageInstallWithErrorCode(distro1));
assertInstallDistroStaged(distro1);
TimeZoneDistro distro2 = createValidTimeZoneDistro(NEW_RULES_VERSION, 2);
assertEquals(
TimeZoneDistroInstaller.INSTALL_SUCCESS,
- installer.stageInstallWithErrorCode(distro2.getBytes()));
+ installer.stageInstallWithErrorCode(distro2));
assertInstallDistroStaged(distro2);
TimeZoneDistro distro3 = createValidTimeZoneDistro(NEWER_RULES_VERSION, 1);
assertEquals(
TimeZoneDistroInstaller.INSTALL_SUCCESS,
- installer.stageInstallWithErrorCode(distro3.getBytes()));
+ installer.stageInstallWithErrorCode(distro3));
assertInstallDistroStaged(distro3);
assertNoInstalledDistro();
}
@@ -179,13 +186,13 @@
TimeZoneDistro distro1 = createValidTimeZoneDistro(NEW_RULES_VERSION, 2);
assertEquals(
TimeZoneDistroInstaller.INSTALL_SUCCESS,
- installer.stageInstallWithErrorCode(distro1.getBytes()));
+ installer.stageInstallWithErrorCode(distro1));
assertInstallDistroStaged(distro1);
TimeZoneDistro distro2 = createValidTimeZoneDistro(OLDER_RULES_VERSION, 1);
assertEquals(
TimeZoneDistroInstaller.INSTALL_FAIL_RULES_TOO_OLD,
- installer.stageInstallWithErrorCode(distro2.getBytes()));
+ installer.stageInstallWithErrorCode(distro2));
assertInstallDistroStaged(distro1);
assertNoInstalledDistro();
}
@@ -195,7 +202,7 @@
TimeZoneDistro stagedDistro = createValidTimeZoneDistro(NEW_RULES_VERSION, 1);
assertEquals(
TimeZoneDistroInstaller.INSTALL_SUCCESS,
- installer.stageInstallWithErrorCode(stagedDistro.getBytes()));
+ installer.stageInstallWithErrorCode(stagedDistro));
assertInstallDistroStaged(stagedDistro);
TimeZoneDistro incompleteDistro =
@@ -204,7 +211,7 @@
.buildUnvalidated();
assertEquals(
TimeZoneDistroInstaller.INSTALL_FAIL_BAD_DISTRO_STRUCTURE,
- installer.stageInstallWithErrorCode(incompleteDistro.getBytes()));
+ installer.stageInstallWithErrorCode(incompleteDistro));
assertInstallDistroStaged(stagedDistro);
assertNoInstalledDistro();
}
@@ -214,7 +221,7 @@
TimeZoneDistro stagedDistro = createValidTimeZoneDistro(NEW_RULES_VERSION, 1);
assertEquals(
TimeZoneDistroInstaller.INSTALL_SUCCESS,
- installer.stageInstallWithErrorCode(stagedDistro.getBytes()));
+ installer.stageInstallWithErrorCode(stagedDistro));
assertInstallDistroStaged(stagedDistro);
TimeZoneDistro incompleteDistro =
@@ -223,7 +230,7 @@
.buildUnvalidated();
assertEquals(
TimeZoneDistroInstaller.INSTALL_FAIL_BAD_DISTRO_STRUCTURE,
- installer.stageInstallWithErrorCode(incompleteDistro.getBytes()));
+ installer.stageInstallWithErrorCode(incompleteDistro));
assertInstallDistroStaged(stagedDistro);
assertNoInstalledDistro();
}
@@ -233,7 +240,7 @@
TimeZoneDistro stagedDistro = createValidTimeZoneDistro(NEW_RULES_VERSION, 1);
assertEquals(
TimeZoneDistroInstaller.INSTALL_SUCCESS,
- installer.stageInstallWithErrorCode(stagedDistro.getBytes()));
+ installer.stageInstallWithErrorCode(stagedDistro));
assertInstallDistroStaged(stagedDistro);
TimeZoneDistro incompleteDistro =
@@ -242,7 +249,7 @@
.buildUnvalidated();
assertEquals(
TimeZoneDistroInstaller.INSTALL_FAIL_BAD_DISTRO_STRUCTURE,
- installer.stageInstallWithErrorCode(incompleteDistro.getBytes()));
+ installer.stageInstallWithErrorCode(incompleteDistro));
assertInstallDistroStaged(stagedDistro);
assertNoInstalledDistro();
}
@@ -252,7 +259,7 @@
TimeZoneDistro stagedDistro = createValidTimeZoneDistro(NEW_RULES_VERSION, 1);
assertEquals(
TimeZoneDistroInstaller.INSTALL_SUCCESS,
- installer.stageInstallWithErrorCode(stagedDistro.getBytes()));
+ installer.stageInstallWithErrorCode(stagedDistro));
assertInstallDistroStaged(stagedDistro);
TimeZoneDistro incompleteDistro =
@@ -261,7 +268,7 @@
.buildUnvalidated();
assertEquals(
TimeZoneDistroInstaller.INSTALL_FAIL_VALIDATION_ERROR,
- installer.stageInstallWithErrorCode(incompleteDistro.getBytes()));
+ installer.stageInstallWithErrorCode(incompleteDistro));
assertInstallDistroStaged(stagedDistro);
assertNoInstalledDistro();
}
@@ -277,7 +284,7 @@
TimeZoneDistro distro = createValidTimeZoneDistro(NEW_RULES_VERSION, 1);
assertEquals(
TimeZoneDistroInstaller.INSTALL_SUCCESS,
- installer.stageInstallWithErrorCode(distro.getBytes()));
+ installer.stageInstallWithErrorCode(distro));
assertInstallDistroStaged(distro);
assertNoInstalledDistro();
}
@@ -292,7 +299,7 @@
.buildUnvalidated();
assertEquals(
TimeZoneDistroInstaller.INSTALL_FAIL_BAD_DISTRO_STRUCTURE,
- installer.stageInstallWithErrorCode(distro.getBytes()));
+ installer.stageInstallWithErrorCode(distro));
assertNoDistroOperationStaged();
assertNoInstalledDistro();
}
@@ -307,7 +314,7 @@
.buildUnvalidated();
assertEquals(
TimeZoneDistroInstaller.INSTALL_FAIL_BAD_DISTRO_FORMAT_VERSION,
- installer.stageInstallWithErrorCode(distro.getBytes()));
+ installer.stageInstallWithErrorCode(distro));
assertNoDistroOperationStaged();
assertNoInstalledDistro();
}
@@ -325,7 +332,7 @@
TimeZoneDistro distro = createTimeZoneDistroWithVersionBytes(invalidFormatVersionBytes);
assertEquals(
TimeZoneDistroInstaller.INSTALL_FAIL_BAD_DISTRO_STRUCTURE,
- installer.stageInstallWithErrorCode(distro.getBytes()));
+ installer.stageInstallWithErrorCode(distro));
assertNoDistroOperationStaged();
assertNoInstalledDistro();
}
@@ -342,7 +349,7 @@
TimeZoneDistro distro = createTimeZoneDistroWithVersionBytes(invalidRevisionBytes);
assertEquals(
TimeZoneDistroInstaller.INSTALL_FAIL_BAD_DISTRO_STRUCTURE,
- installer.stageInstallWithErrorCode(distro.getBytes()));
+ installer.stageInstallWithErrorCode(distro));
assertNoDistroOperationStaged();
assertNoInstalledDistro();
}
@@ -359,7 +366,7 @@
TimeZoneDistro distro = createTimeZoneDistroWithVersionBytes(invalidRulesVersionBytes);
assertEquals(
TimeZoneDistroInstaller.INSTALL_FAIL_BAD_DISTRO_STRUCTURE,
- installer.stageInstallWithErrorCode(distro.getBytes()));
+ installer.stageInstallWithErrorCode(distro));
assertNoDistroOperationStaged();
assertNoInstalledDistro();
}
@@ -442,7 +449,9 @@
assertNoInstalledDistro();
// Check result after staging an install.
- assertTrue(installer.install(distro1.getBytes()));
+ assertEquals(
+ TimeZoneDistroInstaller.INSTALL_SUCCESS,
+ installer.stageInstallWithErrorCode(distro1));
StagedDistroOperation expectedStagedInstall =
StagedDistroOperation.install(distro1.getDistroVersion());
assertEquals(expectedStagedInstall, installer.getStagedDistroOperation());
@@ -469,7 +478,7 @@
// Check state after successfully staging an install.
assertEquals(TimeZoneDistroInstaller.INSTALL_SUCCESS,
- installer.stageInstallWithErrorCode(distro2.getBytes()));
+ installer.stageInstallWithErrorCode(distro2));
StagedDistroOperation expectedStagedInstall2 =
StagedDistroOperation.install(distro2.getDistroVersion());
assertEquals(expectedStagedInstall2, installer.getStagedDistroOperation());
@@ -535,36 +544,45 @@
assertFalse(stagedDistroOperation.isUninstall);
assertEquals(expectedDistro.getDistroVersion(), stagedDistroOperation.distroVersion);
- try (ZipInputStream zis = new ZipInputStream(
- new ByteArrayInputStream(expectedDistro.getBytes()))) {
- ZipEntry entry;
- while ((entry = zis.getNextEntry()) != null) {
- String entryName = entry.getName();
- File actualFile;
- if (entryName.endsWith(TimeZoneDistro.DISTRO_VERSION_FILE_NAME)) {
- actualFile = distroVersionFile;
- } else if (entryName.endsWith(TimeZoneDistro.ICU_DATA_FILE_NAME)) {
- actualFile = icuFile;
- } else if (entryName.endsWith(TimeZoneDistro.TZDATA_FILE_NAME)) {
- actualFile = tzdataFile;
- } else if (entryName.endsWith(TimeZoneDistro.TZLOOKUP_FILE_NAME)) {
- actualFile = tzLookupFile;
- } else {
- throw new AssertionFailedError("Unknown file found");
- }
- assertContentsMatches(zis, actualFile);
- }
- }
+ File expectedZipContentDir = createUniqueDirectory(tempDir, "expectedZipContent");
+ expectedDistro.extractTo(expectedZipContentDir);
+
+ assertContentsMatches(
+ new File(expectedZipContentDir, TimeZoneDistro.DISTRO_VERSION_FILE_NAME),
+ distroVersionFile);
+ assertContentsMatches(
+ new File(expectedZipContentDir, TimeZoneDistro.ICU_DATA_FILE_NAME),
+ icuFile);
+ assertContentsMatches(
+ new File(expectedZipContentDir, TimeZoneDistro.TZDATA_FILE_NAME),
+ tzdataFile);
+ assertContentsMatches(
+ new File(expectedZipContentDir, TimeZoneDistro.TZLOOKUP_FILE_NAME),
+ tzLookupFile);
+ assertFileCount(4, expectedZipContentDir);
// Also check no working directory is left lying around.
File workingDir = installer.getWorkingDir();
assertFalse(workingDir.exists());
}
- private void assertContentsMatches(InputStream expected, File actual)
- throws Exception {
+ private static void assertFileCount(int expectedFiles, File rootDir) throws Exception {
+ final List<Path> paths = new ArrayList<>();
+ FileVisitor<Path> visitor = new SimpleFileVisitor<Path>() {
+ @Override
+ public FileVisitResult visitFile(Path filePath, BasicFileAttributes attrs)
+ throws IOException {
+ paths.add(filePath);
+ return FileVisitResult.CONTINUE;
+ }
+ };
+ Files.walkFileTree(rootDir.toPath(), visitor);
+ assertEquals("Found: " + paths, expectedFiles, paths.size());
+ }
+
+ private void assertContentsMatches(File expected, File actual) throws IOException {
byte[] actualBytes = IoUtils.readFileAsByteArray(actual.getPath());
- byte[] expectedBytes = Streams.readFullyNoClose(expected);
+ byte[] expectedBytes = IoUtils.readFileAsByteArray(expected.getPath());
assertArrayEquals(expectedBytes, actualBytes);
}
@@ -642,32 +660,46 @@
* Creates a TimeZoneDistro containing arbitrary bytes in the version file. Used for testing
* distros with badly formed version info.
*/
- private static TimeZoneDistro createTimeZoneDistroWithVersionBytes(byte[] versionBytes)
+ private TimeZoneDistro createTimeZoneDistroWithVersionBytes(byte[] versionBytes)
throws Exception {
- // Create a valid distro, then manipulate the version file.
+ // Extract the distro to a working dir.
TimeZoneDistro distro = createValidTimeZoneDistro(NEW_RULES_VERSION, 1);
- byte[] distroBytes = distro.getBytes();
+ File workingDir = createUniqueDirectory(tempDir, "versionBytes");
+ distro.extractTo(workingDir);
- ByteArrayOutputStream baos = new ByteArrayOutputStream(distroBytes.length);
- try (ZipInputStream zipInputStream =
- new ZipInputStream(new ByteArrayInputStream(distroBytes));
- ZipOutputStream zipOutputStream = new ZipOutputStream(baos)) {
-
- ZipEntry entry;
- while ((entry = zipInputStream.getNextEntry()) != null) {
- zipOutputStream.putNextEntry(entry);
- if (entry.getName().equals(TimeZoneDistro.DISTRO_VERSION_FILE_NAME)) {
- // Replace the content.
- zipOutputStream.write(versionBytes);
- } else {
- // Just copy the content.
- Streams.copy(zipInputStream, zipOutputStream);
- }
- zipOutputStream.closeEntry();
- zipInputStream.closeEntry();
- }
+ // Modify the version file.
+ File versionFile = new File(workingDir, TimeZoneDistro.DISTRO_VERSION_FILE_NAME);
+ assertTrue(versionFile.exists());
+ try (FileOutputStream fos = new FileOutputStream(versionFile, false /* append */)) {
+ fos.write(versionBytes);
}
+
+ // Zip the distro back up again.
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ try (ZipOutputStream zos = new ZipOutputStream(baos)) {
+ Path workingDirPath = workingDir.toPath();
+ Files.walkFileTree(workingDirPath, new SimpleFileVisitor<Path>() {
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+ throws IOException {
+ byte[] bytes = IoUtils.readFileAsByteArray(file.toString());
+ String relativeFileName = workingDirPath.relativize(file).toString();
+ addZipEntry(zos, relativeFileName, bytes);
+ return FileVisitResult.CONTINUE;
+ }
+ });
+ }
+
return new TimeZoneDistro(baos.toByteArray());
}
+
+ private static void addZipEntry(ZipOutputStream zos, String name, byte[] content)
+ throws IOException {
+ ZipEntry zipEntry = new ZipEntry(name);
+ zipEntry.setSize(content.length);
+ zos.putNextEntry(zipEntry);
+ zos.write(content);
+ zos.closeEntry();
+ }
}