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.jupiter.api.Assertions.assertEquals;
22  import static org.junit.jupiter.api.Assertions.assertFalse;
23  import static org.junit.jupiter.api.Assertions.assertNotNull;
24  import static org.junit.jupiter.api.Assertions.assertTrue;
25  
26  import java.io.File;
27  import java.io.InputStream;
28  import java.io.OutputStream;
29  import java.nio.file.Files;
30  import java.util.HashMap;
31  import java.util.Map;
32  
33  import org.apache.commons.compress.AbstractTest;
34  import org.apache.commons.compress.archivers.cpio.CpioArchiveEntry;
35  import org.apache.commons.compress.archivers.cpio.CpioArchiveInputStream;
36  import org.apache.commons.compress.archivers.cpio.CpioArchiveOutputStream;
37  import org.apache.commons.compress.archivers.cpio.CpioConstants;
38  import org.junit.jupiter.api.Test;
39  
40  public final class CpioTest extends AbstractTest {
41  
42      @Test
43      public void testCpioArchiveCreation() throws Exception {
44          final File output = newTempFile("bla.cpio");
45  
46          final File file1 = getFile("test1.xml");
47          final File file2 = getFile("test2.xml");
48  
49          try (OutputStream outputStream = Files.newOutputStream(output.toPath());
50                  ArchiveOutputStream<CpioArchiveEntry> archiveOutputStream = ArchiveStreamFactory.DEFAULT.createArchiveOutputStream("cpio", outputStream)) {
51              archiveOutputStream.putArchiveEntry(new CpioArchiveEntry("test1.xml", file1.length()));
52              Files.copy(file1.toPath(), archiveOutputStream);
53              archiveOutputStream.closeArchiveEntry();
54  
55              archiveOutputStream.putArchiveEntry(new CpioArchiveEntry("test2.xml", file2.length()));
56              Files.copy(file2.toPath(), archiveOutputStream);
57              archiveOutputStream.closeArchiveEntry();
58          }
59      }
60  
61      @Test
62      public void testCpioUnarchive() throws Exception {
63          final File output = newTempFile("bla.cpio");
64          final File file1 = getFile("test1.xml");
65          final File file2 = getFile("test2.xml");
66          final long file1Length = file1.length();
67          final long file2Length = file2.length();
68  
69          try (OutputStream outputStream = Files.newOutputStream(output.toPath());
70                  ArchiveOutputStream<CpioArchiveEntry> archiveOutputStream = ArchiveStreamFactory.DEFAULT.createArchiveOutputStream("cpio", outputStream)) {
71              CpioArchiveEntry entry = new CpioArchiveEntry("test1.xml", file1Length);
72              entry.setMode(CpioConstants.C_ISREG);
73              archiveOutputStream.putArchiveEntry(entry);
74              Files.copy(file1.toPath(), archiveOutputStream);
75              archiveOutputStream.closeArchiveEntry();
76  
77              entry = new CpioArchiveEntry("test2.xml", file2Length);
78              entry.setMode(CpioConstants.C_ISREG);
79              archiveOutputStream.putArchiveEntry(entry);
80              Files.copy(file2.toPath(), archiveOutputStream);
81              archiveOutputStream.closeArchiveEntry();
82              archiveOutputStream.finish();
83              archiveOutputStream.close();
84              outputStream.close();
85          }
86  
87          // Unarchive Operation
88          final Map<String, File> result = new HashMap<>();
89          try (InputStream inputStream = Files.newInputStream(output.toPath());
90                  ArchiveInputStream<?> archiveInputStream = ArchiveStreamFactory.DEFAULT.createArchiveInputStream("cpio", inputStream)) {
91              ArchiveEntry entry;
92              while ((entry = archiveInputStream.getNextEntry()) != null) {
93                  final File cpioget = newTempFile(entry.getName());
94                  Files.copy(archiveInputStream, cpioget.toPath());
95                  result.put(entry.getName(), cpioget);
96              }
97          }
98  
99          File testFile = result.get("test1.xml");
100         assertTrue(testFile.exists(), "Expected " + testFile.getAbsolutePath() + " to exist");
101         assertEquals(file1Length, testFile.length(), "length of " + testFile.getAbsolutePath());
102 
103         testFile = result.get("test2.xml");
104         assertTrue(testFile.exists(), "Expected " + testFile.getAbsolutePath() + " to exist");
105         assertEquals(file2Length, testFile.length(), "length of " + testFile.getAbsolutePath());
106     }
107 
108     @Test
109     public void testDirectoryEntryFromFile() throws Exception {
110         final File archive = createTempFile("test.", ".cpio");
111         final File dir = getTempDirFile();
112         final long beforeArchiveWrite = dir.lastModified();
113         final CpioArchiveEntry entryIn = new CpioArchiveEntry(dir, "foo");
114         try (CpioArchiveOutputStream tos = new CpioArchiveOutputStream(Files.newOutputStream(archive.toPath()))) {
115             tos.putArchiveEntry(entryIn);
116             tos.closeArchiveEntry();
117         }
118         final CpioArchiveEntry entryOut;
119         try (CpioArchiveInputStream tis = new CpioArchiveInputStream(Files.newInputStream(archive.toPath()))) {
120             entryOut = tis.getNextCPIOEntry();
121         }
122         assertNotNull(entryOut);
123         assertEquals("foo", entryOut.getName());
124         assertEquals(0, entryOut.getSize());
125         // CPIO stores time with a granularity of 1 second
126         assertEquals(beforeArchiveWrite / 1000, entryOut.getLastModifiedDate().getTime() / 1000);
127         assertTrue(entryOut.isDirectory());
128     }
129 
130     @Test
131     public void testExplicitDirectoryEntry() throws Exception {
132         final File archive = createTempFile("test.", ".cpio");
133         final long beforeArchiveWrite;
134         try (CpioArchiveOutputStream tos = new CpioArchiveOutputStream(Files.newOutputStream(archive.toPath()))) {
135             beforeArchiveWrite = getTempDirFile().lastModified();
136             final CpioArchiveEntry in = new CpioArchiveEntry("foo/");
137             in.setTime(beforeArchiveWrite / 1000);
138             in.setMode(CpioConstants.C_ISDIR);
139             tos.putArchiveEntry(in);
140             tos.closeArchiveEntry();
141         }
142         final CpioArchiveEntry out;
143         try (CpioArchiveInputStream tis = new CpioArchiveInputStream(Files.newInputStream(archive.toPath()))) {
144             out = tis.getNextCPIOEntry();
145         }
146         assertNotNull(out);
147         assertEquals("foo/", out.getName());
148         assertEquals(0, out.getSize());
149         assertEquals(beforeArchiveWrite / 1000, out.getLastModifiedDate().getTime() / 1000);
150         assertTrue(out.isDirectory());
151     }
152 
153     @Test
154     public void testExplicitFileEntry() throws Exception {
155         final File tmp = createTempFile();
156         final File archive = createTempFile("test.", ".cpio");
157         try (CpioArchiveOutputStream tos = new CpioArchiveOutputStream(Files.newOutputStream(archive.toPath()))) {
158             final CpioArchiveEntry in = new CpioArchiveEntry("foo");
159             in.setTime(tmp.lastModified() / 1000);
160             in.setSize(tmp.length());
161             in.setMode(CpioConstants.C_ISREG);
162             tos.putArchiveEntry(in);
163             final byte[] b = new byte[(int) tmp.length()];
164             try (InputStream fis = Files.newInputStream(tmp.toPath())) {
165                 while (fis.read(b) > 0) {
166                     tos.write(b);
167                 }
168             }
169             tos.closeArchiveEntry();
170         }
171         final CpioArchiveEntry out;
172         try (CpioArchiveInputStream tis = new CpioArchiveInputStream(Files.newInputStream(archive.toPath()))) {
173             out = tis.getNextCPIOEntry();
174         }
175         assertNotNull(out);
176         assertEquals("foo", out.getName());
177         assertEquals(tmp.length(), out.getSize());
178         assertEquals(tmp.lastModified() / 1000, out.getLastModifiedDate().getTime() / 1000);
179         assertFalse(out.isDirectory());
180     }
181 
182     @Test
183     public void testFileEntryFromFile() throws Exception {
184         final File tmp = createTempFile();
185         final File archive = createTempFile("test.", ".cpio");
186         try (CpioArchiveOutputStream tos = new CpioArchiveOutputStream(Files.newOutputStream(archive.toPath()))) {
187             final CpioArchiveEntry in = new CpioArchiveEntry(tmp, "foo");
188             tos.putArchiveEntry(in);
189             final byte[] b = new byte[(int) tmp.length()];
190             try (InputStream fis = Files.newInputStream(tmp.toPath())) {
191                 while (fis.read(b) > 0) {
192                     tos.write(b);
193                 }
194             }
195             tos.closeArchiveEntry();
196         }
197         final CpioArchiveEntry out;
198         try (CpioArchiveInputStream tis = new CpioArchiveInputStream(Files.newInputStream(archive.toPath()))) {
199             out = tis.getNextCPIOEntry();
200         }
201         assertNotNull(out);
202         assertEquals("foo", out.getName());
203         assertEquals(tmp.length(), out.getSize());
204         assertEquals(tmp.lastModified() / 1000, out.getLastModifiedDate().getTime() / 1000);
205         assertFalse(out.isDirectory());
206     }
207 }