1 package com.atlassian.maven.plugins.amps.util;
2
3 import org.apache.commons.io.FileUtils;
4 import org.junit.After;
5 import org.junit.Before;
6 import org.junit.Test;
7
8 import com.google.common.collect.Lists;
9
10 import java.io.File;
11 import java.io.IOException;
12 import java.net.URISyntaxException;
13 import java.net.URL;
14 import java.util.Enumeration;
15 import java.util.List;
16 import java.util.UUID;
17 import java.util.zip.ZipEntry;
18 import java.util.zip.ZipFile;
19
20 import static org.hamcrest.core.IsEqual.equalTo;
21 import static org.hamcrest.core.IsNot.not;
22 import static org.junit.Assert.assertEquals;
23 import static org.junit.Assert.assertThat;
24 import static org.junit.Assert.assertTrue;
25
26 public class TestZipUtils
27 {
28 public static final int NUM_FILES = 2;
29 public static final int NUM_FOLDERS = 4;
30 public static final int NUM_FOLDERS_NESTED_PREFIX = NUM_FOLDERS + 1;
31
32 public static final String ROOT_DIR = "test-zip-dir";
33 public static final String FIRST_PREFIX = "prefix1";
34 public static final String SECOND_PREFIX = "prefix2";
35 public static final String NESTED_PREFIX = FIRST_PREFIX + "/" + SECOND_PREFIX;
36
37 private File tempDir;
38 private File sourceZipDir;
39 private ZipFile zip;
40
41 @Before
42 public void ensureDirsExist() throws IOException
43 {
44
45
46 final File sysTempDir = new File(System.getProperty("java.io.tmpdir"));
47 String dirName = UUID.randomUUID().toString();
48 tempDir = new File(sysTempDir, dirName);
49 tempDir.mkdirs();
50
51
52 sourceZipDir = new File(tempDir, ROOT_DIR);
53 File level2sub1 = new File(sourceZipDir, "level2sub1");
54 File level2sub2 = new File(sourceZipDir, "level2sub2");
55 File level3sub1 = new File(level2sub2, "level3sub1");
56
57 File level2TextFile = new File(level2sub2, "level2sub2.txt");
58 File level3TextFile = new File(level3sub1, "level3sub1.txt");
59
60 level2sub1.mkdirs();
61 level3sub1.mkdirs();
62
63 FileUtils.writeStringToFile(level2TextFile, "level2sub2");
64 FileUtils.writeStringToFile(level3TextFile, "level3sub1");
65 }
66
67 @After
68 public void removeTempDir() throws IOException
69 {
70
71 if (zip != null)
72 {
73 try
74 {
75 zip.close();
76 }
77 catch (IOException e)
78 {
79
80 }
81 zip = null;
82 }
83 FileUtils.deleteDirectory(tempDir);
84 }
85
86 @Test
87 public void zipContainsSinglePrefix() throws IOException
88 {
89 File zipFile = new File(tempDir, "zip-with-prefix.zip");
90 ZipUtils.zipDir(zipFile, sourceZipDir, FIRST_PREFIX);
91
92 zip = new ZipFile(zipFile);
93 final Enumeration<? extends ZipEntry> entries = zip.entries();
94
95 while (entries.hasMoreElements())
96 {
97 final ZipEntry zipEntry = entries.nextElement();
98 String zipPath = zipEntry.getName();
99 String testPrefix = zipPath.substring(0, zipPath.indexOf("/"));
100
101 assertEquals(FIRST_PREFIX, testPrefix);
102 }
103 }
104
105 @Test
106 public void zipContainsNestedPrefix() throws IOException
107 {
108 File zipFile = new File(tempDir, "zip-nested-prefix.zip");
109 ZipUtils.zipDir(zipFile, sourceZipDir, NESTED_PREFIX);
110
111 zip = new ZipFile(zipFile);
112 final Enumeration<? extends ZipEntry> entries = zip.entries();
113
114 while (entries.hasMoreElements())
115 {
116 final ZipEntry zipEntry = entries.nextElement();
117 String zipPath = zipEntry.getName();
118 String[] segments = zipPath.split("/");
119 if (segments.length > 1)
120 {
121 String testPrefix = segments[0] + "/" + segments[1];
122
123 assertEquals(NESTED_PREFIX, testPrefix);
124 }
125 }
126 }
127
128 @Test
129 public void prefixedZipDoesNotContainRootDir() throws IOException
130 {
131 File zipFile = new File(tempDir, "zip-with-prefix-no-root.zip");
132 ZipUtils.zipDir(zipFile, sourceZipDir, FIRST_PREFIX);
133
134 zip = new ZipFile(zipFile);
135 final Enumeration<? extends ZipEntry> entries = zip.entries();
136
137 while (entries.hasMoreElements())
138 {
139 final ZipEntry zipEntry = entries.nextElement();
140 String zipPath = zipEntry.getName();
141 String[] segments = zipPath.split("/");
142 if (segments.length > 1)
143 {
144 String rootPath = segments[1];
145
146 assertThat(rootPath, not(equalTo(ROOT_DIR)));
147 }
148 }
149 }
150
151 @Test
152 public void nestedPrefixedZipDoesNotContainRootDir() throws IOException
153 {
154 File zipFile = new File(tempDir, "zip-nested-prefix-no-root.zip");
155 ZipUtils.zipDir(zipFile, sourceZipDir, NESTED_PREFIX);
156
157 zip = new ZipFile(zipFile);
158 final Enumeration<? extends ZipEntry> entries = zip.entries();
159
160 while (entries.hasMoreElements())
161 {
162 final ZipEntry zipEntry = entries.nextElement();
163 String zipPath = zipEntry.getName();
164 String[] segments = zipPath.split("/");
165 if (segments.length > 2)
166 {
167 String rootPath = segments[2];
168
169 assertThat(rootPath, not(equalTo(ROOT_DIR)));
170 }
171 }
172 }
173
174 @Test
175 public void emptyPrefixedZipContainsRootDir() throws IOException
176 {
177 File zipFile = new File(tempDir, "zip-empty-prefix.zip");
178 ZipUtils.zipDir(zipFile, sourceZipDir, "");
179
180 zip = new ZipFile(zipFile);
181 final Enumeration<? extends ZipEntry> entries = zip.entries();
182
183 while (entries.hasMoreElements())
184 {
185 final ZipEntry zipEntry = entries.nextElement();
186 String zipPath = zipEntry.getName();
187 String rootPath = zipPath.substring(0, zipPath.indexOf("/"));
188
189 assertEquals(ROOT_DIR, rootPath);
190 }
191 }
192
193 @Test
194 public void nullPrefixedZipContainsRootDir() throws IOException
195 {
196 File zipFile = new File(tempDir, "zip-null-prefix.zip");
197 ZipUtils.zipDir(zipFile, sourceZipDir, null);
198
199 zip = new ZipFile(zipFile);
200 final Enumeration<? extends ZipEntry> entries = zip.entries();
201
202 while (entries.hasMoreElements())
203 {
204 final ZipEntry zipEntry = entries.nextElement();
205 String zipPath = zipEntry.getName();
206 String rootPath = zipPath.substring(0, zipPath.indexOf("/"));
207
208 assertEquals(ROOT_DIR, rootPath);
209 }
210 }
211
212 @Test
213 public void emptyPrefixedZipFolderCountMatches() throws IOException
214 {
215 File zipFile = new File(tempDir, "zip-empty-prefix.zip");
216 ZipUtils.zipDir(zipFile, sourceZipDir, "");
217
218 zip = new ZipFile(zipFile);
219 final Enumeration<? extends ZipEntry> entries = zip.entries();
220
221 int numFolders = 0;
222
223 while (entries.hasMoreElements())
224 {
225 final ZipEntry zipEntry = entries.nextElement();
226 if (zipEntry.isDirectory())
227 {
228 numFolders++;
229 }
230 }
231
232 assertEquals(NUM_FOLDERS, numFolders);
233 }
234
235 @Test
236 public void singlePrefixedZipFolderCountMatches() throws IOException
237 {
238 File zipFile = new File(tempDir, "zip-single-prefix.zip");
239 ZipUtils.zipDir(zipFile, sourceZipDir, FIRST_PREFIX);
240
241 zip = new ZipFile(zipFile);
242 final Enumeration<? extends ZipEntry> entries = zip.entries();
243
244 int numFolders = 0;
245
246 while (entries.hasMoreElements())
247 {
248 final ZipEntry zipEntry = entries.nextElement();
249 if (zipEntry.isDirectory())
250 {
251 numFolders++;
252 }
253 }
254
255 assertEquals(NUM_FOLDERS, numFolders);
256 }
257
258 @Test
259 public void nestedPrefixedZipFolderCountMatches() throws IOException
260 {
261 File zipFile = new File(tempDir, "zip-nested-prefix.zip");
262 ZipUtils.zipDir(zipFile, sourceZipDir, NESTED_PREFIX);
263
264 zip = new ZipFile(zipFile);
265 final Enumeration<? extends ZipEntry> entries = zip.entries();
266
267 int numFolders = 0;
268
269 while (entries.hasMoreElements())
270 {
271 final ZipEntry zipEntry = entries.nextElement();
272 if (zipEntry.isDirectory())
273 {
274 numFolders++;
275 }
276 }
277
278 assertEquals(NUM_FOLDERS_NESTED_PREFIX, numFolders);
279 }
280
281 @Test
282 public void zipFileCountMatches() throws IOException
283 {
284 File zipFile = new File(tempDir, "zip-single-prefix.zip");
285 ZipUtils.zipDir(zipFile, sourceZipDir, FIRST_PREFIX);
286
287 zip = new ZipFile(zipFile);
288 final Enumeration<? extends ZipEntry> entries = zip.entries();
289
290 int numFiles = 0;
291
292 while (entries.hasMoreElements())
293 {
294 final ZipEntry zipEntry = entries.nextElement();
295 if (!zipEntry.isDirectory())
296 {
297 numFiles++;
298 }
299 }
300
301 assertEquals(NUM_FILES, numFiles);
302 }
303
304 @Test
305 public void unzipNonPrefixed() throws IOException
306 {
307 File zipFile = new File(tempDir, "zip-empty-prefix.zip");
308 ZipUtils.zipDir(zipFile, sourceZipDir, "");
309
310 File unzipDir = new File(tempDir, "unzip-empty-prefix");
311 ZipUtils.unzip(zipFile, unzipDir.getAbsolutePath());
312
313 File rootUnzip = new File(unzipDir, ROOT_DIR);
314
315 assertTrue("root folder in zip was not unzipped", (rootUnzip.exists() && rootUnzip.isDirectory()));
316 }
317
318 @Test
319 public void unzipSinglePrefix() throws IOException
320 {
321 File zipFile = new File(tempDir, "zip-single-prefix.zip");
322 ZipUtils.zipDir(zipFile, sourceZipDir, FIRST_PREFIX);
323
324 File unzipDir = new File(tempDir, "unzip-single-prefix");
325 ZipUtils.unzip(zipFile, unzipDir.getAbsolutePath());
326
327 File rootUnzip = new File(unzipDir, FIRST_PREFIX);
328
329 assertTrue("single prefix folder in zip was not unzipped", (rootUnzip.exists() && rootUnzip.isDirectory()));
330 }
331
332 @Test
333 public void unzipNestedPrefix() throws IOException
334 {
335 File zipFile = new File(tempDir, "zip-nested-prefix.zip");
336 ZipUtils.zipDir(zipFile, sourceZipDir, NESTED_PREFIX);
337
338 File unzipDir = new File(tempDir, "unzip-nested-prefix");
339 ZipUtils.unzip(zipFile, unzipDir.getAbsolutePath());
340
341 File rootUnzip = new File(unzipDir, FIRST_PREFIX);
342 File nestedUnzip = new File(rootUnzip, SECOND_PREFIX);
343
344 assertTrue("nested prefix folder in zip was not unzipped", (nestedUnzip.exists() && nestedUnzip.isDirectory()));
345 }
346
347 @Test
348 public void detectPrefix() throws IOException
349 {
350 File zipFile = new File(tempDir, "zip-single-prefix.zip");
351
352 ZipUtils.zipDir(zipFile, sourceZipDir, "");
353
354 int nestedRoots = ZipUtils.countNestingLevel(zipFile);
355
356 assertEquals("One level of nesting should be detected", 1, nestedRoots);
357 }
358
359 @Test
360 public void detectDoublePrefix() throws IOException
361 {
362 File zipFile = new File(tempDir, "zip-double-prefix.zip");
363 ZipUtils.zipDir(zipFile, sourceZipDir, NESTED_PREFIX);
364
365 int nestedRoots = ZipUtils.countNestingLevel(zipFile);
366
367 assertEquals("Two levels of nesting should be detected", 2, nestedRoots);
368 }
369
370 @Test
371 public void detectNoPrefix() throws IOException, URISyntaxException
372 {
373
374
375
376 URL zipPath = TestZipUtils.class.getResource("zip-no-root.zip");
377 File zipFile = new File(zipPath.toURI());
378
379 int nestedRoots = ZipUtils.countNestingLevel(zipFile);
380
381 assertEquals("No nesting should be detected", 0, nestedRoots);
382 }
383
384 @Test
385 public void unzipSinglePrefixTrimmed() throws IOException
386 {
387 File zipFile = new File(tempDir, "zip-single-prefix.zip");
388 ZipUtils.zipDir(zipFile, sourceZipDir, FIRST_PREFIX);
389
390 File unzipDir = new File(tempDir, "unzip-single-prefix");
391 ZipUtils.unzip(zipFile, unzipDir.getAbsolutePath(), 1);
392
393 File rootUnzip = new File(unzipDir, FIRST_PREFIX);
394
395 assertTrue("single prefix folder in zip should have been trimmed", !rootUnzip.exists());
396 }
397
398 @Test
399 public void unzipNestedPrefixTrimmed() throws IOException
400 {
401 File zipFile = new File(tempDir, "zip-nested-prefix.zip");
402 ZipUtils.zipDir(zipFile, sourceZipDir, NESTED_PREFIX);
403
404 File unzipDir = new File(tempDir, "unzip-nested-prefix");
405 ZipUtils.unzip(zipFile, unzipDir.getAbsolutePath(), 2);
406
407 File nestedUnzip = new File(unzipDir, SECOND_PREFIX);
408
409 assertTrue("nested prefix folder in zip should have been trimmed", !nestedUnzip.exists());
410 }
411
412
413 @Test
414 public void countNoNestingLevel()
415 {
416 List<String> filenames = Lists.newArrayList(
417 "file1.txt",
418 "file2.txt");
419
420 int nestedRoots = ZipUtils.countNestingLevel(filenames);
421 assertEquals("The number of nested roots should be detected", 0, nestedRoots);
422 }
423
424 @Test
425 public void countOneNestingLevel()
426 {
427 List<String> filenames = Lists.newArrayList(
428 "root/folder1/file.txt",
429 "root/folder2/file.txt");
430
431 int nestedRoots = ZipUtils.countNestingLevel(filenames);
432 assertEquals("The number of nested roots should be detected", 1, nestedRoots);
433 }
434
435 @Test
436 public void countNestingLevelWithEmptyList()
437 {
438 List<String> filenames = Lists.newArrayList();
439
440 int nestedRoots = ZipUtils.countNestingLevel(filenames);
441 assertEquals("Should work with an empty list", 0, nestedRoots);
442 }
443
444 @Test
445 public void countTwoNestingLevel()
446 {
447 List<String> filenames = Lists.newArrayList(
448 "root/otherRoot/file1.txt",
449 "root/otherRoot/file2.txt");
450 int nestedRoots = ZipUtils.countNestingLevel(filenames);
451 assertEquals("The number of nested roots should be detected", 2, nestedRoots);
452 }
453
454 @Test
455 public void countTwoNestingLevelWithEmptyDirs()
456 {
457 List<String> filenames = Lists.newArrayList(
458 "root/",
459 "root/otherRoot/",
460 "root/otherRoot/file1.txt",
461 "root/otherRoot/file2.txt");
462
463 int nestedRoots = ZipUtils.countNestingLevel(filenames);
464 assertEquals("The number of nested roots should be detected", 2, nestedRoots);
465 }
466
467 @Test
468 public void countTwoNestingLevelWithEmptyDirsInReversedOrder()
469 {
470 List<String> filenames = Lists.newArrayList(
471 "root/otherRoot/file1.txt",
472 "root/otherRoot/file2.txt",
473 "root/otherRoot/",
474 "root/");
475
476 int nestedRoots = ZipUtils.countNestingLevel(filenames);
477 assertEquals("The number of nested roots should be detected", 2, nestedRoots);
478 }
479
480 @Test
481 public void countOneNestingLevelWithEmptyDirs()
482 {
483 List<String> filenames = Lists.newArrayList(
484 "root/folder1/file1.txt",
485 "root/folder1/file2.txt",
486 "root/folder1/",
487 "root/folder2/",
488 "root/");
489
490 int nestedRoots = ZipUtils.countNestingLevel(filenames);
491 assertEquals("The number of nested roots should be detected", 1, nestedRoots);
492 }
493 }