1 package org.brotli.wrapper.enc; 2 3 import static org.junit.Assert.assertEquals; 4 5 import org.brotli.integration.BundleHelper; 6 import org.brotli.wrapper.dec.BrotliInputStream; 7 import java.io.ByteArrayInputStream; 8 import java.io.ByteArrayOutputStream; 9 import java.io.FileInputStream; 10 import java.io.IOException; 11 import java.io.InputStream; 12 import java.nio.ByteBuffer; 13 import java.nio.channels.Channels; 14 import java.nio.channels.WritableByteChannel; 15 import java.util.List; 16 import junit.framework.TestCase; 17 import junit.framework.TestSuite; 18 import org.junit.runner.RunWith; 19 import org.junit.runners.AllTests; 20 21 /** Tests for {@link org.brotli.wrapper.enc.BrotliEncoderChannel}. */ 22 @RunWith(AllTests.class) 23 public class BrotliEncoderChannelTest { 24 25 private enum TestMode { 26 WRITE_ALL, 27 WRITE_CHUNKS 28 } 29 30 // TODO: remove when Bazel get JNI support. 31 static { 32 System.load(new java.io.File(new java.io.File(System.getProperty("java.library.path")), 33 "liblibjni.so").getAbsolutePath()); 34 } 35 36 private static final int CHUNK_SIZE = 256; 37 38 static InputStream getBundle() throws IOException { 39 return new FileInputStream(System.getProperty("TEST_BUNDLE")); 40 } 41 42 /** Creates a test suite. */ 43 public static TestSuite suite() throws IOException { 44 TestSuite suite = new TestSuite(); 45 InputStream bundle = getBundle(); 46 try { 47 List<String> entries = BundleHelper.listEntries(bundle); 48 for (String entry : entries) { 49 suite.addTest(new ChannleTestCase(entry, TestMode.WRITE_ALL)); 50 suite.addTest(new ChannleTestCase(entry, TestMode.WRITE_CHUNKS)); 51 } 52 } finally { 53 bundle.close(); 54 } 55 return suite; 56 } 57 58 /** Test case with a unique name. */ 59 static class ChannleTestCase extends TestCase { 60 final String entryName; 61 final TestMode mode; 62 ChannleTestCase(String entryName, TestMode mode) { 63 super("BrotliEncoderChannelTest." + entryName + "." + mode.name()); 64 this.entryName = entryName; 65 this.mode = mode; 66 } 67 68 @Override 69 protected void runTest() throws Throwable { 70 BrotliEncoderChannelTest.run(entryName, mode); 71 } 72 } 73 74 private static void run(String entryName, TestMode mode) throws Throwable { 75 InputStream bundle = getBundle(); 76 byte[] original; 77 try { 78 original = BundleHelper.readEntry(bundle, entryName); 79 } finally { 80 bundle.close(); 81 } 82 if (original == null) { 83 throw new RuntimeException("Can't read bundle entry: " + entryName); 84 } 85 86 if ((mode == TestMode.WRITE_CHUNKS) && (original.length <= CHUNK_SIZE)) { 87 return; 88 } 89 90 ByteArrayOutputStream dst = new ByteArrayOutputStream(); 91 WritableByteChannel encoder = new BrotliEncoderChannel(Channels.newChannel(dst)); 92 ByteBuffer src = ByteBuffer.wrap(original); 93 try { 94 switch (mode) { 95 case WRITE_ALL: 96 encoder.write(src); 97 break; 98 99 case WRITE_CHUNKS: 100 while (src.hasRemaining()) { 101 int limit = Math.min(CHUNK_SIZE, src.remaining()); 102 ByteBuffer slice = src.slice(); 103 slice.limit(limit); 104 src.position(src.position() + limit); 105 encoder.write(slice); 106 } 107 break; 108 } 109 } finally { 110 encoder.close(); 111 } 112 113 InputStream decoder = new BrotliInputStream(new ByteArrayInputStream(dst.toByteArray())); 114 try { 115 long originalCrc = BundleHelper.fingerprintStream(new ByteArrayInputStream(original)); 116 long crc = BundleHelper.fingerprintStream(decoder); 117 assertEquals(originalCrc, crc); 118 } finally { 119 decoder.close(); 120 } 121 } 122 } 123