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