xref: /aosp_15_r20/tools/apkzlib/src/test/java/com/android/tools/build/apkzlib/zip/ZipToolsTest.java (revision 9c3094a04dff8e70054da9eaa66b6011c81fa00d)
1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.tools.build.apkzlib.zip;
18 
19 import static org.junit.Assert.assertArrayEquals;
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertNotNull;
22 import static org.junit.Assert.assertTrue;
23 import static org.junit.Assert.fail;
24 
25 import com.google.common.base.Charsets;
26 import com.google.common.collect.ImmutableList;
27 import com.google.common.collect.Lists;
28 import com.google.common.collect.Maps;
29 import com.google.common.io.ByteStreams;
30 import com.google.common.io.Files;
31 import java.io.ByteArrayInputStream;
32 import java.io.File;
33 import java.io.InputStream;
34 import java.util.Arrays;
35 import java.util.List;
36 import java.util.Map;
37 import java.util.regex.Matcher;
38 import java.util.regex.Pattern;
39 import javax.annotation.Nonnull;
40 import javax.annotation.Nullable;
41 import org.junit.Assume;
42 import org.junit.Rule;
43 import org.junit.Test;
44 import org.junit.rules.TemporaryFolder;
45 import org.junit.runner.RunWith;
46 import org.junit.runners.Parameterized;
47 
48 @RunWith(Parameterized.class)
49 public class ZipToolsTest {
50 
51     @Parameterized.Parameter(0)
52     @Nullable
53     public String mZipFile;
54 
55     @Parameterized.Parameter(1)
56     @Nullable
57     public List<String> mUnzipCommand;
58 
59     @Parameterized.Parameter(2)
60     @Nullable
61     public String mUnzipLineRegex;
62 
63     @Parameterized.Parameter(3)
64     public boolean mToolStoresDirectories;
65 
66     @Parameterized.Parameter(4)
67     public String mName;
68 
69     @Rule
70     @Nonnull
71     public TemporaryFolder mTemporaryFolder = new TemporaryFolder();
72 
73     @Parameterized.Parameters(name = "{4} {index}")
getConfigurations()74     public static Iterable<Object[]> getConfigurations() {
75         return Arrays.asList(new Object[][] {
76                 {
77                         "linux-zip.zip",
78                         ImmutableList.of("/usr/bin/unzip", "-v"),
79                         "^\\s*(?<size>\\d+)\\s+(?:Stored|Defl:N).*\\s(?<name>\\S+)\\S*$",
80                         true,
81                         "Linux Zip"
82                 },
83                 {
84                         "windows-7zip.zip",
85                         ImmutableList.of("c:\\Program Files\\7-Zip\\7z.exe", "l"),
86                         "^(?:\\S+\\s+){3}(?<size>\\d+)\\s+\\d+\\s+(?<name>\\S+)\\s*$",
87                         true,
88                         "Windows 7-Zip"
89                 },
90                 {
91                         "windows-cf.zip",
92                         ImmutableList.of(
93                                 "Cannot use compressed folders from cmd line to list zip contents"),
94                         "",
95                         false,
96                         "Windows Compressed Folders"
97                 }
98         });
99     }
100 
cloneZipFile()101     private File cloneZipFile() throws Exception {
102         File zfile = mTemporaryFolder.newFile("file.zip");
103         Files.write(ZipTestUtils.rsrcBytes(mZipFile), zfile);
104         return zfile;
105     }
106 
assertFileInZip(@onnull ZFile zfile, @Nonnull String name)107     private static void assertFileInZip(@Nonnull ZFile zfile, @Nonnull String name) throws Exception {
108         StoredEntry root = zfile.get(name);
109         assertNotNull(root);
110 
111         InputStream is = root.open();
112         byte[] inZipData = ByteStreams.toByteArray(is);
113         is.close();
114 
115         byte[] inFileData = ZipTestUtils.rsrcBytes(name);
116         assertArrayEquals(inFileData, inZipData);
117     }
118 
119     @Test
zfileReadsZipFile()120     public void zfileReadsZipFile() throws Exception {
121         try (ZFile zf = new ZFile(cloneZipFile())) {
122             if (mToolStoresDirectories) {
123                 assertEquals(6, zf.entries().size());
124             } else {
125                 assertEquals(4, zf.entries().size());
126             }
127 
128             assertFileInZip(zf, "root");
129             assertFileInZip(zf, "images/lena.png");
130             assertFileInZip(zf, "text-files/rfc2460.txt");
131             assertFileInZip(zf, "text-files/wikipedia.html");
132         }
133     }
134 
135     @Test
toolReadsZfFile()136     public void toolReadsZfFile() throws Exception {
137         testReadZFile(false);
138     }
139 
140     @Test
toolReadsAlignedZfFile()141     public void toolReadsAlignedZfFile() throws Exception {
142         testReadZFile(true);
143     }
144 
testReadZFile(boolean align)145     private void testReadZFile(boolean align) throws Exception {
146         String unzipcmd = mUnzipCommand.get(0);
147         Assume.assumeTrue(new File(unzipcmd).canExecute());
148 
149         ZFileOptions options = new ZFileOptions();
150         if (align) {
151             options.setAlignmentRule(AlignmentRules.constant(500));
152         }
153 
154         File zfile = new File (mTemporaryFolder.getRoot(), "zfile.zip");
155         try (ZFile zf = new ZFile(zfile, options)) {
156             zf.add("root", new ByteArrayInputStream(ZipTestUtils.rsrcBytes("root")));
157             zf.add("images/", new ByteArrayInputStream(new byte[0]));
158             zf.add(
159                     "images/lena.png",
160                     new ByteArrayInputStream(ZipTestUtils.rsrcBytes("images/lena.png")));
161             zf.add("text-files/", new ByteArrayInputStream(new byte[0]));
162             zf.add(
163                     "text-files/rfc2460.txt",
164                     new ByteArrayInputStream(ZipTestUtils.rsrcBytes("text-files/rfc2460.txt")));
165             zf.add(
166                     "text-files/wikipedia.html",
167                     new ByteArrayInputStream(ZipTestUtils.rsrcBytes("text-files/wikipedia.html")));
168         }
169 
170         List<String> command = Lists.newArrayList(mUnzipCommand);
171         command.add(zfile.getAbsolutePath());
172         ProcessBuilder pb = new ProcessBuilder(command);
173         Process proc = pb.start();
174         InputStream is = proc.getInputStream();
175         byte output[] = ByteStreams.toByteArray(is);
176         String text = new String(output, Charsets.US_ASCII);
177         String lines[] = text.split("\n");
178         Map<String, Integer> sizes = Maps.newHashMap();
179         for (String l : lines) {
180             Matcher m = Pattern.compile(mUnzipLineRegex).matcher(l);
181             if (m.matches()) {
182                 String sizeTxt = m.group("size");
183                 int size = Integer.parseInt(sizeTxt);
184                 String name = m.group("name");
185                 sizes.put(name, size);
186             }
187         }
188 
189         assertEquals(6, sizes.size());
190 
191         /*
192          * The "images" directory may show up as "images" or "images/".
193          */
194         String imagesKey = "images/";
195         if (!sizes.containsKey(imagesKey)) {
196             imagesKey = "images";
197         }
198 
199         assertTrue(sizes.containsKey(imagesKey));
200         assertEquals(0, sizes.get(imagesKey).intValue());
201 
202         assertSize(new String[] { "images/", "images" }, 0, sizes);
203         assertSize(new String[] { "text-files/", "text-files"}, 0, sizes);
204         assertSize(new String[] { "root" }, ZipTestUtils.rsrcBytes("root").length, sizes);
205         assertSize(new String[] { "images/lena.png", "images\\lena.png" },
206                 ZipTestUtils.rsrcBytes("images/lena.png").length, sizes);
207         assertSize(new String[] { "text-files/rfc2460.txt", "text-files\\rfc2460.txt" },
208                 ZipTestUtils.rsrcBytes("text-files/rfc2460.txt").length, sizes);
209         assertSize(new String[] { "text-files/wikipedia.html", "text-files\\wikipedia.html" },
210                 ZipTestUtils.rsrcBytes("text-files/wikipedia.html").length, sizes);
211     }
212 
assertSize(String[] names, long size, Map<String, Integer> sizes)213     private static void assertSize(String[] names, long size, Map<String, Integer> sizes) {
214         for (String n : names) {
215             if (sizes.containsKey(n)) {
216                 assertEquals((long) sizes.get(n), size);
217                 return;
218             }
219         }
220 
221         fail();
222     }
223 }
224