1 // Copyright 2016 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 "quiche/http2/test_tools/hpack_block_collector.h"
6
7 #include <algorithm>
8 #include <memory>
9
10 #include "quiche/http2/test_tools/verify_macros.h"
11 #include "quiche/common/platform/api/quiche_logging.h"
12
13 using ::testing::AssertionResult;
14 using ::testing::AssertionSuccess;
15
16 namespace http2 {
17 namespace test {
18
19 HpackBlockCollector::HpackBlockCollector() = default;
HpackBlockCollector(const HpackBlockCollector & other)20 HpackBlockCollector::HpackBlockCollector(const HpackBlockCollector& other)
21 : pending_entry_(other.pending_entry_), entries_(other.entries_) {}
22 HpackBlockCollector::~HpackBlockCollector() = default;
23
OnIndexedHeader(size_t index)24 void HpackBlockCollector::OnIndexedHeader(size_t index) {
25 pending_entry_.OnIndexedHeader(index);
26 PushPendingEntry();
27 }
OnDynamicTableSizeUpdate(size_t size)28 void HpackBlockCollector::OnDynamicTableSizeUpdate(size_t size) {
29 pending_entry_.OnDynamicTableSizeUpdate(size);
30 PushPendingEntry();
31 }
OnStartLiteralHeader(HpackEntryType header_type,size_t maybe_name_index)32 void HpackBlockCollector::OnStartLiteralHeader(HpackEntryType header_type,
33 size_t maybe_name_index) {
34 pending_entry_.OnStartLiteralHeader(header_type, maybe_name_index);
35 }
OnNameStart(bool huffman_encoded,size_t len)36 void HpackBlockCollector::OnNameStart(bool huffman_encoded, size_t len) {
37 pending_entry_.OnNameStart(huffman_encoded, len);
38 }
OnNameData(const char * data,size_t len)39 void HpackBlockCollector::OnNameData(const char* data, size_t len) {
40 pending_entry_.OnNameData(data, len);
41 }
OnNameEnd()42 void HpackBlockCollector::OnNameEnd() { pending_entry_.OnNameEnd(); }
OnValueStart(bool huffman_encoded,size_t len)43 void HpackBlockCollector::OnValueStart(bool huffman_encoded, size_t len) {
44 pending_entry_.OnValueStart(huffman_encoded, len);
45 }
OnValueData(const char * data,size_t len)46 void HpackBlockCollector::OnValueData(const char* data, size_t len) {
47 pending_entry_.OnValueData(data, len);
48 }
OnValueEnd()49 void HpackBlockCollector::OnValueEnd() {
50 pending_entry_.OnValueEnd();
51 PushPendingEntry();
52 }
53
PushPendingEntry()54 void HpackBlockCollector::PushPendingEntry() {
55 EXPECT_TRUE(pending_entry_.IsComplete());
56 QUICHE_DVLOG(2) << "PushPendingEntry: " << pending_entry_;
57 entries_.push_back(pending_entry_);
58 EXPECT_TRUE(entries_.back().IsComplete());
59 pending_entry_.Clear();
60 }
Clear()61 void HpackBlockCollector::Clear() {
62 pending_entry_.Clear();
63 entries_.clear();
64 }
65
ExpectIndexedHeader(size_t index)66 void HpackBlockCollector::ExpectIndexedHeader(size_t index) {
67 entries_.push_back(
68 HpackEntryCollector(HpackEntryType::kIndexedHeader, index));
69 }
ExpectDynamicTableSizeUpdate(size_t size)70 void HpackBlockCollector::ExpectDynamicTableSizeUpdate(size_t size) {
71 entries_.push_back(
72 HpackEntryCollector(HpackEntryType::kDynamicTableSizeUpdate, size));
73 }
ExpectNameIndexAndLiteralValue(HpackEntryType type,size_t index,bool value_huffman,const std::string & value)74 void HpackBlockCollector::ExpectNameIndexAndLiteralValue(
75 HpackEntryType type, size_t index, bool value_huffman,
76 const std::string& value) {
77 entries_.push_back(HpackEntryCollector(type, index, value_huffman, value));
78 }
ExpectLiteralNameAndValue(HpackEntryType type,bool name_huffman,const std::string & name,bool value_huffman,const std::string & value)79 void HpackBlockCollector::ExpectLiteralNameAndValue(HpackEntryType type,
80 bool name_huffman,
81 const std::string& name,
82 bool value_huffman,
83 const std::string& value) {
84 entries_.push_back(
85 HpackEntryCollector(type, name_huffman, name, value_huffman, value));
86 }
87
ShuffleEntries(Http2Random * rng)88 void HpackBlockCollector::ShuffleEntries(Http2Random* rng) {
89 std::shuffle(entries_.begin(), entries_.end(), *rng);
90 }
91
AppendToHpackBlockBuilder(HpackBlockBuilder * hbb) const92 void HpackBlockCollector::AppendToHpackBlockBuilder(
93 HpackBlockBuilder* hbb) const {
94 QUICHE_CHECK(IsNotPending());
95 for (const auto& entry : entries_) {
96 entry.AppendToHpackBlockBuilder(hbb);
97 }
98 }
99
ValidateSoleIndexedHeader(size_t ndx) const100 AssertionResult HpackBlockCollector::ValidateSoleIndexedHeader(
101 size_t ndx) const {
102 HTTP2_VERIFY_TRUE(pending_entry_.IsClear());
103 HTTP2_VERIFY_EQ(1u, entries_.size());
104 HTTP2_VERIFY_TRUE(entries_.front().ValidateIndexedHeader(ndx));
105 return AssertionSuccess();
106 }
ValidateSoleLiteralValueHeader(HpackEntryType expected_type,size_t expected_index,bool expected_value_huffman,absl::string_view expected_value) const107 AssertionResult HpackBlockCollector::ValidateSoleLiteralValueHeader(
108 HpackEntryType expected_type, size_t expected_index,
109 bool expected_value_huffman, absl::string_view expected_value) const {
110 HTTP2_VERIFY_TRUE(pending_entry_.IsClear());
111 HTTP2_VERIFY_EQ(1u, entries_.size());
112 HTTP2_VERIFY_TRUE(entries_.front().ValidateLiteralValueHeader(
113 expected_type, expected_index, expected_value_huffman, expected_value));
114 return AssertionSuccess();
115 }
ValidateSoleLiteralNameValueHeader(HpackEntryType expected_type,bool expected_name_huffman,absl::string_view expected_name,bool expected_value_huffman,absl::string_view expected_value) const116 AssertionResult HpackBlockCollector::ValidateSoleLiteralNameValueHeader(
117 HpackEntryType expected_type, bool expected_name_huffman,
118 absl::string_view expected_name, bool expected_value_huffman,
119 absl::string_view expected_value) const {
120 HTTP2_VERIFY_TRUE(pending_entry_.IsClear());
121 HTTP2_VERIFY_EQ(1u, entries_.size());
122 HTTP2_VERIFY_TRUE(entries_.front().ValidateLiteralNameValueHeader(
123 expected_type, expected_name_huffman, expected_name,
124 expected_value_huffman, expected_value));
125 return AssertionSuccess();
126 }
ValidateSoleDynamicTableSizeUpdate(size_t size) const127 AssertionResult HpackBlockCollector::ValidateSoleDynamicTableSizeUpdate(
128 size_t size) const {
129 HTTP2_VERIFY_TRUE(pending_entry_.IsClear());
130 HTTP2_VERIFY_EQ(1u, entries_.size());
131 HTTP2_VERIFY_TRUE(entries_.front().ValidateDynamicTableSizeUpdate(size));
132 return AssertionSuccess();
133 }
134
VerifyEq(const HpackBlockCollector & that) const135 AssertionResult HpackBlockCollector::VerifyEq(
136 const HpackBlockCollector& that) const {
137 HTTP2_VERIFY_EQ(pending_entry_, that.pending_entry_);
138 HTTP2_VERIFY_EQ(entries_, that.entries_);
139 return AssertionSuccess();
140 }
141
142 } // namespace test
143 } // namespace http2
144