1 package com.atlassian.plugin.util.zip;
2
3 import com.atlassian.plugin.test.PluginTestUtils;
4 import org.apache.commons.io.FileUtils;
5 import org.apache.commons.io.IOUtils;
6 import org.junit.Before;
7 import org.junit.Test;
8
9 import java.io.File;
10 import java.io.FileInputStream;
11 import java.io.FileOutputStream;
12 import java.io.IOException;
13 import java.util.zip.ZipEntry;
14 import java.util.zip.ZipOutputStream;
15
16 import static org.junit.Assert.assertEquals;
17 import static org.mockito.Mockito.mock;
18 import static org.mockito.Mockito.when;
19
20 public class TestUrlUnzipper {
21 private File basedir;
22 private File destdir;
23 private File zip;
24 private File sourcedir;
25 private File source1;
26
27 @Before
28 public void setUp() throws Exception {
29 basedir = PluginTestUtils.createTempDirectory(TestUrlUnzipper.class);
30 FileUtils.cleanDirectory(basedir);
31 destdir = new File(basedir, "dest");
32 destdir.mkdir();
33 zip = new File(basedir, "test.zip");
34 sourcedir = new File(basedir, "source");
35 sourcedir.mkdir();
36 source1 = new File(sourcedir, "source1.jar");
37 FileUtils.writeStringToFile(source1, "source1");
38 source1.setLastModified(source1.lastModified() - 100000);
39 }
40
41 @Test
42 public void testConditionalUnzip() throws IOException, InterruptedException {
43 zip(sourcedir, zip);
44 UrlUnzipper unzipper = new UrlUnzipper(zip.toURI().toURL(), destdir);
45 unzipper.conditionalUnzip();
46
47 assertEquals(1, destdir.listFiles().length);
48 File dest1 = destdir.listFiles()[0];
49 assertEquals(source1.lastModified(), dest1.lastModified());
50 assertEquals("source1", FileUtils.readFileToString(dest1));
51
52 FileUtils.writeStringToFile(source1, "source1-modified");
53 zip(sourcedir, zip);
54 unzipper = new UrlUnzipper(zip.toURI().toURL(), destdir);
55 unzipper.conditionalUnzip();
56
57 assertEquals(1, destdir.listFiles().length);
58 dest1 = destdir.listFiles()[0];
59 assertEquals(source1.lastModified(), dest1.lastModified());
60 assertEquals("source1-modified", FileUtils.readFileToString(dest1));
61
62 }
63
64 @Test
65 public void testConditionalUnzipCleansZipDirectory() throws IOException, InterruptedException {
66 File f = new File(destdir, "bogusfile.txt");
67 zip(sourcedir, zip);
68 UrlUnzipper unzipper = new UrlUnzipper(zip.toURI().toURL(), destdir);
69 unzipper.conditionalUnzip();
70 assertEquals(1, destdir.listFiles().length);
71 assertEquals("source1.jar", destdir.listFiles()[0].getName());
72 }
73
74 @Test
75 public void testConditionalUnzipWithNoUnzipIfNoFileMod() throws IOException, InterruptedException {
76 zip(sourcedir, zip);
77 UrlUnzipper unzipper = new UrlUnzipper(zip.toURI().toURL(), destdir);
78 unzipper.conditionalUnzip();
79
80 assertEquals(1, destdir.listFiles().length);
81 File dest1 = destdir.listFiles()[0];
82 assertEquals(source1.lastModified(), dest1.lastModified());
83 assertEquals("source1", FileUtils.readFileToString(dest1));
84
85 long ts = source1.lastModified();
86 FileUtils.writeStringToFile(source1, "source1-modified");
87 source1.setLastModified(ts);
88 zip(sourcedir, zip);
89 unzipper = new UrlUnzipper(zip.toURI().toURL(), destdir);
90 unzipper.conditionalUnzip();
91
92 assertEquals(1, destdir.listFiles().length);
93 dest1 = destdir.listFiles()[0];
94 assertEquals(source1.lastModified(), dest1.lastModified());
95 assertEquals("source1", FileUtils.readFileToString(dest1));
96 }
97
98 @Test
99 public void testSaveEntryLegalRelativePath() throws IOException {
100 zip(sourcedir, zip);
101 final UrlUnzipper unzipper = new UrlUnzipper(zip.toURI().toURL(), destdir);
102 final ZipEntry entry = mock(ZipEntry.class);
103
104 when(entry.getName()).thenReturn("something/.././test-relative.txt");
105 when(entry.isDirectory()).thenReturn(false);
106 when(entry.getTime()).thenReturn(source1.lastModified());
107 unzipper.saveEntry(new FileInputStream(source1), entry);
108
109 assertEquals(1, destdir.listFiles().length);
110 final File dest1 = destdir.listFiles()[0];
111 assertEquals("test-relative.txt", dest1.getName());
112 assertEquals(source1.lastModified(), dest1.lastModified());
113 assertEquals("source1", FileUtils.readFileToString(dest1));
114 }
115
116 private void zip(File basedir, File destfile) throws IOException {
117 ZipOutputStream zout = new ZipOutputStream(new FileOutputStream(destfile));
118 for (File child : basedir.listFiles()) {
119
120 long ZIP_FILE_GRAIN = 2000;
121
122
123 child.setLastModified((child.lastModified() / ZIP_FILE_GRAIN) * ZIP_FILE_GRAIN);
124
125 ZipEntry entry = new ZipEntry(child.getName());
126 entry.setTime(child.lastModified());
127 zout.putNextEntry(entry);
128 FileInputStream input = new FileInputStream(child);
129 IOUtils.copy(input, zout);
130 input.close();
131 }
132 zout.close();
133 }
134 }