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