diff options
Diffstat (limited to 'src/test/java/com/android/tools/build/apkzlib/zip/ZipMergeTest.java')
-rw-r--r-- | src/test/java/com/android/tools/build/apkzlib/zip/ZipMergeTest.java | 205 |
1 files changed, 205 insertions, 0 deletions
diff --git a/src/test/java/com/android/tools/build/apkzlib/zip/ZipMergeTest.java b/src/test/java/com/android/tools/build/apkzlib/zip/ZipMergeTest.java new file mode 100644 index 0000000..cd1b246 --- /dev/null +++ b/src/test/java/com/android/tools/build/apkzlib/zip/ZipMergeTest.java @@ -0,0 +1,205 @@ +/* + * 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.tools.build.apkzlib.zip; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import com.android.tools.build.apkzlib.utils.CachedFileContents; +import com.google.common.base.Charsets; +import com.google.common.hash.Hashing; +import com.google.common.io.ByteStreams; +import com.google.common.io.Closer; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +public class ZipMergeTest { + @Rule + public TemporaryFolder mTemporaryFolder = new TemporaryFolder(); + + @Test + public void mergeZip() throws Exception { + File aZip = ZipTestUtils.cloneRsrc("simple-zip.zip", mTemporaryFolder, "a.zip"); + + CachedFileContents<Object> changeDetector; + File merged = new File(mTemporaryFolder.getRoot(), "r.zip"); + try (ZFile mergedZf = new ZFile(merged)) { + mergedZf.mergeFrom(new ZFile(aZip), f -> false); + mergedZf.close(); + + assertEquals(3, mergedZf.entries().size()); + + StoredEntry e0 = mergedZf.get("dir/"); + assertNotNull(e0); + assertSame(StoredEntryType.DIRECTORY, e0.getType()); + + StoredEntry e1 = mergedZf.get("dir/inside"); + assertNotNull(e1); + assertSame(StoredEntryType.FILE, e1.getType()); + ByteArrayOutputStream e1BytesOut = new ByteArrayOutputStream(); + ByteStreams.copy(e1.open(), e1BytesOut); + byte e1Bytes[] = e1BytesOut.toByteArray(); + String e1Txt = new String(e1Bytes, Charsets.US_ASCII); + assertEquals("inside", e1Txt); + + StoredEntry e2 = mergedZf.get("file.txt"); + assertNotNull(e2); + assertSame(StoredEntryType.FILE, e2.getType()); + ByteArrayOutputStream e2BytesOut = new ByteArrayOutputStream(); + ByteStreams.copy(e2.open(), e2BytesOut); + byte e2Bytes[] = e2BytesOut.toByteArray(); + String e2Txt = new String(e2Bytes, Charsets.US_ASCII); + assertEquals("file with more text to allow deflating to be useful", e2Txt); + + changeDetector = new CachedFileContents<>(merged); + changeDetector.closed(null); + + /* + * Clone aZip into bZip and merge. Should have no effect on the final zip file. + */ + File bZip = ZipTestUtils.cloneRsrc("simple-zip.zip", mTemporaryFolder, "b.zip"); + + mergedZf.mergeFrom(new ZFile(bZip), f -> false); + } + + assertTrue(changeDetector.isValid()); + } + + @Test + public void mergeZipWithDeferredCrc() throws Exception { + File foo = mTemporaryFolder.newFile("foo"); + + byte[] wBytes = ZipTestUtils.rsrcBytes("text-files/wikipedia.html"); + + try (ZipOutputStream fooOut = new ZipOutputStream(new FileOutputStream(foo))) { + fooOut.putNextEntry(new ZipEntry("w")); + fooOut.write(wBytes); + } + + try (Closer closer = Closer.create()) { + ZFile fooZf = closer.register(new ZFile(foo)); + StoredEntry wStored = fooZf.get("w"); + assertNotNull(wStored); + assertTrue(wStored.getCentralDirectoryHeader().getGpBit().isDeferredCrc()); + assertEquals(CompressionMethod.DEFLATE, + wStored.getCentralDirectoryHeader().getCompressionInfoWithWait().getMethod()); + + ZFile merged = closer.register(new ZFile(new File(mTemporaryFolder.getRoot(), "bar"))); + merged.mergeFrom(fooZf, f -> false); + merged.update(); + + StoredEntry wmStored = merged.get("w"); + assertNotNull(wmStored); + assertFalse(wmStored.getCentralDirectoryHeader().getGpBit().isDeferredCrc()); + assertEquals(CompressionMethod.DEFLATE, + wmStored.getCentralDirectoryHeader().getCompressionInfoWithWait().getMethod()); + } + } + + @Test + public void mergeZipKeepsDeflatedAndStored() throws Exception { + File foo = mTemporaryFolder.newFile("foo"); + + byte[] wBytes = ZipTestUtils.rsrcBytes("text-files/wikipedia.html"); + byte[] lBytes = ZipTestUtils.rsrcBytes("images/lena.png"); + + try (ZipOutputStream fooOut = new ZipOutputStream(new FileOutputStream(foo))) { + fooOut.putNextEntry(new ZipEntry("w")); + fooOut.write(wBytes); + ZipEntry le = new ZipEntry("l"); + le.setMethod(ZipEntry.STORED); + le.setSize(lBytes.length); + le.setCrc(Hashing.crc32().hashBytes(lBytes).padToLong()); + fooOut.putNextEntry(le); + fooOut.write(lBytes); + } + + try (Closer closer = Closer.create()) { + ZFile fooZf = closer.register(new ZFile(foo)); + StoredEntry wStored = fooZf.get("w"); + assertNotNull(wStored); + assertEquals(CompressionMethod.DEFLATE, + wStored.getCentralDirectoryHeader().getCompressionInfoWithWait().getMethod()); + StoredEntry lStored = fooZf.get("l"); + assertNotNull(lStored); + assertEquals(CompressionMethod.STORE, + lStored.getCentralDirectoryHeader().getCompressionInfoWithWait().getMethod()); + + ZFile merged = closer.register(new ZFile(new File(mTemporaryFolder.getRoot(), "bar"))); + merged.mergeFrom(fooZf, f -> false); + merged.update(); + + StoredEntry wmStored = merged.get("w"); + assertNotNull(wmStored); + assertFalse(wmStored.getCentralDirectoryHeader().getGpBit().isDeferredCrc()); + assertEquals(CompressionMethod.DEFLATE, + wmStored.getCentralDirectoryHeader().getCompressionInfoWithWait().getMethod()); + assertArrayEquals(wBytes, wmStored.read()); + + StoredEntry lmStored = merged.get("l"); + assertNotNull(lmStored); + assertEquals(CompressionMethod.STORE, + lmStored.getCentralDirectoryHeader().getCompressionInfoWithWait().getMethod()); + assertArrayEquals(lBytes, lmStored.read()); + } + } + + @Test + public void mergeZipWithSorting() throws Exception { + File foo = mTemporaryFolder.newFile("foo"); + + byte[] wBytes = ZipTestUtils.rsrcBytes("text-files/wikipedia.html"); + byte[] lBytes = ZipTestUtils.rsrcBytes("images/lena.png"); + + try (ZipOutputStream fooOut = new ZipOutputStream(new FileOutputStream(foo))) { + fooOut.putNextEntry(new ZipEntry("w")); + fooOut.write(wBytes); + ZipEntry le = new ZipEntry("l"); + le.setMethod(ZipEntry.STORED); + le.setSize(lBytes.length); + le.setCrc(Hashing.crc32().hashBytes(lBytes).padToLong()); + fooOut.putNextEntry(le); + fooOut.write(lBytes); + } + + try ( + ZFile fooZf = new ZFile(foo); + ZFile merged = new ZFile(new File(mTemporaryFolder.getRoot(), "bar"))) { + merged.mergeFrom(fooZf, f -> false); + merged.sortZipContents(); + merged.update(); + + StoredEntry wmStored = merged.get("w"); + assertNotNull(wmStored); + assertArrayEquals(wBytes, wmStored.read()); + + StoredEntry lmStored = merged.get("l"); + assertNotNull(lmStored); + assertArrayEquals(lBytes, lmStored.read()); + } + } +} |