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.assertEquals;
23 import static org.junit.jupiter.api.Assertions.assertFalse;
24 import static org.junit.jupiter.api.Assertions.assertThrows;
25 import static org.junit.jupiter.api.Assertions.assertTrue;
26
27 import java.io.ByteArrayInputStream;
28 import java.io.ByteArrayOutputStream;
29 import java.io.File;
30 import java.io.IOException;
31 import java.io.InputStream;
32 import java.nio.file.Files;
33 import java.nio.file.Path;
34
35 import org.apache.commons.compress.AbstractTest;
36 import org.apache.commons.compress.archivers.zip.ZipFile;
37 import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
38 import org.apache.commons.io.IOUtils;
39 import org.junit.jupiter.api.Test;
40
41 public final class FramedSnappyCompressorInputStreamTest extends AbstractTest {
42
43 private static byte[] generateTestData(final int inputSize) {
44 final byte[] arr = new byte[inputSize];
45 for (int i = 0; i < arr.length; i++) {
46 arr[i] = (byte) (65 + i % 10);
47 }
48
49 return arr;
50 }
51
52 private long mask(final long x) {
53 return (x >>> 15 | x << 17) + FramedSnappyCompressorInputStream.MASK_OFFSET & 0xffffFFFFL;
54 }
55
56 @Test
57 public void testAvailable() throws Exception {
58 try (InputStream isSz = newInputStream("mixed.txt.sz");
59 FramedSnappyCompressorInputStream in = new FramedSnappyCompressorInputStream(isSz)) {
60 assertEquals(0, in.available());
61 assertEquals('1', in.read());
62 assertEquals(3, in.available());
63 assertEquals(3, in.read(new byte[5], 0, 3));
64 assertEquals('5', in.read());
65 assertEquals(0, in.available());
66 assertEquals(4, in.read(new byte[5], 0, 4));
67 assertEquals('5', in.read());
68 }
69 }
70
71 @Test
72 public void testChecksumUnmasking() {
73 testChecksumUnmasking(0xc757L);
74 testChecksumUnmasking(0xffffc757L);
75 }
76
77 private void testChecksumUnmasking(final long x) {
78 assertEquals(Long.toHexString(x), Long.toHexString(FramedSnappyCompressorInputStream.unmask(mask(x))));
79 }
80
81 @Test
82 public void testFinishWithNoWrite() throws IOException {
83 final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
84 try (FramedSnappyCompressorOutputStream compressor = new FramedSnappyCompressorOutputStream(buffer)) {
85
86 }
87 assertTrue(buffer.size() == 10, "Only the signature gets written.");
88 }
89
90
91
92
93 @Test
94 public void testLoremIpsum() throws Exception {
95 final Path outputSz = newTempPath("lorem-ipsum.1");
96 final Path outputGz = newTempPath("lorem-ipsum.2");
97 try (InputStream isSz = newInputStream("lorem-ipsum.txt.sz")) {
98 try (InputStream in = new FramedSnappyCompressorInputStream(isSz)) {
99 Files.copy(in, outputSz);
100 }
101 try (InputStream isGz = newInputStream("lorem-ipsum.txt.gz");
102 InputStream in = new GzipCompressorInputStream(isGz)) {
103 Files.copy(in, outputGz);
104 }
105 }
106
107 assertArrayEquals(Files.readAllBytes(outputSz), Files.readAllBytes(outputGz));
108 }
109
110 @Test
111 public void testMatches() throws IOException {
112 assertFalse(FramedSnappyCompressorInputStream.matches(new byte[10], 10));
113 final byte[] expected = readAllBytes("bla.tar.sz");
114 assertFalse(FramedSnappyCompressorInputStream.matches(expected, 9));
115 assertTrue(FramedSnappyCompressorInputStream.matches(expected, 10));
116 assertTrue(FramedSnappyCompressorInputStream.matches(expected, 12));
117 }
118
119 @Test
120 public void testMultiByteReadConsistentlyReturnsMinusOneAtEof() throws IOException {
121 final File input = getFile("bla.tar.sz");
122 final byte[] buf = new byte[2];
123 try (InputStream is = Files.newInputStream(input.toPath());
124 FramedSnappyCompressorInputStream in = new FramedSnappyCompressorInputStream(is);) {
125 IOUtils.toByteArray(in);
126 assertEquals(-1, in.read(buf));
127 assertEquals(-1, in.read(buf));
128 }
129 }
130
131 @Test
132 public void testReadIWAFile() throws Exception {
133 try (ZipFile zip = ZipFile.builder().setFile(getFile("testNumbersNew.numbers")).get()) {
134 try (InputStream is = zip.getInputStream(zip.getEntry("Index/Document.iwa"))) {
135 try (FramedSnappyCompressorInputStream in = new FramedSnappyCompressorInputStream(is, FramedSnappyDialect.IWORK_ARCHIVE)) {
136 Files.copy(in, newTempFile("snappyIWATest.raw").toPath());
137 }
138 }
139 }
140 }
141
142
143
144
145 @Test
146 public void testReadIWAFileWithBiggerOffset() throws Exception {
147 final File o = newTempFile("COMPRESS-358.raw");
148 try (InputStream is = newInputStream("COMPRESS-358.iwa");
149 FramedSnappyCompressorInputStream in = new FramedSnappyCompressorInputStream(is, 1 << 16, FramedSnappyDialect.IWORK_ARCHIVE);) {
150 Files.copy(in, o.toPath());
151 }
152 try (InputStream a = Files.newInputStream(o.toPath());
153 InputStream e = newInputStream("COMPRESS-358.uncompressed")) {
154 final byte[] expected = IOUtils.toByteArray(e);
155 final byte[] actual = IOUtils.toByteArray(a);
156 assertArrayEquals(expected, actual);
157 }
158 }
159
160 @Test
161 public void testRemainingChunkTypes() throws Exception {
162 try (ByteArrayOutputStream out = new ByteArrayOutputStream();
163 InputStream isSz = newInputStream("mixed.txt.sz");
164 FramedSnappyCompressorInputStream in = new FramedSnappyCompressorInputStream(isSz);) {
165 IOUtils.copy(in, out);
166 assertArrayEquals(new byte[] { '1', '2', '3', '4', '5', '6', '7', '8', '9', '5', '6', '7', '8', '9', '5', '6', '7', '8', '9', '5', '6', '7', '8',
167 '9', '5', '6', '7', '8', '9', 10, '1', '2', '3', '4', '1', '2', '3', '4', }, out.toByteArray());
168 }
169 }
170
171 @Test
172 public void testSingleByteReadConsistentlyReturnsMinusOneAtEof() throws IOException {
173 final File input = getFile("bla.tar.sz");
174 try (InputStream is = Files.newInputStream(input.toPath());
175 FramedSnappyCompressorInputStream in = new FramedSnappyCompressorInputStream(is);) {
176 IOUtils.toByteArray(in);
177 assertEquals(-1, in.read());
178 assertEquals(-1, in.read());
179 }
180 }
181
182 @Test
183 public void testUnskippableChunk() {
184 final byte[] input = { (byte) 0xff, 6, 0, 0, 's', 'N', 'a', 'P', 'p', 'Y', 2, 2, 0, 0, 1, 1 };
185 try (FramedSnappyCompressorInputStream in = new FramedSnappyCompressorInputStream(new ByteArrayInputStream(input))) {
186 final IOException exception = assertThrows(IOException.class, () -> in.read());
187 assertTrue(exception.getMessage().contains("Unskippable chunk"));
188 } catch (final IOException ex) {
189 }
190 }
191
192 @Test
193 public void testWriteByteArrayVsWriteByte() throws IOException {
194 ByteArrayOutputStream buffer = new ByteArrayOutputStream();
195 final byte[] bytes = "abcdefghijklmnop".getBytes();
196 try (FramedSnappyCompressorOutputStream compressor = new FramedSnappyCompressorOutputStream(buffer)) {
197 compressor.write(bytes);
198 compressor.finish();
199 }
200 final byte[] bulkOutput = buffer.toByteArray();
201 buffer = new ByteArrayOutputStream();
202 try (FramedSnappyCompressorOutputStream compressor = new FramedSnappyCompressorOutputStream(buffer)) {
203 for (final byte element : bytes) {
204 compressor.write(element);
205 }
206 compressor.finish();
207 }
208 assertArrayEquals(bulkOutput, buffer.toByteArray());
209 }
210
211 @Test
212 public void testWriteDataLargerThanBufferOneCall() throws IOException {
213 final int inputSize = 500_000;
214 final byte[] data = generateTestData(inputSize);
215 final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
216 try (FramedSnappyCompressorOutputStream compressor = new FramedSnappyCompressorOutputStream(outputStream)) {
217 compressor.write(data, 0, data.length);
218 compressor.finish();
219 }
220 final byte[] compressed = outputStream.toByteArray();
221
222 byte[] decompressed = {};
223 try (ByteArrayInputStream bytesIn = new ByteArrayInputStream(compressed, 0, compressed.length);
224 FramedSnappyCompressorInputStream decompressor = new FramedSnappyCompressorInputStream(bytesIn)) {
225 int i;
226 final ByteArrayOutputStream decompressedOutputStream = new ByteArrayOutputStream();
227 while (-1 != (i = decompressor.read())) {
228 decompressedOutputStream.write(i);
229 }
230 decompressed = decompressedOutputStream.toByteArray();
231 }
232 assertArrayEquals(data, decompressed);
233 }
234
235 }