From 99cf6f0732d5b8cbe9ab3dd53a73ffac2870c556 Mon Sep 17 00:00:00 2001 From: Idel Pivnitskiy Date: Wed, 23 Jul 2014 18:58:27 +0400 Subject: [PATCH] Refactor integration tests of compression codecs Motivation: Duplicated code of integration tests for different compression codecs. Modifications: - Added abstract class IntegrationTest which contains common tests for any compression codec. - Removed common tests from Bzip2IntegrationTest and LzfIntegrationTest. - Implemented abstract methods of IntegrationTest in Bzip2IntegrationTest, LzfIntegrationTest and SnappyIntegrationTest. Result: Removed duplicated code of integration tests for compression codecs and simplified an addition of integration tests for new compression codecs. --- .../compression/Bzip2IntegrationTest.java | 139 +-------------- .../codec/compression/IntegrationTest.java | 162 ++++++++++++++++++ .../codec/compression/LzfIntegrationTest.java | 139 +-------------- .../compression/SnappyIntegrationTest.java | 86 ++-------- 4 files changed, 191 insertions(+), 335 deletions(-) create mode 100644 codec/src/test/java/io/netty/handler/codec/compression/IntegrationTest.java diff --git a/codec/src/test/java/io/netty/handler/codec/compression/Bzip2IntegrationTest.java b/codec/src/test/java/io/netty/handler/codec/compression/Bzip2IntegrationTest.java index 83df45f450..1485f94df3 100644 --- a/codec/src/test/java/io/netty/handler/codec/compression/Bzip2IntegrationTest.java +++ b/codec/src/test/java/io/netty/handler/codec/compression/Bzip2IntegrationTest.java @@ -15,45 +15,19 @@ */ package io.netty.handler.codec.compression; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.CompositeByteBuf; -import io.netty.buffer.Unpooled; import io.netty.channel.embedded.EmbeddedChannel; -import io.netty.util.ReferenceCountUtil; -import io.netty.util.internal.ThreadLocalRandom; import org.junit.Test; -import java.util.Arrays; +public class Bzip2IntegrationTest extends IntegrationTest { -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.*; - -public class Bzip2IntegrationTest { - - private static final ThreadLocalRandom rand = ThreadLocalRandom.current(); - - public static final byte[] EMPTY = new byte[0]; - - @Test - public void testEmpty() throws Exception { - testIdentity(EMPTY); + @Override + protected EmbeddedChannel createEncoderEmbeddedChannel() { + return new EmbeddedChannel(new Bzip2Encoder()); } - @Test - public void testOneByte() throws Exception { - testIdentity(new byte[] { 'A' }); - } - - @Test - public void testTwoBytes() throws Exception { - testIdentity(new byte[] { 'B', 'A' }); - } - - @Test - public void testRegular() throws Exception { - byte[] data = ("Netty is a NIO client server framework which enables quick and easy development " + - "of network applications such as protocol servers and clients.").getBytes(); - testIdentity(data); + @Override + protected EmbeddedChannel createDecoderEmbeddedChannel() { + return new EmbeddedChannel(new Bzip2Decoder()); } @Test @@ -76,103 +50,4 @@ public class Bzip2IntegrationTest { rand.nextBytes(data); testIdentity(data); } - - @Test - public void testLargeRandom() throws Exception { - byte[] data = new byte[1048576]; - rand.nextBytes(data); - testIdentity(data); - } - - @Test - public void testPartRandom() throws Exception { - byte[] data = new byte[12345]; - rand.nextBytes(data); - for (int i = 0; i < 1024; i++) { - data[i] = 123; - } - testIdentity(data); - } - - @Test - public void testCompressible() throws Exception { - byte[] data = new byte[10000]; - for (int i = 0; i < data.length; i++) { - data[i] = i % 4 != 0 ? 0 : (byte) rand.nextInt(); - } - testIdentity(data); - } - - @Test - public void testLongBlank() throws Exception { - byte[] data = new byte[100000]; - testIdentity(data); - } - - @Test - public void testLongSame() throws Exception { - byte[] data = new byte[100000]; - Arrays.fill(data, (byte) 123); - testIdentity(data); - } - - @Test - public void testSequential() throws Exception { - byte[] data = new byte[49]; - for (int i = 0; i < data.length; i++) { - data[i] = (byte) i; - } - testIdentity(data); - } - - private static void testIdentity(byte[] data) { - ByteBuf in = Unpooled.wrappedBuffer(data); - EmbeddedChannel encoder = new EmbeddedChannel(new Bzip2Encoder()); - EmbeddedChannel decoder = new EmbeddedChannel(new Bzip2Decoder()); - try { - ByteBuf msg; - - encoder.writeOutbound(in.copy()); - encoder.finish(); - CompositeByteBuf compressed = Unpooled.compositeBuffer(); - while ((msg = encoder.readOutbound()) != null) { - compressed.addComponent(msg); - compressed.writerIndex(compressed.writerIndex() + msg.readableBytes()); - } - assertThat(compressed, is(notNullValue())); - assertThat(compressed, is(not(in))); - - decoder.writeInbound(compressed.retain()); - assertFalse(compressed.isReadable()); - CompositeByteBuf decompressed = Unpooled.compositeBuffer(); - while ((msg = decoder.readInbound()) != null) { - decompressed.addComponent(msg); - decompressed.writerIndex(decompressed.writerIndex() + msg.readableBytes()); - } - assertEquals(in, decompressed); - - compressed.release(); - decompressed.release(); - in.release(); - } finally { - encoder.close(); - decoder.close(); - - for (;;) { - Object msg = encoder.readOutbound(); - if (msg == null) { - break; - } - ReferenceCountUtil.release(msg); - } - - for (;;) { - Object msg = decoder.readInbound(); - if (msg == null) { - break; - } - ReferenceCountUtil.release(msg); - } - } - } } diff --git a/codec/src/test/java/io/netty/handler/codec/compression/IntegrationTest.java b/codec/src/test/java/io/netty/handler/codec/compression/IntegrationTest.java new file mode 100644 index 0000000000..cf17f18971 --- /dev/null +++ b/codec/src/test/java/io/netty/handler/codec/compression/IntegrationTest.java @@ -0,0 +1,162 @@ +/* + * Copyright 2014 The Netty Project + * + * The Netty Project licenses this file to you 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. + */ +package io.netty.handler.codec.compression; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.CompositeByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.embedded.EmbeddedChannel; +import io.netty.util.CharsetUtil; +import io.netty.util.ReferenceCountUtil; +import io.netty.util.internal.EmptyArrays; +import io.netty.util.internal.ThreadLocalRandom; +import org.junit.Test; + +import java.util.Arrays; + +import static org.hamcrest.Matchers.*; +import static org.junit.Assert.*; + +public abstract class IntegrationTest { + + protected static final ThreadLocalRandom rand = ThreadLocalRandom.current(); + + protected abstract EmbeddedChannel createEncoderEmbeddedChannel(); + protected abstract EmbeddedChannel createDecoderEmbeddedChannel(); + + @Test + public void testEmpty() throws Exception { + testIdentity(EmptyArrays.EMPTY_BYTES); + } + + @Test + public void testOneByte() throws Exception { + final byte[] data = { 'A' }; + testIdentity(data); + } + + @Test + public void testTwoBytes() throws Exception { + final byte[] data = { 'B', 'A' }; + testIdentity(data); + } + + @Test + public void testRegular() throws Exception { + final byte[] data = ("Netty is a NIO client server framework which enables " + + "quick and easy development of network applications such as protocol " + + "servers and clients.").getBytes(CharsetUtil.UTF_8); + testIdentity(data); + } + + @Test + public void testLargeRandom() throws Exception { + final byte[] data = new byte[1024 * 1024]; + rand.nextBytes(data); + testIdentity(data); + } + + @Test + public void testPartRandom() throws Exception { + final byte[] data = new byte[10240]; + rand.nextBytes(data); + for (int i = 0; i < 1024; i++) { + data[i] = 2; + } + testIdentity(data); + } + + @Test + public void testCompressible() throws Exception { + final byte[] data = new byte[10240]; + for (int i = 0; i < data.length; i++) { + data[i] = i % 4 != 0 ? 0 : (byte) rand.nextInt(); + } + testIdentity(data); + } + + @Test + public void testLongBlank() throws Exception { + final byte[] data = new byte[102400]; + testIdentity(data); + } + + @Test + public void testLongSame() throws Exception { + final byte[] data = new byte[102400]; + Arrays.fill(data, (byte) 123); + testIdentity(data); + } + + @Test + public void testSequential() throws Exception { + final byte[] data = new byte[1024]; + for (int i = 0; i < data.length; i++) { + data[i] = (byte) i; + } + testIdentity(data); + } + + protected void testIdentity(final byte[] data) { + final ByteBuf in = Unpooled.wrappedBuffer(data); + final EmbeddedChannel encoder = createEncoderEmbeddedChannel(); + final EmbeddedChannel decoder = createDecoderEmbeddedChannel(); + try { + ByteBuf msg; + + encoder.writeOutbound(in.copy()); + encoder.finish(); + final CompositeByteBuf compressed = Unpooled.compositeBuffer(); + while ((msg = encoder.readOutbound()) != null) { + compressed.addComponent(msg); + compressed.writerIndex(compressed.writerIndex() + msg.readableBytes()); + } + assertThat(compressed, is(notNullValue())); + + decoder.writeInbound(compressed.retain()); + assertFalse(compressed.isReadable()); + final CompositeByteBuf decompressed = Unpooled.compositeBuffer(); + while ((msg = decoder.readInbound()) != null) { + decompressed.addComponent(msg); + decompressed.writerIndex(decompressed.writerIndex() + msg.readableBytes()); + } + assertEquals(in, decompressed); + + compressed.release(); + decompressed.release(); + in.release(); + } finally { + encoder.close(); + decoder.close(); + + for (;;) { + Object msg = encoder.readOutbound(); + if (msg == null) { + break; + } + ReferenceCountUtil.release(msg); + } + + for (;;) { + Object msg = decoder.readInbound(); + if (msg == null) { + break; + } + ReferenceCountUtil.release(msg); + } + } + } +} diff --git a/codec/src/test/java/io/netty/handler/codec/compression/LzfIntegrationTest.java b/codec/src/test/java/io/netty/handler/codec/compression/LzfIntegrationTest.java index a4f8fd1e71..4904d46e4b 100644 --- a/codec/src/test/java/io/netty/handler/codec/compression/LzfIntegrationTest.java +++ b/codec/src/test/java/io/netty/handler/codec/compression/LzfIntegrationTest.java @@ -15,142 +15,17 @@ */ package io.netty.handler.codec.compression; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.CompositeByteBuf; -import io.netty.buffer.Unpooled; import io.netty.channel.embedded.EmbeddedChannel; -import io.netty.util.ReferenceCountUtil; -import io.netty.util.internal.ThreadLocalRandom; -import org.junit.Test; -import java.util.Arrays; +public class LzfIntegrationTest extends IntegrationTest { -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.*; - -public class LzfIntegrationTest { - - private static final ThreadLocalRandom rand = ThreadLocalRandom.current(); - - public static final byte[] EMPTY = new byte[0]; - - @Test - public void testEmpty() throws Exception { - testIdentity(EMPTY); + @Override + protected EmbeddedChannel createEncoderEmbeddedChannel() { + return new EmbeddedChannel(new LzfEncoder()); } - @Test - public void testOneByte() throws Exception { - testIdentity(new byte[] { 'A' }); - } - - @Test - public void testTwoBytes() throws Exception { - testIdentity(new byte[] { 'B', 'A' }); - } - - @Test - public void testRegular() throws Exception { - byte[] data = ("Netty is a NIO client server framework which enables quick and easy development " + - "of network applications such as protocol servers and clients.").getBytes(); - testIdentity(data); - } - - @Test - public void testLargeRandom() throws Exception { - byte[] data = new byte[1048576]; - rand.nextBytes(data); - testIdentity(data); - } - - @Test - public void testPartRandom() throws Exception { - byte[] data = new byte[12345]; - rand.nextBytes(data); - for (int i = 0; i < 1024; i++) { - data[i] = 123; - } - testIdentity(data); - } - - @Test - public void testCompressible() throws Exception { - byte[] data = new byte[10000]; - for (int i = 0; i < data.length; i++) { - data[i] = i % 4 != 0 ? 0 : (byte) rand.nextInt(); - } - testIdentity(data); - } - - @Test - public void testLongBlank() throws Exception { - byte[] data = new byte[100000]; - testIdentity(data); - } - - @Test - public void testLongSame() throws Exception { - byte[] data = new byte[100000]; - Arrays.fill(data, (byte) 123); - testIdentity(data); - } - - @Test - public void testSequential() throws Exception { - byte[] data = new byte[49]; - for (int i = 0; i < data.length; i++) { - data[i] = (byte) i; - } - testIdentity(data); - } - - private static void testIdentity(byte[] data) { - ByteBuf in = Unpooled.wrappedBuffer(data); - EmbeddedChannel encoder = new EmbeddedChannel(new LzfEncoder()); - EmbeddedChannel decoder = new EmbeddedChannel(new LzfDecoder()); - try { - ByteBuf msg; - - encoder.writeOutbound(in.copy()); - encoder.finish(); - CompositeByteBuf compressed = Unpooled.compositeBuffer(); - while ((msg = encoder.readOutbound()) != null) { - compressed.addComponent(msg); - compressed.writerIndex(compressed.writerIndex() + msg.readableBytes()); - } - assertThat(compressed, is(notNullValue())); - - decoder.writeInbound(compressed.retain()); - assertFalse(compressed.isReadable()); - CompositeByteBuf decompressed = Unpooled.compositeBuffer(); - while ((msg = decoder.readInbound()) != null) { - decompressed.addComponent(msg); - decompressed.writerIndex(decompressed.writerIndex() + msg.readableBytes()); - } - assertEquals(in, decompressed); - - compressed.release(); - decompressed.release(); - in.release(); - } finally { - encoder.close(); - decoder.close(); - - for (;;) { - Object msg = encoder.readOutbound(); - if (msg == null) { - break; - } - ReferenceCountUtil.release(msg); - } - - for (;;) { - Object msg = decoder.readInbound(); - if (msg == null) { - break; - } - ReferenceCountUtil.release(msg); - } - } + @Override + protected EmbeddedChannel createDecoderEmbeddedChannel() { + return new EmbeddedChannel(new LzfDecoder()); } } diff --git a/codec/src/test/java/io/netty/handler/codec/compression/SnappyIntegrationTest.java b/codec/src/test/java/io/netty/handler/codec/compression/SnappyIntegrationTest.java index 565215b381..6e6852ae0e 100644 --- a/codec/src/test/java/io/netty/handler/codec/compression/SnappyIntegrationTest.java +++ b/codec/src/test/java/io/netty/handler/codec/compression/SnappyIntegrationTest.java @@ -15,20 +15,12 @@ */ package io.netty.handler.codec.compression; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.CompositeByteBuf; import io.netty.channel.embedded.EmbeddedChannel; -import io.netty.util.CharsetUtil; -import io.netty.util.ReferenceCountUtil; import org.junit.Test; import java.util.Random; -import static io.netty.buffer.Unpooled.*; -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.*; - -public class SnappyIntegrationTest { +public class SnappyIntegrationTest extends IntegrationTest { /** * The number of random regression tests run by testRandom() runs. Whenever testRandom() finds the case that @@ -39,18 +31,20 @@ public class SnappyIntegrationTest { **/ private static final int RANDOM_RUNS = 1; - @Test - public void testText() throws Exception { - testIdentity(copiedBuffer( - "Netty has been designed carefully with the experiences earned from the implementation of a lot of " + - "protocols such as FTP, SMTP, HTTP, and various binary and text-based legacy protocols", - CharsetUtil.US_ASCII)); + @Override + protected EmbeddedChannel createEncoderEmbeddedChannel() { + return new EmbeddedChannel(new SnappyFramedEncoder()); + } + + @Override + protected EmbeddedChannel createDecoderEmbeddedChannel() { + return new EmbeddedChannel(new SnappyFramedDecoder()); } @Test public void test1002() throws Throwable { // Data from https://github.com/netty/netty/issues/1002 - testIdentity(wrappedBuffer(new byte[] { + final byte[] data = { 11, 0, 0, 0, 0, 0, 16, 65, 96, 119, -22, 79, -43, 76, -75, -93, 11, 104, 96, -99, 126, -98, 27, -36, 40, 117, -65, -3, -57, -83, -58, 7, 114, -14, 68, -122, 124, 88, 118, 54, 45, -26, 117, 13, -45, -9, 60, -73, @@ -69,7 +63,8 @@ public class SnappyIntegrationTest { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 - })); + }; + testIdentity(data); } // These tests were found using testRandom() with large RANDOM_RUNS. @@ -89,9 +84,8 @@ public class SnappyIntegrationTest { @Test public void testRandom() throws Throwable { - Random rnd = new Random(); for (int i = 0; i < RANDOM_RUNS; i++) { - long seed = rnd.nextLong(); + long seed = rand.nextLong(); if (seed < 0) { // Use only positive seed to get prettier test name. :-) continue; @@ -102,67 +96,17 @@ public class SnappyIntegrationTest { } catch (Throwable t) { System.out.println("Failed with random seed " + seed + ". Here is a test for it:\n"); printSeedAsTest(seed); - //throw t; + throw t; } } } - private static void testWithSeed(long seed) { + private void testWithSeed(long seed) { byte[] data = new byte[16 * 1048576]; new Random(seed).nextBytes(data); testIdentity(data); } - private static void testIdentity(byte[] data) { - testIdentity(wrappedBuffer(data)); - } - - private static void testIdentity(ByteBuf in) { - EmbeddedChannel encoder = new EmbeddedChannel(new SnappyFramedEncoder()); - EmbeddedChannel decoder = new EmbeddedChannel(new SnappyFramedDecoder()); - try { - encoder.writeOutbound(in.copy()); - ByteBuf compressed = encoder.readOutbound(); - assertThat(compressed, is(notNullValue())); - assertThat(compressed, is(not(in))); - decoder.writeInbound(compressed.retain()); - assertFalse(compressed.isReadable()); - compressed.release(); - CompositeByteBuf decompressed = compositeBuffer(); - for (;;) { - Object o = decoder.readInbound(); - if (o == null) { - break; - } - decompressed.addComponent((ByteBuf) o); - decompressed.writerIndex(decompressed.writerIndex() + ((ByteBuf) o).readableBytes()); - } - assertEquals(in, decompressed); - decompressed.release(); - in.release(); - } finally { - // Avoids memory leak through AbstractChannel.allChannels - encoder.close(); - decoder.close(); - - for (;;) { - Object msg = encoder.readOutbound(); - if (msg == null) { - break; - } - ReferenceCountUtil.release(msg); - } - - for (;;) { - Object msg = decoder.readInbound(); - if (msg == null) { - break; - } - ReferenceCountUtil.release(msg); - } - } - } - private static void printSeedAsTest(long l) { System.out.println("@Test"); System.out.println("@Ignore");