aboutsummaryrefslogtreecommitdiff
path: root/src/test/java/org/apache/commons/compress/archivers/sevenz/SevenZOutputFileTest.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/java/org/apache/commons/compress/archivers/sevenz/SevenZOutputFileTest.java')
-rw-r--r--src/test/java/org/apache/commons/compress/archivers/sevenz/SevenZOutputFileTest.java522
1 files changed, 522 insertions, 0 deletions
diff --git a/src/test/java/org/apache/commons/compress/archivers/sevenz/SevenZOutputFileTest.java b/src/test/java/org/apache/commons/compress/archivers/sevenz/SevenZOutputFileTest.java
new file mode 100644
index 000000000..7139ec39a
--- /dev/null
+++ b/src/test/java/org/apache/commons/compress/archivers/sevenz/SevenZOutputFileTest.java
@@ -0,0 +1,522 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.commons.compress.archivers.sevenz;
+
+import static org.junit.Assert.*;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Iterator;
+import org.apache.commons.compress.AbstractTestCase;
+import org.apache.commons.compress.utils.SeekableInMemoryByteChannel;
+import org.tukaani.xz.LZMA2Options;
+
+public class SevenZOutputFileTest extends AbstractTestCase {
+
+ private static final boolean XZ_BCJ_IS_BUGGY;
+
+ static {
+ final String version = org.tukaani.xz.XZ.class.getPackage().getImplementationVersion();
+
+ XZ_BCJ_IS_BUGGY= version != null && version.equals("1.4");
+ if (XZ_BCJ_IS_BUGGY) {
+ System.out.println("XZ version is " + version + " - skipping BCJ tests");
+ }
+ }
+ private File output;
+
+ @Override
+ public void tearDown() throws Exception {
+ if (output != null && !output.delete()) {
+ output.deleteOnExit();
+ }
+ super.tearDown();
+ }
+
+ @Test
+ public void testDirectoriesAndEmptyFiles() throws Exception {
+ output = new File(dir, "empties.7z");
+
+ final Date accessDate = new Date();
+ final Calendar cal = Calendar.getInstance();
+ cal.add(Calendar.HOUR, -1);
+ final Date creationDate = cal.getTime();
+
+ try (SevenZOutputFile outArchive = new SevenZOutputFile(output)) {
+ SevenZArchiveEntry entry = outArchive.createArchiveEntry(dir, "foo/");
+ outArchive.putArchiveEntry(entry);
+ outArchive.closeArchiveEntry();
+
+ entry = new SevenZArchiveEntry();
+ entry.setName("foo/bar");
+ entry.setCreationDate(creationDate);
+ entry.setAccessDate(accessDate);
+ outArchive.putArchiveEntry(entry);
+ outArchive.write(new byte[0]);
+ outArchive.closeArchiveEntry();
+
+ entry = new SevenZArchiveEntry();
+ entry.setName("xyzzy");
+ outArchive.putArchiveEntry(entry);
+ outArchive.write(0);
+ outArchive.closeArchiveEntry();
+
+ entry = outArchive.createArchiveEntry(dir, "baz/");
+ entry.setAntiItem(true);
+ outArchive.putArchiveEntry(entry);
+ outArchive.closeArchiveEntry();
+
+ entry = new SevenZArchiveEntry();
+ entry.setName("dada");
+ entry.setHasWindowsAttributes(true);
+ entry.setWindowsAttributes(17);
+ outArchive.putArchiveEntry(entry);
+ outArchive.write(5);
+ outArchive.write(42);
+ outArchive.closeArchiveEntry();
+
+ outArchive.finish();
+ }
+
+ try (SevenZFile archive = new SevenZFile(output)) {
+ SevenZArchiveEntry entry = archive.getNextEntry();
+ assert (entry != null);
+ assertEquals("foo/", entry.getName());
+ assertTrue(entry.isDirectory());
+ assertFalse(entry.isAntiItem());
+
+ entry = archive.getNextEntry();
+ assert (entry != null);
+ assertEquals("foo/bar", entry.getName());
+ assertFalse(entry.isDirectory());
+ assertFalse(entry.isAntiItem());
+ assertEquals(0, entry.getSize());
+ assertFalse(entry.getHasLastModifiedDate());
+ assertEquals(accessDate, entry.getAccessDate());
+ assertEquals(creationDate, entry.getCreationDate());
+
+ entry = archive.getNextEntry();
+ assert (entry != null);
+ assertEquals("xyzzy", entry.getName());
+ assertEquals(1, entry.getSize());
+ assertFalse(entry.getHasAccessDate());
+ assertFalse(entry.getHasCreationDate());
+ assertEquals(0, archive.read());
+
+ entry = archive.getNextEntry();
+ assert (entry != null);
+ assertEquals("baz/", entry.getName());
+ assertTrue(entry.isDirectory());
+ assertTrue(entry.isAntiItem());
+
+ entry = archive.getNextEntry();
+ assert (entry != null);
+ assertEquals("dada", entry.getName());
+ assertEquals(2, entry.getSize());
+ final byte[] content = new byte[2];
+ assertEquals(2, archive.read(content));
+ assertEquals(5, content[0]);
+ assertEquals(42, content[1]);
+ assertEquals(17, entry.getWindowsAttributes());
+
+ assert (archive.getNextEntry() == null);
+ }
+
+ }
+
+ @Test
+ public void testDirectoriesOnly() throws Exception {
+ output = new File(dir, "dirs.7z");
+ try (SevenZOutputFile outArchive = new SevenZOutputFile(output)) {
+ final SevenZArchiveEntry entry = new SevenZArchiveEntry();
+ entry.setName("foo/");
+ entry.setDirectory(true);
+ outArchive.putArchiveEntry(entry);
+ outArchive.closeArchiveEntry();
+ }
+
+ try (SevenZFile archive = new SevenZFile(output)) {
+ final SevenZArchiveEntry entry = archive.getNextEntry();
+ assert (entry != null);
+ assertEquals("foo/", entry.getName());
+ assertTrue(entry.isDirectory());
+ assertFalse(entry.isAntiItem());
+
+ assert (archive.getNextEntry() == null);
+ }
+
+ }
+
+ @Test
+ public void testCantFinishTwice() throws Exception {
+ output = new File(dir, "finish.7z");
+ try (SevenZOutputFile outArchive = new SevenZOutputFile(output)) {
+ outArchive.finish();
+ outArchive.finish();
+ fail("shouldn't be able to call finish twice");
+ } catch (final IOException ex) {
+ assertEquals("This archive has already been finished", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testSixEmptyFiles() throws Exception {
+ testCompress252(6, 0);
+ }
+
+ @Test
+ public void testSixFilesSomeNotEmpty() throws Exception {
+ testCompress252(6, 2);
+ }
+
+ @Test
+ public void testSevenEmptyFiles() throws Exception {
+ testCompress252(7, 0);
+ }
+
+ @Test
+ public void testSevenFilesSomeNotEmpty() throws Exception {
+ testCompress252(7, 2);
+ }
+
+ @Test
+ public void testEightEmptyFiles() throws Exception {
+ testCompress252(8, 0);
+ }
+
+ @Test
+ public void testEightFilesSomeNotEmpty() throws Exception {
+ testCompress252(8, 2);
+ }
+
+ @Test
+ public void testNineEmptyFiles() throws Exception {
+ testCompress252(9, 0);
+ }
+
+ @Test
+ public void testNineFilesSomeNotEmpty() throws Exception {
+ testCompress252(9, 2);
+ }
+
+ @Test
+ public void testTwentyNineEmptyFiles() throws Exception {
+ testCompress252(29, 0);
+ }
+
+ @Test
+ public void testTwentyNineFilesSomeNotEmpty() throws Exception {
+ testCompress252(29, 7);
+ }
+
+ @Test
+ public void testCopyRoundtrip() throws Exception {
+ testRoundTrip(SevenZMethod.COPY);
+ }
+
+ @Test
+ public void testBzip2Roundtrip() throws Exception {
+ testRoundTrip(SevenZMethod.BZIP2);
+ }
+
+ @Test
+ public void testLzma2Roundtrip() throws Exception {
+ testRoundTrip(SevenZMethod.LZMA2);
+ }
+
+ @Test
+ public void testDeflateRoundtrip() throws Exception {
+ testRoundTrip(SevenZMethod.DEFLATE);
+ }
+
+ @Test
+ public void testBCJX86Roundtrip() throws Exception {
+ if (XZ_BCJ_IS_BUGGY) { return; }
+ testFilterRoundTrip(new SevenZMethodConfiguration(SevenZMethod.BCJ_X86_FILTER));
+ }
+
+ @Test
+ public void testBCJARMRoundtrip() throws Exception {
+ if (XZ_BCJ_IS_BUGGY) { return; }
+ testFilterRoundTrip(new SevenZMethodConfiguration(SevenZMethod.BCJ_ARM_FILTER));
+ }
+
+ @Test
+ public void testBCJARMThumbRoundtrip() throws Exception {
+ if (XZ_BCJ_IS_BUGGY) { return; }
+ testFilterRoundTrip(new SevenZMethodConfiguration(SevenZMethod.BCJ_ARM_THUMB_FILTER));
+ }
+
+ @Test
+ public void testBCJIA64Roundtrip() throws Exception {
+ if (XZ_BCJ_IS_BUGGY) { return; }
+ testFilterRoundTrip(new SevenZMethodConfiguration(SevenZMethod.BCJ_IA64_FILTER));
+ }
+
+ @Test
+ public void testBCJPPCRoundtrip() throws Exception {
+ if (XZ_BCJ_IS_BUGGY) { return; }
+ testFilterRoundTrip(new SevenZMethodConfiguration(SevenZMethod.BCJ_PPC_FILTER));
+ }
+
+ @Test
+ public void testBCJSparcRoundtrip() throws Exception {
+ if (XZ_BCJ_IS_BUGGY) { return; }
+ testFilterRoundTrip(new SevenZMethodConfiguration(SevenZMethod.BCJ_SPARC_FILTER));
+ }
+
+ @Test
+ public void testDeltaRoundtrip() throws Exception {
+ testFilterRoundTrip(new SevenZMethodConfiguration(SevenZMethod.DELTA_FILTER));
+ }
+
+ @Test
+ public void testStackOfContentCompressions() throws Exception {
+ output = new File(dir, "multiple-methods.7z");
+ final ArrayList<SevenZMethodConfiguration> methods = new ArrayList<>();
+ methods.add(new SevenZMethodConfiguration(SevenZMethod.LZMA2));
+ methods.add(new SevenZMethodConfiguration(SevenZMethod.COPY));
+ methods.add(new SevenZMethodConfiguration(SevenZMethod.DEFLATE));
+ methods.add(new SevenZMethodConfiguration(SevenZMethod.BZIP2));
+ createAndReadBack(output, methods);
+ }
+
+ @Test
+ public void testStackOfContentCompressionsInMemory() throws Exception {
+ final ArrayList<SevenZMethodConfiguration> methods = new ArrayList<>();
+ methods.add(new SevenZMethodConfiguration(SevenZMethod.LZMA2));
+ methods.add(new SevenZMethodConfiguration(SevenZMethod.COPY));
+ methods.add(new SevenZMethodConfiguration(SevenZMethod.DEFLATE));
+ methods.add(new SevenZMethodConfiguration(SevenZMethod.BZIP2));
+ createAndReadBack(new SeekableInMemoryByteChannel(), methods);
+ }
+
+ @Test
+ public void testDeflateWithConfiguration() throws Exception {
+ output = new File(dir, "deflate-options.7z");
+ // Deflater.BEST_SPEED
+ createAndReadBack(output, Collections
+ .singletonList(new SevenZMethodConfiguration(SevenZMethod.DEFLATE, 1)));
+ }
+
+ @Test
+ public void testBzip2WithConfiguration() throws Exception {
+ output = new File(dir, "bzip2-options.7z");
+ // 400k block size
+ createAndReadBack(output, Collections
+ .singletonList(new SevenZMethodConfiguration(SevenZMethod.BZIP2, 4)));
+ }
+
+ @Test
+ public void testLzmaWithIntConfiguration() throws Exception {
+ output = new File(dir, "lzma-options.7z");
+ // 1 MB dictionary
+ createAndReadBack(output, Collections
+ .singletonList(new SevenZMethodConfiguration(SevenZMethod.LZMA, 1 << 20)));
+ }
+
+ @Test
+ public void testLzmaWithOptionsConfiguration() throws Exception {
+ output = new File(dir, "lzma-options2.7z");
+ final LZMA2Options opts = new LZMA2Options(1);
+ createAndReadBack(output, Collections
+ .singletonList(new SevenZMethodConfiguration(SevenZMethod.LZMA, opts)));
+ }
+
+ @Test
+ public void testLzma2WithIntConfiguration() throws Exception {
+ output = new File(dir, "lzma2-options.7z");
+ // 1 MB dictionary
+ createAndReadBack(output, Collections
+ .singletonList(new SevenZMethodConfiguration(SevenZMethod.LZMA2, 1 << 20)));
+ }
+
+ @Test
+ public void testLzma2WithOptionsConfiguration() throws Exception {
+ output = new File(dir, "lzma2-options2.7z");
+ final LZMA2Options opts = new LZMA2Options(1);
+ createAndReadBack(output, Collections
+ .singletonList(new SevenZMethodConfiguration(SevenZMethod.LZMA2, opts)));
+ }
+
+ @Test
+ public void testArchiveWithMixedMethods() throws Exception {
+ output = new File(dir, "mixed-methods.7z");
+ try (SevenZOutputFile outArchive = new SevenZOutputFile(output)) {
+ addFile(outArchive, 0, true);
+ addFile(outArchive, 1, true, Arrays.asList(new SevenZMethodConfiguration(SevenZMethod.BZIP2)));
+ }
+
+ try (SevenZFile archive = new SevenZFile(output)) {
+ assertEquals(Boolean.TRUE,
+ verifyFile(archive, 0, Arrays.asList(new SevenZMethodConfiguration(SevenZMethod.LZMA2))));
+ assertEquals(Boolean.TRUE,
+ verifyFile(archive, 1, Arrays.asList(new SevenZMethodConfiguration(SevenZMethod.BZIP2))));
+ }
+ }
+
+ private void testCompress252(final int numberOfFiles, final int numberOfNonEmptyFiles)
+ throws Exception {
+ final int nonEmptyModulus = numberOfNonEmptyFiles != 0
+ ? numberOfFiles / numberOfNonEmptyFiles
+ : numberOfFiles + 1;
+ int nonEmptyFilesAdded = 0;
+ output = new File(dir, "COMPRESS252-" + numberOfFiles + "-" + numberOfNonEmptyFiles + ".7z");
+ try (SevenZOutputFile archive = new SevenZOutputFile(output)) {
+ addDir(archive);
+ for (int i = 0; i < numberOfFiles; i++) {
+ addFile(archive, i,
+ (i + 1) % nonEmptyModulus == 0 && nonEmptyFilesAdded++ < numberOfNonEmptyFiles);
+ }
+ }
+ verifyCompress252(output, numberOfFiles, numberOfNonEmptyFiles);
+ }
+
+ private void verifyCompress252(final File output, final int numberOfFiles, final int numberOfNonEmptyFiles)
+ throws Exception {
+ int filesFound = 0;
+ int nonEmptyFilesFound = 0;
+ try (SevenZFile archive = new SevenZFile(output)) {
+ verifyDir(archive);
+ Boolean b = verifyFile(archive, filesFound++);
+ while (b != null) {
+ if (Boolean.TRUE.equals(b)) {
+ nonEmptyFilesFound++;
+ }
+ b = verifyFile(archive, filesFound++);
+ }
+ }
+ assertEquals(numberOfFiles + 1, filesFound);
+ assertEquals(numberOfNonEmptyFiles, nonEmptyFilesFound);
+ }
+
+ private void addDir(final SevenZOutputFile archive) throws Exception {
+ final SevenZArchiveEntry entry = archive.createArchiveEntry(dir, "foo/");
+ archive.putArchiveEntry(entry);
+ archive.closeArchiveEntry();
+ }
+
+ private void verifyDir(final SevenZFile archive) throws Exception {
+ final SevenZArchiveEntry entry = archive.getNextEntry();
+ assertNotNull(entry);
+ assertEquals("foo/", entry.getName());
+ assertTrue(entry.isDirectory());
+ }
+
+ private void addFile(final SevenZOutputFile archive, final int index, final boolean nonEmpty)
+ throws Exception {
+ addFile(archive, index, nonEmpty, null);
+ }
+
+ private void addFile(final SevenZOutputFile archive, final int index, final boolean nonEmpty, final Iterable<SevenZMethodConfiguration> methods)
+ throws Exception {
+ final SevenZArchiveEntry entry = new SevenZArchiveEntry();
+ entry.setName("foo/" + index + ".txt");
+ entry.setContentMethods(methods);
+ archive.putArchiveEntry(entry);
+ archive.write(nonEmpty ? new byte[] { 'A' } : new byte[0]);
+ archive.closeArchiveEntry();
+ }
+
+ private Boolean verifyFile(final SevenZFile archive, final int index) throws Exception {
+ return verifyFile(archive, index, null);
+ }
+
+ private Boolean verifyFile(final SevenZFile archive, final int index,
+ final Iterable<SevenZMethodConfiguration> methods) throws Exception {
+ final SevenZArchiveEntry entry = archive.getNextEntry();
+ if (entry == null) {
+ return null;
+ }
+ assertEquals("foo/" + index + ".txt", entry.getName());
+ assertEquals(false, entry.isDirectory());
+ if (entry.getSize() == 0) {
+ return Boolean.FALSE;
+ }
+ assertEquals(1, entry.getSize());
+ assertEquals('A', archive.read());
+ assertEquals(-1, archive.read());
+ if (methods != null) {
+ assertContentMethodsEquals(methods, entry.getContentMethods());
+ }
+ return Boolean.TRUE;
+ }
+
+ private void testRoundTrip(final SevenZMethod method) throws Exception {
+ output = new File(dir, method + "-roundtrip.7z");
+ final ArrayList<SevenZMethodConfiguration> methods = new ArrayList<>();
+ methods.add(new SevenZMethodConfiguration(method));
+ createAndReadBack(output, methods);
+ }
+
+ private void testFilterRoundTrip(final SevenZMethodConfiguration method) throws Exception {
+ output = new File(dir, method.getMethod() + "-roundtrip.7z");
+ final ArrayList<SevenZMethodConfiguration> methods = new ArrayList<>();
+ methods.add(method);
+ methods.add(new SevenZMethodConfiguration(SevenZMethod.LZMA2));
+ createAndReadBack(output, methods);
+ }
+
+ private void createAndReadBack(final File output, final Iterable<SevenZMethodConfiguration> methods) throws Exception {
+ final SevenZOutputFile outArchive = new SevenZOutputFile(output);
+ outArchive.setContentMethods(methods);
+ try {
+ addFile(outArchive, 0, true);
+ } finally {
+ outArchive.close();
+ }
+
+ try (SevenZFile archive = new SevenZFile(output)) {
+ assertEquals(Boolean.TRUE, verifyFile(archive, 0, methods));
+ }
+ }
+
+ private void createAndReadBack(final SeekableInMemoryByteChannel output, final Iterable<SevenZMethodConfiguration> methods) throws Exception {
+ final SevenZOutputFile outArchive = new SevenZOutputFile(output);
+ outArchive.setContentMethods(methods);
+ try {
+ addFile(outArchive, 0, true);
+ } finally {
+ outArchive.close();
+ }
+ try (SevenZFile archive =
+ new SevenZFile(new SeekableInMemoryByteChannel(output.array()), "in memory")) {
+ assertEquals(Boolean.TRUE, verifyFile(archive, 0, methods));
+ }
+ }
+
+ private static void assertContentMethodsEquals(final Iterable<? extends SevenZMethodConfiguration> expected,
+ final Iterable<? extends SevenZMethodConfiguration> actual) {
+ assertNotNull(actual);
+ final Iterator<? extends SevenZMethodConfiguration> expectedIter = expected.iterator();
+ final Iterator<? extends SevenZMethodConfiguration> actualIter = actual.iterator();
+ while (expectedIter.hasNext()) {
+ assertTrue(actualIter.hasNext());
+ final SevenZMethodConfiguration expConfig = expectedIter.next();
+ final SevenZMethodConfiguration actConfig = actualIter.next();
+ assertEquals(expConfig.getMethod(), actConfig.getMethod());
+ }
+ assertFalse(actualIter.hasNext());
+ }
+}