Index: net/quic/core/quic_data_writer_test.cc |
diff --git a/net/quic/core/quic_data_writer_test.cc b/net/quic/core/quic_data_writer_test.cc |
index 3e32ef9a4dc598d5609e2ae3282f3dfbbc3aaa3b..339c9907c13bd544cad198ebda382b3b3bdce810 100644 |
--- a/net/quic/core/quic_data_writer_test.cc |
+++ b/net/quic/core/quic_data_writer_test.cc |
@@ -16,7 +16,34 @@ namespace net { |
namespace test { |
namespace { |
-class QuicDataWriterTest : public ::testing::TestWithParam<Perspective> {}; |
+char* AsChars(unsigned char* data) { |
+ return reinterpret_cast<char*>(data); |
+} |
+ |
+struct TestParams { |
+ TestParams(Perspective perspective, Endianness endianness) |
+ : perspective(perspective), endianness(endianness) {} |
+ |
+ Perspective perspective; |
+ Endianness endianness; |
+}; |
+ |
+std::vector<TestParams> GetTestParams() { |
+ std::vector<TestParams> params; |
+ for (Perspective perspective : |
+ {Perspective::IS_CLIENT, Perspective::IS_SERVER}) { |
+ for (Endianness endianness : {NETWORK_BYTE_ORDER, HOST_BYTE_ORDER}) { |
+ params.push_back(TestParams(perspective, endianness)); |
+ } |
+ } |
+ return params; |
+} |
+ |
+class QuicDataWriterTest : public ::testing::TestWithParam<TestParams> {}; |
+ |
+INSTANTIATE_TEST_CASE_P(QuicDataWriterTests, |
+ QuicDataWriterTest, |
+ ::testing::ValuesIn(GetTestParams())); |
TEST_P(QuicDataWriterTest, SanityCheckUFloat16Consts) { |
// Check the arithmetic on the constants - otherwise the values below make |
@@ -99,10 +126,14 @@ TEST_P(QuicDataWriterTest, WriteUFloat16) { |
for (int i = 0; i < num_test_cases; ++i) { |
char buffer[2]; |
- QuicDataWriter writer(2, buffer, GetParam()); |
+ QuicDataWriter writer(2, buffer, GetParam().perspective, |
+ GetParam().endianness); |
EXPECT_TRUE(writer.WriteUFloat16(test_cases[i].decoded)); |
- EXPECT_EQ(test_cases[i].encoded, |
- *reinterpret_cast<uint16_t*>(writer.data())); |
+ uint16_t result = *reinterpret_cast<uint16_t*>(writer.data()); |
+ if (GetParam().endianness == NETWORK_BYTE_ORDER) { |
+ result = QuicEndian::HostToNet16(result); |
+ } |
+ EXPECT_EQ(test_cases[i].encoded, result); |
} |
} |
@@ -159,8 +190,12 @@ TEST_P(QuicDataWriterTest, ReadUFloat16) { |
int num_test_cases = sizeof(test_cases) / sizeof(test_cases[0]); |
for (int i = 0; i < num_test_cases; ++i) { |
- QuicDataReader reader(reinterpret_cast<char*>(&test_cases[i].encoded), 2, |
- GetParam()); |
+ uint16_t encoded_ufloat = test_cases[i].encoded; |
+ if (GetParam().endianness == NETWORK_BYTE_ORDER) { |
+ encoded_ufloat = QuicEndian::HostToNet16(encoded_ufloat); |
+ } |
+ QuicDataReader reader(reinterpret_cast<char*>(&encoded_ufloat), 2, |
+ GetParam().perspective, GetParam().endianness); |
uint64_t value; |
EXPECT_TRUE(reader.ReadUFloat16(&value)); |
EXPECT_EQ(test_cases[i].decoded, value); |
@@ -172,33 +207,48 @@ TEST_P(QuicDataWriterTest, RoundTripUFloat16) { |
uint64_t previous_value = 0; |
for (uint16_t i = 1; i < 0xFFFF; ++i) { |
// Read the two bytes. |
- QuicDataReader reader(reinterpret_cast<char*>(&i), 2, GetParam()); |
+ uint16_t read_number = i; |
+ if (GetParam().endianness == NETWORK_BYTE_ORDER) { |
+ read_number = QuicEndian::HostToNet16(read_number); |
+ } |
+ QuicDataReader reader(reinterpret_cast<char*>(&read_number), 2, |
+ GetParam().perspective, GetParam().endianness); |
uint64_t value; |
// All values must be decodable. |
EXPECT_TRUE(reader.ReadUFloat16(&value)); |
// Check that small numbers represent themselves |
- if (i < 4097) |
+ if (i < 4097) { |
EXPECT_EQ(i, value); |
+ } |
// Check there's monotonic growth. |
EXPECT_LT(previous_value, value); |
// Check that precision is within 0.5% away from the denormals. |
- if (i > 2000) |
+ if (i > 2000) { |
EXPECT_GT(previous_value * 1005, value * 1000); |
+ } |
// Check we're always within the promised range. |
EXPECT_LT(value, UINT64_C(0x3FFC0000000)); |
previous_value = value; |
char buffer[6]; |
- QuicDataWriter writer(6, buffer, GetParam()); |
+ QuicDataWriter writer(6, buffer, GetParam().perspective, |
+ GetParam().endianness); |
EXPECT_TRUE(writer.WriteUFloat16(value - 1)); |
EXPECT_TRUE(writer.WriteUFloat16(value)); |
EXPECT_TRUE(writer.WriteUFloat16(value + 1)); |
// Check minimal decoding (previous decoding has previous encoding). |
- EXPECT_EQ(i - 1, *reinterpret_cast<uint16_t*>(writer.data())); |
+ uint16_t encoded1 = *reinterpret_cast<uint16_t*>(writer.data()); |
+ uint16_t encoded2 = *reinterpret_cast<uint16_t*>(writer.data() + 2); |
+ uint16_t encoded3 = *reinterpret_cast<uint16_t*>(writer.data() + 4); |
+ if (GetParam().endianness == NETWORK_BYTE_ORDER) { |
+ encoded1 = QuicEndian::NetToHost16(encoded1); |
+ encoded2 = QuicEndian::NetToHost16(encoded2); |
+ encoded3 = QuicEndian::NetToHost16(encoded3); |
+ } |
+ EXPECT_EQ(i - 1, encoded1); |
// Check roundtrip. |
- EXPECT_EQ(i, *reinterpret_cast<uint16_t*>(writer.data() + 2)); |
+ EXPECT_EQ(i, encoded2); |
// Check next decoding. |
- EXPECT_EQ(i < 4096 ? i + 1 : i, |
- *reinterpret_cast<uint16_t*>(writer.data() + 4)); |
+ EXPECT_EQ(i < 4096 ? i + 1 : i, encoded3); |
} |
} |
@@ -212,16 +262,19 @@ TEST_P(QuicDataWriterTest, WriteConnectionId) { |
}; |
const int kBufferLength = sizeof(connection_id); |
char buffer[kBufferLength]; |
- QuicDataWriter writer(kBufferLength, buffer, GetParam()); |
+ QuicDataWriter writer(kBufferLength, buffer, GetParam().perspective, |
+ GetParam().endianness); |
writer.WriteConnectionId(connection_id); |
test::CompareCharArraysWithHexError( |
"connection_id", buffer, kBufferLength, |
- QuicUtils::IsConnectionIdWireFormatBigEndian(GetParam()) ? big_endian |
- : little_endian, |
+ QuicUtils::IsConnectionIdWireFormatBigEndian(GetParam().perspective) |
+ ? big_endian |
+ : little_endian, |
kBufferLength); |
uint64_t read_connection_id; |
- QuicDataReader reader(buffer, kBufferLength, GetParam()); |
+ QuicDataReader reader(buffer, kBufferLength, GetParam().perspective, |
+ GetParam().endianness); |
reader.ReadConnectionId(&read_connection_id); |
EXPECT_EQ(connection_id, read_connection_id); |
} |
@@ -232,17 +285,315 @@ TEST_P(QuicDataWriterTest, WriteTag) { |
}; |
const int kBufferLength = sizeof(QuicTag); |
char buffer[kBufferLength]; |
- QuicDataWriter writer(kBufferLength, buffer, GetParam()); |
+ QuicDataWriter writer(kBufferLength, buffer, GetParam().perspective, |
+ GetParam().endianness); |
writer.WriteTag(kCHLO); |
test::CompareCharArraysWithHexError("CHLO", buffer, kBufferLength, CHLO, |
kBufferLength); |
QuicTag read_chlo; |
- QuicDataReader reader(buffer, kBufferLength, GetParam()); |
+ QuicDataReader reader(buffer, kBufferLength, GetParam().perspective, |
+ GetParam().endianness); |
reader.ReadTag(&read_chlo); |
EXPECT_EQ(kCHLO, read_chlo); |
} |
+TEST_P(QuicDataWriterTest, Write16BitUnsignedIntegers) { |
+ char little_endian16[] = {0x22, 0x11}; |
+ char big_endian16[] = {0x11, 0x22}; |
+ char buffer16[2]; |
+ { |
+ uint16_t in_memory16 = 0x1122; |
+ QuicDataWriter writer(2, buffer16, GetParam().perspective, |
+ GetParam().endianness); |
+ writer.WriteUInt16(in_memory16); |
+ test::CompareCharArraysWithHexError( |
+ "uint16_t", buffer16, 2, |
+ GetParam().endianness == NETWORK_BYTE_ORDER ? big_endian16 |
+ : little_endian16, |
+ 2); |
+ |
+ uint16_t read_number16; |
+ QuicDataReader reader(buffer16, 2, GetParam().perspective, |
+ GetParam().endianness); |
+ reader.ReadUInt16(&read_number16); |
+ EXPECT_EQ(in_memory16, read_number16); |
+ } |
+ |
+ { |
+ uint64_t in_memory16 = 0x0000000000001122; |
+ QuicDataWriter writer(2, buffer16, GetParam().perspective, |
+ GetParam().endianness); |
+ writer.WriteBytesToUInt64(2, in_memory16); |
+ test::CompareCharArraysWithHexError( |
+ "uint16_t", buffer16, 2, |
+ GetParam().endianness == NETWORK_BYTE_ORDER ? big_endian16 |
+ : little_endian16, |
+ 2); |
+ |
+ uint64_t read_number16 = 0u; |
+ QuicDataReader reader(buffer16, 2, GetParam().perspective, |
+ GetParam().endianness); |
+ reader.ReadBytesToUInt64(2, &read_number16); |
+ EXPECT_EQ(in_memory16, read_number16); |
+ } |
+} |
+ |
+TEST_P(QuicDataWriterTest, Write24BitUnsignedIntegers) { |
+ char little_endian24[] = {0x33, 0x22, 0x11}; |
+ char big_endian24[] = {0x11, 0x22, 0x33}; |
+ char buffer24[3]; |
+ uint64_t in_memory24 = 0x0000000000112233; |
+ QuicDataWriter writer(3, buffer24, GetParam().perspective, |
+ GetParam().endianness); |
+ writer.WriteBytesToUInt64(3, in_memory24); |
+ test::CompareCharArraysWithHexError( |
+ "uint24", buffer24, 3, |
+ GetParam().endianness == NETWORK_BYTE_ORDER ? big_endian24 |
+ : little_endian24, |
+ 3); |
+ |
+ uint64_t read_number24 = 0u; |
+ QuicDataReader reader(buffer24, 3, GetParam().perspective, |
+ GetParam().endianness); |
+ reader.ReadBytesToUInt64(3, &read_number24); |
+ EXPECT_EQ(in_memory24, read_number24); |
+} |
+ |
+TEST_P(QuicDataWriterTest, Write32BitUnsignedIntegers) { |
+ char little_endian32[] = {0x44, 0x33, 0x22, 0x11}; |
+ char big_endian32[] = {0x11, 0x22, 0x33, 0x44}; |
+ char buffer32[4]; |
+ { |
+ uint32_t in_memory32 = 0x11223344; |
+ QuicDataWriter writer(4, buffer32, GetParam().perspective, |
+ GetParam().endianness); |
+ writer.WriteUInt32(in_memory32); |
+ test::CompareCharArraysWithHexError( |
+ "uint32_t", buffer32, 4, |
+ GetParam().endianness == NETWORK_BYTE_ORDER ? big_endian32 |
+ : little_endian32, |
+ 4); |
+ |
+ uint32_t read_number32; |
+ QuicDataReader reader(buffer32, 4, GetParam().perspective, |
+ GetParam().endianness); |
+ reader.ReadUInt32(&read_number32); |
+ EXPECT_EQ(in_memory32, read_number32); |
+ } |
+ |
+ { |
+ uint64_t in_memory32 = 0x11223344; |
+ QuicDataWriter writer(4, buffer32, GetParam().perspective, |
+ GetParam().endianness); |
+ writer.WriteBytesToUInt64(4, in_memory32); |
+ test::CompareCharArraysWithHexError( |
+ "uint32_t", buffer32, 4, |
+ GetParam().endianness == NETWORK_BYTE_ORDER ? big_endian32 |
+ : little_endian32, |
+ 4); |
+ |
+ uint64_t read_number32 = 0u; |
+ QuicDataReader reader(buffer32, 4, GetParam().perspective, |
+ GetParam().endianness); |
+ reader.ReadBytesToUInt64(4, &read_number32); |
+ EXPECT_EQ(in_memory32, read_number32); |
+ } |
+} |
+ |
+TEST_P(QuicDataWriterTest, Write40BitUnsignedIntegers) { |
+ uint64_t in_memory40 = 0x0000001122334455; |
+ char little_endian40[] = {0x55, 0x44, 0x33, 0x22, 0x11}; |
+ char big_endian40[] = {0x11, 0x22, 0x33, 0x44, 0x55}; |
+ char buffer40[5]; |
+ QuicDataWriter writer(5, buffer40, GetParam().perspective, |
+ GetParam().endianness); |
+ writer.WriteBytesToUInt64(5, in_memory40); |
+ test::CompareCharArraysWithHexError( |
+ "uint40", buffer40, 5, |
+ GetParam().endianness == NETWORK_BYTE_ORDER ? big_endian40 |
+ : little_endian40, |
+ 5); |
+ |
+ uint64_t read_number40 = 0u; |
+ QuicDataReader reader(buffer40, 5, GetParam().perspective, |
+ GetParam().endianness); |
+ reader.ReadBytesToUInt64(5, &read_number40); |
+ EXPECT_EQ(in_memory40, read_number40); |
+} |
+ |
+TEST_P(QuicDataWriterTest, Write48BitUnsignedIntegers) { |
+ uint64_t in_memory48 = 0x0000112233445566; |
+ char little_endian48[] = {0x66, 0x55, 0x44, 0x33, 0x22, 0x11}; |
+ char big_endian48[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; |
+ char buffer48[6]; |
+ QuicDataWriter writer(6, buffer48, GetParam().perspective, |
+ GetParam().endianness); |
+ writer.WriteBytesToUInt64(6, in_memory48); |
+ test::CompareCharArraysWithHexError( |
+ "uint48", buffer48, 6, |
+ GetParam().endianness == NETWORK_BYTE_ORDER ? big_endian48 |
+ : little_endian48, |
+ 6); |
+ |
+ uint64_t read_number48 = 0u; |
+ QuicDataReader reader(buffer48, 6, GetParam().perspective, |
+ GetParam().endianness); |
+ reader.ReadBytesToUInt64(6., &read_number48); |
+ EXPECT_EQ(in_memory48, read_number48); |
+} |
+ |
+TEST_P(QuicDataWriterTest, Write56BitUnsignedIntegers) { |
+ uint64_t in_memory56 = 0x0011223344556677; |
+ char little_endian56[] = {0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11}; |
+ char big_endian56[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; |
+ char buffer56[7]; |
+ QuicDataWriter writer(7, buffer56, GetParam().perspective, |
+ GetParam().endianness); |
+ writer.WriteBytesToUInt64(7, in_memory56); |
+ test::CompareCharArraysWithHexError( |
+ "uint56", buffer56, 7, |
+ GetParam().endianness == NETWORK_BYTE_ORDER ? big_endian56 |
+ : little_endian56, |
+ 7); |
+ |
+ uint64_t read_number56 = 0u; |
+ QuicDataReader reader(buffer56, 7, GetParam().perspective, |
+ GetParam().endianness); |
+ reader.ReadBytesToUInt64(7, &read_number56); |
+ EXPECT_EQ(in_memory56, read_number56); |
+} |
+ |
+TEST_P(QuicDataWriterTest, Write64BitUnsignedIntegers) { |
+ uint64_t in_memory64 = 0x1122334455667788; |
+ unsigned char little_endian64[] = {0x88, 0x77, 0x66, 0x55, |
+ 0x44, 0x33, 0x22, 0x11}; |
+ unsigned char big_endian64[] = {0x11, 0x22, 0x33, 0x44, |
+ 0x55, 0x66, 0x77, 0x88}; |
+ char buffer64[8]; |
+ QuicDataWriter writer(8, buffer64, GetParam().perspective, |
+ GetParam().endianness); |
+ writer.WriteBytesToUInt64(8, in_memory64); |
+ test::CompareCharArraysWithHexError( |
+ "uint64_t", buffer64, 8, |
+ GetParam().endianness == NETWORK_BYTE_ORDER ? AsChars(big_endian64) |
+ : AsChars(little_endian64), |
+ 8); |
+ |
+ uint64_t read_number64 = 0u; |
+ QuicDataReader reader(buffer64, 8, GetParam().perspective, |
+ GetParam().endianness); |
+ reader.ReadBytesToUInt64(8, &read_number64); |
+ EXPECT_EQ(in_memory64, read_number64); |
+ |
+ QuicDataWriter writer2(8, buffer64, GetParam().perspective, |
+ GetParam().endianness); |
+ writer2.WriteUInt64(in_memory64); |
+ test::CompareCharArraysWithHexError( |
+ "uint64_t", buffer64, 8, |
+ GetParam().endianness == NETWORK_BYTE_ORDER ? AsChars(big_endian64) |
+ : AsChars(little_endian64), |
+ 8); |
+ read_number64 = 0u; |
+ QuicDataReader reader2(buffer64, 8, GetParam().perspective, |
+ GetParam().endianness); |
+ reader2.ReadUInt64(&read_number64); |
+ EXPECT_EQ(in_memory64, read_number64); |
+} |
+ |
+TEST_P(QuicDataWriterTest, WriteIntegers) { |
+ char buf[43]; |
+ uint8_t i8 = 0x01; |
+ uint16_t i16 = 0x0123; |
+ uint32_t i32 = 0x01234567; |
+ uint64_t i64 = 0x0123456789ABCDEF; |
+ QuicDataWriter writer(46, buf, GetParam().perspective, GetParam().endianness); |
+ for (size_t i = 0; i < 10; ++i) { |
+ switch (i) { |
+ case 0u: |
+ EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64)); |
+ break; |
+ case 1u: |
+ EXPECT_TRUE(writer.WriteUInt8(i8)); |
+ EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64)); |
+ break; |
+ case 2u: |
+ EXPECT_TRUE(writer.WriteUInt16(i16)); |
+ EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64)); |
+ break; |
+ case 3u: |
+ EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64)); |
+ break; |
+ case 4u: |
+ EXPECT_TRUE(writer.WriteUInt32(i32)); |
+ EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64)); |
+ break; |
+ case 5u: |
+ case 6u: |
+ case 7u: |
+ case 8u: |
+ EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64)); |
+ break; |
+ default: |
+ EXPECT_FALSE(writer.WriteBytesToUInt64(i, i64)); |
+ } |
+ } |
+ |
+ QuicDataReader reader(buf, 46, GetParam().perspective, GetParam().endianness); |
+ for (size_t i = 0; i < 10; ++i) { |
+ uint8_t read8; |
+ uint16_t read16; |
+ uint32_t read32; |
+ uint64_t read64 = 0u; |
+ switch (i) { |
+ case 0u: |
+ EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64)); |
+ EXPECT_EQ(0u, read64); |
+ break; |
+ case 1u: |
+ EXPECT_TRUE(reader.ReadUInt8(&read8)); |
+ EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64)); |
+ EXPECT_EQ(i8, read8); |
+ EXPECT_EQ(0xEFu, read64); |
+ break; |
+ case 2u: |
+ EXPECT_TRUE(reader.ReadUInt16(&read16)); |
+ EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64)); |
+ EXPECT_EQ(i16, read16); |
+ EXPECT_EQ(0xCDEFu, read64); |
+ break; |
+ case 3u: |
+ EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64)); |
+ EXPECT_EQ(0xABCDEFu, read64); |
+ break; |
+ case 4u: |
+ EXPECT_TRUE(reader.ReadUInt32(&read32)); |
+ EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64)); |
+ EXPECT_EQ(i32, read32); |
+ EXPECT_EQ(0x89ABCDEFu, read64); |
+ break; |
+ case 5u: |
+ EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64)); |
+ EXPECT_EQ(0x6789ABCDEFu, read64); |
+ break; |
+ case 6u: |
+ EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64)); |
+ EXPECT_EQ(0x456789ABCDEFu, read64); |
+ break; |
+ case 7u: |
+ EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64)); |
+ EXPECT_EQ(0x23456789ABCDEFu, read64); |
+ break; |
+ case 8u: |
+ EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64)); |
+ EXPECT_EQ(0x0123456789ABCDEFu, read64); |
+ break; |
+ default: |
+ EXPECT_FALSE(reader.ReadBytesToUInt64(i, &read64)); |
+ } |
+ } |
+} |
+ |
} // namespace |
} // namespace test |
} // namespace net |