1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.commons.compress;
20
21 import static org.junit.jupiter.api.Assertions.assertEquals;
22 import static org.junit.jupiter.api.Assertions.fail;
23
24 import java.io.BufferedInputStream;
25 import java.io.Closeable;
26 import java.io.File;
27 import java.io.FileNotFoundException;
28 import java.io.IOException;
29 import java.io.InputStream;
30 import java.io.OutputStream;
31 import java.net.URISyntaxException;
32 import java.net.URL;
33 import java.nio.file.Files;
34 import java.nio.file.Path;
35 import java.util.ArrayList;
36 import java.util.Arrays;
37 import java.util.List;
38
39 import org.apache.commons.compress.archivers.ArchiveEntry;
40 import org.apache.commons.compress.archivers.ArchiveInputStream;
41 import org.apache.commons.compress.archivers.ArchiveOutputStream;
42 import org.apache.commons.compress.archivers.ArchiveStreamFactory;
43 import org.apache.commons.compress.archivers.ar.ArArchiveOutputStream;
44 import org.apache.commons.io.FileUtils;
45 import org.apache.commons.io.IOUtils;
46 import org.junit.jupiter.api.io.TempDir;
47
48 public abstract class AbstractTest extends AbstractTempDirTest {
49
50 protected interface StreamWrapper<I extends InputStream> {
51 I wrap(InputStream inputStream) throws Exception;
52 }
53
54
55
56
57
58
59
60 public static boolean forceDelete(final File file) {
61 try {
62 if (file != null && file.exists()) {
63 FileUtils.forceDelete(file);
64 }
65 return true;
66 } catch (final IOException e) {
67 e.printStackTrace();
68 file.deleteOnExit();
69 return false;
70 }
71 }
72
73
74
75
76
77
78
79 public static boolean forceDelete(final Path path) {
80 return forceDelete(path != null ? path.toFile() : null);
81 }
82
83 public static File getFile(final String path) throws IOException {
84 final URL url = AbstractTest.class.getClassLoader().getResource(path);
85 if (url == null) {
86 throw new FileNotFoundException("couldn't find " + path);
87 }
88 try {
89 return new File(url.toURI());
90 } catch (final URISyntaxException ex) {
91 throw new IOException(ex);
92 }
93 }
94
95 public static Path getPath(final String path) throws IOException {
96 return getFile(path).toPath();
97 }
98
99 public static InputStream newInputStream(final String path) throws IOException {
100 return Files.newInputStream(getPath(path));
101 }
102
103 public static byte[] readAllBytes(final String path) throws IOException {
104 return Files.readAllBytes(getPath(path));
105 }
106
107 @TempDir
108 protected File tempResultDir;
109
110
111 protected List<String> archiveList;
112
113 protected final ArchiveStreamFactory factory = ArchiveStreamFactory.DEFAULT;
114
115
116
117
118
119
120
121
122
123
124 private <O extends ArchiveOutputStream<E>, E extends ArchiveEntry> void addArchiveEntry(final O outputStream, final String fileName, final File inputFile)
125 throws IOException, FileNotFoundException {
126 final E entry = outputStream.createArchiveEntry(inputFile, fileName);
127 outputStream.putArchiveEntry(entry);
128 Files.copy(inputFile.toPath(), outputStream);
129 outputStream.closeArchiveEntry();
130 archiveList.add(fileName);
131 }
132
133
134
135
136
137
138
139
140 protected void checkArchiveContent(final ArchiveInputStream<?> inputStream, final List<String> expected) throws Exception {
141 checkArchiveContent(inputStream, expected, true);
142 }
143
144
145
146
147
148
149
150
151
152
153 protected File checkArchiveContent(final ArchiveInputStream<?> inputStream, final List<String> expected, final boolean cleanUp) throws Exception {
154 final Path targetDir = createTempDirectory("dir-result");
155 final Path result = targetDir.resolve("result");
156 try {
157 ArchiveEntry entry;
158 while ((entry = inputStream.getNextEntry()) != null) {
159 final Path outputFile = entry.resolveIn(result);
160 long bytesCopied = 0;
161 if (entry.isDirectory()) {
162 Files.createDirectories(outputFile);
163 } else {
164 Files.createDirectories(outputFile.getParent());
165 bytesCopied = Files.copy(inputStream, outputFile);
166 }
167 final long size = entry.getSize();
168 if (size != ArchiveEntry.SIZE_UNKNOWN) {
169 assertEquals(size, bytesCopied, "Entry.size should equal bytes read.");
170 }
171
172 if (!Files.exists(outputFile)) {
173 fail("Extraction failed: " + entry.getName());
174 }
175 if (expected != null && !expected.remove(getExpectedString(entry))) {
176 fail("Unexpected entry: " + getExpectedString(entry));
177 }
178 }
179 inputStream.close();
180 if (expected != null && !expected.isEmpty()) {
181 fail(expected.size() + " missing entries: " + Arrays.toString(expected.toArray()));
182 }
183 if (expected != null) {
184 assertEquals(0, expected.size());
185 }
186 } finally {
187 if (cleanUp) {
188 forceDelete(targetDir);
189 }
190 }
191 return targetDir.toFile();
192 }
193
194
195
196
197
198
199
200
201 protected void checkArchiveContent(final File archive, final List<String> expected) throws Exception {
202 checkArchiveContent(archive.toPath(), expected);
203 }
204
205
206
207
208
209
210
211
212 protected void checkArchiveContent(final Path archive, final List<String> expected) throws Exception {
213 try (InputStream inputStream = Files.newInputStream(archive);
214 ArchiveInputStream<?> archiveInputStream = factory.createArchiveInputStream(new BufferedInputStream(inputStream))) {
215 checkArchiveContent(archiveInputStream, expected);
216 }
217 }
218
219 protected void closeQuietly(final Closeable closeable) {
220 IOUtils.closeQuietly(closeable);
221 }
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244 protected Path createArchive(final String archiveName) throws Exception {
245 final Path archivePath = createTempPath("test", "." + archiveName);
246 archiveList = new ArrayList<>();
247 try (OutputStream outputStream = Files.newOutputStream(archivePath);
248 ArchiveOutputStream<ArchiveEntry> archiveOutputStream = factory.createArchiveOutputStream(archiveName, outputStream)) {
249 setLongFileMode(archiveOutputStream);
250 final File file1 = getFile("test1.xml");
251 final File file2 = getFile("test2.xml");
252 final File file3 = getFile("test3.xml");
253 final File file4 = getFile("test4.xml");
254 final File file5 = getFile("test.txt");
255 final File file6 = getFile("test with spaces.txt");
256
257 addArchiveEntry(archiveOutputStream, "testdata/test1.xml", file1);
258 addArchiveEntry(archiveOutputStream, "testdata/test2.xml", file2);
259 addArchiveEntry(archiveOutputStream, "test/test3.xml", file3);
260 addArchiveEntry(archiveOutputStream, "bla/test4.xml", file4);
261 addArchiveEntry(archiveOutputStream, "bla/test5.xml", file4);
262 addArchiveEntry(archiveOutputStream, "bla/blubber/test6.xml", file4);
263 addArchiveEntry(archiveOutputStream, "test.txt", file5);
264 addArchiveEntry(archiveOutputStream, "something/bla", file6);
265 addArchiveEntry(archiveOutputStream, "test with spaces.txt", file6);
266
267 archiveOutputStream.finish();
268 return archivePath;
269 }
270 }
271
272
273
274
275
276
277
278
279 protected Path createEmptyArchive(final String archiveName) throws Exception {
280 archiveList = new ArrayList<>();
281 final Path archivePath = createTempPath("empty", "." + archiveName);
282 try (OutputStream outputStream = Files.newOutputStream(archivePath);
283 ArchiveOutputStream<?> archiveOutputStream = factory.createArchiveOutputStream(archiveName, outputStream)) {
284 archiveOutputStream.finish();
285 }
286 return archivePath;
287 }
288
289
290
291
292
293
294
295
296 protected Path createSingleEntryArchive(final String archiveName) throws Exception {
297 archiveList = new ArrayList<>();
298 final Path archivePath = createTempPath("empty", "." + archiveName);
299 try (OutputStream outputStream = Files.newOutputStream(archivePath);
300 ArchiveOutputStream<?> archiveOutputStream = factory.createArchiveOutputStream(archiveName, outputStream)) {
301
302 addArchiveEntry(archiveOutputStream, "test1.xml", getFile("test1.xml"));
303 archiveOutputStream.finish();
304 }
305 return archivePath;
306 }
307
308 public Path createTempDirectory(final String prefix) throws IOException {
309 return Files.createTempDirectory(getTempDirPath(), prefix);
310 }
311
312
313
314
315
316
317
318 protected String getExpectedString(final ArchiveEntry entry) {
319 return entry.getName();
320 }
321
322 protected void setLongFileMode(final ArchiveOutputStream<?> outputStream) {
323 if (outputStream instanceof ArArchiveOutputStream) {
324 ((ArArchiveOutputStream) outputStream).setLongFileMode(ArArchiveOutputStream.LONGFILE_BSD);
325 }
326 }
327
328 }