aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/test/java/com/google/devtools/build/android/ZipFilterActionTest.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/java/com/google/devtools/build/android/ZipFilterActionTest.java')
-rw-r--r--src/test/java/com/google/devtools/build/android/ZipFilterActionTest.java296
1 files changed, 296 insertions, 0 deletions
diff --git a/src/test/java/com/google/devtools/build/android/ZipFilterActionTest.java b/src/test/java/com/google/devtools/build/android/ZipFilterActionTest.java
new file mode 100644
index 0000000000..a59f2cb58d
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/android/ZipFilterActionTest.java
@@ -0,0 +1,296 @@
+// Copyright 2017 The Bazel Authors. All rights reserved.
+//
+// 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.google.devtools.build.android;
+
+import static com.google.common.truth.Truth.assertThat;
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSetMultimap;
+import com.google.common.collect.Multimap;
+import com.google.devtools.build.singlejar.ZipEntryFilter.CustomMergeStrategy;
+import com.google.devtools.build.singlejar.ZipEntryFilter.StrategyCallback;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipException;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipOutputStream;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.rules.TemporaryFolder;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Tests for {@link ZipFilterAction}. */
+@RunWith(JUnit4.class)
+public class ZipFilterActionTest {
+
+ private static final class Entry {
+ private final String name;
+ private final String contents;
+
+ public Entry(String name, String contents) {
+ this.name = name;
+ this.contents = contents;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getContents() {
+ return contents;
+ }
+ }
+
+ private enum FilterOperation {
+ SKIP,
+ RENAME,
+ CUSTOM_MERGE,
+ COPY
+ }
+
+ private static final class TestingStrategyCallback implements StrategyCallback {
+ private FilterOperation operation;
+
+ public void assertOp(FilterOperation operation) {
+ assertThat(this.operation).isEqualTo(operation);
+ }
+
+ @Override
+ public void skip() throws IOException {
+ operation = FilterOperation.SKIP;
+ }
+
+ @Override
+ public void rename(String filename, Date date) throws IOException {
+ operation = FilterOperation.RENAME;
+ }
+
+ @Override
+ public void customMerge(Date date, CustomMergeStrategy strategy) throws IOException {
+ operation = FilterOperation.CUSTOM_MERGE;
+ }
+
+ @Override
+ public void copy(Date date) throws IOException {
+ operation = FilterOperation.COPY;
+ }
+ }
+
+ @Rule public ExpectedException thrown = ExpectedException.none();
+ @Rule public TemporaryFolder tmp = new TemporaryFolder();
+
+ private int fileCount;
+ private TestingStrategyCallback callback;
+
+ private Path createZip(String... filenames) throws IOException {
+ Entry[] entries = new Entry[filenames.length];
+ int i = 0;
+ for (String filename : filenames) {
+ entries[i++] = new Entry(filename, "" + fileCount++);
+ }
+ return createZip(entries);
+ }
+
+ private Path createZip(Entry... entries) throws IOException {
+ File zip = tmp.newFile();
+ try (ZipOutputStream zout = new ZipOutputStream(new FileOutputStream(zip))) {
+ for (Entry entry : entries) {
+ ZipEntry e = new ZipEntry(entry.getName());
+ zout.putNextEntry(e);
+ zout.write(entry.getContents().getBytes(UTF_8));
+ zout.closeEntry();
+ }
+ }
+ return zip.toPath();
+ }
+
+ @Before public void setup() {
+ callback = new TestingStrategyCallback();
+ }
+
+ @Test public void testCreateFilter() throws IOException {
+ ImmutableSet<Path> filters = ImmutableSet.of(
+ createZip("foo.class", "bar.java"),
+ createZip("foo.java", "bar.java", "baz.class"));
+ ImmutableSet<String> types = ImmutableSet.of(".class");
+ Multimap<String, Long> filterFiles = ZipFilterAction.getEntriesToOmit(filters, types);
+ assertThat(filterFiles.keySet()).containsExactly("foo.class", "baz.class");
+ assertThat(filterFiles).valuesForKey("foo.class").hasSize(1);
+ assertThat(filterFiles).valuesForKey("baz.class").hasSize(1);
+ }
+
+ @Test public void testCreateFilter_NoZips() throws IOException {
+ ImmutableSet<Path> filters = ImmutableSet.of();
+ ImmutableSet<String> types = ImmutableSet.of(".class");
+ Multimap<String, Long> filterFiles = ZipFilterAction.getEntriesToOmit(filters, types);
+ assertThat(filterFiles).isEmpty();
+ }
+
+ @Test public void testCreateFilter_NoTypes() throws IOException {
+ ImmutableSet<Path> filters = ImmutableSet.of(
+ createZip("foo.class", "bar.java"),
+ createZip("foo.java", "bar.java", "baz.class"));
+ ImmutableSet<String> types = ImmutableSet.of();
+ Multimap<String, Long> filterFiles = ZipFilterAction.getEntriesToOmit(filters, types);
+ assertThat(filterFiles.keySet())
+ .containsExactly("foo.class", "bar.java", "foo.java", "baz.class");
+ }
+
+ @Test public void testCreateFilter_MultipleTypes() throws IOException {
+ ImmutableSet<Path> filters = ImmutableSet.of(
+ createZip("foo.class", "bar.java"),
+ createZip("foo.java", "bar.java", "baz.class"));
+ ImmutableSet<String> types = ImmutableSet.of(".class", "bar.java");
+ Multimap<String, Long> filterFiles = ZipFilterAction.getEntriesToOmit(filters, types);
+ assertThat(filterFiles.keySet()).containsExactly("foo.class", "baz.class", "bar.java");
+ assertThat(filterFiles).valuesForKey("foo.class").hasSize(1);
+ assertThat(filterFiles).valuesForKey("bar.java").hasSize(2);
+ }
+
+ @Test public void testZipEntryFilter() throws Exception {
+ ZipFilterEntryFilter filter = new ZipFilterEntryFilter(".*R.class.*",
+ ImmutableSetMultimap.of("foo.class", 1L, "baz.class", 2L),
+ ImmutableMap.of("foo.class", 1L, "bar.class", 2L, "baz.class", 3L, "res/R.class", 4L),
+ false);
+ filter.accept("foo.class", callback);
+ callback.assertOp(FilterOperation.SKIP);
+ filter.accept("bar.class", callback);
+ callback.assertOp(FilterOperation.COPY);
+ filter.accept("baz.class", callback);
+ callback.assertOp(FilterOperation.COPY);
+ filter.accept("res/R.class", callback);
+ callback.assertOp(FilterOperation.SKIP);
+ }
+
+ @Test public void testZipEntryFilter_ErrorOnMismatch() throws Exception {
+ ZipFilterEntryFilter filter = new ZipFilterEntryFilter(".*R.class.*",
+ ImmutableSetMultimap.of("foo.class", 1L, "baz.class", 2L),
+ ImmutableMap.of("foo.class", 1L, "bar.class", 2L, "baz.class", 3L, "res/R.class", 4L),
+ true);
+ filter.accept("foo.class", callback);
+ callback.assertOp(FilterOperation.SKIP);
+ filter.accept("bar.class", callback);
+ callback.assertOp(FilterOperation.COPY);
+ filter.accept("res/R.class", callback);
+ callback.assertOp(FilterOperation.SKIP);
+ thrown.expect(IllegalStateException.class);
+ thrown.expectMessage("name matches but the hash does not.");
+ filter.accept("baz.class", callback);
+ }
+
+ @Test public void testFlags() throws Exception {
+ File input = tmp.newFile("input");
+ File output = tmp.newFile("output");
+ output.delete();
+ File filter1 = tmp.newFile("filter1");
+ File filter2 = tmp.newFile("filter2");
+
+ ImmutableList<String> args = ImmutableList.of(
+ "--inputZip", input.getPath(),
+ "--outputZip", output.getPath(),
+ "--filterZips", Joiner.on(",").join(filter1.getPath(), filter2.getPath(),
+ filter1.getPath()),
+ "--filterTypes", Joiner.on(",").join(".class", ".class", ".java"),
+ "--explicitFilters", Joiner.on(",").join("R\\.class", "R\\$.*\\.class"),
+ "--outputMode", "DONT_CARE",
+ "--noerrorOnHashMismatch");
+ thrown.expect(ZipException.class);
+ thrown.expectMessage("Zip file 'filter1' is malformed");
+ ZipFilterAction.main(args.toArray(new String[0]));
+ }
+
+ @Test public void testFullIntegration() throws IOException {
+ Path input = createZip(new Entry("foo.java", "foo"), new Entry("bar.class", "bar"),
+ new Entry("baz.class", "baz"), new Entry("1.class", "1"), new Entry("2.class", "2"),
+ new Entry("R.class", "r"), new Entry("Read.class", "read"));
+ File output = tmp.newFile();
+ output.delete();
+ Path filter1 = createZip(new Entry("1.class", "1"), new Entry("b.class", "b"));
+ Path filter2 = createZip(new Entry("1.class", "2"), new Entry("2.class", "1"),
+ new Entry("foo.java", "foo"), new Entry("bar.class", "bar"));
+ ImmutableList<String> args = ImmutableList.of(
+ "--inputZip", input.toFile().getPath(),
+ "--outputZip", output.getPath(),
+ "--filterZips", Joiner.on(",").join(filter1.toFile().getPath(), filter2.toFile().getPath(),
+ filter1.toFile().getPath()),
+ "--filterTypes", ".class",
+ "--explicitFilters", Joiner.on(",").join("R\\.class", "R\\$.*\\.class"),
+ "--outputMode", "DONT_CARE");
+ ZipFilterAction.main(args.toArray(new String[0]));
+ List<String> filteredEntries = new ArrayList<>();
+ try (ZipFile zip = new ZipFile(output)) {
+ Enumeration<? extends ZipEntry> entries = zip.entries();
+ while (entries.hasMoreElements()) {
+ filteredEntries.add(entries.nextElement().getName());
+ }
+ }
+ assertThat(filteredEntries).containsExactly("foo.java", "baz.class", "2.class", "Read.class");
+ }
+
+ @Test public void testFullIntegrationErrorsOnHash() throws IOException {
+ Path input = createZip("foo.java", "bar.class", "baz.class");
+ File output = tmp.newFile();
+ output.delete();
+ Path filter = createZip("foo.java", "bar.class");
+ ImmutableList<String> args = ImmutableList.of(
+ "--inputZip", input.toFile().getPath(),
+ "--outputZip", output.getPath(),
+ "--filterZips", filter.toFile().getPath(),
+ "--filterTypes", ".class",
+ "--outputMode", "DONT_CARE",
+ "--errorOnHashMismatch");
+ thrown.expect(IllegalStateException.class);
+ thrown.expectMessage("name matches but the hash does not");
+ ZipFilterAction.main(args.toArray(new String[0]));
+ }
+
+ @Test public void testFullIntegrationErrorsOnHash_WithExplicitOverride()
+ throws IOException {
+ Path input = createZip("foo.java", "bar.class", "baz.class");
+ File output = tmp.newFile();
+ output.delete();
+ Path filter = createZip("foo.java", "bar.class");
+ ImmutableList<String> args = ImmutableList.of(
+ "--inputZip", input.toFile().getPath(),
+ "--outputZip", output.getPath(),
+ "--filterZips", filter.toFile().getPath(),
+ "--filterTypes", ".class",
+ "--explicitFilters", "bar\\.class",
+ "--outputMode", "DONT_CARE",
+ "--errorOnHashMismatch");
+ ZipFilterAction.main(args.toArray(new String[0]));
+ List<String> filteredEntries = new ArrayList<>();
+ try (ZipFile zip = new ZipFile(output)) {
+ Enumeration<? extends ZipEntry> entries = zip.entries();
+ while (entries.hasMoreElements()) {
+ filteredEntries.add(entries.nextElement().getName());
+ }
+ }
+ assertThat(filteredEntries).containsExactly("foo.java", "baz.class");
+ }
+}