View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.commons.compress.archivers;
20  
21  import static org.junit.Assert.*;
22  
23  import java.io.File;
24  import java.io.FileInputStream;
25  import java.io.FileOutputStream;
26  import java.io.IOException;
27  import java.io.InputStream;
28  import java.io.OutputStream;
29  
30  import org.apache.commons.compress.AbstractTestCase;
31  import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
32  import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
33  import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
34  import org.apache.commons.compress.utils.CharsetNames;
35  import org.apache.commons.compress.utils.IOUtils;
36  import org.junit.Test;
37  
38  public final class TarTestCase extends AbstractTestCase {
39  
40      @Test
41      public void testTarArchiveCreation() throws Exception {
42          final File output = new File(dir, "bla.tar");
43          final File file1 = getFile("test1.xml");
44          final OutputStream out = new FileOutputStream(output);
45          final ArchiveOutputStream os = new ArchiveStreamFactory().createArchiveOutputStream("tar", out);
46          final TarArchiveEntry entry = new TarArchiveEntry("testdata/test1.xml");
47          entry.setModTime(0);
48          entry.setSize(file1.length());
49          entry.setUserId(0);
50          entry.setGroupId(0);
51          entry.setUserName("avalon");
52          entry.setGroupName("excalibur");
53          entry.setMode(0100000);
54          os.putArchiveEntry(entry);
55          IOUtils.copy(new FileInputStream(file1), os);
56          os.closeArchiveEntry();
57          os.close();
58      }
59  
60      @Test
61      public void testTarArchiveLongNameCreation() throws Exception {
62          String name = "testdata/12345678901234567890123456789012345678901234567890123456789012345678901234567890123456.xml";
63          byte[] bytes = name.getBytes(CharsetNames.UTF_8);
64          assertEquals(bytes.length, 99);
65  
66          final File output = new File(dir, "bla.tar");
67          final File file1 = getFile("test1.xml");
68          final OutputStream out = new FileOutputStream(output);
69          final ArchiveOutputStream os = new ArchiveStreamFactory().createArchiveOutputStream("tar", out);
70          final TarArchiveEntry entry = new TarArchiveEntry(name);
71          entry.setModTime(0);
72          entry.setSize(file1.length());
73          entry.setUserId(0);
74          entry.setGroupId(0);
75          entry.setUserName("avalon");
76          entry.setGroupName("excalibur");
77          entry.setMode(0100000);
78          os.putArchiveEntry(entry);
79          FileInputStream in = new FileInputStream(file1);
80          IOUtils.copy(in, os);
81          os.closeArchiveEntry();
82          os.close();
83          out.close();
84          in.close();
85  
86  
87          ArchiveOutputStream os2 = null;
88          try {
89              String toLongName = "testdata/123456789012345678901234567890123456789012345678901234567890123456789012345678901234567.xml";
90              final File output2 = new File(dir, "bla.tar");
91              final OutputStream out2 = new FileOutputStream(output2);
92              os2 = new ArchiveStreamFactory().createArchiveOutputStream("tar", out2);
93              final TarArchiveEntry entry2 = new TarArchiveEntry(toLongName);
94              entry2.setModTime(0);
95              entry2.setSize(file1.length());
96              entry2.setUserId(0);
97              entry2.setGroupId(0);
98              entry2.setUserName("avalon");
99              entry2.setGroupName("excalibur");
100             entry2.setMode(0100000);
101             os2.putArchiveEntry(entry);
102             IOUtils.copy(new FileInputStream(file1), os2);
103             os2.closeArchiveEntry();
104         } catch(IOException e) {
105             assertTrue(true);
106         } finally {
107             if (os2 != null){
108                 os2.close();
109             }
110         }
111     }
112 
113     @Test
114     public void testTarUnarchive() throws Exception {
115         final File input = getFile("bla.tar");
116         final InputStream is = new FileInputStream(input);
117         final ArchiveInputStream in = new ArchiveStreamFactory().createArchiveInputStream("tar", is);
118         final TarArchiveEntry entry = (TarArchiveEntry)in.getNextEntry();
119         final OutputStream out = new FileOutputStream(new File(dir, entry.getName()));
120         IOUtils.copy(in, out);
121         in.close();
122         out.close();
123     }
124 
125     @Test
126     public void testCOMPRESS114() throws Exception {
127         final File input = getFile("COMPRESS-114.tar");
128         final InputStream is = new FileInputStream(input);
129         final ArchiveInputStream in = new TarArchiveInputStream(is,
130                 CharsetNames.ISO_8859_1);
131         TarArchiveEntry entry = (TarArchiveEntry)in.getNextEntry();
132         assertEquals("3\u00b1\u00b1\u00b1F06\u00b1W2345\u00b1ZB\u00b1la\u00b1\u00b1\u00b1\u00b1\u00b1\u00b1\u00b1\u00b1BLA", entry.getName());
133         entry = (TarArchiveEntry)in.getNextEntry();
134         assertEquals("0302-0601-3\u00b1\u00b1\u00b1F06\u00b1W2345\u00b1ZB\u00b1la\u00b1\u00b1\u00b1\u00b1\u00b1\u00b1\u00b1\u00b1BLA",entry.getName());
135         in.close();
136     }
137 
138     @Test
139     public void testDirectoryEntryFromFile() throws Exception {
140         File[] tmp = createTempDirAndFile();
141         File archive = null;
142         TarArchiveOutputStream tos = null;
143         TarArchiveInputStream tis = null;
144         try {
145             archive = File.createTempFile("test.", ".tar", tmp[0]);
146             archive.deleteOnExit();
147             tos = new TarArchiveOutputStream(new FileOutputStream(archive));
148             long beforeArchiveWrite = tmp[0].lastModified();
149             TarArchiveEntry in = new TarArchiveEntry(tmp[0], "foo");
150             tos.putArchiveEntry(in);
151             tos.closeArchiveEntry();
152             tos.close();
153             tos = null;
154             tis = new TarArchiveInputStream(new FileInputStream(archive));
155             TarArchiveEntry out = tis.getNextTarEntry();
156             tis.close();
157             tis = null;
158             assertNotNull(out);
159             assertEquals("foo/", out.getName());
160             assertEquals(0, out.getSize());
161             // TAR stores time with a granularity of 1 second
162             assertEquals(beforeArchiveWrite / 1000,
163                          out.getLastModifiedDate().getTime() / 1000);
164             assertTrue(out.isDirectory());
165         } finally {
166             if (tis != null) {
167                 tis.close();
168             }
169             if (tos != null) {
170                 tos.close();
171             }
172             tryHardToDelete(archive);
173             tryHardToDelete(tmp[1]);
174             rmdir(tmp[0]);
175         }
176     }
177 
178     @Test
179     public void testExplicitDirectoryEntry() throws Exception {
180         File[] tmp = createTempDirAndFile();
181         File archive = null;
182         TarArchiveOutputStream tos = null;
183         TarArchiveInputStream tis = null;
184         try {
185             archive = File.createTempFile("test.", ".tar", tmp[0]);
186             archive.deleteOnExit();
187             tos = new TarArchiveOutputStream(new FileOutputStream(archive));
188             long beforeArchiveWrite = tmp[0].lastModified();
189             TarArchiveEntry in = new TarArchiveEntry("foo/");
190             in.setModTime(beforeArchiveWrite);
191             tos.putArchiveEntry(in);
192             tos.closeArchiveEntry();
193             tos.close();
194             tos = null;
195             tis = new TarArchiveInputStream(new FileInputStream(archive));
196             TarArchiveEntry out = tis.getNextTarEntry();
197             tis.close();
198             tis = null;
199             assertNotNull(out);
200             assertEquals("foo/", out.getName());
201             assertEquals(0, out.getSize());
202             assertEquals(beforeArchiveWrite / 1000,
203                          out.getLastModifiedDate().getTime() / 1000);
204             assertTrue(out.isDirectory());
205         } finally {
206             if (tis != null) {
207                 tis.close();
208             }
209             if (tos != null) {
210                 tos.close();
211             }
212             tryHardToDelete(archive);
213             tryHardToDelete(tmp[1]);
214             rmdir(tmp[0]);
215         }
216     }
217 
218     @Test
219     public void testFileEntryFromFile() throws Exception {
220         File[] tmp = createTempDirAndFile();
221         File archive = null;
222         TarArchiveOutputStream tos = null;
223         TarArchiveInputStream tis = null;
224         FileInputStream fis = null;
225         try {
226             archive = File.createTempFile("test.", ".tar", tmp[0]);
227             archive.deleteOnExit();
228             tos = new TarArchiveOutputStream(new FileOutputStream(archive));
229             TarArchiveEntry in = new TarArchiveEntry(tmp[1], "foo");
230             tos.putArchiveEntry(in);
231             byte[] b = new byte[(int) tmp[1].length()];
232             fis = new FileInputStream(tmp[1]);
233             while (fis.read(b) > 0) {
234                 tos.write(b);
235             }
236             fis.close();
237             fis = null;
238             tos.closeArchiveEntry();
239             tos.close();
240             tos = null;
241             tis = new TarArchiveInputStream(new FileInputStream(archive));
242             TarArchiveEntry out = tis.getNextTarEntry();
243             tis.close();
244             tis = null;
245             assertNotNull(out);
246             assertEquals("foo", out.getName());
247             assertEquals(tmp[1].length(), out.getSize());
248             assertEquals(tmp[1].lastModified() / 1000,
249                          out.getLastModifiedDate().getTime() / 1000);
250             assertFalse(out.isDirectory());
251         } finally {
252             if (tis != null) {
253                 tis.close();
254             }
255             if (tos != null) {
256                 tos.close();
257             }
258             tryHardToDelete(archive);
259             if (fis != null) {
260                 fis.close();
261             }
262             tryHardToDelete(tmp[1]);
263             rmdir(tmp[0]);
264         }
265     }
266 
267     @Test
268     public void testExplicitFileEntry() throws Exception {
269         File[] tmp = createTempDirAndFile();
270         File archive = null;
271         TarArchiveOutputStream tos = null;
272         TarArchiveInputStream tis = null;
273         FileInputStream fis = null;
274         try {
275             archive = File.createTempFile("test.", ".tar", tmp[0]);
276             archive.deleteOnExit();
277             tos = new TarArchiveOutputStream(new FileOutputStream(archive));
278             TarArchiveEntry in = new TarArchiveEntry("foo");
279             in.setModTime(tmp[1].lastModified());
280             in.setSize(tmp[1].length());
281             tos.putArchiveEntry(in);
282             byte[] b = new byte[(int) tmp[1].length()];
283             fis = new FileInputStream(tmp[1]);
284             while (fis.read(b) > 0) {
285                 tos.write(b);
286             }
287             fis.close();
288             fis = null;
289             tos.closeArchiveEntry();
290             tos.close();
291             tos = null;
292             tis = new TarArchiveInputStream(new FileInputStream(archive));
293             TarArchiveEntry out = tis.getNextTarEntry();
294             tis.close();
295             tis = null;
296             assertNotNull(out);
297             assertEquals("foo", out.getName());
298             assertEquals(tmp[1].length(), out.getSize());
299             assertEquals(tmp[1].lastModified() / 1000,
300                          out.getLastModifiedDate().getTime() / 1000);
301             assertFalse(out.isDirectory());
302         } finally {
303             if (tis != null) {
304                 tis.close();
305             }
306             if (tos != null) {
307                 tos.close();
308             }
309             tryHardToDelete(archive);
310             if (fis != null) {
311                 fis.close();
312             }
313             tryHardToDelete(tmp[1]);
314             rmdir(tmp[0]);
315         }
316     }
317 
318     @Test
319     public void testCOMPRESS178() throws Exception {
320         final File input = getFile("COMPRESS-178.tar");
321         final InputStream is = new FileInputStream(input);
322         final ArchiveInputStream in = new ArchiveStreamFactory().createArchiveInputStream("tar", is);
323         try {
324             in.getNextEntry();
325             fail("Expected IOException");
326         } catch (IOException e) {
327             Throwable t = e.getCause();
328             assertTrue("Expected cause = IllegalArgumentException", t instanceof IllegalArgumentException);
329         }
330         in.close();
331     }
332 
333 }