View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   https://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  
20  package org.apache.commons.compress.compressors.zstandard;
21  
22  import static org.junit.jupiter.api.Assertions.assertArrayEquals;
23  import static org.junit.jupiter.api.Assertions.assertEquals;
24  import static org.junit.jupiter.api.Assertions.assertTrue;
25  
26  import java.io.ByteArrayOutputStream;
27  import java.io.File;
28  import java.io.IOException;
29  import java.io.InputStream;
30  import java.nio.file.Files;
31  
32  import org.apache.commons.compress.AbstractTest;
33  import org.apache.commons.compress.compressors.CompressorInputStream;
34  import org.apache.commons.compress.compressors.CompressorStreamFactory;
35  import org.apache.commons.io.IOUtils;
36  import org.junit.jupiter.api.Test;
37  
38  import com.github.luben.zstd.NoPool;
39  import com.github.luben.zstd.RecyclingBufferPool;
40  
41  class ZstdCompressorInputStreamTest extends AbstractTest {
42  
43      @Test
44      void testCachingIsEnabledByDefaultAndZstdUtilsPresent() {
45          assertEquals(ZstdUtils.CachedAvailability.CACHED_AVAILABLE, ZstdUtils.getCachedZstdAvailability());
46          assertTrue(ZstdUtils.isZstdCompressionAvailable());
47      }
48  
49      @Test
50      void testCanTurnOffCaching() {
51          try {
52              ZstdUtils.setCacheZstdAvailablity(false);
53              assertEquals(ZstdUtils.CachedAvailability.DONT_CACHE, ZstdUtils.getCachedZstdAvailability());
54              assertTrue(ZstdUtils.isZstdCompressionAvailable());
55          } finally {
56              ZstdUtils.setCacheZstdAvailablity(true);
57          }
58      }
59  
60      @Test
61      void testMultiByteReadConsistentlyReturnsMinusOneAtEof() throws IOException {
62          final File input = getFile("zstandard.testdata.zst");
63          final byte[] buf = new byte[2];
64          try (InputStream is = Files.newInputStream(input.toPath());
65                  ZstdCompressorInputStream in = new ZstdCompressorInputStream(is)) {
66              IOUtils.toByteArray(in);
67              assertEquals(-1, in.read(buf));
68              assertEquals(-1, in.read(buf));
69          }
70      }
71  
72      @Test
73      void testShouldBeAbleToSkipAByte() throws IOException {
74          final File input = getFile("zstandard.testdata.zst");
75          try (InputStream is = Files.newInputStream(input.toPath());
76                  ZstdCompressorInputStream in = new ZstdCompressorInputStream(is)) {
77              assertEquals(1, in.skip(1));
78          }
79      }
80  
81      @Test
82      void testSingleByteReadConsistentlyReturnsMinusOneAtEof() throws IOException {
83          final File input = getFile("zstandard.testdata.zst");
84          try (InputStream is = Files.newInputStream(input.toPath());
85                  ZstdCompressorInputStream in = new ZstdCompressorInputStream(is)) {
86              IOUtils.toByteArray(in);
87              assertEquals(-1, in.read());
88              assertEquals(-1, in.read());
89          }
90      }
91  
92      @Test
93      void testSingleByteReadWorksAsExpected() throws IOException {
94  
95          final File input = getFile("zstandard.testdata.zst");
96  
97          final File original = getFile("zstandard.testdata");
98          final long originalFileLength = original.length();
99  
100         final byte[] originalFileContent = new byte[(int) originalFileLength];
101 
102         try (InputStream ois = Files.newInputStream(original.toPath())) {
103             ois.read(originalFileContent);
104         }
105 
106         try (InputStream is = Files.newInputStream(input.toPath());
107                 ZstdCompressorInputStream in = new ZstdCompressorInputStream(is)) {
108             assertEquals(originalFileContent[0], in.read());
109         }
110     }
111 
112     @Test
113     void testTurningOnCachingReEvaluatesAvailability() {
114         try {
115             ZstdUtils.setCacheZstdAvailablity(false);
116             assertEquals(ZstdUtils.CachedAvailability.DONT_CACHE, ZstdUtils.getCachedZstdAvailability());
117             ZstdUtils.setCacheZstdAvailablity(true);
118             assertEquals(ZstdUtils.CachedAvailability.CACHED_AVAILABLE, ZstdUtils.getCachedZstdAvailability());
119         } finally {
120             ZstdUtils.setCacheZstdAvailablity(true);
121         }
122     }
123 
124     @Test
125     void testZstandardUnarchive() throws Exception {
126         final File input = getFile("bla.tar.zst");
127         final File output = newTempFile("bla.tar");
128         try (InputStream is = Files.newInputStream(input.toPath())) {
129             try (CompressorInputStream in = new CompressorStreamFactory().createCompressorInputStream("zstd", is);) {
130                 Files.copy(in, output.toPath());
131             }
132         }
133     }
134 
135     /**
136      * Test bridge works fine.
137      *
138      * @throws IOException if an I/O error occurs.
139      */
140     @Test
141     void testZstdDecode() throws IOException {
142         final File input = getFile("zstandard.testdata.zst");
143         try (InputStream inputStream = Files.newInputStream(input.toPath());
144                 ZstdCompressorInputStream zstdInputStream = new ZstdCompressorInputStream(inputStream)) {
145             final byte[] expected = readAllBytes("zstandard.testdata");
146             final ByteArrayOutputStream bos = new ByteArrayOutputStream();
147             IOUtils.copy(zstdInputStream, bos);
148             assertArrayEquals(expected, bos.toByteArray());
149         }
150     }
151 
152     @Test
153     void testZstdDecodeWithNoPool() throws IOException {
154         final File input = getFile("zstandard.testdata.zst");
155         try (InputStream inputStream = Files.newInputStream(input.toPath());
156                 ZstdCompressorInputStream zstdInputStream = new ZstdCompressorInputStream(inputStream, NoPool.INSTANCE)) {
157             final byte[] expected = readAllBytes("zstandard.testdata");
158             final ByteArrayOutputStream bos = new ByteArrayOutputStream();
159             IOUtils.copy(zstdInputStream, bos);
160             assertArrayEquals(expected, bos.toByteArray());
161         }
162     }
163 
164     @Test
165     void testZstdDecodeWithRecyclingBufferPool() throws IOException {
166         final File input = getFile("zstandard.testdata.zst");
167         try (InputStream inputStream = Files.newInputStream(input.toPath());
168                 ZstdCompressorInputStream zstdInputStream = new ZstdCompressorInputStream(inputStream, RecyclingBufferPool.INSTANCE)) {
169             final byte[] expected = readAllBytes("zstandard.testdata");
170             final ByteArrayOutputStream bos = new ByteArrayOutputStream();
171             IOUtils.copy(zstdInputStream, bos);
172             assertArrayEquals(expected, bos.toByteArray());
173         }
174     }
175 
176 }