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