From b4bf662b3ea6922f694c1b0a04cbdd4db3c784ff Mon Sep 17 00:00:00 2001 From: akwizgran <akwizgran@users.sourceforge.net> Date: Thu, 21 Jul 2011 10:58:42 +0100 Subject: [PATCH] Unit tests for HeaderReader. --- .../net/sf/briar/protocol/HeaderReader.java | 5 +- test/build.xml | 1 + .../sf/briar/protocol/BatchReaderTest.java | 4 + .../sf/briar/protocol/HeaderReaderTest.java | 165 ++++++++++++++++++ 4 files changed, 173 insertions(+), 2 deletions(-) create mode 100644 test/net/sf/briar/protocol/HeaderReaderTest.java diff --git a/components/net/sf/briar/protocol/HeaderReader.java b/components/net/sf/briar/protocol/HeaderReader.java index 7db1158300..e42db8d03f 100644 --- a/components/net/sf/briar/protocol/HeaderReader.java +++ b/components/net/sf/briar/protocol/HeaderReader.java @@ -23,8 +23,9 @@ class HeaderReader implements ObjectReader<Header> { public Header readObject(Reader reader) throws IOException, GeneralSecurityException { - // Initialise and add the consumer - CountingConsumer counting = new CountingConsumer(Header.MAX_SIZE); + // Initialise and add the consumer - the initial tag has already been + // read, so subtract one from the maximum size + CountingConsumer counting = new CountingConsumer(Header.MAX_SIZE - 1); reader.addConsumer(counting); // Acks reader.addObjectReader(Tags.BATCH_ID, new BatchIdReader()); diff --git a/test/build.xml b/test/build.xml index 48d81ca5ad..c39f9726cc 100644 --- a/test/build.xml +++ b/test/build.xml @@ -24,6 +24,7 @@ <test name='net.sf.briar.protocol.BundleReaderImplTest'/> <test name='net.sf.briar.protocol.BundleReadWriteTest'/> <test name='net.sf.briar.protocol.ConsumersTest'/> + <test name='net.sf.briar.protocol.HeaderReaderTest'/> <test name='net.sf.briar.protocol.SigningDigestingOutputStreamTest'/> <test name='net.sf.briar.serial.ReaderImplTest'/> <test name='net.sf.briar.serial.WriterImplTest'/> diff --git a/test/net/sf/briar/protocol/BatchReaderTest.java b/test/net/sf/briar/protocol/BatchReaderTest.java index 1b56ab9ec2..9c93620c65 100644 --- a/test/net/sf/briar/protocol/BatchReaderTest.java +++ b/test/net/sf/briar/protocol/BatchReaderTest.java @@ -70,6 +70,7 @@ public class BatchReaderTest extends TestCase { reader.readUserDefinedObject(Tags.BATCH, Batch.class); assertTrue(false); } catch(FormatException expected) {} + context.assertIsSatisfied(); } @Test @@ -93,6 +94,7 @@ public class BatchReaderTest extends TestCase { reader.readUserDefinedTag(Tags.BATCH); assertEquals(batch, reader.readUserDefinedObject(Tags.BATCH, Batch.class)); + context.assertIsSatisfied(); } @Test @@ -122,6 +124,7 @@ public class BatchReaderTest extends TestCase { reader.readUserDefinedTag(Tags.BATCH); assertEquals(batch, reader.readUserDefinedObject(Tags.BATCH, Batch.class)); + context.assertIsSatisfied(); } @Test @@ -145,6 +148,7 @@ public class BatchReaderTest extends TestCase { reader.readUserDefinedTag(Tags.BATCH); assertEquals(batch, reader.readUserDefinedObject(Tags.BATCH, Batch.class)); + context.assertIsSatisfied(); } private byte[] createBatch(int size) throws Exception { diff --git a/test/net/sf/briar/protocol/HeaderReaderTest.java b/test/net/sf/briar/protocol/HeaderReaderTest.java new file mode 100644 index 0000000000..329e422449 --- /dev/null +++ b/test/net/sf/briar/protocol/HeaderReaderTest.java @@ -0,0 +1,165 @@ +package net.sf.briar.protocol; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.util.Collection; +import java.util.Collections; +import java.util.Map; +import java.util.Random; + +import junit.framework.TestCase; +import net.sf.briar.api.protocol.BatchId; +import net.sf.briar.api.protocol.GroupId; +import net.sf.briar.api.protocol.Header; +import net.sf.briar.api.protocol.Tags; +import net.sf.briar.api.protocol.UniqueId; +import net.sf.briar.api.serial.FormatException; +import net.sf.briar.api.serial.Reader; +import net.sf.briar.api.serial.ReaderFactory; +import net.sf.briar.api.serial.Writer; +import net.sf.briar.api.serial.WriterFactory; +import net.sf.briar.serial.SerialModule; + +import org.jmock.Expectations; +import org.jmock.Mockery; +import org.junit.Test; + +import com.google.inject.Guice; +import com.google.inject.Injector; + +public class HeaderReaderTest extends TestCase { + + private final ReaderFactory readerFactory; + private final WriterFactory writerFactory; + private final Mockery context; + + public HeaderReaderTest() throws Exception { + super(); + Injector i = Guice.createInjector(new SerialModule()); + readerFactory = i.getInstance(ReaderFactory.class); + writerFactory = i.getInstance(WriterFactory.class); + context = new Mockery(); + } + + @Test + public void testFormatExceptionIfHeaderIsTooLarge() throws Exception { + HeaderFactory headerFactory = context.mock(HeaderFactory.class); + HeaderReader headerReader = new HeaderReader(headerFactory); + + byte[] b = createHeader(Header.MAX_SIZE + 1); + ByteArrayInputStream in = new ByteArrayInputStream(b); + Reader reader = readerFactory.createReader(in); + reader.addObjectReader(Tags.HEADER, headerReader); + + reader.readUserDefinedTag(Tags.HEADER); + try { + reader.readUserDefinedObject(Tags.HEADER, Header.class); + assertTrue(false); + } catch(FormatException expected) {} + context.assertIsSatisfied(); + } + + @Test + @SuppressWarnings("unchecked") + public void testNoFormatExceptionIfHeaderIsMaximumSize() throws Exception { + final HeaderFactory headerFactory = context.mock(HeaderFactory.class); + HeaderReader headerReader = new HeaderReader(headerFactory); + final Header header = context.mock(Header.class); + context.checking(new Expectations() {{ + oneOf(headerFactory).createHeader( + with(Collections.<BatchId>emptyList()), + with(any(Collection.class)), with(any(Map.class)), + with(any(long.class))); + will(returnValue(header)); + }}); + + byte[] b = createHeader(Header.MAX_SIZE); + ByteArrayInputStream in = new ByteArrayInputStream(b); + Reader reader = readerFactory.createReader(in); + reader.addObjectReader(Tags.HEADER, headerReader); + + reader.readUserDefinedTag(Tags.HEADER); + assertEquals(header, reader.readUserDefinedObject(Tags.HEADER, + Header.class)); + context.assertIsSatisfied(); + } + + @Test + public void testEmptyHeader() throws Exception { + final HeaderFactory headerFactory = context.mock(HeaderFactory.class); + HeaderReader headerReader = new HeaderReader(headerFactory); + final Header header = context.mock(Header.class); + context.checking(new Expectations() {{ + oneOf(headerFactory).createHeader( + with(Collections.<BatchId>emptyList()), + with(Collections.<GroupId>emptyList()), + with(Collections.<String, String>emptyMap()), + with(any(long.class))); + will(returnValue(header)); + }}); + + byte[] b = createEmptyHeader(); + ByteArrayInputStream in = new ByteArrayInputStream(b); + Reader reader = readerFactory.createReader(in); + reader.addObjectReader(Tags.HEADER, headerReader); + + reader.readUserDefinedTag(Tags.HEADER); + assertEquals(header, reader.readUserDefinedObject(Tags.HEADER, + Header.class)); + context.assertIsSatisfied(); + } + + private byte[] createHeader(int size) throws Exception { + Random random = new Random(); + ByteArrayOutputStream out = new ByteArrayOutputStream(size); + Writer w = writerFactory.createWriter(out); + w.writeUserDefinedTag(Tags.HEADER); + // Acks + w.writeListStart(); + w.writeListEnd(); + // Subs + w.writeListStart(); + // Fill most of the header with subscriptions + while(w.getBytesWritten() < size - 45) { + w.writeUserDefinedTag(Tags.GROUP_ID); + byte[] b = new byte[UniqueId.LENGTH]; + random.nextBytes(b); + w.writeRaw(b); + } + w.writeListEnd(); + // Transports + w.writeMapStart(); + w.writeString("foo"); + // Build a string that will bring the header up to the expected size + int length = (int) (size - w.getBytesWritten() - 12); + StringBuilder s = new StringBuilder(); + for(int i = 0; i < length; i++) s.append((char) ('0' + i % 10)); + w.writeString(s.toString()); + w.writeMapEnd(); + // Timestamp + w.writeInt64(System.currentTimeMillis()); + w.close(); + byte[] b = out.toByteArray(); + assertEquals(size, b.length); + return b; + } + + private byte[] createEmptyHeader() throws Exception { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + Writer w = writerFactory.createWriter(out); + w.writeUserDefinedTag(Tags.HEADER); + // Acks + w.writeListStart(); + w.writeListEnd(); + // Subs + w.writeListStart(); + w.writeListEnd(); + // Transports + w.writeMapStart(); + w.writeMapEnd(); + // Timestamp + w.writeInt64(System.currentTimeMillis()); + w.close(); + return out.toByteArray(); + } +} -- GitLab