xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/http2/test_tools/hpack_block_collector.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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 #ifndef QUICHE_HTTP2_TEST_TOOLS_HPACK_BLOCK_COLLECTOR_H_
6 #define QUICHE_HTTP2_TEST_TOOLS_HPACK_BLOCK_COLLECTOR_H_
7 
8 // HpackBlockCollector implements HpackEntryDecoderListener in order to record
9 // the calls using HpackEntryCollector instances (one per HPACK entry). This
10 // supports testing of HpackBlockDecoder, which decodes entire HPACK blocks.
11 //
12 // In addition to implementing the callback methods, HpackBlockCollector also
13 // supports comparing two HpackBlockCollector instances (i.e. an expected and
14 // an actual), or a sole HPACK entry against an expected value.
15 
16 #include <stddef.h>
17 
18 #include <string>
19 #include <vector>
20 
21 #include "absl/strings/string_view.h"
22 #include "quiche/http2/hpack/decoder/hpack_entry_decoder_listener.h"
23 #include "quiche/http2/hpack/http2_hpack_constants.h"
24 #include "quiche/http2/test_tools/hpack_block_builder.h"
25 #include "quiche/http2/test_tools/hpack_entry_collector.h"
26 #include "quiche/http2/test_tools/http2_random.h"
27 #include "quiche/common/platform/api/quiche_export.h"
28 
29 namespace http2 {
30 namespace test {
31 
32 class QUICHE_NO_EXPORT HpackBlockCollector : public HpackEntryDecoderListener {
33  public:
34   HpackBlockCollector();
35   HpackBlockCollector(const HpackBlockCollector& other);
36   ~HpackBlockCollector() override;
37 
38   // Implementations of HpackEntryDecoderListener, forwarding to pending_entry_,
39   // an HpackEntryCollector for the "in-progress" HPACK entry. OnIndexedHeader
40   // and OnDynamicTableSizeUpdate are pending only for that one call, while
41   // OnStartLiteralHeader is followed by many calls, ending with OnValueEnd.
42   // Once all the calls for one HPACK entry have been received, PushPendingEntry
43   // is used to append the pending_entry_ entry to the collected entries_.
44   void OnIndexedHeader(size_t index) override;
45   void OnDynamicTableSizeUpdate(size_t size) override;
46   void OnStartLiteralHeader(HpackEntryType header_type,
47                             size_t maybe_name_index) override;
48   void OnNameStart(bool huffman_encoded, size_t len) override;
49   void OnNameData(const char* data, size_t len) override;
50   void OnNameEnd() override;
51   void OnValueStart(bool huffman_encoded, size_t len) override;
52   void OnValueData(const char* data, size_t len) override;
53   void OnValueEnd() override;
54 
55   // Methods for creating a set of expectations (i.e. HPACK entries to compare
56   // against those collected by another instance of HpackBlockCollector).
57 
58   // Add an HPACK entry for an indexed header.
59   void ExpectIndexedHeader(size_t index);
60 
61   // Add an HPACK entry for a dynamic table size update.
62   void ExpectDynamicTableSizeUpdate(size_t size);
63 
64   // Add an HPACK entry for a header entry with an index for the name, and a
65   // literal value.
66   void ExpectNameIndexAndLiteralValue(HpackEntryType type, size_t index,
67                                       bool value_huffman,
68                                       const std::string& value);
69 
70   // Add an HPACK entry for a header entry with a literal name and value.
71   void ExpectLiteralNameAndValue(HpackEntryType type, bool name_huffman,
72                                  const std::string& name, bool value_huffman,
73                                  const std::string& value);
74 
75   // Shuffle the entries, in support of generating an HPACK block of entries
76   // in some random order.
77   void ShuffleEntries(Http2Random* rng);
78 
79   // Serialize entries_ to the HpackBlockBuilder.
80   void AppendToHpackBlockBuilder(HpackBlockBuilder* hbb) const;
81 
82   // Return AssertionSuccess if there is just one entry, and it is an
83   // Indexed Header with the specified index.
84   ::testing::AssertionResult ValidateSoleIndexedHeader(size_t ndx) const;
85 
86   // Return AssertionSuccess if there is just one entry, and it is a
87   // Dynamic Table Size Update with the specified size.
88   ::testing::AssertionResult ValidateSoleDynamicTableSizeUpdate(
89       size_t size) const;
90 
91   // Return AssertionSuccess if there is just one entry, and it is a Header
92   // entry with an index for the name and a literal value.
93   ::testing::AssertionResult ValidateSoleLiteralValueHeader(
94       HpackEntryType expected_type, size_t expected_index,
95       bool expected_value_huffman, absl::string_view expected_value) const;
96 
97   // Return AssertionSuccess if there is just one entry, and it is a Header
98   // with a literal name and literal value.
99   ::testing::AssertionResult ValidateSoleLiteralNameValueHeader(
100       HpackEntryType expected_type, bool expected_name_huffman,
101       absl::string_view expected_name, bool expected_value_huffman,
102       absl::string_view expected_value) const;
103 
IsNotPending()104   bool IsNotPending() const { return pending_entry_.IsClear(); }
IsClear()105   bool IsClear() const { return IsNotPending() && entries_.empty(); }
106   void Clear();
107 
108   ::testing::AssertionResult VerifyEq(const HpackBlockCollector& that) const;
109 
110  private:
111   // Push the value of pending_entry_ onto entries_, and clear pending_entry_.
112   // The pending_entry_ must be complete.
113   void PushPendingEntry();
114 
115   HpackEntryCollector pending_entry_;
116   std::vector<HpackEntryCollector> entries_;
117 };
118 
119 }  // namespace test
120 }  // namespace http2
121 
122 #endif  // QUICHE_HTTP2_TEST_TOOLS_HPACK_BLOCK_COLLECTOR_H_
123