blob: b3067023b976c904f5967c3783bc31b2724e8827 [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright (c) 2018 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/quic/core/qpack/qpack_progressive_decoder.h"
6
7#include "net/third_party/quiche/src/quic/platform/api/quic_arraysize.h"
8#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
9
10namespace quic {
11namespace test {
12namespace {
13
14// For testing valid decodings, the Encoded Required Insert Count is calculated
15// from Required Insert Count, so that there is an expected value to compare
16// the decoded value against, and so that intricate inequalities can be
17// documented.
18struct {
19 uint64_t required_insert_count;
20 uint64_t max_entries;
21 uint64_t total_number_of_inserts;
22} kTestData[] = {
23 // Maximum dynamic table capacity is zero.
24 {0, 0, 0},
25 // No dynamic entries in header.
26 {0, 100, 0},
27 {0, 100, 500},
28 // Required Insert Count has not wrapped around yet, no entries evicted.
29 {15, 100, 25},
30 {20, 100, 10},
31 // Required Insert Count has not wrapped around yet, some entries evicted.
32 {90, 100, 110},
33 // Required Insert Count has wrapped around.
34 {234, 100, 180},
35 // Required Insert Count has wrapped around many times.
36 {5678, 100, 5701},
37 // Lowest and highest possible Required Insert Count values
38 // for given MaxEntries and total number of insertions.
39 {401, 100, 500},
40 {600, 100, 500}};
41
42uint64_t EncodeRequiredInsertCount(uint64_t required_insert_count,
43 uint64_t max_entries) {
44 if (required_insert_count == 0) {
45 return 0;
46 }
47
48 return required_insert_count % (2 * max_entries) + 1;
49}
50
51TEST(QpackProgressiveDecoderTest, DecodeRequiredInsertCount) {
52 for (size_t i = 0; i < QUIC_ARRAYSIZE(kTestData); ++i) {
53 const uint64_t required_insert_count = kTestData[i].required_insert_count;
54 const uint64_t max_entries = kTestData[i].max_entries;
55 const uint64_t total_number_of_inserts =
56 kTestData[i].total_number_of_inserts;
57
58 if (required_insert_count != 0) {
59 // Dynamic entries cannot be referenced if dynamic table capacity is zero.
60 ASSERT_LT(0u, max_entries) << i;
61 // Entry |total_number_of_inserts - 1 - max_entries| and earlier entries
62 // are evicted. Entry |required_insert_count - 1| is referenced. No
63 // evicted entry can be referenced.
64 ASSERT_LT(total_number_of_inserts, required_insert_count + max_entries)
65 << i;
66 // Entry |required_insert_count - 1 - max_entries| and earlier entries are
67 // evicted, entry |total_number_of_inserts - 1| is the last acknowledged
68 // entry. Every evicted entry must be acknowledged.
69 ASSERT_LE(required_insert_count, total_number_of_inserts + max_entries)
70 << i;
71 }
72
73 uint64_t encoded_required_insert_count =
74 EncodeRequiredInsertCount(required_insert_count, max_entries);
75
76 // Initialize to a value different from the expected output to confirm that
77 // DecodeRequiredInsertCount() modifies the value of
78 // |decoded_required_insert_count|.
79 uint64_t decoded_required_insert_count = required_insert_count + 1;
80 EXPECT_TRUE(QpackProgressiveDecoder::DecodeRequiredInsertCount(
81 encoded_required_insert_count, max_entries, total_number_of_inserts,
82 &decoded_required_insert_count))
83 << i;
84
85 EXPECT_EQ(decoded_required_insert_count, required_insert_count) << i;
86 }
87}
88
89// Failures are tested with hardcoded values for encoded required insert count,
90// to provide test coverage for values that would never be produced by a well
91// behaved encoding function.
92struct {
93 uint64_t encoded_required_insert_count;
94 uint64_t max_entries;
95 uint64_t total_number_of_inserts;
96} kInvalidTestData[] = {
97 // Maximum dynamic table capacity is zero, yet header block
98 // claims to have a reference to a dynamic table entry.
99 {1, 0, 0},
100 {9, 0, 0},
101 // Examples from
102 // https://github.com/quicwg/base-drafts/issues/2112#issue-389626872.
103 {1, 10, 2},
104 {18, 10, 2},
105 // Encoded Required Insert Count value too small or too large
106 // for given MaxEntries and total number of insertions.
107 {400, 100, 500},
108 {601, 100, 500}};
109
110TEST(QpackProgressiveDecoderTest, DecodeRequiredInsertCountError) {
111 for (size_t i = 0; i < QUIC_ARRAYSIZE(kInvalidTestData); ++i) {
112 uint64_t decoded_required_insert_count = 0;
113 EXPECT_FALSE(QpackProgressiveDecoder::DecodeRequiredInsertCount(
114 kInvalidTestData[i].encoded_required_insert_count,
115 kInvalidTestData[i].max_entries,
116 kInvalidTestData[i].total_number_of_inserts,
117 &decoded_required_insert_count))
118 << i;
119 }
120}
121
122} // namespace
123} // namespace test
124} // namespace quic