1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.commons.compress.compressors.snappy;
20
21 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
22 import static org.junit.jupiter.api.Assertions.assertTrue;
23
24 import java.io.ByteArrayInputStream;
25 import java.io.ByteArrayOutputStream;
26 import java.io.File;
27 import java.io.IOException;
28 import java.io.OutputStream;
29 import java.nio.file.Files;
30 import java.nio.file.Path;
31 import java.util.Random;
32
33 import org.apache.commons.compress.AbstractTest;
34 import org.apache.commons.compress.compressors.lz77support.Parameters;
35 import org.apache.commons.io.IOUtils;
36 import org.junit.jupiter.api.Test;
37
38 public final class SnappyRoundtripTest extends AbstractTest {
39
40 private static Parameters newParameters(final int windowSize, final int minBackReferenceLength, final int maxBackReferenceLength, final int maxOffset,
41 final int maxLiteralLength) {
42 return Parameters.builder(windowSize).withMinBackReferenceLength(minBackReferenceLength).withMaxBackReferenceLength(maxBackReferenceLength)
43 .withMaxOffset(maxOffset).withMaxLiteralLength(maxLiteralLength).build();
44 }
45
46 private void roundTripTest(final byte[] input, final Parameters params) throws IOException {
47 final ByteArrayOutputStream os = new ByteArrayOutputStream();
48 try (SnappyCompressorOutputStream sos = new SnappyCompressorOutputStream(os, input.length, params)) {
49 sos.write(input);
50 }
51 try (SnappyCompressorInputStream sis = new SnappyCompressorInputStream(new ByteArrayInputStream(os.toByteArray()), params.getWindowSize())) {
52 final byte[] actual = IOUtils.toByteArray(sis);
53 assertArrayEquals(input, actual);
54 }
55 }
56
57 private void roundTripTest(final Path input, final Parameters params) throws IOException {
58 final File outputSz = newTempFile(input.getFileName() + ".raw.sz");
59 try (OutputStream os = Files.newOutputStream(outputSz.toPath());
60 SnappyCompressorOutputStream sos = new SnappyCompressorOutputStream(os, Files.size(input), params)) {
61 sos.write(input);
62 sos.close();
63 assertTrue(sos.isClosed());
64 }
65 try (SnappyCompressorInputStream sis = new SnappyCompressorInputStream(Files.newInputStream(outputSz.toPath()), params.getWindowSize())) {
66 final byte[] expected = Files.readAllBytes(input);
67 final byte[] actual = IOUtils.toByteArray(sis);
68 assertArrayEquals(expected, actual);
69 }
70 }
71
72 private void roundTripTest(final String testFile) throws IOException {
73 roundTripTest(getPath(testFile), SnappyCompressorOutputStream.createParameterBuilder(SnappyCompressorInputStream.DEFAULT_BLOCK_SIZE).build());
74 }
75
76
77 @Test
78 void testBiggerFileRoundtrip() throws IOException {
79 roundTripTest("COMPRESS-256.7z");
80 }
81
82
83 @Test
84 void testBlaTarRoundtrip() throws IOException {
85
86 roundTripTest("bla.tar");
87 }
88
89 @Test
90 void testBlaTarRoundtripTunedForCompressionRatio() throws IOException {
91
92 roundTripTest(getPath("bla.tar"),
93 SnappyCompressorOutputStream.createParameterBuilder(SnappyCompressorInputStream.DEFAULT_BLOCK_SIZE).tunedForCompressionRatio().build());
94 }
95
96 @Test
97 void testBlaTarRoundtripTunedForSpeed() throws IOException {
98
99 roundTripTest(getPath("bla.tar"),
100 SnappyCompressorOutputStream.createParameterBuilder(SnappyCompressorInputStream.DEFAULT_BLOCK_SIZE).tunedForSpeed().build());
101 }
102
103
104 @Test
105 void testGzippedLoremIpsumRoundtrip() throws IOException {
106 roundTripTest("lorem-ipsum.txt.gz");
107 }
108
109 @Test
110 void testTryReallyBigOffset() throws IOException {
111
112
113
114
115
116
117
118
119
120
121 final ByteArrayOutputStream fs = new ByteArrayOutputStream((1 << 16) + 1024);
122 fs.write(0);
123 fs.write(0);
124 fs.write(0);
125 fs.write(0);
126 final int cnt = 1 << 16 + 5;
127 final Random r = new Random();
128 for (int i = 0; i < cnt; i++) {
129 fs.write(r.nextInt(255) + 1);
130 }
131 fs.write(0);
132 fs.write(0);
133 fs.write(0);
134 fs.write(0);
135
136 roundTripTest(fs.toByteArray(), newParameters(1 << 17, 4, 64, 1 << 17 - 1, 1 << 17 - 1));
137 }
138
139 @Test
140 void testTryReallyLongLiterals() throws IOException {
141
142
143
144
145
146
147
148
149
150
151
152
153
154 final Path path = newTempPath("reallyBigLiteralTest");
155 try (OutputStream outputStream = Files.newOutputStream(path)) {
156 final int cnt = 1 << 19;
157 final Random r = new Random();
158 for (int i = 0; i < cnt; i++) {
159 outputStream.write(r.nextInt(256));
160 }
161 }
162 roundTripTest(path, newParameters(1 << 18, 4, 64, 1 << 16 - 1, 1 << 18 - 1));
163 }
164 }