Moved the messaging protocol one step closer to BSP.

This breaks backward compatibility for the wire protocol and messages
stored in the database. The database schema version has been
incremented.
This commit is contained in:
akwizgran
2015-05-01 16:58:49 +01:00
parent ffcc8b6b38
commit 32c9ce50d9
33 changed files with 732 additions and 750 deletions

View File

@@ -9,7 +9,7 @@ import static org.briarproject.api.TransportPropertyConstants.MAX_TRANSPORT_ID_L
import static org.briarproject.api.messaging.MessagingConstants.MAX_BODY_LENGTH;
import static org.briarproject.api.messaging.MessagingConstants.MAX_CONTENT_TYPE_LENGTH;
import static org.briarproject.api.messaging.MessagingConstants.MAX_GROUP_NAME_LENGTH;
import static org.briarproject.api.messaging.MessagingConstants.MAX_PACKET_LENGTH;
import static org.briarproject.api.messaging.MessagingConstants.MAX_PAYLOAD_LENGTH;
import static org.briarproject.api.messaging.MessagingConstants.MAX_SUBSCRIPTIONS;
import java.io.ByteArrayOutputStream;
@@ -106,7 +106,7 @@ public class ConstantsTest extends BriarTestCase {
@Test
public void testMessageIdsFitIntoLargeAck() throws Exception {
testMessageIdsFitIntoAck(MAX_PACKET_LENGTH);
testMessageIdsFitIntoAck(MAX_PAYLOAD_LENGTH);
}
@Test
@@ -139,12 +139,12 @@ public class ConstantsTest extends BriarTestCase {
+ MAX_PUBLIC_KEY_LENGTH + MAX_AUTHOR_NAME_LENGTH
+ MAX_PUBLIC_KEY_LENGTH + MAX_CONTENT_TYPE_LENGTH
+ MAX_BODY_LENGTH);
assertTrue(length <= MAX_PACKET_LENGTH);
assertTrue(length <= MAX_PAYLOAD_LENGTH);
}
@Test
public void testMessageIdsFitIntoLargeOffer() throws Exception {
testMessageIdsFitIntoOffer(MAX_PACKET_LENGTH);
testMessageIdsFitIntoOffer(MAX_PAYLOAD_LENGTH);
}
@Test
@@ -154,7 +154,7 @@ public class ConstantsTest extends BriarTestCase {
@Test
public void testMessageIdsFitIntoLargeRequest() throws Exception {
testMessageIdsFitIntoRequest(MAX_PACKET_LENGTH);
testMessageIdsFitIntoRequest(MAX_PAYLOAD_LENGTH);
}
@Test
@@ -180,7 +180,7 @@ public class ConstantsTest extends BriarTestCase {
PacketWriter writer = packetWriterFactory.createPacketWriter(out);
writer.writeTransportUpdate(u);
// Check the size of the serialised transport update
assertTrue(out.size() <= MAX_PACKET_LENGTH);
assertTrue(out.size() <= MAX_PAYLOAD_LENGTH);
}
@Test
@@ -198,7 +198,7 @@ public class ConstantsTest extends BriarTestCase {
PacketWriter writer = packetWriterFactory.createPacketWriter(out);
writer.writeSubscriptionUpdate(u);
// Check the size of the serialised subscription update
assertTrue(out.size() <= MAX_PACKET_LENGTH);
assertTrue(out.size() <= MAX_PAYLOAD_LENGTH);
}
private void testMessageIdsFitIntoAck(int length) throws Exception {

View File

@@ -1,9 +1,10 @@
package org.briarproject.messaging;
import static org.briarproject.api.messaging.MessagingConstants.MAX_PACKET_LENGTH;
import static org.briarproject.api.messaging.Types.ACK;
import static org.briarproject.api.messaging.Types.OFFER;
import static org.briarproject.api.messaging.Types.REQUEST;
import static org.briarproject.api.messaging.MessagingConstants.HEADER_LENGTH;
import static org.briarproject.api.messaging.MessagingConstants.MAX_PAYLOAD_LENGTH;
import static org.briarproject.api.messaging.PacketTypes.ACK;
import static org.briarproject.api.messaging.PacketTypes.OFFER;
import static org.briarproject.api.messaging.PacketTypes.REQUEST;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -16,6 +17,7 @@ import org.briarproject.api.serial.SerialComponent;
import org.briarproject.api.serial.Writer;
import org.briarproject.api.serial.WriterFactory;
import org.briarproject.serial.SerialModule;
import org.briarproject.util.ByteUtils;
import org.junit.Test;
import com.google.inject.Guice;
@@ -137,85 +139,106 @@ public class PacketReaderImplTest extends BriarTestCase {
private byte[] createAck(boolean tooBig) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
out.write(new byte[HEADER_LENGTH]);
Writer w = writerFactory.createWriter(out);
w.writeStructStart(ACK);
w.writeListStart();
w.writeListStart();
while(out.size() + serial.getSerialisedUniqueIdLength()
+ serial.getSerialisedListEndLength()
+ serial.getSerialisedStructEndLength()
< MAX_PACKET_LENGTH) {
+ serial.getSerialisedListEndLength() * 2
< HEADER_LENGTH + MAX_PAYLOAD_LENGTH) {
w.writeBytes(TestUtils.getRandomId());
}
if(tooBig) w.writeBytes(TestUtils.getRandomId());
w.writeListEnd();
w.writeStructEnd();
assertEquals(tooBig, out.size() > MAX_PACKET_LENGTH);
return out.toByteArray();
w.writeListEnd();
assertEquals(tooBig, out.size() > HEADER_LENGTH + MAX_PAYLOAD_LENGTH);
byte[] packet = out.toByteArray();
packet[1] = ACK;
ByteUtils.writeUint16(packet.length - HEADER_LENGTH, packet, 2);
return packet;
}
private byte[] createEmptyAck() throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
out.write(new byte[HEADER_LENGTH]);
Writer w = writerFactory.createWriter(out);
w.writeStructStart(ACK);
w.writeListStart();
w.writeListStart();
w.writeListEnd();
w.writeStructEnd();
return out.toByteArray();
w.writeListEnd();
byte[] packet = out.toByteArray();
packet[1] = ACK;
ByteUtils.writeUint16(packet.length - HEADER_LENGTH, packet, 2);
return packet;
}
private byte[] createOffer(boolean tooBig) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
out.write(new byte[HEADER_LENGTH]);
Writer w = writerFactory.createWriter(out);
w.writeStructStart(OFFER);
w.writeListStart();
w.writeListStart();
while(out.size() + serial.getSerialisedUniqueIdLength()
+ serial.getSerialisedListEndLength()
+ serial.getSerialisedStructEndLength()
< MAX_PACKET_LENGTH) {
+ serial.getSerialisedListEndLength() * 2
< HEADER_LENGTH + MAX_PAYLOAD_LENGTH) {
w.writeBytes(TestUtils.getRandomId());
}
if(tooBig) w.writeBytes(TestUtils.getRandomId());
w.writeListEnd();
w.writeStructEnd();
assertEquals(tooBig, out.size() > MAX_PACKET_LENGTH);
return out.toByteArray();
w.writeListEnd();
assertEquals(tooBig, out.size() > HEADER_LENGTH + MAX_PAYLOAD_LENGTH);
byte[] packet = out.toByteArray();
packet[1] = OFFER;
ByteUtils.writeUint16(packet.length - HEADER_LENGTH, packet, 2);
return packet;
}
private byte[] createEmptyOffer() throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
out.write(new byte[HEADER_LENGTH]);
Writer w = writerFactory.createWriter(out);
w.writeStructStart(OFFER);
w.writeListStart();
w.writeListStart();
w.writeListEnd();
w.writeStructEnd();
return out.toByteArray();
w.writeListEnd();
byte[] packet = out.toByteArray();
packet[1] = OFFER;
ByteUtils.writeUint16(packet.length - HEADER_LENGTH, packet, 2);
return packet;
}
private byte[] createRequest(boolean tooBig) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
out.write(new byte[HEADER_LENGTH]);
Writer w = writerFactory.createWriter(out);
w.writeStructStart(REQUEST);
w.writeListStart();
w.writeListStart();
while(out.size() + serial.getSerialisedUniqueIdLength()
+ serial.getSerialisedListEndLength()
+ serial.getSerialisedStructEndLength()
< MAX_PACKET_LENGTH) {
+ serial.getSerialisedListEndLength() * 2
< HEADER_LENGTH + MAX_PAYLOAD_LENGTH) {
w.writeBytes(TestUtils.getRandomId());
}
if(tooBig) w.writeBytes(TestUtils.getRandomId());
w.writeListEnd();
w.writeStructEnd();
assertEquals(tooBig, out.size() > MAX_PACKET_LENGTH);
return out.toByteArray();
w.writeListEnd();
assertEquals(tooBig, out.size() > HEADER_LENGTH + MAX_PAYLOAD_LENGTH);
byte[] packet = out.toByteArray();
packet[1] = REQUEST;
ByteUtils.writeUint16(packet.length - HEADER_LENGTH, packet, 2);
return packet;
}
private byte[] createEmptyRequest() throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
out.write(new byte[HEADER_LENGTH]);
Writer w = writerFactory.createWriter(out);
w.writeStructStart(REQUEST);
w.writeListStart();
w.writeListStart();
w.writeListEnd();
w.writeStructEnd();
return out.toByteArray();
w.writeListEnd();
byte[] packet = out.toByteArray();
packet[1] = REQUEST;
ByteUtils.writeUint16(packet.length - HEADER_LENGTH, packet, 2);
return packet;
}
}

