diff --git a/.classpath b/.classpath index 058b340..c48898b 100644 --- a/.classpath +++ b/.classpath @@ -7,7 +7,5 @@ - - diff --git a/build.xml b/build.xml index 1bdc702..919386f 100644 --- a/build.xml +++ b/build.xml @@ -14,7 +14,6 @@ @@ -105,15 +104,6 @@ - - - - - - - - - @@ -236,37 +226,14 @@ - - - - - - + + - - - - - - - - - - - + + + + + diff --git a/ivy-pure-java.xml b/ivy-pure-java.xml index 6e99e19..9c1c99b 100644 --- a/ivy-pure-java.xml +++ b/ivy-pure-java.xml @@ -21,6 +21,6 @@ - + diff --git a/ivy.xml b/ivy.xml index 6643da7..e5a9620 100644 --- a/ivy.xml +++ b/ivy.xml @@ -21,6 +21,6 @@ - + diff --git a/src/test/net/jpountz/lz4/AbstractLZ4Test.java b/src/test/net/jpountz/lz4/AbstractLZ4Test.java deleted file mode 100644 index 8c5cd38..0000000 --- a/src/test/net/jpountz/lz4/AbstractLZ4Test.java +++ /dev/null @@ -1,257 +0,0 @@ -package net.jpountz.lz4; - -/* - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.util.Arrays; - -import com.carrotsearch.randomizedtesting.RandomizedTest; - -public abstract class AbstractLZ4Test extends RandomizedTest { - - public interface Tester { - - T allocate(int length); - T copyOf(byte[] array); - byte[] copyOf(T data, int off, int len); - int maxCompressedLength(int len); - int compress(LZ4Compressor compressor, T src, int srcOff, int srcLen, T dest, int destOff, int maxDestLen); - int decompress(LZ4FastDecompressor decompressor, T src, int srcOff, T dest, int destOff, int destLen); - int decompress(LZ4SafeDecompressor decompressor, T src, int srcOff, int srcLen, T dest, int destOff, int maxDestLen); - void fill(T instance, byte b); - - public static class ByteArrayTester implements Tester { - - @Override - public byte[] allocate(int length) { - return new byte[length]; - } - - @Override - public byte[] copyOf(byte[] array) { - return Arrays.copyOf(array, array.length); - } - - @Override - public byte[] copyOf(byte[] data, int off, int len) { - return Arrays.copyOfRange(data, off, off + len); - } - - @Override - public int maxCompressedLength(int len) { - return LZ4Utils.maxCompressedLength(len); - } - - @Override - public int compress(LZ4Compressor compressor, byte[] src, int srcOff, - int srcLen, byte[] dest, int destOff, int maxDestLen) { - return compressor.compress(src, srcOff, srcLen, dest, destOff, maxDestLen); - } - - @Override - public int decompress(LZ4FastDecompressor decompressor, - byte[] src, int srcOff, byte[] dest, int destOff, int destLen) { - return decompressor.decompress(src, srcOff, dest, destOff, destLen); - } - - @Override - public int decompress(LZ4SafeDecompressor decompressor, - byte[] src, int srcOff, int srcLen, byte[] dest, int destOff, int maxDestLen) { - return decompressor.decompress(src, srcOff, srcLen, dest, destOff, maxDestLen); - } - - @Override - public void fill(byte[] instance, byte b) { - Arrays.fill(instance, b); - } - } - public static final Tester BYTE_ARRAY = new ByteArrayTester(); - public static final Tester BYTE_ARRAY_WITH_LENGTH = new ByteArrayTester() { - @Override - public int compress(LZ4Compressor compressor, byte[] src, int srcOff, - int srcLen, byte[] dest, int destOff, int maxDestLen) { - return new LZ4CompressorWithLength(compressor).compress(src, srcOff, srcLen, dest, destOff, maxDestLen); - } - - @Override - public int decompress(LZ4FastDecompressor decompressor, - byte[] src, int srcOff, byte[] dest, int destOff, int destLen) { - return new LZ4DecompressorWithLength(decompressor).decompress(src, srcOff, dest, destOff); - } - - @Override - public int decompress(LZ4SafeDecompressor decompressor, - byte[] src, int srcOff, int srcLen, byte[] dest, int destOff, int maxDestLen) { - return -1; - } - }; - - public static class ByteBufferTester implements Tester { - - @Override - public ByteBuffer allocate(int length) { - ByteBuffer bb; - int slice = randomInt(5); - if (randomBoolean()) { - bb = ByteBuffer.allocate(length + slice); - } else { - bb = ByteBuffer.allocateDirect(length + slice); - } - bb.position(slice); - bb = bb.slice(); - if (randomBoolean()) { - bb.order(ByteOrder.LITTLE_ENDIAN); - } else { - bb.order(ByteOrder.BIG_ENDIAN); - } - return bb; - } - - @Override - public ByteBuffer copyOf(byte[] array) { - ByteBuffer bb = allocate(array.length).put(array); - if (randomBoolean()) { - bb = bb.asReadOnlyBuffer(); - } - bb.position(0); - return bb; - } - - @Override - public byte[] copyOf(ByteBuffer data, int off, int len) { - byte[] copy = new byte[len]; - data.position(off); - data.get(copy); - return copy; - } - - @Override - public int maxCompressedLength(int len) { - return LZ4Utils.maxCompressedLength(len); - } - - @Override - public int compress(LZ4Compressor compressor, ByteBuffer src, int srcOff, - int srcLen, ByteBuffer dest, int destOff, int maxDestLen) { - return compressor.compress(src, srcOff, srcLen, dest, destOff, maxDestLen); - } - - @Override - public int decompress(LZ4FastDecompressor decompressor, ByteBuffer src, - int srcOff, ByteBuffer dest, int destOff, int destLen) { - return decompressor.decompress(src, srcOff, dest, destOff, destLen); - } - - @Override - public int decompress(LZ4SafeDecompressor decompressor, ByteBuffer src, - int srcOff, int srcLen, ByteBuffer dest, int destOff, int maxDestLen) { - return decompressor.decompress(src, srcOff, srcLen, dest, destOff, maxDestLen); - } - - @Override - public void fill(ByteBuffer instance, byte b) { - for (int i = 0; i < instance.capacity(); ++i) { - instance.put(i, b); - } - } - } - public static final Tester BYTE_BUFFER = new ByteBufferTester(); - public static final Tester BYTE_BUFFER_WITH_LENGTH = new ByteBufferTester() { - @Override - public int compress(LZ4Compressor compressor, ByteBuffer src, int srcOff, - int srcLen, ByteBuffer dest, int destOff, int maxDestLen) { - return new LZ4CompressorWithLength(compressor).compress(src, srcOff, srcLen, dest, destOff, maxDestLen); - } - - @Override - public int decompress(LZ4FastDecompressor decompressor, ByteBuffer src, - int srcOff, ByteBuffer dest, int destOff, int destLen) { - return new LZ4DecompressorWithLength(decompressor).decompress(src, srcOff, dest, destOff); - } - - @Override - public int decompress(LZ4SafeDecompressor decompressor, ByteBuffer src, - int srcOff, int srcLen, ByteBuffer dest, int destOff, int maxDestLen) { - return -1; - } - }; - } - - protected class RandomBytes { - private final byte[] bytes; - RandomBytes(int n) { - assert n > 0 && n <= 256; - bytes = new byte[n]; - for (int i = 0; i < n; ++i) { - bytes[i] = (byte) randomInt(255); - } - } - byte next() { - final int i = randomInt(bytes.length - 1); - return bytes[i]; - } - } - - protected static byte[] readResource(String resource) throws IOException { - InputStream is = LZ4Test.class.getResourceAsStream(resource); - if (is == null) { - throw new IllegalStateException("Cannot find " + resource); - } - byte[] buf = new byte[4096]; - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try { - while (true) { - final int read = is.read(buf); - if (read == -1) { - break; - } - baos.write(buf, 0, read); - } - } finally { - is.close(); - } - return baos.toByteArray(); - } - - protected byte[] randomArray(int len, int n) { - byte[] result = new byte[len]; - RandomBytes randomBytes = new RandomBytes(n); - for (int i = 0; i < result.length; ++i) { - result[i] = randomBytes.next(); - } - return result; - } - - protected ByteBuffer copyOf(byte[] bytes, int offset, int len) { - ByteBuffer buffer; - if (randomBoolean()) { - buffer = ByteBuffer.allocate(bytes.length); - } else { - buffer = ByteBuffer.allocateDirect(bytes.length); - } - buffer.put(bytes); - buffer.position(offset); - buffer.limit(offset + len); - if (randomBoolean()) { - buffer = buffer.asReadOnlyBuffer(); - } - return buffer; - } - -} diff --git a/src/test/net/jpountz/lz4/LZ4BlockStreamingTest.java b/src/test/net/jpountz/lz4/LZ4BlockStreamingTest.java deleted file mode 100644 index 9d6fc5b..0000000 --- a/src/test/net/jpountz/lz4/LZ4BlockStreamingTest.java +++ /dev/null @@ -1,347 +0,0 @@ -package net.jpountz.lz4; - -/* - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.FilterInputStream; -import java.io.FilterOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.charset.Charset; -import java.util.Arrays; -import java.util.zip.Adler32; -import java.util.zip.CRC32; -import java.util.zip.Checksum; - -import net.jpountz.xxhash.XXHashFactory; - -import org.junit.Test; -import static org.junit.Assert.*; - -import com.carrotsearch.randomizedtesting.annotations.Repeat; - -public class LZ4BlockStreamingTest extends AbstractLZ4Test { - - // An input stream that might read less data than it is able to - class MockInputStream extends FilterInputStream { - - MockInputStream(InputStream in) { - super(in); - } - - @Override - public int read(byte[] b, int off, int len) throws IOException { - return super.read(b, off, randomIntBetween(0, len)); - } - - @Override - public long skip(long n) throws IOException { - return super.skip(randomInt((int) Math.min(n, Integer.MAX_VALUE))); - } - - } - - // an output stream that delays the actual writes - class MockOutputStream extends FilterOutputStream { - - private final byte[] buffer; - private int delayedBytes; - - MockOutputStream(OutputStream out) { - super(out); - buffer = new byte[randomIntBetween(10, 1000)]; - delayedBytes = 0; - } - - private void flushIfNecessary() throws IOException { - if (delayedBytes == buffer.length) { - flushPendingData(); - } - } - - private void flushPendingData() throws IOException { - out.write(buffer, 0, delayedBytes); - delayedBytes = 0; - } - - @Override - public void write(int b) throws IOException { - if (rarely()) { - flushPendingData(); - } else { - flushIfNecessary(); - } - buffer[delayedBytes++] = (byte) b; - } - - @Override - public void write(byte[] b, int off, int len) throws IOException { - if (rarely()) { - flushPendingData(); - } - if (len + delayedBytes > buffer.length) { - flushPendingData(); - delayedBytes = randomInt(Math.min(len, buffer.length)); - out.write(b, off, len - delayedBytes); - System.arraycopy(b, off + len - delayedBytes, buffer, 0, delayedBytes); - } else { - System.arraycopy(b, off, buffer, delayedBytes, len); - delayedBytes += len; - } - } - - @Override - public void write(byte[] b) throws IOException { - write(b, 0, b.length); - } - - @Override - public void flush() throws IOException { - // no-op - } - - @Override - public void close() throws IOException { - flushPendingData(); - out.close(); - } - - } - - private InputStream open(byte[] data) { - return new MockInputStream(new ByteArrayInputStream(data)); - } - - private OutputStream wrap(OutputStream other) { - return new MockOutputStream(other); - } - - @Test - @Repeat(iterations=5) - public void testRoundtripGeo() throws IOException { - testRoundTrip("/calgary/geo"); - } - - @Test - @Repeat(iterations=5) - public void testRoundtripBook1() throws IOException { - testRoundTrip("/calgary/book1"); - } - - @Test - @Repeat(iterations=5) - public void testRoundtripPic() throws IOException { - testRoundTrip("/calgary/pic"); - } - - public void testRoundTrip(String resource) throws IOException { - testRoundTrip(readResource(resource)); - } - - public void testRoundTrip(byte[] data) throws IOException { - final ByteArrayOutputStream compressed = new ByteArrayOutputStream(); - final int blockSize; - switch (randomInt(2)) { - case 0: - blockSize = LZ4BlockOutputStream.MIN_BLOCK_SIZE; - break; - case 1: - blockSize = LZ4BlockOutputStream.MAX_BLOCK_SIZE; - break; - default: - blockSize = randomIntBetween(LZ4BlockOutputStream.MIN_BLOCK_SIZE, LZ4BlockOutputStream.MAX_BLOCK_SIZE); - break; - } - final LZ4Compressor compressor = randomBoolean() - ? LZ4Factory.fastestInstance().fastCompressor() - : LZ4Factory.fastestInstance().highCompressor(); - final Checksum checksum; - switch (randomInt(2)) { - case 0: - checksum = new Adler32(); - break; - case 1: - checksum = new CRC32(); - break; - default: - checksum = XXHashFactory.fastestInstance().newStreamingHash32(randomInt()).asChecksum(); - break; - } - final boolean syncFlush = randomBoolean(); - final LZ4BlockOutputStream os = new LZ4BlockOutputStream(wrap(compressed), blockSize, compressor, checksum, syncFlush); - final int half = data.length / 2; - switch (randomInt(2)) { - case 0: - os.write(data, 0, half); - for (int i = half; i < data.length; ++i) { - os.write(data[i]); - } - break; - case 1: - for (int i = 0; i < half; ++i) { - os.write(data[i]); - } - os.write(data, half, data.length - half); - break; - case 2: - os.write(data, 0, data.length); - break; - } - os.close(); - - final LZ4FastDecompressor decompressor = LZ4Factory.fastestInstance().fastDecompressor(); - InputStream is = new LZ4BlockInputStream(open(compressed.toByteArray()), decompressor, checksum); - assertFalse(is.markSupported()); - try { - is.mark(1); - is.reset(); - assertFalse(true); - } catch (IOException e) { - // OK - } - byte[] restored = new byte[data.length + 1000]; - int read = 0; - while (true) { - if (randomFloat() < 0.01f) { - final int r = is.read(restored, read, restored.length - read); - if (r == -1) { - break; - } else { - read += r; - } - } else { - final int b = is.read(); - if (b == -1) { - break; - } else { - restored[read++] = (byte) b; - } - } - } - is.close(); - assertEquals(data.length, read); - assertArrayEquals(data, Arrays.copyOf(restored, read)); - - // test skip - final int offset = data.length <= 1 ? 0 : randomInt(data.length - 1); - final int length = randomInt(data.length - offset); - is = new LZ4BlockInputStream(open(compressed.toByteArray()), decompressor, checksum); - restored = new byte[length + 1000]; - read = 0; - while (read < offset) { - final long skipped = is.skip(offset - read); - assertTrue(skipped >= 0); - read += skipped; - } - read = 0; - while (read < length) { - final int r = is.read(restored, read, length - read); - assertTrue(r >= 0); - read += r; - } - is.close(); - assertArrayEquals(Arrays.copyOfRange(data, offset, offset + length), Arrays.copyOfRange(restored, 0, length)); - } - - @Test - @Repeat(iterations=20) - public void testRoundtripRandom() throws IOException { - final int size = randomFloat() < 0.1f ? randomInt(5) : randomInt(1 << 20); - final byte[] data = randomArray(size, randomBoolean() ? randomIntBetween(1, 5) : randomIntBetween(6, 100)); - testRoundTrip(data); - } - - @Test - public void testRoundtripEmpty() throws IOException { - testRoundTrip(new byte[0]); - } - - @Test - public void testDoubleClose() throws IOException { - final byte[] testBytes = "Testing!".getBytes(Charset.forName("UTF-8")); - - ByteArrayOutputStream bytes = new ByteArrayOutputStream(); - LZ4BlockOutputStream out = new LZ4BlockOutputStream(bytes); - - out.write(testBytes); - - out.close(); - out.close(); - - LZ4BlockInputStream in = new LZ4BlockInputStream(new ByteArrayInputStream(bytes.toByteArray())); - byte[] actual = new byte[testBytes.length]; - in.read(actual); - - assertArrayEquals(testBytes, actual); - - in.close(); - in.close(); - } - - private static int readFully(InputStream in, byte[] b) throws IOException { - int total; - int result; - for (total = 0; total < b.length; total += result) { - result = in.read(b, total, b.length - total); - if(result == -1) { - break; - } - } - return total; - } - - @Test - public void testConcatenationOfSerializedStreams() throws IOException { - final byte[] testBytes1 = randomArray(64, 256); - final byte[] testBytes2 = randomArray(64, 256); - byte[] expected = new byte[128]; - System.arraycopy(testBytes1, 0, expected, 0, 64); - System.arraycopy(testBytes2, 0, expected, 64, 64); - - ByteArrayOutputStream bytes1os = new ByteArrayOutputStream(); - LZ4BlockOutputStream out1 = new LZ4BlockOutputStream(bytes1os); - out1.write(testBytes1); - out1.close(); - - ByteArrayOutputStream bytes2os = new ByteArrayOutputStream(); - LZ4BlockOutputStream out2 = new LZ4BlockOutputStream(bytes2os); - out2.write(testBytes2); - out2.close(); - - byte[] bytes1 = bytes1os.toByteArray(); - byte[] bytes2 = bytes2os.toByteArray(); - byte[] concatenatedBytes = new byte[bytes1.length + bytes2.length]; - System.arraycopy(bytes1, 0, concatenatedBytes, 0, bytes1.length); - System.arraycopy(bytes2, 0, concatenatedBytes, bytes1.length, bytes2.length); - - // In a default behaviour, we can read the first block of the concatenated bytes only - LZ4BlockInputStream in1 = new LZ4BlockInputStream(new ByteArrayInputStream(concatenatedBytes)); - byte[] actual1 = new byte[128]; - assertEquals(64, readFully(in1, actual1)); - assertEquals(-1, in1.read()); - in1.close(); - - // Check if we can read concatenated byte stream - LZ4BlockInputStream in2 = new LZ4BlockInputStream(new ByteArrayInputStream(concatenatedBytes), false); - byte[] actual2 = new byte[128]; - assertEquals(128, readFully(in2, actual2)); - assertEquals(-1, in2.read()); - in2.close(); - - assertArrayEquals(expected, actual2); - } -} diff --git a/src/test/net/jpountz/lz4/LZ4Test.java b/src/test/net/jpountz/lz4/LZ4Test.java deleted file mode 100644 index 161899c..0000000 --- a/src/test/net/jpountz/lz4/LZ4Test.java +++ /dev/null @@ -1,562 +0,0 @@ -package net.jpountz.lz4; - -/* - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import static net.jpountz.lz4.Instances.COMPRESSORS; -import static net.jpountz.lz4.Instances.FAST_DECOMPRESSORS; -import static net.jpountz.lz4.Instances.SAFE_DECOMPRESSORS; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.ReadOnlyBufferException; -import java.util.Arrays; -import java.io.File; -import java.io.FilenameFilter; - -import org.junit.Test; -import static org.junit.Assert.*; - -import com.carrotsearch.randomizedtesting.annotations.Repeat; - -public class LZ4Test extends AbstractLZ4Test { - - @Test - public void testLockFileOfTemporaryNativeLibrary() { - // Load the native library - LZ4JNI.LZ4_compressBound(100); - String tempFolder = new File(System.getProperty("java.io.tmpdir")).getAbsolutePath(); - File tempDir = new File(new File(System.getProperty("java.io.tmpdir")).getAbsolutePath()); - if (!System.getProperty("os.name").contains("Windows")) { - // A temporary library must be accompanied by a lock file. - // On Windows, JVM does not remove a temporary library on exit. - // This means on Windows, there might be a temporary library - // that is not accompanied by a lock file when there was - // a Java process using lz4-java that was running concurrently - // to this test process. - File[] tempLibFiles = tempDir.listFiles(new FilenameFilter() { - public boolean accept(File dir, String name) { - return name.startsWith("liblz4-java-") && !name.endsWith(".lck"); - } - }); - if (tempLibFiles != null) { - for (File tempLibFile : tempLibFiles) { - File lckFile = new File(tempLibFile.getAbsolutePath() + ".lck"); - assertTrue(tempLibFile.getAbsolutePath(), lckFile.exists()); - } - } - } - // A lock file must be accompanied by a temporary library. - File[] tempLockFiles = tempDir.listFiles(new FilenameFilter() { - public boolean accept(File dir, String name) { - return name.startsWith("liblz4-java-") && name.endsWith(".lck"); - } - }); - if (tempLockFiles != null) { - for (File tempLockFile : tempLockFiles) { - String tempLockFilePath = tempLockFile.getAbsolutePath(); - File libFile = new File(tempLockFilePath.substring(0, tempLockFilePath.length() - 4)); - assertTrue(tempLockFilePath, libFile.exists()); - } - } - } - - @Test - @Repeat(iterations=50) - public void testMaxCompressedLength() { - final int len = randomBoolean() ? randomInt(16) : randomInt(1 << 30); - for (LZ4Compressor compressor : COMPRESSORS) { - assertEquals(LZ4JNI.LZ4_compressBound(len), compressor.maxCompressedLength(len)); - } - } - - private static byte[] getCompressedWorstCase(byte[] decompressed) { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - int len = decompressed.length; - if (len >= LZ4Constants.RUN_MASK) { - baos.write(LZ4Constants.RUN_MASK << LZ4Constants.ML_BITS); - len -= LZ4Constants.RUN_MASK; - } - while (len >= 255) { - baos.write(255); - len -= 255; - } - baos.write(len); - try { - baos.write(decompressed); - } catch (IOException e) { - throw new AssertionError(); - } - return baos.toByteArray(); - } - - @Test - public void testEmpty() { - testRoundTrip(new byte[0]); - } - - public void testUncompressWorstCase(LZ4FastDecompressor decompressor) { - final int len = randomInt(100 * 1024); - final int max = randomIntBetween(1, 255); - byte[] decompressed = randomArray(len, max); - byte[] compressed = getCompressedWorstCase(decompressed); - byte[] restored = new byte[decompressed.length]; - int cpLen = decompressor.decompress(compressed, 0, restored, 0, decompressed.length); - assertEquals(compressed.length, cpLen); - assertArrayEquals(decompressed, restored); - } - - @Test - public void testUncompressWorstCase() { - for (LZ4FastDecompressor decompressor : FAST_DECOMPRESSORS) { - testUncompressWorstCase(decompressor); - } - } - - public void testUncompressWorstCase(LZ4SafeDecompressor decompressor) { - final int len = randomInt(100 * 1024); - final int max = randomIntBetween(1, 256); - byte[] decompressed = randomArray(len, max); - byte[] compressed = getCompressedWorstCase(decompressed); - byte[] restored = new byte[decompressed.length]; - int uncpLen = decompressor.decompress(compressed, 0, compressed.length, restored, 0); - assertEquals(decompressed.length, uncpLen); - assertArrayEquals(decompressed, restored); - } - - @Test - public void testUncompressSafeWorstCase() { - for (LZ4SafeDecompressor decompressor : SAFE_DECOMPRESSORS) { - testUncompressWorstCase(decompressor); - } - } - - public void testRoundTrip(byte[] data, int off, int len, - LZ4Compressor compressor, - LZ4FastDecompressor decompressor, - LZ4SafeDecompressor decompressor2) { - for (Tester tester : Arrays.asList(Tester.BYTE_ARRAY, Tester.BYTE_BUFFER, Tester.BYTE_ARRAY_WITH_LENGTH, Tester.BYTE_BUFFER_WITH_LENGTH)) { - testRoundTrip(tester, data, off, len, compressor, decompressor, decompressor2); - } - } - - public void testRoundTrip( - Tester tester, - byte[] data, int off, int len, - LZ4Compressor compressor, - LZ4FastDecompressor decompressor, - LZ4SafeDecompressor decompressor2) { - final int maxCompressedLength = tester.maxCompressedLength(len); - // "maxCompressedLength + 1" for the over-estimated compressed length test below - final T compressed = tester.allocate(maxCompressedLength + 1); - final int compressedLen = tester.compress(compressor, - tester.copyOf(data), off, len, - compressed, 0, maxCompressedLength); - - // test decompression - final T restored = tester.allocate(len); - assertEquals(compressedLen, tester.decompress(decompressor, compressed, 0, restored, 0, len)); - assertArrayEquals(Arrays.copyOfRange(data, off, off + len), tester.copyOf(restored, 0, len)); - - // make sure it fails if the compression dest is not large enough - tester.fill(restored, randomByte()); - final T compressed2 = tester.allocate(compressedLen-1); - try { - final int compressedLen2 = tester.compress(compressor, - tester.copyOf(data), off, len, - compressed2, 0, compressedLen - 1); - // Compression can succeed even with the smaller dest - // because the compressor is allowed to return different compression results - // even when it is invoked with the same input data. - // In this case, just make sure the compressed data can be successfully decompressed. - assertEquals(compressedLen2, tester.decompress(decompressor, compressed2, 0, restored, 0, len)); - assertArrayEquals(Arrays.copyOfRange(data, off, off + len), tester.copyOf(restored, 0, len)); - } catch (LZ4Exception e) { - // OK - } - - if (tester != Tester.BYTE_ARRAY_WITH_LENGTH && tester != Tester.BYTE_BUFFER_WITH_LENGTH) { - if (len > 0) { - // decompression dest is too small - try { - tester.decompress(decompressor, compressed, 0, restored, 0, len - 1); - fail(); - } catch (LZ4Exception e) { - // OK - } - } - - // decompression dest is too large - final T restored2 = tester.allocate(len+1); - try { - final int cpLen = tester.decompress(decompressor, compressed, 0, restored2, 0, len + 1); - fail("compressedLen=" + cpLen); - } catch (LZ4Exception e) { - // OK - } - - // try decompression when only the size of the compressed buffer is known - if (len > 0) { - tester.fill(restored, randomByte()); - assertEquals(len, tester.decompress(decompressor2, compressed, 0, compressedLen, restored, 0, len)); - assertArrayEquals(Arrays.copyOfRange(data, off, off + len), tester.copyOf(restored, 0, len)); - tester.fill(restored, randomByte()); - } else { - assertEquals(0, tester.decompress(decompressor2, compressed, 0, compressedLen, tester.allocate(1), 0, 1)); - } - - // over-estimated compressed length - try { - final int decompressedLen = tester.decompress(decompressor2, compressed, 0, compressedLen + 1, tester.allocate(len + 100), 0, len + 100); - fail("decompressedLen=" + decompressedLen); - } catch (LZ4Exception e) { - // OK - } - - // under-estimated compressed length - try { - final int decompressedLen = tester.decompress(decompressor2, compressed, 0, compressedLen - 1, tester.allocate(len + 100), 0, len + 100); - if (!(decompressor2 instanceof LZ4JNISafeDecompressor)) { - fail("decompressedLen=" + decompressedLen); - } - } catch (LZ4Exception e) { - // OK - } - } - } - - public void testRoundTrip(byte[] data, int off, int len, LZ4Factory compressorFactory, LZ4Factory decompressorFactory) { - for (LZ4Compressor compressor : Arrays.asList( - compressorFactory.fastCompressor(), compressorFactory.highCompressor())) { - testRoundTrip(data, off, len, compressor, decompressorFactory.fastDecompressor(), decompressorFactory.safeDecompressor()); - } - } - - public void testRoundTrip(byte[] data, int off, int len) { - for (LZ4Factory compressorFactory : Arrays.asList( - LZ4Factory.nativeInstance(), - LZ4Factory.unsafeInstance(), - LZ4Factory.safeInstance())) { - for (LZ4Factory decompressorFactory : Arrays.asList( - LZ4Factory.nativeInstance(), - LZ4Factory.unsafeInstance(), - LZ4Factory.safeInstance())) { - testRoundTrip(data, off, len, compressorFactory, decompressorFactory); - } - } - } - - public void testRoundTrip(byte[] data) { - testRoundTrip(data, 0, data.length); - } - - public void testRoundTrip(String resource) throws IOException { - final byte[] data = readResource(resource); - testRoundTrip(data); - } - - @Test - public void testRoundtripGeo() throws IOException { - testRoundTrip("/calgary/geo"); - } - - @Test - public void testRoundtripBook1() throws IOException { - testRoundTrip("/calgary/book1"); - } - - @Test - public void testRoundtripPic() throws IOException { - testRoundTrip("/calgary/pic"); - } - - @Test - public void testNullMatchDec() { - // 1 literal, 4 matchs with matchDec=0, 8 literals - final byte[] invalid = new byte[] { 16, 42, 0, 0, (byte) 128, 42, 42, 42, 42, 42, 42, 42, 42 }; - // decompression should neither throw an exception nor loop indefinitely - for (LZ4FastDecompressor decompressor : FAST_DECOMPRESSORS) { - decompressor.decompress(invalid, 0, new byte[13], 0, 13); - } - for (LZ4SafeDecompressor decompressor : SAFE_DECOMPRESSORS) { - decompressor.decompress(invalid, 0, invalid.length, new byte[20], 0); - } - } - - @Test - public void testEndsWithMatch() { - // 6 literals, 4 matchs - final byte[] invalid = new byte[] { 96, 42, 43, 44, 45, 46, 47, 5, 0 }; - final int decompressedLength = 10; - - for (LZ4FastDecompressor decompressor : FAST_DECOMPRESSORS) { - try { - // it is invalid to end with a match, should be at least 5 literals - decompressor.decompress(invalid, 0, new byte[decompressedLength], 0, decompressedLength); - assertTrue(decompressor.toString(), false); - } catch (LZ4Exception e) { - // OK - } - } - - for (LZ4SafeDecompressor decompressor : SAFE_DECOMPRESSORS) { - try { - // it is invalid to end with a match, should be at least 5 literals - decompressor.decompress(invalid, 0, invalid.length, new byte[20], 0); - assertTrue(false); - } catch (LZ4Exception e) { - // OK - } - } - } - - @Test - public void testEndsWithLessThan5Literals() { - // 6 literals, 4 matchs - final byte[] invalidBase = new byte[] { 96, 42, 43, 44, 45, 46, 47, 5, 0 }; - - for (int i = 1; i < 5; ++i) { - final byte[] invalid = Arrays.copyOf(invalidBase, invalidBase.length + 1 + i); - invalid[invalidBase.length] = (byte) (i << 4); // i literals at the end - - for (LZ4FastDecompressor decompressor : FAST_DECOMPRESSORS) { - try { - // it is invalid to end with a match, should be at least 5 literals - decompressor.decompress(invalid, 0, new byte[20], 0, 20); - assertTrue(decompressor.toString(), false); - } catch (LZ4Exception e) { - // OK - } - } - - for (LZ4SafeDecompressor decompressor : SAFE_DECOMPRESSORS) { - try { - // it is invalid to end with a match, should be at least 5 literals - decompressor.decompress(invalid, 0, invalid.length, new byte[20], 0); - assertTrue(false); - } catch (LZ4Exception e) { - // OK - } - } - } - } - - @Test - public void testWriteToReadOnlyBuffer() { - for (LZ4Compressor compressor : COMPRESSORS) { - ByteBuffer in = Tester.BYTE_BUFFER.copyOf(new byte[] {2, 3}); - ByteBuffer out = Tester.BYTE_BUFFER.allocate(100).asReadOnlyBuffer(); - try { - compressor.compress(in, out); - fail(); - } catch (ReadOnlyBufferException e) { - // ok - } - } - for (LZ4SafeDecompressor decompressor : SAFE_DECOMPRESSORS) { - ByteBuffer in = Tester.BYTE_BUFFER.copyOf(COMPRESSORS[0].compress(new byte[] {2, 3})); - ByteBuffer out = Tester.BYTE_BUFFER.allocate(100).asReadOnlyBuffer(); - try { - decompressor.decompress(in, out); - fail(); - } catch (ReadOnlyBufferException e) { - // ok - } - } - for (LZ4FastDecompressor decompressor : FAST_DECOMPRESSORS) { - ByteBuffer in = Tester.BYTE_BUFFER.copyOf(COMPRESSORS[0].compress(new byte[] {2, 3})); - ByteBuffer out = Tester.BYTE_BUFFER.allocate(100).asReadOnlyBuffer(); - out.limit(2); - try { - decompressor.decompress(in, out); - fail(); - } catch (ReadOnlyBufferException e) { - // ok - } - } - } - - @Test - @Repeat(iterations=5) - public void testAllEqual() { - final int len = randomBoolean() ? randomInt(20) : randomInt(100000); - final byte[] buf = new byte[len]; - Arrays.fill(buf, randomByte()); - testRoundTrip(buf); - } - - @Test - public void testMaxDistance() { - final int len = randomIntBetween(1 << 17, 1 << 18); - final int off = randomInt(len - (1 << 16) - (1 << 15)); - final byte[] buf = new byte[len]; - for (int i = 0; i < (1 << 15); ++i) { - buf[off + i] = randomByte(); - } - System.arraycopy(buf, off, buf, off + 65535, 1 << 15); - testRoundTrip(buf); - } - - @Test - @Repeat(iterations=10) - public void testRandomData() { - final int n = randomIntBetween(1, 15); - final int off = randomInt(1000); - final int len = randomBoolean() ? randomInt(1 << 16) : randomInt(1 << 20); - final byte[] data = randomArray(off + len + randomInt(100), n); - testRoundTrip(data, off, len); - } - - @Test - // https://github.com/jpountz/lz4-java/issues/12 - public void testRoundtripIssue12() { - byte[] data = new byte[]{ - 14, 72, 14, 85, 3, 72, 14, 85, 3, 72, 14, 72, 14, 72, 14, 85, 3, 72, 14, 72, 14, 72, 14, 72, 14, 72, 14, 72, 14, 85, 3, 72, - 14, 85, 3, 72, 14, 85, 3, 72, 14, 85, 3, 72, 14, 85, 3, 72, 14, 85, 3, 72, 14, 50, 64, 0, 46, -1, 0, 0, 0, 29, 3, 85, - 8, -113, 0, 68, -97, 3, 0, 2, 3, -97, 6, 0, 68, -113, 0, 2, 3, -97, 6, 0, 68, -113, 0, 2, 3, 85, 8, -113, 0, 68, -97, 3, - 0, 2, 3, -97, 6, 0, 68, -113, 0, 2, 3, -97, 6, 0, 68, -113, 0, 2, 3, -97, 6, 0, 68, -113, 0, 2, 3, -97, 6, 0, 68, -113, - 0, 2, 3, -97, 6, 0, 68, -113, 0, 2, 3, -97, 6, 0, 68, -113, 0, 2, 3, -97, 6, 0, 68, -113, 0, 2, 3, -97, 6, 0, 68, -113, - 0, 2, 3, -97, 6, 0, 68, -113, 0, 2, 3, -97, 6, 0, 68, -113, 0, 50, 64, 0, 47, -105, 0, 0, 0, 30, 3, -97, 6, 0, 68, -113, - 0, 2, 3, -97, 6, 0, 68, -113, 0, 2, 3, 85, 8, -113, 0, 68, -97, 3, 0, 2, 3, 85, 8, -113, 0, 68, -97, 3, 0, 2, 3, 85, - 8, -113, 0, 68, -97, 3, 0, 2, -97, 6, 0, 2, 3, 85, 8, -113, 0, 68, -97, 3, 0, 2, 3, -97, 6, 0, 68, -113, 0, 2, 3, -97, - 6, 0, 68, -113, 0, 120, 64, 0, 48, 4, 0, 0, 0, 31, 34, 72, 29, 72, 37, 72, 35, 72, 45, 72, 23, 72, 46, 72, 20, 72, 40, 72, - 33, 72, 25, 72, 39, 72, 38, 72, 26, 72, 28, 72, 42, 72, 24, 72, 27, 72, 36, 72, 41, 72, 32, 72, 18, 72, 30, 72, 22, 72, 31, 72, - 43, 72, 19, 72, 34, 72, 29, 72, 37, 72, 35, 72, 45, 72, 23, 72, 46, 72, 20, 72, 40, 72, 33, 72, 25, 72, 39, 72, 38, 72, 26, 72, - 28, 72, 42, 72, 24, 72, 27, 72, 36, 72, 41, 72, 32, 72, 18, 72, 30, 72, 22, 72, 31, 72, 43, 72, 19, 72, 34, 72, 29, 72, 37, 72, - 35, 72, 45, 72, 23, 72, 46, 72, 20, 72, 40, 72, 33, 72, 25, 72, 39, 72, 38, 72, 26, 72, 28, 72, 42, 72, 24, 72, 27, 72, 36, 72, - 41, 72, 32, 72, 18, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 39, 24, 32, 34, 124, 0, 120, 64, 0, 48, 80, 0, 0, 0, 31, 30, 72, 22, 72, 31, 72, 43, 72, 19, 72, 34, 72, 29, 72, 37, 72, - 35, 72, 45, 72, 23, 72, 46, 72, 20, 72, 40, 72, 33, 72, 25, 72, 39, 72, 38, 72, 26, 72, 28, 72, 42, 72, 24, 72, 27, 72, 36, 72, - 41, 72, 32, 72, 18, 72, 30, 72, 22, 72, 31, 72, 43, 72, 19, 72, 34, 72, 29, 72, 37, 72, 35, 72, 45, 72, 23, 72, 46, 72, 20, 72, - 40, 72, 33, 72, 25, 72, 39, 72, 38, 72, 26, 72, 28, 72, 42, 72, 24, 72, 27, 72, 36, 72, 41, 72, 32, 72, 18, 72, 30, 72, 22, 72, - 31, 72, 43, 72, 19, 72, 34, 72, 29, 72, 37, 72, 35, 72, 45, 72, 23, 72, 46, 72, 20, 72, 40, 72, 33, 72, 25, 72, 39, 72, 38, 72, - 26, 72, 28, 72, 42, 72, 24, 72, 27, 72, 36, 72, 41, 72, 32, 72, 18, 72, 30, 72, 22, 72, 31, 72, 43, 72, 19, 72, 34, 72, 29, 72, - 37, 72, 35, 72, 45, 72, 23, 72, 46, 72, 20, 72, 40, 72, 33, 72, 25, 72, 39, 72, 38, 72, 26, 72, 28, 72, 42, 72, 24, 72, 27, 72, - 36, 72, 41, 72, 32, 72, 18, 72, 30, 72, 22, 72, 31, 72, 43, 72, 19, 72, 34, 72, 29, 72, 37, 72, 35, 72, 45, 72, 23, 72, 46, 72, - 20, 72, 40, 72, 33, 72, 25, 72, 39, 72, 38, 72, 26, 72, 28, 72, 42, 72, 24, 72, 27, 72, 36, 72, 41, 72, 32, 72, 18, 72, 30, 72, - 22, 72, 31, 72, 43, 72, 19, 72, 34, 72, 29, 72, 37, 72, 35, 72, 45, 72, 23, 72, 46, 72, 20, 72, 40, 72, 33, 72, 25, 72, 39, 72, - 38, 72, 26, 72, 28, 72, 42, 72, 24, 72, 27, 72, 36, 72, 41, 72, 32, 72, 18, 72, 30, 72, 22, 72, 31, 72, 43, 72, 19, 72, 34, 72, - 29, 72, 37, 72, 35, 72, 45, 72, 23, 72, 46, 72, 20, 72, 40, 72, 33, 72, 25, 72, 39, 72, 38, 72, 26, 72, 28, 72, 42, 72, 24, 72, - 27, 72, 36, 72, 41, 72, 32, 72, 18, 72, 30, 72, 22, 72, 31, 72, 43, 72, 19, 50, 64, 0, 49, 20, 0, 0, 0, 32, 3, -97, 6, 0, - 68, -113, 0, 2, 3, 85, 8, -113, 0, 68, -97, 3, 0, 2, 3, -97, 6, 0, 68, -113, 0, 2, 3, -97, 6, 0, 68, -113, 0, 2, 3, -97, - 6, 0, 68, -113, 0, 2, 3, 85, 8, -113, 0, 68, -97, 3, 0, 2, 3, -97, 6, 0, 68, -113, 0, 2, 3, -97, 6, 0, 68, -113, 0, 2, - 3, -97, 6, 0, 68, -113, 0, 2, 3, -97, 6, 0, 68, -113, 0, 2, 3, -97, 6, 0, 68, -113, 0, 2, 3, -97, 6, 0, 68, -113, 0, 2, - 3, -97, 6, 0, 50, 64, 0, 50, 53, 0, 0, 0, 34, 3, -97, 6, 0, 68, -113, 0, 2, 3, 85, 8, -113, 0, 68, -113, 0, 2, 3, -97, - 6, 0, 68, -113, 0, 2, 3, 85, 8, -113, 0, 68, -113, 0, 2, 3, -97, 6, 0, 68, -113, 0, 2, 3, -97, 6, 0, 68, -113, 0, 2, 3, - -97, 6, 0, 68, -113, 0, 2, 3, 85, 8, -113, 0, 68, -97, 3, 0, 2, 3, -97, 6, 0, 68, -113, 0, 2, 3, 85, 8, -113, 0, 68, -97, - 3, 0, 2, 3, 85, 8, -113, 0, 68, -97, 3, 0, 2, 3, -97, 6, 0, 68, -113, 0, 2, 3, 85, 8, -113, 0, 68, -97, 3, 0, 2, 3, - 85, 8, -113, 0, 68, -97, 3, 0, 2, 3, -97, 6, 0, 68, -113, 0, 2, 3, -97, 6, 0, 68, -113, 0, 2, 3, -97, 6, 0, 68, -113, 0, - 2, 3, 85, 8, -113, 0, 68, -97, 3, 0, 2, 3, 85, 8, -113, 0, 68, -97, 3, 0, 2, 3, 85, 8, -113, 0, 68, -97, 3, 0, 2, 3, - -97, 6, 0, 50, 64, 0, 51, 85, 0, 0, 0, 36, 3, 85, 8, -113, 0, 68, -97, 3, 0, 2, 3, -97, 6, 0, 68, -113, 0, 2, 3, -97, - 6, 0, 68, -113, 0, 2, 3, -97, 6, 0, 68, -113, 0, 2, 3, -97, 6, 0, 68, -113, 0, 2, -97, 5, 0, 2, 3, 85, 8, -113, 0, 68, - -97, 3, 0, 2, 3, -97, 6, 0, 68, -113, 0, 2, 3, -97, 6, 0, 68, -113, 0, 2, 3, -97, 6, 0, 68, -113, 0, 2, 3, -97, 6, 0, - 68, -113, 0, 2, 3, -97, 6, 0, 50, -64, 0, 51, -45, 0, 0, 0, 37, 68, -113, 0, 2, 3, -97, 6, 0, 68, -113, 0, 2, 3, -97, 6, - 0, 68, -113, 0, 2, 3, -97, 6, 0, 68, -113, 0, 2, 3, -97, 6, 0, 68, -113, 0, 2, 3, 85, 8, -113, 0, 68, -113, 0, 2, 3, -97, - 6, 0, 68, -113, 0, 2, 3, 85, 8, -113, 0, 68, -97, 3, 0, 2, 3, 85, 8, -113, 0, 68, -97, 3, 0, 120, 64, 0, 52, -88, 0, 0, - 0, 39, 13, 85, 5, 72, 13, 85, 5, 72, 13, 85, 5, 72, 13, 72, 13, 85, 5, 72, 13, 85, 5, 72, 13, 85, 5, 72, 13, 85, 5, 72, - 13, 72, 13, 85, 5, 72, 13, 85, 5, 72, 13, 72, 13, 72, 13, 85, 5, 72, 13, 85, 5, 72, 13, 85, 5, 72, 13, 85, 5, 72, 13, 85, - 5, 72, 13, 85, 5, 72, 13, 72, 13, 72, 13, 72, 13, 85, 5, 72, 13, 85, 5, 72, 13, 72, 13, 85, 5, 72, 13, 85, 5, 72, 13, 85, - 5, 72, 13, 85, 5, 72, 13, 85, 5, 72, 13, 85, 5, 72, 13, 85, 5, 72, 13, 85, 5, 72, 13, 85, 5, 72, 13, 85, 5, 72, 13, 85, - 5, 72, 13, 85, 5, 72, 13, 72, 13, 72, 13, 72, 13, 85, 5, 72, 13, 85, 5, 72, 13, 85, 5, 72, 13, 72, 13, 85, 5, 72, 13, 72, - 13, 85, 5, 72, 13, 72, 13, 85, 5, 72, 13, -19, -24, -101, -35 - }; - testRoundTrip(data, 9, data.length - 9); - } - - private static void assertCompressedArrayEquals(String message, byte[] expected, byte[] actual) { - int off = 0; - int decompressedOff = 0; - while (true) { - if (off == expected.length) { - break; - } - final Sequence sequence1 = readSequence(expected, off); - final Sequence sequence2 = readSequence(actual, off); - assertEquals(message + ", off=" + off + ", decompressedOff=" + decompressedOff, sequence1, sequence2); - off += sequence1.length; - decompressedOff += sequence1.literalLen + sequence1.matchLen; - } - } - - private static Sequence readSequence(byte[] buf, int off) { - final int start = off; - final int token = buf[off++] & 0xFF; - int literalLen = token >>> 4; - if (literalLen >= 0x0F) { - int len; - while ((len = buf[off++] & 0xFF) == 0xFF) { - literalLen += 0xFF; - } - literalLen += len; - } - off += literalLen; - if (off == buf.length) { - return new Sequence(literalLen, -1, -1, off - start); - } - int matchDec = (buf[off++] & 0xFF) | ((buf[off++] & 0xFF) << 8); - int matchLen = token & 0x0F; - if (matchLen >= 0x0F) { - int len; - while ((len = buf[off++] & 0xFF) == 0xFF) { - matchLen += 0xFF; - } - matchLen += len; - } - matchLen += 4; - return new Sequence(literalLen, matchDec, matchLen, off - start); - } - - private static class Sequence { - final int literalLen, matchDec, matchLen, length; - - public Sequence(int literalLen, int matchDec, int matchLen, int length) { - this.literalLen = literalLen; - this.matchDec = matchDec; - this.matchLen = matchLen; - this.length = length; - } - - @Override - public String toString() { - return "Sequence [literalLen=" + literalLen + ", matchDec=" + matchDec - + ", matchLen=" + matchLen + "]"; - } - - @Override - public int hashCode() { - return 42; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - Sequence other = (Sequence) obj; - if (literalLen != other.literalLen) - return false; - if (matchDec != other.matchDec) - return false; - if (matchLen != other.matchLen) - return false; - return true; - } - - } - -} diff --git a/src/test/net/jpountz/xxhash/XXHash32Test.java b/src/test/net/jpountz/xxhash/XXHash32Test.java deleted file mode 100644 index 98c9436..0000000 --- a/src/test/net/jpountz/xxhash/XXHash32Test.java +++ /dev/null @@ -1,189 +0,0 @@ -package net.jpountz.xxhash; - -/* - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import java.nio.ByteBuffer; - -import net.jpountz.lz4.AbstractLZ4Test; -import net.jpountz.util.SafeUtils; - -import org.junit.Test; -import static org.junit.Assert.*; - -import com.carrotsearch.randomizedtesting.annotations.Repeat; - -public class XXHash32Test extends AbstractLZ4Test { - - private static abstract class StreamingXXHash32Adapter extends XXHash32 { - - protected abstract StreamingXXHash32 streamingHash(int seed); - - @Override - public int hash(byte[] buf, int off, int len, int seed) { - SafeUtils.checkRange(buf, off, len); - int originalOff = off; - int remainingPasses = randomInt(5); - StreamingXXHash32 h = streamingHash(seed); - final int end = off + len; - while (off < end) { - final int l = randomIntBetween(off, end) - off; - h.update(buf, off, l); - off += l; - if (remainingPasses > 0 && randomInt(5) == 0) { - h.reset(); - --remainingPasses; - off = originalOff; - } - if (randomBoolean()) { - h.getValue(); - } - } - return h.getValue(); - } - - @Override - public int hash(ByteBuffer buf, int off, int len, int seed) { - byte[] bytes = new byte[len]; - int originalPosition = buf.position(); - try { - buf.position(off); - buf.get(bytes, 0, len); - return hash(bytes, 0, len, seed); - } finally { - buf.position(originalPosition); - } - } - - public String toString() { - return streamingHash(0).toString(); - } - - } - - private static XXHash32[] INSTANCES = new XXHash32[] { - XXHashFactory.nativeInstance().hash32(), - XXHashFactory.unsafeInstance().hash32(), - XXHashFactory.safeInstance().hash32(), - new StreamingXXHash32Adapter() { - protected StreamingXXHash32 streamingHash(int seed) { - return XXHashFactory.nativeInstance().newStreamingHash32(seed); - } - }, - new StreamingXXHash32Adapter() { - protected StreamingXXHash32 streamingHash(int seed) { - return XXHashFactory.unsafeInstance().newStreamingHash32(seed); - } - }, - new StreamingXXHash32Adapter() { - protected StreamingXXHash32 streamingHash(int seed) { - return XXHashFactory.safeInstance().newStreamingHash32(seed); - } - } - }; - - @Test - public void testEmpty() { - final int seed = randomInt(); - for (XXHash32 xxHash : INSTANCES) { - xxHash.hash(new byte[0], 0, 0, seed); - xxHash.hash(copyOf(new byte[0], 0, 0), 0, 0, seed); - } - } - - @Test - @Repeat(iterations = 20) - public void testAIOOBE() { - final int seed = randomInt(); - final int max = randomBoolean() ? 32 : 1000; - final int bufLen = randomIntBetween(1, max); - final byte[] buf = randomArray(bufLen, 256); - final int off = randomInt(buf.length - 1); - final int len = randomInt(buf.length - off); - for (XXHash32 xxHash : INSTANCES) { - xxHash.hash(buf, off, len, seed); - xxHash.hash(copyOf(buf, off, len), off, len, seed); - } - } - - @Test - @Repeat(iterations=40) - public void testInstances() { - final int maxLenLog = randomInt(20); - final int bufLen = randomInt(1 << maxLenLog); - byte[] buf = randomArray(bufLen, 256); - final int seed = randomInt(); - final int off = randomIntBetween(0, Math.max(0, bufLen - 1)); - final int len = randomIntBetween(0, bufLen - off); - - final int ref = XXHashFactory.nativeInstance().hash32().hash(buf, off, len, seed); - for (XXHash32 hash : INSTANCES) { - final int h = hash.hash(buf, off, len, seed); - assertEquals(hash.toString(), ref, h); - final ByteBuffer copy = copyOf(buf, off, len); - final int h2 = hash.hash(copy, off, len, seed); - assertEquals(off, copy.position()); - assertEquals(len, copy.remaining()); - assertEquals(hash.toString(), ref, h2); - } - } - - @Test - public void test4GB() { - byte[] bytes = new byte[randomIntBetween(1 << 22, 1 << 26)]; - for (int i = 0; i < bytes.length; ++i) { - bytes[i] = randomByte(); - } - final int off = randomInt(5); - final int len = randomIntBetween(bytes.length - off - 1024, bytes.length - off); - long totalLen = 0; - final int seed = randomInt(); - StreamingXXHash32 hash1 = XXHashFactory.nativeInstance().newStreamingHash32(seed); - StreamingXXHash32 hash2 = XXHashFactory.unsafeInstance().newStreamingHash32(seed); - StreamingXXHash32 hash3 = XXHashFactory.safeInstance().newStreamingHash32(seed); - while (totalLen < (1L << 33)) { - hash1.update(bytes, off, len); - hash2.update(bytes, off, len); - hash3.update(bytes, off, len); - assertEquals(hash2.toString() + " " + totalLen, hash1.getValue(), hash2.getValue()); - assertEquals(hash3.toString() + " " + totalLen, hash1.getValue(), hash3.getValue()); - totalLen += len; - } - } - - @Test - public void testClose() { - StreamingXXHash32 hash = XXHashFactory.nativeInstance().newStreamingHash32(randomInt()); - hash.close(); - hash.close(); - try { - hash.getValue(); - assertTrue(hash.toString(), false); - } catch (AssertionError e) { - // OK - } - try { - hash.update(null, 0, 0); - assertTrue(hash.toString(), false); - } catch (AssertionError e) { - // OK - } - try { - hash.reset(); - assertTrue(hash.toString(), false); - } catch (AssertionError e) { - // OK - } - } -} diff --git a/src/test/net/jpountz/xxhash/XXHash64Test.java b/src/test/net/jpountz/xxhash/XXHash64Test.java deleted file mode 100644 index dadbeda..0000000 --- a/src/test/net/jpountz/xxhash/XXHash64Test.java +++ /dev/null @@ -1,194 +0,0 @@ -package net.jpountz.xxhash; - -/* - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import java.nio.ByteBuffer; - -import net.jpountz.lz4.AbstractLZ4Test; -import net.jpountz.util.SafeUtils; - -import org.junit.Test; -import static org.junit.Assert.*; - -import com.carrotsearch.randomizedtesting.annotations.Repeat; - -public class XXHash64Test extends AbstractLZ4Test { - - private static abstract class StreamingXXHash64Adapter extends XXHash64 { - - protected abstract StreamingXXHash64 streamingHash(long seed); - - @Override - public long hash(byte[] buf, int off, int len, long seed) { - SafeUtils.checkRange(buf, off, len); - int originalOff = off; - int remainingPasses = randomInt(5); - StreamingXXHash64 h = streamingHash(seed); - final int end = off + len; - while (off < end) { - final int l = randomIntBetween(off, end) - off; - h.update(buf, off, l); - off += l; - if (remainingPasses > 0 && randomInt(5) == 0) { - h.reset(); - --remainingPasses; - off = originalOff; - } - if (randomBoolean()) { - h.getValue(); - } - } - return h.getValue(); - } - - @Override - public long hash(ByteBuffer buf, int off, int len, long seed) { - byte[] bytes = new byte[len]; - int originalPosition = buf.position(); - try { - buf.position(off); - buf.get(bytes, 0, len); - return hash(bytes, 0, len, seed); - } finally { - buf.position(originalPosition); - } - } - - public String toString() { - return streamingHash(0).toString(); - } - - } - - private static XXHash64[] INSTANCES = new XXHash64[] { - XXHashFactory.nativeInstance().hash64(), - XXHashFactory.unsafeInstance().hash64(), - XXHashFactory.safeInstance().hash64(), - new StreamingXXHash64Adapter() { - protected StreamingXXHash64 streamingHash(long seed) { - return XXHashFactory.nativeInstance().newStreamingHash64(seed); - } - }, - new StreamingXXHash64Adapter() { - protected StreamingXXHash64 streamingHash(long seed) { - return XXHashFactory.unsafeInstance().newStreamingHash64(seed); - } - }, - new StreamingXXHash64Adapter() { - protected StreamingXXHash64 streamingHash(long seed) { - return XXHashFactory.safeInstance().newStreamingHash64(seed); - } - } - }; - - @Test - public void testEmpty() { - final long seed = randomLong(); - for (XXHash64 xxHash : INSTANCES) { - xxHash.hash(new byte[0], 0, 0, seed); - xxHash.hash(copyOf(new byte[0], 0, 0), 0, 0, seed); - } - } - - @Test - @Repeat(iterations = 20) - public void testAIOOBE() { - final long seed = randomLong(); - final int max = randomBoolean() ? 64 : 1000; - final int bufLen = randomIntBetween(1, max); - final byte[] buf = new byte[bufLen]; - for (int i = 0; i < buf.length; ++i) { - buf[i] = randomByte(); - } - final int off = randomInt(buf.length - 1); - final int len = randomInt(buf.length - off); - for (XXHash64 xxHash : INSTANCES) { - xxHash.hash(buf, off, len, seed); - } - } - - @Test - @Repeat(iterations=40) - public void testInstances() { - final int maxLenLog = randomInt(20); - final int bufLen = randomInt(1 << maxLenLog); - byte[] buf = new byte[bufLen]; - for (int i = 0; i < bufLen; ++i) { - buf[i] = randomByte(); - } - final long seed = randomLong(); - final int off = randomIntBetween(0, Math.max(0, bufLen - 1)); - final int len = randomIntBetween(0, bufLen - off); - - final long ref = XXHashFactory.nativeInstance().hash64().hash(buf, off, len, seed); - for (XXHash64 hash : INSTANCES) { - final long h = hash.hash(buf, off, len, seed); - assertEquals(hash.toString(), ref, h); - final ByteBuffer copy = copyOf(buf, off, len); - final long h2 = hash.hash(copy, off, len, seed); - assertEquals(off, copy.position()); - assertEquals(len, copy.remaining()); - assertEquals(hash.toString(), ref, h2); - } - } - - @Test - public void test4GB() { - byte[] bytes = new byte[randomIntBetween(1 << 22, 1 << 26)]; - for (int i = 0; i < bytes.length; ++i) { - bytes[i] = randomByte(); - } - final int off = randomInt(5); - final int len = randomIntBetween(bytes.length - off - 1024, bytes.length - off); - long totalLen = 0; - final long seed = randomLong(); - StreamingXXHash64 hash1 = XXHashFactory.nativeInstance().newStreamingHash64(seed); - StreamingXXHash64 hash2 = XXHashFactory.unsafeInstance().newStreamingHash64(seed); - StreamingXXHash64 hash3 = XXHashFactory.safeInstance().newStreamingHash64(seed); - while (totalLen < (1L << 33)) { - hash1.update(bytes, off, len); - hash2.update(bytes, off, len); - hash3.update(bytes, off, len); - assertEquals(hash2.toString() + " " + totalLen, hash1.getValue(), hash2.getValue()); - assertEquals(hash3.toString() + " " + totalLen, hash1.getValue(), hash3.getValue()); - totalLen += len; - } - } - - @Test - public void testClose() { - StreamingXXHash64 hash = XXHashFactory.nativeInstance().newStreamingHash64(randomInt()); - hash.close(); - hash.close(); - try { - hash.getValue(); - assertTrue(hash.toString(), false); - } catch (AssertionError e) { - // OK - } - try { - hash.update(null, 0, 0); - assertTrue(hash.toString(), false); - } catch (AssertionError e) { - // OK - } - try { - hash.reset(); - assertTrue(hash.toString(), false); - } catch (AssertionError e) { - // OK - } - } -}