Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(997)

Side by Side Diff: net/http2/tools/random_decoder_test.h

Issue 2554683003: Revert of Add new HTTP/2 and HPACK decoder in net/http2/. (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/http2/tools/http2_random.cc ('k') | net/http2/tools/random_decoder_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 NET_HTTP2_TOOLS_RANDOM_DECODER_TEST_H_
6 #define NET_HTTP2_TOOLS_RANDOM_DECODER_TEST_H_
7
8 // RandomDecoderTest is a base class for tests of decoding various kinds
9 // of HTTP/2 and HPACK encodings.
10
11 // TODO(jamessynge): Move more methods into .cc file.
12
13 #include <stddef.h>
14
15 #include <memory>
16 #include <string>
17 #include <type_traits>
18
19 #include "base/bind.h"
20 #include "base/callback.h"
21 #include "base/logging.h"
22 #include "base/strings/string_piece.h"
23 #include "base/template_util.h"
24 #include "net/http2/decoder/decode_buffer.h"
25 #include "net/http2/decoder/decode_status.h"
26 #include "net/http2/tools/failure.h"
27 #include "net/http2/tools/http2_random.h"
28 #include "testing/gtest/include/gtest/gtest.h"
29
30 namespace net {
31 namespace test {
32
33 // Some helpers.
34
35 template <typename T, size_t N>
36 base::StringPiece ToStringPiece(T (&data)[N]) {
37 return base::StringPiece(reinterpret_cast<const char*>(data), N * sizeof(T));
38 }
39
40 // strings/hex_ascii_dump.h doesn't support StringPiece args for this case.
41 std::string HexEncode(base::StringPiece s);
42
43 // Overwrite the enum with some random value, probably not a valid value for
44 // the enum type, but which fits into its storage.
45 template <typename T,
46 typename E = typename std::enable_if<std::is_enum<T>::value>::type>
47 void CorruptEnum(T* out, RandomBase* rng) {
48 // Per cppreference.com, if the destination type of a static_cast is
49 // smaller than the source type (i.e. type of r and uint32 below), the
50 // resulting value is the smallest unsigned value equal to the source value
51 // modulo 2^n, where n is the number of bits used to represent the
52 // destination type unsigned U.
53 typedef typename base::underlying_type<T>::type underlying_type_T;
54 typedef typename std::make_unsigned<underlying_type_T>::type
55 unsigned_underlying_type_T;
56 auto r = static_cast<unsigned_underlying_type_T>(rng->Rand32());
57 *out = static_cast<T>(r);
58 }
59
60 // Base class for tests of the ability to decode a sequence of bytes with
61 // various boundaries between the DecodeBuffers provided to the decoder.
62 class RandomDecoderTest : public ::testing::Test {
63 public:
64 // SelectSize returns the size of the next DecodeBuffer to be passed to the
65 // decoder. Note that RandomDecoderTest allows that size to be zero, though
66 // some decoders can't deal with that on the first byte, hence the |first|
67 // parameter.
68 typedef base::Callback<size_t(bool first, size_t offset, size_t remaining)>
69 SelectSize;
70
71 // Validator returns an AssertionResult so test can do:
72 // EXPECT_THAT(DecodeAndValidate(..., validator));
73 typedef ::testing::AssertionResult AssertionResult;
74 typedef base::Callback<AssertionResult(const DecodeBuffer& input,
75 DecodeStatus status)>
76 Validator;
77 typedef base::Callback<AssertionResult()> NoArgValidator;
78
79 RandomDecoderTest();
80
81 protected:
82 // TODO(jamessynge): Modify StartDecoding, etc. to (somehow) return
83 // AssertionResult so that the VERIFY_* methods exported from
84 // gunit_helpers.h can be widely used.
85
86 // Start decoding; call allows sub-class to Reset the decoder, or deal with
87 // the first byte if that is done in a unique fashion. Might be called with
88 // a zero byte buffer.
89 virtual DecodeStatus StartDecoding(DecodeBuffer* db) = 0;
90
91 // Resume decoding of the input after a prior call to StartDecoding, and
92 // possibly many calls to ResumeDecoding.
93 virtual DecodeStatus ResumeDecoding(DecodeBuffer* db) = 0;
94
95 // Return true if a decode status of kDecodeDone indicates that
96 // decoding should stop.
97 virtual bool StopDecodeOnDone();
98
99 // Decode buffer |original| until we run out of input, or kDecodeDone is
100 // returned by the decoder AND StopDecodeOnDone() returns true. Segments
101 // (i.e. cuts up) the original DecodeBuffer into (potentially) smaller buffers
102 // by calling |select_size| to decide how large each buffer should be.
103 // We do this to test the ability to deal with arbitrary boundaries, as might
104 // happen in transport.
105 // Returns the final DecodeStatus.
106 DecodeStatus DecodeSegments(DecodeBuffer* original,
107 const SelectSize& select_size);
108
109 // Decode buffer |original| until we run out of input, or kDecodeDone is
110 // returned by the decoder AND StopDecodeOnDone() returns true. Segments
111 // (i.e. cuts up) the original DecodeBuffer into (potentially) smaller buffers
112 // by calling |select_size| to decide how large each buffer should be.
113 // We do this to test the ability to deal with arbitrary boundaries, as might
114 // happen in transport.
115 // Invokes |validator| with the final decode status and the original decode
116 // buffer, with the cursor advanced as far as has been consumed by the decoder
117 // and returns validator's result.
118 ::testing::AssertionResult DecodeSegmentsAndValidate(
119 DecodeBuffer* original,
120 const SelectSize& select_size,
121 const Validator& validator) {
122 DecodeStatus status = DecodeSegments(original, select_size);
123 VERIFY_AND_RETURN_SUCCESS(validator.Run(*original, status));
124 }
125
126 // Returns a size for fast decoding, i.e. passing all that
127 // is available to the decoder.
128 static size_t SelectRemaining(bool first, size_t offset, size_t remaining) {
129 return remaining;
130 }
131
132 // Returns a size for decoding a single byte at a time.
133 static size_t SelectOne(bool first, size_t offset, size_t remaining) {
134 return 1;
135 }
136
137 // Returns a size for decoding a single byte at a time, where
138 // zero byte buffers are also allowed. Alternates between zero and one.
139 static size_t SelectZeroAndOne(bool* zero_next,
140 bool first,
141 size_t offset,
142 size_t remaining);
143
144 // Returns a size for decoding random sized segments.
145 size_t SelectRandom(bool return_non_zero_on_first,
146 bool first,
147 size_t offset,
148 size_t remaining);
149
150 // Decode |original| multiple times, with different segmentations of the
151 // decode buffer, validating after each decode, and confirming that they
152 // each decode the same amount. Returns on the first failure, else returns
153 // success.
154 AssertionResult DecodeAndValidateSeveralWays(DecodeBuffer* original,
155 bool return_non_zero_on_first,
156 const Validator& validator);
157
158 static AssertionResult SucceedingValidator(const DecodeBuffer& input,
159 DecodeStatus status) {
160 return ::testing::AssertionSuccess();
161 }
162
163 static Validator ToValidator(const Validator& validator) { return validator; }
164
165 static AssertionResult RunNoArgValidator(const NoArgValidator& validator,
166 const DecodeBuffer& input,
167 DecodeStatus status) {
168 return validator.Run();
169 }
170
171 static Validator ToValidator(const NoArgValidator& validator) {
172 return base::Bind(&RunNoArgValidator, validator);
173 }
174
175 // Wraps a validator with another validator
176 // that first checks that the DecodeStatus is kDecodeDone and
177 // that the DecodeBuffer is empty.
178 // TODO(jamessynge): Replace this overload with the next, as using this method
179 // usually means that the wrapped function doesn't need to be passed the
180 // DecodeBuffer nor the DecodeStatus.
181 static AssertionResult ValidateDoneAndEmptyImpl(const Validator& wrapped,
182 const DecodeBuffer& input,
183 DecodeStatus status) {
184 VERIFY_EQ(status, DecodeStatus::kDecodeDone);
185 VERIFY_EQ(0u, input.Remaining()) << "\nOffset=" << input.Offset();
186 return wrapped.Run(input, status);
187 }
188 static Validator ValidateDoneAndEmpty(const Validator& wrapped) {
189 return base::Bind(&ValidateDoneAndEmptyImpl, wrapped);
190 }
191 static AssertionResult ValidateDoneAndEmptyNoArgImpl(
192 const NoArgValidator& wrapped,
193 const DecodeBuffer& input,
194 DecodeStatus status) {
195 VERIFY_EQ(status, DecodeStatus::kDecodeDone);
196 VERIFY_EQ(0u, input.Remaining()) << "\nOffset=" << input.Offset();
197 return wrapped.Run();
198 }
199 static Validator ValidateDoneAndEmpty(const NoArgValidator& wrapped) {
200 return base::Bind(&ValidateDoneAndEmptyNoArgImpl, wrapped);
201 }
202 static Validator ValidateDoneAndEmpty() {
203 return ValidateDoneAndEmpty(base::Bind(&SucceedingValidator));
204 }
205
206 // Wraps a validator with another validator
207 // that first checks that the DecodeStatus is kDecodeDone and
208 // that the DecodeBuffer has the expected offset.
209 // TODO(jamessynge): Replace this overload with the next, as using this method
210 // usually means that the wrapped function doesn't need to be passed the
211 // DecodeBuffer nor the DecodeStatus.
212 static AssertionResult ValidateDoneAndOffsetImpl(uint32_t offset,
213 const Validator& wrapped,
214 const DecodeBuffer& input,
215 DecodeStatus status) {
216 VERIFY_EQ(status, DecodeStatus::kDecodeDone);
217 VERIFY_EQ(offset, input.Offset()) << "\nRemaining=" << input.Remaining();
218 return wrapped.Run(input, status);
219 }
220 static Validator ValidateDoneAndOffset(uint32_t offset,
221 const Validator& wrapped) {
222 // Make a copy of |wrapped| (by not using base::ConstRef) to avoid lifetime
223 // issues if this method is called with a temporary Validator.
224 return base::Bind(&ValidateDoneAndOffsetImpl, offset, wrapped);
225 }
226 static AssertionResult ValidateDoneAndOffsetNoArgImpl(
227 uint32_t offset,
228 const NoArgValidator& wrapped,
229 const DecodeBuffer& input,
230 DecodeStatus status) {
231 VERIFY_EQ(status, DecodeStatus::kDecodeDone);
232 VERIFY_EQ(offset, input.Offset()) << "\nRemaining=" << input.Remaining();
233 return wrapped.Run();
234 }
235 static Validator ValidateDoneAndOffset(uint32_t offset,
236 const NoArgValidator& wrapped) {
237 // Make a copy of |wrapped| (by not using base::ConstRef) to avoid lifetime
238 // issues if this method is called with a temporary Validator.
239 return base::Bind(&ValidateDoneAndOffsetNoArgImpl, offset, wrapped);
240 }
241 static Validator ValidateDoneAndOffset(uint32_t offset) {
242 // Make a copy of |wrapped| (by not using base::ConstRef) to avoid lifetime
243 // issues if this method is called with a temporary Validator.
244 return ValidateDoneAndOffset(offset, base::Bind(&SucceedingValidator));
245 }
246
247 // Expose |random_| as RandomBase so callers do not have to care about which
248 // sub-class of RandomBase is used, nor can they rely on the specific
249 // sub-class that RandomDecoderTest uses.
250 RandomBase& Random() { return random_; }
251 RandomBase* RandomPtr() { return &random_; }
252
253 uint32_t RandStreamId();
254
255 bool stop_decode_on_done_ = true;
256
257 private:
258 Http2Random random_;
259 };
260
261 } // namespace test
262 } // namespace net
263
264 #endif // NET_HTTP2_TOOLS_RANDOM_DECODER_TEST_H_
OLDNEW
« no previous file with comments | « net/http2/tools/http2_random.cc ('k') | net/http2/tools/random_decoder_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698