View File

@@ -15,9 +15,29 @@ public class ReaderImplTest extends BriarTestCase {
private ByteArrayInputStream in = null;
private ReaderImpl r = null;
@Test
public void testReadEmptyInput() throws Exception {
setContents("");
assertTrue(r.eof());
}
@Test
public void testReadNull() throws Exception {
setContents("00");
r.readNull();
assertTrue(r.eof());
}
@Test
public void testSkipNull() throws Exception {
setContents("00");
r.skipNull();
assertTrue(r.eof());
}
@Test
public void testReadBoolean() throws Exception {
setContents("00" + "01");
setContents("11" + "00" + "11" + "01");
assertFalse(r.readBoolean());
assertTrue(r.readBoolean());
assertTrue(r.eof());
@@ -25,7 +45,7 @@ public class ReaderImplTest extends BriarTestCase {
@Test
public void testSkipBoolean() throws Exception {
setContents("00" + "01");
setContents("11" + "00" + "11" + "01");
r.skipBoolean();
r.skipBoolean();
assertTrue(r.eof());
@@ -33,8 +53,8 @@ public class ReaderImplTest extends BriarTestCase {
@Test
public void testReadInt8() throws Exception {
setContents("02" + "00" + "02" + "FF"
+ "02" + "7F" + "02" + "80");
setContents("21" + "00" + "21" + "FF"
+ "21" + "7F" + "21" + "80");
assertEquals(0, r.readInteger());
assertEquals(-1, r.readInteger());
assertEquals(Byte.MAX_VALUE, r.readInteger());
@@ -44,15 +64,15 @@ public class ReaderImplTest extends BriarTestCase {
@Test
public void testSkipInt8() throws Exception {
setContents("02" + "00");
setContents("21" + "00");
r.skipInteger();
assertTrue(r.eof());
}
@Test
public void testReadInt16() throws Exception {
setContents("03" + "0080" + "03" + "FF7F"
+ "03" + "7FFF" + "03" + "8000");
setContents("22" + "0080" + "22" + "FF7F"
+ "22" + "7FFF" + "22" + "8000");
assertEquals(Byte.MAX_VALUE + 1, r.readInteger());
assertEquals(Byte.MIN_VALUE - 1, r.readInteger());
assertEquals(Short.MAX_VALUE, r.readInteger());
@@ -62,15 +82,15 @@ public class ReaderImplTest extends BriarTestCase {
@Test
public void testSkipInt16() throws Exception {
setContents("03" + "0080");
setContents("22" + "0080");
r.skipInteger();
assertTrue(r.eof());
}
@Test
public void testReadInt32() throws Exception {
setContents("04" + "00008000" + "04" + "FFFF7FFF"
+ "04" + "7FFFFFFF" + "04" + "80000000");
setContents("24" + "00008000" + "24" + "FFFF7FFF"
+ "24" + "7FFFFFFF" + "24" + "80000000");
assertEquals(Short.MAX_VALUE + 1, r.readInteger());
assertEquals(Short.MIN_VALUE - 1, r.readInteger());
assertEquals(Integer.MAX_VALUE, r.readInteger());
@@ -80,15 +100,15 @@ public class ReaderImplTest extends BriarTestCase {
@Test
public void testSkipInt32() throws Exception {
setContents("04" + "00008000");
setContents("24" + "00008000");
r.skipInteger();
assertTrue(r.eof());
}
@Test
public void testReadInt64() throws Exception {
setContents("05" + "0000000080000000" + "05" + "FFFFFFFF7FFFFFFF"
+ "05" + "7FFFFFFFFFFFFFFF" + "05" + "8000000000000000");
setContents("28" + "0000000080000000" + "28" + "FFFFFFFF7FFFFFFF"
+ "28" + "7FFFFFFFFFFFFFFF" + "28" + "8000000000000000");
assertEquals(Integer.MAX_VALUE + 1L, r.readInteger());
assertEquals(Integer.MIN_VALUE - 1L, r.readInteger());
assertEquals(Long.MAX_VALUE, r.readInteger());
@@ -98,7 +118,7 @@ public class ReaderImplTest extends BriarTestCase {
@Test
public void testSkipInt64() throws Exception {
setContents("05" + "0000000080000000");
setContents("28" + "0000000080000000");
r.skipInteger();
assertTrue(r.eof());
}
@@ -106,39 +126,39 @@ public class ReaderImplTest extends BriarTestCase {
@Test
public void testIntegersMustHaveMinimalLength() throws Exception {
// INTEGER_16 could be encoded as INTEGER_8
setContents("02" + "7F" + "03" + "007F");
setContents("21" + "7F" + "22" + "007F");
assertEquals(Byte.MAX_VALUE, r.readInteger());
try {
r.readInteger();
fail();
} catch(FormatException expected) {}
setContents("02" + "80" + "03" + "FF80");
setContents("21" + "80" + "22" + "FF80");
assertEquals(Byte.MIN_VALUE, r.readInteger());
try {
r.readInteger();
fail();
} catch(FormatException expected) {}
// INTEGER_32 could be encoded as INTEGER_16
setContents("03" + "7FFF" + "04" + "00007FFF");
setContents("22" + "7FFF" + "24" + "00007FFF");
assertEquals(Short.MAX_VALUE, r.readInteger());
try {
r.readInteger();
fail();
} catch(FormatException expected) {}
setContents("03" + "8000" + "04" + "FFFF8000");
setContents("22" + "8000" + "24" + "FFFF8000");
assertEquals(Short.MIN_VALUE, r.readInteger());
try {
r.readInteger();
fail();
} catch(FormatException expected) {}
// INTEGER_64 could be encoded as INTEGER_32
setContents("04" + "7FFFFFFF" + "05" + "000000007FFFFFFF");
setContents("24" + "7FFFFFFF" + "28" + "000000007FFFFFFF");
assertEquals(Integer.MAX_VALUE, r.readInteger());
try {
r.readInteger();
fail();
} catch(FormatException expected) {}
setContents("04" + "80000000" + "05" + "FFFFFFFF80000000");
setContents("24" + "80000000" + "28" + "FFFFFFFF80000000");
assertEquals(Integer.MIN_VALUE, r.readInteger());
try {
r.readInteger();
@@ -150,10 +170,10 @@ public class ReaderImplTest extends BriarTestCase {
public void testReadFloat() throws Exception {
// http://babbage.cs.qc.edu/IEEE-754/Decimal.html
// http://steve.hollasch.net/cgindex/coding/ieeefloat.html
setContents("06" + "0000000000000000" + "06" + "3FF0000000000000"
+ "06" + "4000000000000000" + "06" + "BFF0000000000000"
+ "06" + "8000000000000000" + "06" + "FFF0000000000000"
+ "06" + "7FF0000000000000" + "06" + "7FF8000000000000");
setContents("38" + "0000000000000000" + "38" + "3FF0000000000000"
+ "38" + "4000000000000000" + "38" + "BFF0000000000000"
+ "38" + "8000000000000000" + "38" + "FFF0000000000000"
+ "38" + "7FF0000000000000" + "38" + "7FF8000000000000");
assertEquals(0.0, r.readFloat());
assertEquals(1.0, r.readFloat());
assertEquals(2.0, r.readFloat());
@@ -167,7 +187,7 @@ public class ReaderImplTest extends BriarTestCase {
@Test
public void testSkipFloat() throws Exception {
setContents("06" + "0000000000000000");
setContents("38" + "0000000000000000");
r.skipFloat();
assertTrue(r.eof());
}
@@ -177,8 +197,8 @@ public class ReaderImplTest extends BriarTestCase {
String longest = TestUtils.createRandomString(Byte.MAX_VALUE);
String longHex = StringUtils.toHexString(longest.getBytes("UTF-8"));
// "foo", the empty string, and 127 random letters
setContents("07" + "03" + "666F6F" + "07" + "00" +
"07" + "7F" + longHex);
setContents("41" + "03" + "666F6F" + "41" + "00" +
"41" + "7F" + longHex);
assertEquals("foo", r.readString(Integer.MAX_VALUE));
assertEquals("", r.readString(Integer.MAX_VALUE));
assertEquals(longest, r.readString(Integer.MAX_VALUE));
@@ -188,7 +208,7 @@ public class ReaderImplTest extends BriarTestCase {
@Test
public void testReadString8ChecksMaxLength() throws Exception {
// "foo" twice
setContents("07" + "03" + "666F6F" + "07" + "03" + "666F6F");
setContents("41" + "03" + "666F6F" + "41" + "03" + "666F6F");
assertEquals("foo", r.readString(3));
assertTrue(r.hasString());
try {
@@ -202,26 +222,14 @@ public class ReaderImplTest extends BriarTestCase {
String longest = TestUtils.createRandomString(Byte.MAX_VALUE);
String longHex = StringUtils.toHexString(longest.getBytes("UTF-8"));
// "foo", the empty string, and 127 random letters
setContents("07" + "03" + "666F6F" + "07" + "00" +
"07" + "7F" + longHex);
r.skipString(Integer.MAX_VALUE);
r.skipString(Integer.MAX_VALUE);
r.skipString(Integer.MAX_VALUE);
setContents("41" + "03" + "666F6F" + "41" + "00" +
"41" + "7F" + longHex);
r.skipString();
r.skipString();
r.skipString();
assertTrue(r.eof());
}
@Test
public void testSkipString8ChecksMaxLength() throws Exception {
// "foo" twice
setContents("07" + "03" + "666F6F" + "07" + "03" + "666F6F");
r.skipString(3);
assertTrue(r.hasString());
try {
r.skipString(2);
fail();
} catch(FormatException expected) {}
}
@Test
public void testReadString16() throws Exception {
String shortest = TestUtils.createRandomString(Byte.MAX_VALUE + 1);
@@ -229,7 +237,7 @@ public class ReaderImplTest extends BriarTestCase {
String longest = TestUtils.createRandomString(Short.MAX_VALUE);
String longHex = StringUtils.toHexString(longest.getBytes("UTF-8"));
// 128 random letters and 2^15 -1 random letters
setContents("08" + "0080" + shortHex + "08" + "7FFF" + longHex);
setContents("42" + "0080" + shortHex + "42" + "7FFF" + longHex);
assertEquals(shortest, r.readString(Integer.MAX_VALUE));
assertEquals(longest, r.readString(Integer.MAX_VALUE));
assertTrue(r.eof());
@@ -240,7 +248,7 @@ public class ReaderImplTest extends BriarTestCase {
String shortest = TestUtils.createRandomString(Byte.MAX_VALUE + 1);
String shortHex = StringUtils.toHexString(shortest.getBytes("UTF-8"));
// 128 random letters, twice
setContents("08" + "0080" + shortHex + "08" + "0080" + shortHex);
setContents("42" + "0080" + shortHex + "42" + "0080" + shortHex);
assertEquals(shortest, r.readString(Byte.MAX_VALUE + 1));
assertTrue(r.hasString());
try {
@@ -256,32 +264,18 @@ public class ReaderImplTest extends BriarTestCase {
String longest = TestUtils.createRandomString(Short.MAX_VALUE);
String longHex = StringUtils.toHexString(longest.getBytes("UTF-8"));
// 128 random letters and 2^15 - 1 random letters
setContents("08" + "0080" + shortHex + "08" + "7FFF" + longHex);
r.skipString(Integer.MAX_VALUE);
r.skipString(Integer.MAX_VALUE);
setContents("42" + "0080" + shortHex + "42" + "7FFF" + longHex);
r.skipString();
r.skipString();
assertTrue(r.eof());
}
@Test
public void testSkipString16ChecksMaxLength() throws Exception {
String shortest = TestUtils.createRandomString(Byte.MAX_VALUE + 1);
String shortHex = StringUtils.toHexString(shortest.getBytes("UTF-8"));
// 128 random letters, twice
setContents("08" + "0080" + shortHex + "08" + "0080" + shortHex);
r.skipString(Byte.MAX_VALUE + 1);
assertTrue(r.hasString());
try {
r.skipString(Byte.MAX_VALUE);
fail();
} catch(FormatException expected) {}
}
@Test
public void testReadString32() throws Exception {
String shortest = TestUtils.createRandomString(Short.MAX_VALUE + 1);
String shortHex = StringUtils.toHexString(shortest.getBytes("UTF-8"));
// 2^15 random letters
setContents("09" + "00008000" + shortHex);
setContents("44" + "00008000" + shortHex);
assertEquals(shortest, r.readString(Integer.MAX_VALUE));
assertTrue(r.eof());
}
@@ -291,8 +285,8 @@ public class ReaderImplTest extends BriarTestCase {
String shortest = TestUtils.createRandomString(Short.MAX_VALUE + 1);
String shortHex = StringUtils.toHexString(shortest.getBytes("UTF-8"));
// 2^15 random letters, twice
setContents("09" + "00008000" + shortHex +
"09" + "00008000" + shortHex);
setContents("44" + "00008000" + shortHex +
"44" + "00008000" + shortHex);
assertEquals(shortest, r.readString(Short.MAX_VALUE + 1));
assertTrue(r.hasString());
try {
@@ -306,34 +300,19 @@ public class ReaderImplTest extends BriarTestCase {
String shortest = TestUtils.createRandomString(Short.MAX_VALUE + 1);
String shortHex = StringUtils.toHexString(shortest.getBytes("UTF-8"));
// 2^15 random letters, twice
setContents("09" + "00008000" + shortHex +
"09" + "00008000" + shortHex);
r.skipString(Integer.MAX_VALUE);
r.skipString(Integer.MAX_VALUE);
setContents("44" + "00008000" + shortHex +
"44" + "00008000" + shortHex);
r.skipString();
r.skipString();
assertTrue(r.eof());
}
@Test
public void testSkipString32ChecksMaxLength() throws Exception {
String shortest = TestUtils.createRandomString(Short.MAX_VALUE + 1);
String shortHex = StringUtils.toHexString(shortest.getBytes("UTF-8"));
// 2^15 random letters, twice
setContents("09" + "00008000" + shortHex +
"09" + "00008000" + shortHex);
r.skipString(Short.MAX_VALUE + 1);
assertTrue(r.hasString());
try {
r.skipString(Short.MAX_VALUE);
fail();
} catch(FormatException expected) {}
}
@Test
public void testStringsMustHaveMinimalLength() throws Exception {
// STRING_16 could be encoded as STRING_8
String longest8 = TestUtils.createRandomString(Byte.MAX_VALUE);
String long8Hex = StringUtils.toHexString(longest8.getBytes("UTF-8"));
setContents("07" + "7F" + long8Hex + "08" + "007F" + long8Hex);
setContents("41" + "7F" + long8Hex + "42" + "007F" + long8Hex);
assertEquals(longest8, r.readString(Integer.MAX_VALUE));
try {
r.readString(Integer.MAX_VALUE);
@@ -342,7 +321,7 @@ public class ReaderImplTest extends BriarTestCase {
// STRING_32 could be encoded as STRING_16
String longest16 = TestUtils.createRandomString(Short.MAX_VALUE);
String long16Hex = StringUtils.toHexString(longest16.getBytes("UTF-8"));
setContents("08" + "7FFF" + long16Hex + "09" + "00007FFF" + long16Hex);
setContents("42" + "7FFF" + long16Hex + "44" + "00007FFF" + long16Hex);
assertEquals(longest16, r.readString(Integer.MAX_VALUE));
try {
r.readString(Integer.MAX_VALUE);
@@ -355,8 +334,8 @@ public class ReaderImplTest extends BriarTestCase {
byte[] longest = new byte[Byte.MAX_VALUE];
String longHex = StringUtils.toHexString(longest);
// {1, 2, 3}, {}, and 127 zero bytes
setContents("0A" + "03" + "010203" + "0A" + "00" +
"0A" + "7F" + longHex);
setContents("51" + "03" + "010203" + "51" + "00" +
"51" + "7F" + longHex);
assertArrayEquals(new byte[] {1, 2, 3}, r.readBytes(Integer.MAX_VALUE));
assertArrayEquals(new byte[0], r.readBytes(Integer.MAX_VALUE));
assertArrayEquals(longest, r.readBytes(Integer.MAX_VALUE));
@@ -366,7 +345,7 @@ public class ReaderImplTest extends BriarTestCase {
@Test
public void testReadBytes8ChecksMaxLength() throws Exception {
// {1, 2, 3} twice
setContents("0A" + "03" + "010203" + "0A" + "03" + "010203");
setContents("51" + "03" + "010203" + "51" + "03" + "010203");
assertArrayEquals(new byte[] {1, 2, 3}, r.readBytes(3));
assertTrue(r.hasBytes());
try {
@@ -380,26 +359,14 @@ public class ReaderImplTest extends BriarTestCase {
byte[] longest = new byte[Byte.MAX_VALUE];
String longHex = StringUtils.toHexString(longest);
// {1, 2, 3}, {}, and 127 zero bytes
setContents("0A" + "03" + "010203" + "0A" + "00" +
"0A" + "7F" + longHex);
r.skipBytes(Integer.MAX_VALUE);
r.skipBytes(Integer.MAX_VALUE);
r.skipBytes(Integer.MAX_VALUE);
setContents("51" + "03" + "010203" + "51" + "00" +
"51" + "7F" + longHex);
r.skipBytes();
r.skipBytes();
r.skipBytes();
assertTrue(r.eof());
}
@Test
public void testSkipBytes8ChecksMaxLength() throws Exception {
// {1, 2, 3} twice
setContents("0A" + "03" + "010203" + "0A" + "03" + "010203");
r.skipBytes(3);
assertTrue(r.hasBytes());
try {
r.skipBytes(2);
fail();
} catch(FormatException expected) {}
}
@Test
public void testReadBytes16() throws Exception {
byte[] shortest = new byte[Byte.MAX_VALUE + 1];
@@ -407,7 +374,7 @@ public class ReaderImplTest extends BriarTestCase {
byte[] longest = new byte[Short.MAX_VALUE];
String longHex = StringUtils.toHexString(longest);
// 128 zero bytes and 2^15 - 1 zero bytes
setContents("0B" + "0080" + shortHex + "0B" + "7FFF" + longHex);
setContents("52" + "0080" + shortHex + "52" + "7FFF" + longHex);
assertArrayEquals(shortest, r.readBytes(Integer.MAX_VALUE));
assertArrayEquals(longest, r.readBytes(Integer.MAX_VALUE));
assertTrue(r.eof());
@@ -418,7 +385,7 @@ public class ReaderImplTest extends BriarTestCase {
byte[] shortest = new byte[Byte.MAX_VALUE + 1];
String shortHex = StringUtils.toHexString(shortest);
// 128 zero bytes, twice
setContents("0B" + "0080" + shortHex + "0B" + "0080" + shortHex);
setContents("52" + "0080" + shortHex + "52" + "0080" + shortHex);
assertArrayEquals(shortest, r.readBytes(Byte.MAX_VALUE + 1));
assertTrue(r.hasBytes());
try {
@@ -434,32 +401,18 @@ public class ReaderImplTest extends BriarTestCase {
byte[] longest = new byte[Short.MAX_VALUE];
String longHex = StringUtils.toHexString(longest);
// 128 zero bytes and 2^15 - 1 zero bytes
setContents("0B" + "0080" + shortHex + "0B" + "7FFF" + longHex);
r.skipBytes(Integer.MAX_VALUE);
r.skipBytes(Integer.MAX_VALUE);
setContents("52" + "0080" + shortHex + "52" + "7FFF" + longHex);
r.skipBytes();
r.skipBytes();
assertTrue(r.eof());
}
@Test
public void testSkipBytes16ChecksMaxLength() throws Exception {
byte[] shortest = new byte[Byte.MAX_VALUE + 1];
String shortHex = StringUtils.toHexString(shortest);
// 128 zero bytes, twice
setContents("0B" + "0080" + shortHex + "0B" + "0080" + shortHex);
r.skipBytes(Byte.MAX_VALUE + 1);
assertTrue(r.hasBytes());
try {
r.skipBytes(Byte.MAX_VALUE);
fail();
} catch(FormatException expected) {}
}
@Test
public void testReadBytes32() throws Exception {
byte[] shortest = new byte[Short.MAX_VALUE + 1];
String shortHex = StringUtils.toHexString(shortest);
// 2^15 zero bytes
setContents("0C" + "00008000" + shortHex);
setContents("54" + "00008000" + shortHex);
assertArrayEquals(shortest, r.readBytes(Integer.MAX_VALUE));
assertTrue(r.eof());
}
@@ -469,8 +422,8 @@ public class ReaderImplTest extends BriarTestCase {
byte[] shortest = new byte[Short.MAX_VALUE + 1];
String shortHex = StringUtils.toHexString(shortest);
// 2^15 zero bytes, twice
setContents("0C" + "00008000" + shortHex +
"0C" + "00008000" + shortHex);
setContents("54" + "00008000" + shortHex +
"54" + "00008000" + shortHex);
assertArrayEquals(shortest, r.readBytes(Short.MAX_VALUE + 1));
assertTrue(r.hasBytes());
try {
@@ -484,43 +437,28 @@ public class ReaderImplTest extends BriarTestCase {
byte[] shortest = new byte[Short.MAX_VALUE + 1];
String shortHex = StringUtils.toHexString(shortest);
// 2^15 zero bytes, twice
setContents("0C" + "00008000" + shortHex +
"0C" + "00008000" + shortHex);
r.skipBytes(Integer.MAX_VALUE);
r.skipBytes(Integer.MAX_VALUE);
setContents("54" + "00008000" + shortHex +
"54" + "00008000" + shortHex);
r.skipBytes();
r.skipBytes();
assertTrue(r.eof());
}
@Test
public void testSkipBytes32ChecksMaxLength() throws Exception {
byte[] shortest = new byte[Short.MAX_VALUE + 1];
String shortHex = StringUtils.toHexString(shortest);
// 2^15 zero bytes, twice
setContents("0C" + "00008000" + shortHex +
"0C" + "00008000" + shortHex);
r.skipBytes(Short.MAX_VALUE + 1);
assertTrue(r.hasBytes());
try {
r.skipBytes(Short.MAX_VALUE);
fail();
} catch(FormatException expected) {}
}
@Test
public void testBytesMustHaveMinimalLength() throws Exception {
// BYTES_16 could be encoded as BYTES_8
// RAW_16 could be encoded as RAW_8
byte[] longest8 = new byte[Byte.MAX_VALUE];
String long8Hex = StringUtils.toHexString(longest8);
setContents("0A" + "7F" + long8Hex + "0B" + "007F" + long8Hex);
setContents("51" + "7F" + long8Hex + "52" + "007F" + long8Hex);
assertArrayEquals(longest8, r.readBytes(Integer.MAX_VALUE));
try {
r.readBytes(Integer.MAX_VALUE);
fail();
} catch(FormatException expected) {}
// BYTES_32 could be encoded as BYTES_16
// RAW_32 could be encoded as RAW_16
byte[] longest16 = new byte[Short.MAX_VALUE];
String long16Hex = StringUtils.toHexString(longest16);
setContents("0B" + "7FFF" + long16Hex + "0C" + "00007FFF" + long16Hex);
setContents("52" + "7FFF" + long16Hex + "54" + "00007FFF" + long16Hex);
assertArrayEquals(longest16, r.readBytes(Integer.MAX_VALUE));
try {
r.readBytes(Integer.MAX_VALUE);
@@ -531,9 +469,9 @@ public class ReaderImplTest extends BriarTestCase {
@Test
public void testReadList() throws Exception {
// A list containing 1, "foo", and 128
setContents("0D" + "02" + "01" +
"07" + "03" + "666F6F" +
"03" + "0080" + "10");
setContents("60" + "21" + "01" +
"41" + "03" + "666F6F" +
"22" + "0080" + "80");
r.readListStart();
assertFalse(r.hasListEnd());
assertEquals(1, r.readInteger());
@@ -549,25 +487,25 @@ public class ReaderImplTest extends BriarTestCase {
@Test
public void testSkipList() throws Exception {
// A list containing 1, "foo", and 128
setContents("0D" + "02" + "01" +
"07" + "03" + "666F6F" +
"03" + "0080" + "10");
setContents("60" + "21" + "01" +
"41" + "03" + "666F6F" +
"22" + "0080" + "80");
r.skipList();
assertTrue(r.eof());
}
@Test
public void testReadMap() throws Exception {
// A map containing "foo" -> 123 and byte[0] -> null
setContents("0E" + "07" + "03" + "666F6F" + "02" + "7B" +
"0A" + "00" + "11" + "10");
// A map containing "foo" -> 123 and "bar" -> null
setContents("70" + "41" + "03" + "666F6F" + "21" + "7B" +
"41" + "03" + "626172" + "00" + "80");
r.readMapStart();
assertFalse(r.hasMapEnd());
assertEquals("foo", r.readString(1000));
assertFalse(r.hasMapEnd());
assertEquals(123, r.readInteger());
assertFalse(r.hasMapEnd());
assertArrayEquals(new byte[0], r.readBytes(1000));
assertEquals("bar", r.readString(1000));
assertFalse(r.hasMapEnd());
assertTrue(r.hasNull());
r.readNull();
@@ -578,58 +516,18 @@ public class ReaderImplTest extends BriarTestCase {
@Test
public void testSkipMap() throws Exception {
// A map containing "foo" -> 123 and byte[0] -> null
setContents("0E" + "07" + "03" + "666F6F" + "02" + "7B" +
"0A" + "00" + "11" + "10");
// A map containing "foo" -> 123 and "bar" -> null
setContents("70" + "41" + "03" + "666F6F" + "21" + "7B" +
"41" + "03" + "626172" + "00" + "80");
r.skipMap();
assertTrue(r.eof());
}
@Test
public void testReadStruct() throws Exception {
// Two empty structs with IDs 0 and 255
setContents("0F00" + "10" + "0FFF" + "10");
r.readStructStart(0);
r.readStructEnd();
r.readStructStart(255);
r.readStructEnd();
assertTrue(r.eof());
}
@Test
public void testSkipStruct() throws Exception {
// Two empty structs with IDs 0 and 255
setContents("0F00" + "10" + "0FFF" + "10");
r.skipStruct();
r.skipStruct();
assertTrue(r.eof());
}
@Test
public void testSkipNestedStructMapAndList() throws Exception {
// A struct containing a map containing two empty lists
setContents("0F00" + "0E" + "0D" + "10" + "0D" + "10" + "10" + "10");
r.skipStruct();
assertTrue(r.eof());
}
@Test
public void testReadNull() throws Exception {
setContents("11");
r.readNull();
assertTrue(r.eof());
}
@Test
public void testSkipNull() throws Exception {
setContents("11");
r.skipNull();
assertTrue(r.eof());
}
@Test
public void testReadEmptyInput() throws Exception {
setContents("");
public void testSkipNestedListsAndMaps() throws Exception {
// A list containing a map containing two empty lists
setContents("60" + "70" + "60" + "80" + "60" + "80" + "80" + "80");
r.skipList();
assertTrue(r.eof());
}

View File

@@ -19,18 +19,25 @@ public class WriterImplTest extends BriarTestCase {
private ByteArrayOutputStream out = null;
private WriterImpl w = null;
@Override
@Before
public void setUp() {
out = new ByteArrayOutputStream();
w = new WriterImpl(out);
}
@Test
public void testWriteNull() throws IOException {
w.writeNull();
checkContents("00");
}
@Test
public void testWriteBoolean() throws IOException {
w.writeBoolean(true);
w.writeBoolean(false);
// TRUE tag, FALSE tag
checkContents("01" + "00");
// BOOLEAN tag, 1, BOOLEAN tag, 0
checkContents("11" + "01" + "11" + "00");
}
@Test
@@ -46,11 +53,11 @@ public class WriterImplTest extends BriarTestCase {
w.writeInteger(Long.MAX_VALUE);
w.writeInteger(Long.MIN_VALUE);
// INTEGER_8 tag, 0, INTEGER_8 tag, -1, etc
checkContents("02" + "00" + "02" + "FF" +
"02" + "7F" + "02" + "80" +
"03" + "7FFF" + "03" + "8000" +
"04" + "7FFFFFFF" + "04" + "80000000" +
"05" + "7FFFFFFFFFFFFFFF" + "05" + "8000000000000000");
checkContents("21" + "00" + "21" + "FF" +
"21" + "7F" + "21" + "80" +
"22" + "7FFF" + "22" + "8000" +
"24" + "7FFFFFFF" + "24" + "80000000" +
"28" + "7FFFFFFFFFFFFFFF" + "28" + "8000000000000000");
}
@Test
@@ -65,10 +72,10 @@ public class WriterImplTest extends BriarTestCase {
w.writeFloat(Double.NEGATIVE_INFINITY); // 1 2047 0 -> 0xFFF00000...
w.writeFloat(Double.POSITIVE_INFINITY); // 0 2047 0 -> 0x7FF00000...
w.writeFloat(Double.NaN); // 0 2047 1 -> 0x7FF8000000000000
checkContents("06" + "0000000000000000" + "06" + "3FF0000000000000"
+ "06" + "4000000000000000" + "06" + "BFF0000000000000"
+ "06" + "8000000000000000" + "06" + "FFF0000000000000"
+ "06" + "7FF0000000000000" + "06" + "7FF8000000000000");
checkContents("38" + "0000000000000000" + "38" + "3FF0000000000000"
+ "38" + "4000000000000000" + "38" + "BFF0000000000000"
+ "38" + "8000000000000000" + "38" + "FFF0000000000000"
+ "38" + "7FF0000000000000" + "38" + "7FF8000000000000");
}
@Test
@@ -79,8 +86,8 @@ public class WriterImplTest extends BriarTestCase {
w.writeString(longest);
// STRING_8 tag, length 16, UTF-8 bytes, STRING_8 tag, length 127,
// UTF-8 bytes
checkContents("07" + "10" + "666F6F206261722062617A2062616D20" +
"07" + "7F" + longHex);
checkContents("41" + "10" + "666F6F206261722062617A2062616D20" +
"41" + "7F" + longHex);
}
@Test
@@ -93,7 +100,7 @@ public class WriterImplTest extends BriarTestCase {
w.writeString(longest);
// STRING_16 tag, length 128, UTF-8 bytes, STRING_16 tag,
// length 2^15 - 1, UTF-8 bytes
checkContents("08" + "0080" + shortHex + "08" + "7FFF" + longHex);
checkContents("42" + "0080" + shortHex + "42" + "7FFF" + longHex);
}
@Test
@@ -102,7 +109,7 @@ public class WriterImplTest extends BriarTestCase {
String shortHex = StringUtils.toHexString(shortest.getBytes("UTF-8"));
w.writeString(shortest);
// STRING_32 tag, length 2^15, UTF-8 bytes
checkContents("09" + "00008000" + shortHex);
checkContents("44" + "00008000" + shortHex);
}
@Test
@@ -111,8 +118,8 @@ public class WriterImplTest extends BriarTestCase {
String longHex = StringUtils.toHexString(longest);
w.writeBytes(new byte[] {1, 2, 3});
w.writeBytes(longest);
// BYTES_8 tag, length 3, bytes, BYTES_8 tag, length 127, bytes
checkContents("0A" + "03" + "010203" + "0A" + "7F" + longHex);
// RAW_8 tag, length 3, bytes, RAW_8 tag, length 127, bytes
checkContents("51" + "03" + "010203" + "51" + "7F" + longHex);
}
@Test
@@ -123,8 +130,8 @@ public class WriterImplTest extends BriarTestCase {
String longHex = StringUtils.toHexString(longest);
w.writeBytes(shortest);
w.writeBytes(longest);
// BYTES_16 tag, length 128, bytes, BYTES_16 tag, length 2^15 - 1, bytes
checkContents("0B" + "0080" + shortHex + "0B" + "7FFF" + longHex);
// RAW_16 tag, length 128, bytes, RAW_16 tag, length 2^15 - 1, bytes
checkContents("52" + "0080" + shortHex + "52" + "7FFF" + longHex);
}
@Test
@@ -132,8 +139,8 @@ public class WriterImplTest extends BriarTestCase {
byte[] shortest = new byte[Short.MAX_VALUE + 1];
String shortHex = StringUtils.toHexString(shortest);
w.writeBytes(shortest);
// BYTES_32 tag, length 2^15, bytes
checkContents("0C" + "00008000" + shortHex);
// RAW_32 tag, length 2^15, bytes
checkContents("54" + "00008000" + shortHex);
}
@Test
@@ -142,7 +149,7 @@ public class WriterImplTest extends BriarTestCase {
for(int i = 0; i < 3; i++) l.add(i);
w.writeList(l);
// LIST tag, elements as integers, END tag
checkContents("0D" + "02" + "00" + "02" + "01" + "02" + "02" + "10");
checkContents("60" + "21" + "00" + "21" + "01" + "21" + "02" + "80");
}
@Test
@@ -153,20 +160,20 @@ public class WriterImplTest extends BriarTestCase {
l.add(2);
w.writeList(l);
// LIST tag, 1 as integer, NULL tag, 2 as integer, END tag
checkContents("0D" + "02" + "01" + "11" + "02" + "02" + "10");
checkContents("60" + "21" + "01" + "00" + "21" + "02" + "80");
}
@Test
public void testWriteMap() throws IOException {
// Use LinkedHashMap to get predictable iteration order
Map<Object, Object> m = new LinkedHashMap<Object, Object>();
for(int i = 0; i < 4; i++) m.put(i, i + 1);
Map<String, Object> m = new LinkedHashMap<String, Object>();
for(int i = 0; i < 4; i++) m.put(String.valueOf(i), i);
w.writeMap(m);
// MAP tag, entries as integers, END tag
checkContents("0E" + "02" + "00" + "02" + "01" +
"02" + "01" + "02" + "02" +
"02" + "02" + "02" + "03" +
"02" + "03" + "02" + "04" + "10");
// MAP tag, keys as strings and values as integers, END tag
checkContents("70" + "41" + "01" + "30" + "21" + "00" +
"41" + "01" + "31" + "21" + "01" +
"41" + "01" + "32" + "21" + "02" +
"41" + "01" + "33" + "21" + "03" + "80");
}
@Test
@@ -177,9 +184,9 @@ public class WriterImplTest extends BriarTestCase {
w.writeInteger(128);
w.writeListEnd();
// LIST tag, 1 as integer, "foo" as string, 128 as integer, END tag
checkContents("0D" + "02" + "01" +
"07" + "03" + "666F6F" +
"03" + "0080" + "10");
checkContents("60" + "21" + "01" +
"41" + "03" + "666F6F" +
"22" + "0080" + "80");
}
@Test
@@ -187,42 +194,30 @@ public class WriterImplTest extends BriarTestCase {
w.writeMapStart();
w.writeString("foo");
w.writeInteger(123);
w.writeBytes(new byte[0]);
w.writeString("bar");
w.writeNull();
w.writeMapEnd();
// MAP tag, "foo" as string, 123 as integer, {} as bytes, NULL tag,
// END tag
checkContents("0E" + "07" + "03" + "666F6F" +
"02" + "7B" + "0A" + "00" + "11" + "10");
// MAP tag, "foo" as string, 123 as integer, "bar" as string,
// NULL tag, END tag
checkContents("70" + "41" + "03" + "666F6F" +
"21" + "7B" + "41" + "03" + "626172" + "00" + "80");
}
@Test
public void testWriteNestedMapsAndLists() throws IOException {
Map<Object, Object> m = new LinkedHashMap<Object, Object>();
m.put("foo", 123);
List<Object> l = new ArrayList<Object>();
l.add((byte) 1);
Map<Object, Object> m1 = new LinkedHashMap<Object, Object>();
m1.put(m, l);
w.writeMap(m1);
// MAP tag, MAP tag, "foo" as string, 123 as integer, END tag,
// LIST tag, 1 as integer, END tag, END tag
checkContents("0E" + "0E" + "07" + "03" + "666F6F" +
"02" + "7B" + "10" + "0D" + "02" + "01" + "10" + "10");
}
@Test
public void testWriteStruct() throws IOException {
w.writeStructStart(123);
w.writeStructEnd();
// STRUCT tag, 123 as struct ID, END tag
checkContents("0F" + "7B" + "10");
}
@Test
public void testWriteNull() throws IOException {
w.writeNull();
checkContents("11");
Map<String, Object> inner = new LinkedHashMap<String, Object>();
inner.put("bar", new byte[0]);
List<Object> list = new ArrayList<Object>();
list.add(1);
list.add(inner);
Map<String, Object> outer = new LinkedHashMap<String, Object>();
outer.put("foo", list);
w.writeMap(outer);
// MAP tag, "foo" as string, LIST tag, 1 as integer, MAP tag,
// "bar" as string, {} as raw, END tag, END tag, END tag
checkContents("70" + "41" + "03" + "666F6F" + "60" +
"21" + "01" + "70" + "41" + "03" + "626172" + "51" + "00" +
"80" + "80" + "80");
}
private void checkContents(String hex) throws IOException {