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;
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.assertThrows;
24
25 import java.io.ByteArrayInputStream;
26 import java.io.ByteArrayOutputStream;
27 import java.io.File;
28 import java.io.IOException;
29 import java.io.InputStream;
30 import java.io.OutputStream;
31 import java.nio.file.Files;
32 import java.time.Instant;
33 import java.util.zip.Deflater;
34 import java.util.zip.GZIPInputStream;
35
36 import org.apache.commons.compress.AbstractTest;
37 import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
38 import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;
39 import org.apache.commons.compress.compressors.gzip.GzipParameters;
40 import org.apache.commons.io.IOUtils;
41 import org.junit.jupiter.api.Test;
42 import org.junit.jupiter.params.ParameterizedTest;
43 import org.junit.jupiter.params.provider.ValueSource;
44
45 public final class GZipTest extends AbstractTest {
46
47 private static final int MTIME = 123456000;
48 private static final Instant MTIME_INSTANT = Instant.ofEpochSecond(MTIME);
49
50 @Test
51 void testConcatenatedStreamsReadFirstOnly() throws Exception {
52 final File input = getFile("multiple.gz");
53 try (InputStream is = Files.newInputStream(input.toPath())) {
54 try (CompressorInputStream in = new CompressorStreamFactory().createCompressorInputStream("gz", is)) {
55 assertEquals('a', in.read());
56 assertEquals(-1, in.read());
57 }
58 }
59 }
60
61 @Test
62 void testConcatenatedStreamsReadFully() throws Exception {
63 final File input = getFile("multiple.gz");
64 try (InputStream is = Files.newInputStream(input.toPath())) {
65 try (CompressorInputStream in = new GzipCompressorInputStream(is, true)) {
66 assertEquals('a', in.read());
67 assertEquals('b', in.read());
68 assertEquals(0, in.available());
69 assertEquals(-1, in.read());
70 }
71 }
72 }
73
74
75
76
77 @Test
78 void testCorruptedInput() throws Exception {
79 final byte[] data = readAllBytes("bla.tgz");
80 try (InputStream in = new ByteArrayInputStream(data, 0, data.length - 1);
81 CompressorInputStream cin = new CompressorStreamFactory().createCompressorInputStream("gz", in);
82 OutputStream out = new ByteArrayOutputStream()) {
83 assertThrows(IOException.class, () -> IOUtils.copy(cin, out), "Expected an exception");
84 }
85 }
86
87 private void testExtraFlags(final int compressionLevel, final int flag, final int bufferSize) throws Exception {
88 final byte[] content = readAllBytes("test3.xml");
89
90 final ByteArrayOutputStream bout = new ByteArrayOutputStream();
91
92 final GzipParameters parameters = new GzipParameters();
93 parameters.setCompressionLevel(compressionLevel);
94 parameters.setBufferSize(bufferSize);
95 try (GzipCompressorOutputStream out = new GzipCompressorOutputStream(bout, parameters)) {
96 IOUtils.copy(new ByteArrayInputStream(content), out);
97 out.flush();
98 }
99
100 assertEquals(flag, bout.toByteArray()[8], "extra flags (XFL)");
101 }
102
103 @Test
104 void testExtraFlagsBestCompression() throws Exception {
105 testExtraFlags(Deflater.BEST_COMPRESSION, 2, 1024);
106 }
107
108 @Test
109 void testExtraFlagsDefaultCompression() throws Exception {
110 testExtraFlags(Deflater.DEFAULT_COMPRESSION, 0, 4096);
111 }
112
113 @Test
114 void testExtraFlagsFastestCompression() throws Exception {
115 testExtraFlags(Deflater.BEST_SPEED, 4, 128);
116 }
117
118 @Test
119 void testGzipCreation() throws Exception {
120 final File input = getFile("test1.xml");
121 final File output = newTempFile("test1.xml.gz");
122 try (OutputStream out = Files.newOutputStream(output.toPath())) {
123 try (CompressorOutputStream<?> cos = new CompressorStreamFactory().createCompressorOutputStream("gz", out)) {
124 cos.write(input);
125 }
126 }
127 }
128
129 @Test
130 void testGzipUnarchive() throws Exception {
131 final File input = getFile("bla.tgz");
132 final File output = newTempFile("bla.tar");
133 try (InputStream is = Files.newInputStream(input.toPath())) {
134 try (CompressorInputStream in = new CompressorStreamFactory().createCompressorInputStream("gz", is);) {
135 Files.copy(in, output.toPath());
136 }
137 }
138 }
139
140 @Test
141 void testInteroperabilityWithGzipCompressorInputStream() throws Exception {
142 final byte[] content = readAllBytes("test3.xml");
143 final ByteArrayOutputStream bout = new ByteArrayOutputStream();
144 final GzipParameters parameters = new GzipParameters();
145 parameters.setCompressionLevel(Deflater.BEST_COMPRESSION);
146 parameters.setOperatingSystem(3);
147 parameters.setFilename("test3.xml");
148 assertEquals(parameters.getFilename(), parameters.getFileName());
149 parameters.setFileName("test3.xml");
150 assertEquals(parameters.getFilename(), parameters.getFileName());
151 parameters.setComment("Test file");
152 parameters.setModificationTime(System.currentTimeMillis());
153 try (GzipCompressorOutputStream out = new GzipCompressorOutputStream(bout, parameters)) {
154 out.write(content);
155 out.flush();
156 }
157 try (GzipCompressorInputStream in = new GzipCompressorInputStream(new ByteArrayInputStream(bout.toByteArray()))) {
158 final byte[] content2 = IOUtils.toByteArray(in);
159 assertArrayEquals(content, content2, "uncompressed content");
160 }
161 }
162
163 @Test
164 void testInteroperabilityWithGZIPInputStream() throws Exception {
165 final byte[] content = readAllBytes("test3.xml");
166 final ByteArrayOutputStream bout = new ByteArrayOutputStream();
167 final GzipParameters parameters = new GzipParameters();
168 parameters.setCompressionLevel(Deflater.BEST_COMPRESSION);
169 parameters.setOperatingSystem(3);
170 parameters.setFilename("test3.xml");
171 assertEquals(parameters.getFilename(), parameters.getFileName());
172 parameters.setFileName("test3.xml");
173 assertEquals(parameters.getFilename(), parameters.getFileName());
174 parameters.setComment("Test file");
175 parameters.setModificationTime(System.currentTimeMillis());
176 try (GzipCompressorOutputStream out = new GzipCompressorOutputStream(bout, parameters)) {
177 out.write(content);
178 out.flush();
179 }
180 final GZIPInputStream in = new GZIPInputStream(new ByteArrayInputStream(bout.toByteArray()));
181 final byte[] content2 = IOUtils.toByteArray(in);
182 assertArrayEquals(content, content2, "uncompressed content");
183 }
184
185 @ParameterizedTest
186 @ValueSource(ints = { 0, -1 })
187 void testInvalidBufferSize(final int bufferSize) {
188 final GzipParameters parameters = new GzipParameters();
189 assertThrows(IllegalArgumentException.class, () -> parameters.setBufferSize(bufferSize), "IllegalArgumentException not thrown");
190 }
191
192 @ParameterizedTest
193 @ValueSource(ints = { 10, -5 })
194 void testInvalidCompressionLevel(final int compressionLevel) {
195 final GzipParameters parameters = new GzipParameters();
196 assertThrows(IllegalArgumentException.class, () -> parameters.setCompressionLevel(compressionLevel), "IllegalArgumentException not thrown");
197 }
198
199 @Test
200 void testMetadataRoundTrip() throws Exception {
201 final ByteArrayOutputStream bout = new ByteArrayOutputStream();
202
203 final GzipParameters parameters = new GzipParameters();
204 parameters.setCompressionLevel(Deflater.BEST_COMPRESSION);
205 assertEquals(0, parameters.getModificationTime());
206 parameters.setModificationInstant(null);
207 assertEquals(0, parameters.getModificationTime());
208 parameters.setModificationInstant(MTIME_INSTANT);
209 assertEquals(MTIME_INSTANT.getEpochSecond(), parameters.getModificationTime());
210 assertEquals(MTIME_INSTANT, parameters.getModificationInstant());
211 parameters.setOS(GzipParameters.OS.Z_SYSTEM);
212 assertEquals(GzipParameters.OS.Z_SYSTEM, parameters.getOS());
213 parameters.setOS(null);
214 assertEquals(GzipParameters.OS.UNKNOWN, parameters.getOS());
215 parameters.setOperatingSystem(13);
216 assertEquals(GzipParameters.OS.ACORN_RISCOS, parameters.getOS());
217 parameters.setFilename("test3.xml");
218 assertEquals(parameters.getFilename(), parameters.getFileName());
219 parameters.setFileName("test3.xml");
220 assertEquals(parameters.getFilename(), parameters.getFileName());
221 parameters.setComment("Umlaute möglich?");
222 try (GzipCompressorOutputStream out = new GzipCompressorOutputStream(bout, parameters)) {
223 out.write(getFile("test3.xml"));
224 }
225
226 final GzipCompressorInputStream input = new GzipCompressorInputStream(new ByteArrayInputStream(bout.toByteArray()));
227 input.close();
228 final GzipParameters readParams = input.getMetaData();
229 assertEquals(Deflater.BEST_COMPRESSION, readParams.getCompressionLevel());
230 assertEquals(123456000, readParams.getModificationTime());
231 assertEquals(13, readParams.getOperatingSystem());
232 assertEquals(GzipParameters.OS.ACORN_RISCOS, readParams.getOS());
233 assertEquals("test3.xml", readParams.getFileName());
234 assertEquals("test3.xml", readParams.getFilename());
235 assertEquals("Umlaute möglich?", readParams.getComment());
236 }
237
238 @Test
239 void testMultiByteReadConsistentlyReturnsMinusOneAtEof() throws IOException {
240 final File input = getFile("bla.tgz");
241 final byte[] buf = new byte[2];
242 try (InputStream is = Files.newInputStream(input.toPath());
243 GzipCompressorInputStream in = new GzipCompressorInputStream(is)) {
244 IOUtils.toByteArray(in);
245 assertEquals(-1, in.read(buf));
246 assertEquals(-1, in.read(buf));
247 }
248 }
249
250 @Test
251 void testOverWrite() throws Exception {
252 final GzipCompressorOutputStream out = new GzipCompressorOutputStream(new ByteArrayOutputStream());
253 out.close();
254 assertThrows(IOException.class, () -> out.write(0));
255 }
256
257 @Test
258 void testSingleByteReadConsistentlyReturnsMinusOneAtEof() throws IOException {
259 final File input = getFile("bla.tgz");
260 try (InputStream is = Files.newInputStream(input.toPath());
261 GzipCompressorInputStream in = new GzipCompressorInputStream(is)) {
262 IOUtils.toByteArray(in);
263 assertEquals(-1, in.read());
264 assertEquals(-1, in.read());
265 }
266 }
267 }