View Javadoc

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); // there's only one..
74          assertEquals("source1.jar", destdir.listFiles()[0].getName()); // ..and it's not randomfile.txt
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             // Zip files have a time granularity of 2 seconds.
125             long ZIP_FILE_GRAIN = 2000;
126             // Since we want to check that the unzipper restores modification times from the zip, we
127             // ensure all our files have exactly representable modification times.
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 }