View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   * 
17   */
18  
19  package org.apache.commons.compress.archivers;
20  
21  import java.io.BufferedInputStream;
22  import java.io.BufferedReader;
23  import java.io.File;
24  import java.io.FileInputStream;
25  import java.io.FileReader;
26  import java.io.IOException;
27  import java.util.ArrayList;
28  import java.util.Map;
29  import java.util.HashMap;
30  
31  import junit.framework.AssertionFailedError;
32  import junit.framework.Test;
33  import junit.framework.TestSuite;
34  
35  import org.apache.commons.compress.AbstractTestCase;
36  import org.apache.commons.compress.archivers.ar.ArArchiveInputStream;
37  import org.apache.commons.compress.archivers.cpio.CpioArchiveInputStream;
38  import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
39  import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
40  import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
41  
42  /**
43   * Test that can read various tar file examples.
44   * 
45   * The class uses nested suites in order to be able to name the test after the file name,
46   * as JUnit does not allow one to change the display name of a test.
47   */
48  public class LongPathTest extends AbstractTestCase {
49  
50      private String name;
51      private File file;
52  
53      private static final Map<String, ArrayList<String>> fileLists = new HashMap<String, ArrayList<String>>();
54  
55      public LongPathTest(String name) {
56          super(name);
57      }
58  
59      private LongPathTest(String name, String function, File file) {
60          super(function);
61          this.name = name;
62          this.file = file;
63      }
64  
65      public static TestSuite suite() throws IOException{
66          TestSuite suite = new TestSuite("LongPathTests");
67          suite.addTest(createSuite("LongPathTest", "longpath"));
68          suite.addTest(createSuite("LongSymlinkTest", "longsymlink"));
69          return suite;
70      }
71  
72      public static TestSuite createSuite(String name, String dirname) throws IOException {
73          TestSuite suite = new TestSuite(name);
74          File arcdir = getFile(dirname);
75          assertTrue(arcdir.exists());
76          File listing= new File(arcdir,"files.txt");
77          assertTrue("File listing is readable",listing.canRead());
78          BufferedReader br = new BufferedReader(new FileReader(listing));
79  
80          ArrayList<String> fileList = new ArrayList<String>();
81          String line;
82          while ((line=br.readLine())!=null){
83              if (line.startsWith("#")){
84                  continue;
85              }
86              fileList.add(line);
87          }
88          fileLists.put(name, fileList);
89          br.close();
90          File[]files=arcdir.listFiles();
91          for (final File file : files) {
92              if (file.getName().endsWith(".txt")){
93                  continue;
94              }
95              // Appears to be the only way to give the test a variable name
96              TestSuite namedSuite = new TestSuite(file.getName());
97              Test test = new LongPathTest(name, "testArchive", file);
98              namedSuite.addTest(test);
99              suite.addTest(namedSuite);
100         }
101         return suite;
102     }
103 
104     @Override
105     protected String getExpectedString(ArchiveEntry entry) {
106         if (entry instanceof TarArchiveEntry) {
107             TarArchiveEntry tarEntry = (TarArchiveEntry) entry;
108             if (tarEntry.isSymbolicLink()) {
109                 return tarEntry.getName() + " -> " + tarEntry.getLinkName();
110             }
111         }
112         return entry.getName();
113     }
114 
115     public void testArchive() throws Exception {
116         ArrayList<String> fileList = fileLists.get(name);
117         @SuppressWarnings("unchecked") // fileList is of correct type
118         ArrayList<String> expected = (ArrayList<String>) fileList.clone();
119         String name = file.getName();
120         if ("minotaur.jar".equals(name) || "minotaur-0.jar".equals(name)){
121             expected.add("META-INF/");
122             expected.add("META-INF/MANIFEST.MF");
123         }
124         ArchiveInputStream ais = factory.createArchiveInputStream(new BufferedInputStream(new FileInputStream(file)));
125         // check if expected type recognised
126         if (name.endsWith(".tar")){
127             assertTrue(ais instanceof TarArchiveInputStream);
128         } else if (name.endsWith(".jar") || name.endsWith(".zip")){
129             assertTrue(ais instanceof ZipArchiveInputStream);
130         } else if (name.endsWith(".cpio")){
131             assertTrue(ais instanceof CpioArchiveInputStream);
132             // Hack: cpio does not add trailing "/" to directory names
133             for(int i=0; i < expected.size(); i++){
134                 String ent = expected.get(i);
135                 if (ent.endsWith("/")){
136                     expected.set(i, ent.substring(0, ent.length()-1));
137                 }
138             }
139         } else if (name.endsWith(".ar")){
140             assertTrue(ais instanceof ArArchiveInputStream);
141             // CPIO does not store directories or directory names
142             expected.clear();
143             for(int i=0; i < fileList.size(); i++){
144                 String ent = fileList.get(i);
145                 if (!ent.endsWith("/")){// not a directory
146                     final int lastSlash = ent.lastIndexOf('/');
147                     if (lastSlash >= 0) { // extract path name
148                         expected.add(ent.substring(lastSlash+1, ent.length()));
149                     } else {
150                         expected.add(ent);
151                     }
152                 }
153             }
154         } else {
155             fail("Unexpected file type: "+name);
156         }
157         try {
158             checkArchiveContent(ais, expected);
159         } catch (AssertionFailedError e) {
160             fail("Error processing "+file.getName()+" "+e);
161         } finally {
162             ais.close();
163         }
164     }
165 }