dmcardle | 2b64f50 | 2020-01-07 15:22:36 -0800 | [diff] [blame] | 1 | // Copyright (c) 2020 The Chromium Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include "net/third_party/quiche/src/common/quiche_data_writer.h" |
| 6 | |
| 7 | #include <cstdint> |
| 8 | #include <cstring> |
| 9 | |
| 10 | #include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" |
| 11 | #include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" |
| 12 | #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" |
| 13 | #include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" |
| 14 | #include "net/third_party/quiche/src/common/platform/api/quiche_test.h" |
| 15 | #include "net/third_party/quiche/src/common/quiche_data_reader.h" |
| 16 | #include "net/third_party/quiche/src/common/test_tools/quiche_test_utils.h" |
| 17 | |
| 18 | namespace quiche { |
| 19 | namespace test { |
| 20 | namespace { |
| 21 | |
| 22 | char* AsChars(unsigned char* data) { |
| 23 | return reinterpret_cast<char*>(data); |
| 24 | } |
| 25 | |
| 26 | struct TestParams { |
| 27 | explicit TestParams(quiche::Endianness endianness) : endianness(endianness) {} |
| 28 | |
| 29 | quiche::Endianness endianness; |
| 30 | }; |
| 31 | |
| 32 | // Used by ::testing::PrintToStringParamName(). |
| 33 | std::string PrintToString(const TestParams& p) { |
| 34 | return quiche::QuicheStrCat( |
| 35 | (p.endianness == quiche::NETWORK_BYTE_ORDER ? "Network" : "Host"), |
| 36 | "ByteOrder"); |
| 37 | } |
| 38 | |
| 39 | std::vector<TestParams> GetTestParams() { |
| 40 | std::vector<TestParams> params; |
| 41 | for (quiche::Endianness endianness : |
| 42 | {quiche::NETWORK_BYTE_ORDER, quiche::HOST_BYTE_ORDER}) { |
| 43 | params.push_back(TestParams(endianness)); |
| 44 | } |
| 45 | return params; |
| 46 | } |
| 47 | |
| 48 | class QuicheDataWriterTest : public QuicheTestWithParam<TestParams> {}; |
| 49 | |
| 50 | INSTANTIATE_TEST_SUITE_P(QuicheDataWriterTests, |
| 51 | QuicheDataWriterTest, |
| 52 | ::testing::ValuesIn(GetTestParams()), |
| 53 | ::testing::PrintToStringParamName()); |
| 54 | |
| 55 | TEST_P(QuicheDataWriterTest, Write16BitUnsignedIntegers) { |
| 56 | char little_endian16[] = {0x22, 0x11}; |
| 57 | char big_endian16[] = {0x11, 0x22}; |
| 58 | char buffer16[2]; |
| 59 | { |
| 60 | uint16_t in_memory16 = 0x1122; |
| 61 | QuicheDataWriter writer(2, buffer16, GetParam().endianness); |
| 62 | writer.WriteUInt16(in_memory16); |
| 63 | test::CompareCharArraysWithHexError( |
| 64 | "uint16_t", buffer16, 2, |
| 65 | GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian16 |
| 66 | : little_endian16, |
| 67 | 2); |
| 68 | |
| 69 | uint16_t read_number16; |
| 70 | QuicheDataReader reader(buffer16, 2, GetParam().endianness); |
| 71 | reader.ReadUInt16(&read_number16); |
| 72 | EXPECT_EQ(in_memory16, read_number16); |
| 73 | } |
| 74 | |
| 75 | { |
| 76 | uint64_t in_memory16 = 0x0000000000001122; |
| 77 | QuicheDataWriter writer(2, buffer16, GetParam().endianness); |
| 78 | writer.WriteBytesToUInt64(2, in_memory16); |
| 79 | test::CompareCharArraysWithHexError( |
| 80 | "uint16_t", buffer16, 2, |
| 81 | GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian16 |
| 82 | : little_endian16, |
| 83 | 2); |
| 84 | |
| 85 | uint64_t read_number16; |
| 86 | QuicheDataReader reader(buffer16, 2, GetParam().endianness); |
| 87 | reader.ReadBytesToUInt64(2, &read_number16); |
| 88 | EXPECT_EQ(in_memory16, read_number16); |
| 89 | } |
| 90 | } |
| 91 | |
| 92 | TEST_P(QuicheDataWriterTest, Write24BitUnsignedIntegers) { |
| 93 | char little_endian24[] = {0x33, 0x22, 0x11}; |
| 94 | char big_endian24[] = {0x11, 0x22, 0x33}; |
| 95 | char buffer24[3]; |
| 96 | uint64_t in_memory24 = 0x0000000000112233; |
| 97 | QuicheDataWriter writer(3, buffer24, GetParam().endianness); |
| 98 | writer.WriteBytesToUInt64(3, in_memory24); |
| 99 | test::CompareCharArraysWithHexError( |
| 100 | "uint24", buffer24, 3, |
| 101 | GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian24 |
| 102 | : little_endian24, |
| 103 | 3); |
| 104 | |
| 105 | uint64_t read_number24; |
| 106 | QuicheDataReader reader(buffer24, 3, GetParam().endianness); |
| 107 | reader.ReadBytesToUInt64(3, &read_number24); |
| 108 | EXPECT_EQ(in_memory24, read_number24); |
| 109 | } |
| 110 | |
| 111 | TEST_P(QuicheDataWriterTest, Write32BitUnsignedIntegers) { |
| 112 | char little_endian32[] = {0x44, 0x33, 0x22, 0x11}; |
| 113 | char big_endian32[] = {0x11, 0x22, 0x33, 0x44}; |
| 114 | char buffer32[4]; |
| 115 | { |
| 116 | uint32_t in_memory32 = 0x11223344; |
| 117 | QuicheDataWriter writer(4, buffer32, GetParam().endianness); |
| 118 | writer.WriteUInt32(in_memory32); |
| 119 | test::CompareCharArraysWithHexError( |
| 120 | "uint32_t", buffer32, 4, |
| 121 | GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian32 |
| 122 | : little_endian32, |
| 123 | 4); |
| 124 | |
| 125 | uint32_t read_number32; |
| 126 | QuicheDataReader reader(buffer32, 4, GetParam().endianness); |
| 127 | reader.ReadUInt32(&read_number32); |
| 128 | EXPECT_EQ(in_memory32, read_number32); |
| 129 | } |
| 130 | |
| 131 | { |
| 132 | uint64_t in_memory32 = 0x11223344; |
| 133 | QuicheDataWriter writer(4, buffer32, GetParam().endianness); |
| 134 | writer.WriteBytesToUInt64(4, in_memory32); |
| 135 | test::CompareCharArraysWithHexError( |
| 136 | "uint32_t", buffer32, 4, |
| 137 | GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian32 |
| 138 | : little_endian32, |
| 139 | 4); |
| 140 | |
| 141 | uint64_t read_number32; |
| 142 | QuicheDataReader reader(buffer32, 4, GetParam().endianness); |
| 143 | reader.ReadBytesToUInt64(4, &read_number32); |
| 144 | EXPECT_EQ(in_memory32, read_number32); |
| 145 | } |
| 146 | } |
| 147 | |
| 148 | TEST_P(QuicheDataWriterTest, Write40BitUnsignedIntegers) { |
| 149 | uint64_t in_memory40 = 0x0000001122334455; |
| 150 | char little_endian40[] = {0x55, 0x44, 0x33, 0x22, 0x11}; |
| 151 | char big_endian40[] = {0x11, 0x22, 0x33, 0x44, 0x55}; |
| 152 | char buffer40[5]; |
| 153 | QuicheDataWriter writer(5, buffer40, GetParam().endianness); |
| 154 | writer.WriteBytesToUInt64(5, in_memory40); |
| 155 | test::CompareCharArraysWithHexError( |
| 156 | "uint40", buffer40, 5, |
| 157 | GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian40 |
| 158 | : little_endian40, |
| 159 | 5); |
| 160 | |
| 161 | uint64_t read_number40; |
| 162 | QuicheDataReader reader(buffer40, 5, GetParam().endianness); |
| 163 | reader.ReadBytesToUInt64(5, &read_number40); |
| 164 | EXPECT_EQ(in_memory40, read_number40); |
| 165 | } |
| 166 | |
| 167 | TEST_P(QuicheDataWriterTest, Write48BitUnsignedIntegers) { |
| 168 | uint64_t in_memory48 = 0x0000112233445566; |
| 169 | char little_endian48[] = {0x66, 0x55, 0x44, 0x33, 0x22, 0x11}; |
| 170 | char big_endian48[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; |
| 171 | char buffer48[6]; |
| 172 | QuicheDataWriter writer(6, buffer48, GetParam().endianness); |
| 173 | writer.WriteBytesToUInt64(6, in_memory48); |
| 174 | test::CompareCharArraysWithHexError( |
| 175 | "uint48", buffer48, 6, |
| 176 | GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian48 |
| 177 | : little_endian48, |
| 178 | 6); |
| 179 | |
| 180 | uint64_t read_number48; |
| 181 | QuicheDataReader reader(buffer48, 6, GetParam().endianness); |
| 182 | reader.ReadBytesToUInt64(6., &read_number48); |
| 183 | EXPECT_EQ(in_memory48, read_number48); |
| 184 | } |
| 185 | |
| 186 | TEST_P(QuicheDataWriterTest, Write56BitUnsignedIntegers) { |
| 187 | uint64_t in_memory56 = 0x0011223344556677; |
| 188 | char little_endian56[] = {0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11}; |
| 189 | char big_endian56[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; |
| 190 | char buffer56[7]; |
| 191 | QuicheDataWriter writer(7, buffer56, GetParam().endianness); |
| 192 | writer.WriteBytesToUInt64(7, in_memory56); |
| 193 | test::CompareCharArraysWithHexError( |
| 194 | "uint56", buffer56, 7, |
| 195 | GetParam().endianness == quiche::NETWORK_BYTE_ORDER ? big_endian56 |
| 196 | : little_endian56, |
| 197 | 7); |
| 198 | |
| 199 | uint64_t read_number56; |
| 200 | QuicheDataReader reader(buffer56, 7, GetParam().endianness); |
| 201 | reader.ReadBytesToUInt64(7, &read_number56); |
| 202 | EXPECT_EQ(in_memory56, read_number56); |
| 203 | } |
| 204 | |
| 205 | TEST_P(QuicheDataWriterTest, Write64BitUnsignedIntegers) { |
| 206 | uint64_t in_memory64 = 0x1122334455667788; |
| 207 | unsigned char little_endian64[] = {0x88, 0x77, 0x66, 0x55, |
| 208 | 0x44, 0x33, 0x22, 0x11}; |
| 209 | unsigned char big_endian64[] = {0x11, 0x22, 0x33, 0x44, |
| 210 | 0x55, 0x66, 0x77, 0x88}; |
| 211 | char buffer64[8]; |
| 212 | QuicheDataWriter writer(8, buffer64, GetParam().endianness); |
| 213 | writer.WriteBytesToUInt64(8, in_memory64); |
| 214 | test::CompareCharArraysWithHexError( |
| 215 | "uint64_t", buffer64, 8, |
| 216 | GetParam().endianness == quiche::NETWORK_BYTE_ORDER |
| 217 | ? AsChars(big_endian64) |
| 218 | : AsChars(little_endian64), |
| 219 | 8); |
| 220 | |
| 221 | uint64_t read_number64; |
| 222 | QuicheDataReader reader(buffer64, 8, GetParam().endianness); |
| 223 | reader.ReadBytesToUInt64(8, &read_number64); |
| 224 | EXPECT_EQ(in_memory64, read_number64); |
| 225 | |
| 226 | QuicheDataWriter writer2(8, buffer64, GetParam().endianness); |
| 227 | writer2.WriteUInt64(in_memory64); |
| 228 | test::CompareCharArraysWithHexError( |
| 229 | "uint64_t", buffer64, 8, |
| 230 | GetParam().endianness == quiche::NETWORK_BYTE_ORDER |
| 231 | ? AsChars(big_endian64) |
| 232 | : AsChars(little_endian64), |
| 233 | 8); |
| 234 | read_number64 = 0u; |
| 235 | QuicheDataReader reader2(buffer64, 8, GetParam().endianness); |
| 236 | reader2.ReadUInt64(&read_number64); |
| 237 | EXPECT_EQ(in_memory64, read_number64); |
| 238 | } |
| 239 | |
| 240 | TEST_P(QuicheDataWriterTest, WriteIntegers) { |
| 241 | char buf[43]; |
| 242 | uint8_t i8 = 0x01; |
| 243 | uint16_t i16 = 0x0123; |
| 244 | uint32_t i32 = 0x01234567; |
| 245 | uint64_t i64 = 0x0123456789ABCDEF; |
| 246 | QuicheDataWriter writer(46, buf, GetParam().endianness); |
| 247 | for (size_t i = 0; i < 10; ++i) { |
| 248 | switch (i) { |
| 249 | case 0u: |
| 250 | EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64)); |
| 251 | break; |
| 252 | case 1u: |
| 253 | EXPECT_TRUE(writer.WriteUInt8(i8)); |
| 254 | EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64)); |
| 255 | break; |
| 256 | case 2u: |
| 257 | EXPECT_TRUE(writer.WriteUInt16(i16)); |
| 258 | EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64)); |
| 259 | break; |
| 260 | case 3u: |
| 261 | EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64)); |
| 262 | break; |
| 263 | case 4u: |
| 264 | EXPECT_TRUE(writer.WriteUInt32(i32)); |
| 265 | EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64)); |
| 266 | break; |
| 267 | case 5u: |
| 268 | case 6u: |
| 269 | case 7u: |
| 270 | case 8u: |
| 271 | EXPECT_TRUE(writer.WriteBytesToUInt64(i, i64)); |
| 272 | break; |
| 273 | default: |
| 274 | EXPECT_FALSE(writer.WriteBytesToUInt64(i, i64)); |
| 275 | } |
| 276 | } |
| 277 | |
| 278 | QuicheDataReader reader(buf, 46, GetParam().endianness); |
| 279 | for (size_t i = 0; i < 10; ++i) { |
| 280 | uint8_t read8; |
| 281 | uint16_t read16; |
| 282 | uint32_t read32; |
| 283 | uint64_t read64; |
| 284 | switch (i) { |
| 285 | case 0u: |
| 286 | EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64)); |
| 287 | EXPECT_EQ(0u, read64); |
| 288 | break; |
| 289 | case 1u: |
| 290 | EXPECT_TRUE(reader.ReadUInt8(&read8)); |
| 291 | EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64)); |
| 292 | EXPECT_EQ(i8, read8); |
| 293 | EXPECT_EQ(0xEFu, read64); |
| 294 | break; |
| 295 | case 2u: |
| 296 | EXPECT_TRUE(reader.ReadUInt16(&read16)); |
| 297 | EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64)); |
| 298 | EXPECT_EQ(i16, read16); |
| 299 | EXPECT_EQ(0xCDEFu, read64); |
| 300 | break; |
| 301 | case 3u: |
| 302 | EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64)); |
| 303 | EXPECT_EQ(0xABCDEFu, read64); |
| 304 | break; |
| 305 | case 4u: |
| 306 | EXPECT_TRUE(reader.ReadUInt32(&read32)); |
| 307 | EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64)); |
| 308 | EXPECT_EQ(i32, read32); |
| 309 | EXPECT_EQ(0x89ABCDEFu, read64); |
| 310 | break; |
| 311 | case 5u: |
| 312 | EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64)); |
| 313 | EXPECT_EQ(0x6789ABCDEFu, read64); |
| 314 | break; |
| 315 | case 6u: |
| 316 | EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64)); |
| 317 | EXPECT_EQ(0x456789ABCDEFu, read64); |
| 318 | break; |
| 319 | case 7u: |
| 320 | EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64)); |
| 321 | EXPECT_EQ(0x23456789ABCDEFu, read64); |
| 322 | break; |
| 323 | case 8u: |
| 324 | EXPECT_TRUE(reader.ReadBytesToUInt64(i, &read64)); |
| 325 | EXPECT_EQ(0x0123456789ABCDEFu, read64); |
| 326 | break; |
| 327 | default: |
| 328 | EXPECT_FALSE(reader.ReadBytesToUInt64(i, &read64)); |
| 329 | } |
| 330 | } |
| 331 | } |
| 332 | |
| 333 | TEST_P(QuicheDataWriterTest, WriteBytes) { |
| 334 | char bytes[] = {0, 1, 2, 3, 4, 5, 6, 7, 8}; |
| 335 | char buf[QUICHE_ARRAYSIZE(bytes)]; |
| 336 | QuicheDataWriter writer(QUICHE_ARRAYSIZE(buf), buf, GetParam().endianness); |
| 337 | EXPECT_TRUE(writer.WriteBytes(bytes, QUICHE_ARRAYSIZE(bytes))); |
| 338 | for (unsigned int i = 0; i < QUICHE_ARRAYSIZE(bytes); ++i) { |
| 339 | EXPECT_EQ(bytes[i], buf[i]); |
| 340 | } |
| 341 | } |
| 342 | |
| 343 | TEST_P(QuicheDataWriterTest, Seek) { |
| 344 | char buffer[3] = {}; |
| 345 | QuicheDataWriter writer(QUICHE_ARRAYSIZE(buffer), buffer, |
| 346 | GetParam().endianness); |
| 347 | EXPECT_TRUE(writer.WriteUInt8(42)); |
| 348 | EXPECT_TRUE(writer.Seek(1)); |
| 349 | EXPECT_TRUE(writer.WriteUInt8(3)); |
| 350 | |
| 351 | char expected[] = {42, 0, 3}; |
| 352 | for (size_t i = 0; i < QUICHE_ARRAYSIZE(expected); ++i) { |
| 353 | EXPECT_EQ(buffer[i], expected[i]); |
| 354 | } |
| 355 | } |
| 356 | |
| 357 | TEST_P(QuicheDataWriterTest, SeekTooFarFails) { |
| 358 | char buffer[20]; |
| 359 | |
| 360 | // Check that one can seek to the end of the writer, but not past. |
| 361 | { |
| 362 | QuicheDataWriter writer(QUICHE_ARRAYSIZE(buffer), buffer, |
| 363 | GetParam().endianness); |
| 364 | EXPECT_TRUE(writer.Seek(20)); |
| 365 | EXPECT_FALSE(writer.Seek(1)); |
| 366 | } |
| 367 | |
| 368 | // Seeking several bytes past the end fails. |
| 369 | { |
| 370 | QuicheDataWriter writer(QUICHE_ARRAYSIZE(buffer), buffer, |
| 371 | GetParam().endianness); |
| 372 | EXPECT_FALSE(writer.Seek(100)); |
| 373 | } |
| 374 | |
| 375 | // Seeking so far that arithmetic overflow could occur also fails. |
| 376 | { |
| 377 | QuicheDataWriter writer(QUICHE_ARRAYSIZE(buffer), buffer, |
| 378 | GetParam().endianness); |
| 379 | EXPECT_TRUE(writer.Seek(10)); |
| 380 | EXPECT_FALSE(writer.Seek(std::numeric_limits<size_t>::max())); |
| 381 | } |
| 382 | } |
| 383 | |
| 384 | TEST_P(QuicheDataWriterTest, PayloadReads) { |
| 385 | char buffer[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; |
| 386 | char expected_first_read[4] = {1, 2, 3, 4}; |
| 387 | char expected_remaining[12] = {5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; |
| 388 | QuicheDataReader reader(buffer, sizeof(buffer)); |
dschinazi | 278efae | 2020-01-28 17:03:09 -0800 | [diff] [blame] | 389 | quiche::QuicheStringPiece previously_read_payload1 = |
| 390 | reader.PreviouslyReadPayload(); |
| 391 | EXPECT_TRUE(previously_read_payload1.empty()); |
dmcardle | 2b64f50 | 2020-01-07 15:22:36 -0800 | [diff] [blame] | 392 | char first_read_buffer[4] = {}; |
| 393 | EXPECT_TRUE(reader.ReadBytes(first_read_buffer, sizeof(first_read_buffer))); |
| 394 | test::CompareCharArraysWithHexError( |
| 395 | "first read", first_read_buffer, sizeof(first_read_buffer), |
| 396 | expected_first_read, sizeof(expected_first_read)); |
| 397 | quiche::QuicheStringPiece peeked_remaining_payload = |
| 398 | reader.PeekRemainingPayload(); |
| 399 | test::CompareCharArraysWithHexError( |
| 400 | "peeked_remaining_payload", peeked_remaining_payload.data(), |
| 401 | peeked_remaining_payload.length(), expected_remaining, |
| 402 | sizeof(expected_remaining)); |
| 403 | quiche::QuicheStringPiece full_payload = reader.FullPayload(); |
| 404 | test::CompareCharArraysWithHexError("full_payload", full_payload.data(), |
| 405 | full_payload.length(), buffer, |
| 406 | sizeof(buffer)); |
dschinazi | 278efae | 2020-01-28 17:03:09 -0800 | [diff] [blame] | 407 | quiche::QuicheStringPiece previously_read_payload2 = |
| 408 | reader.PreviouslyReadPayload(); |
| 409 | test::CompareCharArraysWithHexError( |
| 410 | "previously_read_payload2", previously_read_payload2.data(), |
| 411 | previously_read_payload2.length(), first_read_buffer, |
| 412 | sizeof(first_read_buffer)); |
dmcardle | 2b64f50 | 2020-01-07 15:22:36 -0800 | [diff] [blame] | 413 | quiche::QuicheStringPiece read_remaining_payload = |
| 414 | reader.ReadRemainingPayload(); |
| 415 | test::CompareCharArraysWithHexError( |
| 416 | "read_remaining_payload", read_remaining_payload.data(), |
| 417 | read_remaining_payload.length(), expected_remaining, |
| 418 | sizeof(expected_remaining)); |
| 419 | EXPECT_TRUE(reader.IsDoneReading()); |
| 420 | quiche::QuicheStringPiece full_payload2 = reader.FullPayload(); |
| 421 | test::CompareCharArraysWithHexError("full_payload2", full_payload2.data(), |
| 422 | full_payload2.length(), buffer, |
| 423 | sizeof(buffer)); |
dschinazi | 278efae | 2020-01-28 17:03:09 -0800 | [diff] [blame] | 424 | quiche::QuicheStringPiece previously_read_payload3 = |
| 425 | reader.PreviouslyReadPayload(); |
| 426 | test::CompareCharArraysWithHexError( |
| 427 | "previously_read_payload3", previously_read_payload3.data(), |
| 428 | previously_read_payload3.length(), buffer, sizeof(buffer)); |
dmcardle | 2b64f50 | 2020-01-07 15:22:36 -0800 | [diff] [blame] | 429 | } |
| 430 | |
| 431 | } // namespace |
| 432 | } // namespace test |
| 433 | } // namespace quiche |