OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/http2/decoder/http2_frame_decoder.h" | 5 #include "net/http2/decoder/http2_frame_decoder.h" |
6 | 6 |
7 // Tests of Http2FrameDecoder. | 7 // Tests of Http2FrameDecoder. |
8 | 8 |
9 #include <string> | 9 #include <string> |
10 #include <vector> | 10 #include <vector> |
11 | 11 |
12 #include "base/bind.h" | |
13 #include "base/bind_helpers.h" | |
14 #include "base/logging.h" | 12 #include "base/logging.h" |
15 #include "net/http2/decoder/frame_parts.h" | 13 #include "net/http2/decoder/frame_parts.h" |
16 #include "net/http2/decoder/frame_parts_collector_listener.h" | 14 #include "net/http2/decoder/frame_parts_collector_listener.h" |
17 #include "net/http2/http2_constants.h" | 15 #include "net/http2/http2_constants.h" |
18 #include "net/http2/tools/failure.h" | 16 #include "net/http2/tools/failure.h" |
19 #include "net/http2/tools/http2_random.h" | 17 #include "net/http2/tools/http2_random.h" |
20 #include "net/http2/tools/random_decoder_test.h" | 18 #include "net/http2/tools/random_decoder_test.h" |
21 #include "testing/gtest/include/gtest/gtest.h" | 19 #include "testing/gtest/include/gtest/gtest.h" |
22 | 20 |
23 using base::StringPiece; | 21 using base::StringPiece; |
24 using std::string; | 22 using std::string; |
25 using ::testing::AssertionResult; | 23 using ::testing::AssertionResult; |
26 using ::testing::AssertionSuccess; | 24 using ::testing::AssertionSuccess; |
27 | 25 |
28 namespace net { | 26 namespace net { |
29 namespace test { | 27 namespace test { |
30 class Http2FrameDecoderPeer { | 28 class Http2FrameDecoderPeer { |
31 public: | 29 public: |
32 static size_t remaining_total_payload(Http2FrameDecoder* decoder) { | 30 static size_t remaining_total_payload(Http2FrameDecoder* decoder) { |
33 return decoder->frame_decoder_state_.remaining_total_payload(); | 31 return decoder->frame_decoder_state_.remaining_total_payload(); |
34 } | 32 } |
35 }; | 33 }; |
36 | 34 |
37 namespace { | 35 namespace { |
38 | 36 |
39 class Http2FrameDecoderTest : public RandomDecoderTest { | 37 class Http2FrameDecoderTest : public RandomDecoderTest { |
40 public: | |
41 AssertionResult ValidatorForDecodePayloadExpectingError( | |
42 const FrameParts& expected, | |
43 const DecodeBuffer& input, | |
44 DecodeStatus status) { | |
45 VERIFY_EQ(status, DecodeStatus::kDecodeError); | |
46 VERIFY_AND_RETURN_SUCCESS(VerifyCollected(expected)); | |
47 } | |
48 | |
49 AssertionResult ValidatorForBeyondMaximum(const FrameParts& expected, | |
50 const DecodeBuffer& input, | |
51 DecodeStatus status) { | |
52 VERIFY_EQ(status, DecodeStatus::kDecodeError); | |
53 // The decoder detects this error after decoding the header, and without | |
54 // trying to decode the payload. | |
55 VERIFY_EQ(input.Offset(), Http2FrameHeader::EncodedSize()); | |
56 VERIFY_AND_RETURN_SUCCESS(VerifyCollected(expected)); | |
57 } | |
58 | 38 |
59 protected: | 39 protected: |
60 void SetUp() override { | 40 void SetUp() override { |
61 // On any one run of this suite, we'll always choose the same value for | 41 // On any one run of this suite, we'll always choose the same value for |
62 // use_default_reconstruct_ because the random seed is the same for each | 42 // use_default_reconstruct_ because the random seed is the same for each |
63 // test case, but across runs the random seed changes. | 43 // test case, but across runs the random seed changes. |
64 use_default_reconstruct_ = Random().OneIn(2); | 44 use_default_reconstruct_ = Random().OneIn(2); |
65 } | 45 } |
66 | 46 |
67 DecodeStatus StartDecoding(DecodeBuffer* db) override { | 47 DecodeStatus StartDecoding(DecodeBuffer* db) override { |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
144 } | 124 } |
145 | 125 |
146 AssertionResult DecodePayloadAndValidateSeveralWays(StringPiece payload, | 126 AssertionResult DecodePayloadAndValidateSeveralWays(StringPiece payload, |
147 Validator validator) { | 127 Validator validator) { |
148 DecodeBuffer db(payload); | 128 DecodeBuffer db(payload); |
149 bool start_decoding_requires_non_empty = false; | 129 bool start_decoding_requires_non_empty = false; |
150 return DecodeAndValidateSeveralWays(&db, start_decoding_requires_non_empty, | 130 return DecodeAndValidateSeveralWays(&db, start_decoding_requires_non_empty, |
151 validator); | 131 validator); |
152 } | 132 } |
153 | 133 |
154 AssertionResult ValidatorForDecodePayloadAndValidateSeveralWays( | |
155 const FrameParts& expected, | |
156 const DecodeBuffer& input, | |
157 DecodeStatus status) { | |
158 VERIFY_EQ(status, DecodeStatus::kDecodeDone); | |
159 VERIFY_AND_RETURN_SUCCESS(VerifyCollected(expected)); | |
160 } | |
161 | 134 |
162 // Decode one frame's payload and confirm that the listener recorded the | 135 // Decode one frame's payload and confirm that the listener recorded the |
163 // expected FrameParts instance, and only one FrameParts instance. The | 136 // expected FrameParts instance, and only one FrameParts instance. The |
164 // payload will be decoded several times with different partitionings | 137 // payload will be decoded several times with different partitionings |
165 // of the payload, and after each the validator will be called. | 138 // of the payload, and after each the validator will be called. |
166 AssertionResult DecodePayloadAndValidateSeveralWays( | 139 AssertionResult DecodePayloadAndValidateSeveralWays( |
167 StringPiece payload, | 140 StringPiece payload, |
168 const FrameParts& expected) { | 141 const FrameParts& expected) { |
169 Validator validator = base::Bind( | 142 Validator validator = [&expected, this]( |
James Synge
2017/01/05 21:39:06
I'm curious why "auto validator" became "Validator
Bence
2017/01/06 01:42:40
If I use auto here, I get the compile error below.
| |
170 &Http2FrameDecoderTest::ValidatorForDecodePayloadAndValidateSeveralWays, | 143 const DecodeBuffer& input, DecodeStatus status) -> AssertionResult { |
171 base::Unretained(this), base::ConstRef(expected)); | 144 VERIFY_EQ(status, DecodeStatus::kDecodeDone); |
145 VERIFY_AND_RETURN_SUCCESS(VerifyCollected(expected)); | |
146 }; | |
172 ResetDecodeSpeedCounters(); | 147 ResetDecodeSpeedCounters(); |
173 VERIFY_SUCCESS(DecodePayloadAndValidateSeveralWays( | 148 VERIFY_SUCCESS(DecodePayloadAndValidateSeveralWays( |
174 payload, ValidateDoneAndEmpty(validator))); | 149 payload, ValidateDoneAndEmpty(validator))); |
175 VERIFY_GT(fast_decode_count_, 0u); | 150 VERIFY_GT(fast_decode_count_, 0u); |
176 VERIFY_GT(slow_decode_count_, 0u); | 151 VERIFY_GT(slow_decode_count_, 0u); |
177 | 152 |
178 // Repeat with more input; it should stop without reading that input. | 153 // Repeat with more input; it should stop without reading that input. |
179 string next_frame = Random().RandString(10); | 154 string next_frame = Random().RandString(10); |
180 string input; | 155 string input; |
181 payload.AppendToString(&input); | 156 payload.AppendToString(&input); |
(...skipping 19 matching lines...) Expand all Loading... | |
201 AssertionResult DecodePayloadAndValidateSeveralWays( | 176 AssertionResult DecodePayloadAndValidateSeveralWays( |
202 const char (&buf)[N], | 177 const char (&buf)[N], |
203 const Http2FrameHeader& header) { | 178 const Http2FrameHeader& header) { |
204 return DecodePayloadAndValidateSeveralWays(StringPiece(buf, N), | 179 return DecodePayloadAndValidateSeveralWays(StringPiece(buf, N), |
205 FrameParts(header)); | 180 FrameParts(header)); |
206 } | 181 } |
207 | 182 |
208 template <size_t N> | 183 template <size_t N> |
209 AssertionResult DecodePayloadExpectingError(const char (&buf)[N], | 184 AssertionResult DecodePayloadExpectingError(const char (&buf)[N], |
210 const FrameParts& expected) { | 185 const FrameParts& expected) { |
186 auto validator = [&expected, this](const DecodeBuffer& input, | |
187 DecodeStatus status) -> AssertionResult { | |
188 VERIFY_EQ(status, DecodeStatus::kDecodeError); | |
189 VERIFY_AND_RETURN_SUCCESS(VerifyCollected(expected)); | |
190 }; | |
211 ResetDecodeSpeedCounters(); | 191 ResetDecodeSpeedCounters(); |
212 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays( | 192 EXPECT_TRUE( |
213 ToStringPiece(buf), | 193 DecodePayloadAndValidateSeveralWays(ToStringPiece(buf), validator)); |
214 base::Bind( | |
215 &Http2FrameDecoderTest::ValidatorForDecodePayloadExpectingError, | |
216 base::Unretained(this), expected))); | |
217 EXPECT_GT(fast_decode_count_, 0u); | 194 EXPECT_GT(fast_decode_count_, 0u); |
218 EXPECT_GT(slow_decode_count_, 0u); | 195 EXPECT_GT(slow_decode_count_, 0u); |
219 return AssertionSuccess(); | 196 return AssertionSuccess(); |
220 } | 197 } |
221 | 198 |
222 template <size_t N> | 199 template <size_t N> |
223 AssertionResult DecodePayloadExpectingFrameSizeError(const char (&buf)[N], | 200 AssertionResult DecodePayloadExpectingFrameSizeError(const char (&buf)[N], |
224 FrameParts expected) { | 201 FrameParts expected) { |
225 expected.has_frame_size_error = true; | 202 expected.has_frame_size_error = true; |
226 VERIFY_AND_RETURN_SUCCESS(DecodePayloadExpectingError(buf, expected)); | 203 VERIFY_AND_RETURN_SUCCESS(DecodePayloadExpectingError(buf, expected)); |
(...skipping 630 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
857 0x00, 0x00, 0x00, 0x02, // Stream ID: 0 (REQUIRES ID) | 834 0x00, 0x00, 0x00, 0x02, // Stream ID: 0 (REQUIRES ID) |
858 0x03, // Pad Len | 835 0x03, // Pad Len |
859 'a', 'b', 'c', // Data | 836 'a', 'b', 'c', // Data |
860 0x00, 0x00, 0x00, // Padding | 837 0x00, 0x00, 0x00, // Padding |
861 }; | 838 }; |
862 Http2FrameHeader header( | 839 Http2FrameHeader header( |
863 7, Http2FrameType::DATA, | 840 7, Http2FrameType::DATA, |
864 Http2FrameFlag::FLAG_END_STREAM | Http2FrameFlag::FLAG_PADDED, 2); | 841 Http2FrameFlag::FLAG_END_STREAM | Http2FrameFlag::FLAG_PADDED, 2); |
865 FrameParts expected(header); | 842 FrameParts expected(header); |
866 expected.has_frame_size_error = true; | 843 expected.has_frame_size_error = true; |
844 auto validator = [&expected, this](const DecodeBuffer& input, | |
845 DecodeStatus status) -> AssertionResult { | |
846 VERIFY_EQ(status, DecodeStatus::kDecodeError); | |
847 // The decoder detects this error after decoding the header, and without | |
848 // trying to decode the payload. | |
849 VERIFY_EQ(input.Offset(), Http2FrameHeader::EncodedSize()); | |
850 VERIFY_AND_RETURN_SUCCESS(VerifyCollected(expected)); | |
851 }; | |
867 ResetDecodeSpeedCounters(); | 852 ResetDecodeSpeedCounters(); |
868 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays( | 853 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(ToStringPiece(kFrameData), |
869 ToStringPiece(kFrameData), | 854 validator)); |
870 base::Bind(&Http2FrameDecoderTest::ValidatorForBeyondMaximum, | |
871 base::Unretained(this), expected))); | |
872 EXPECT_GT(fast_decode_count_, 0u); | 855 EXPECT_GT(fast_decode_count_, 0u); |
873 EXPECT_GT(slow_decode_count_, 0u); | 856 EXPECT_GT(slow_decode_count_, 0u); |
874 } | 857 } |
875 | 858 |
876 TEST_F(Http2FrameDecoderTest, PriorityTooLong) { | 859 TEST_F(Http2FrameDecoderTest, PriorityTooLong) { |
877 const char kFrameData[] = { | 860 const char kFrameData[] = { |
878 0x00, 0x00, 0x06, // Length: 5 | 861 0x00, 0x00, 0x06, // Length: 5 |
879 0x02, // Type: PRIORITY | 862 0x02, // Type: PRIORITY |
880 0x00, // Flags: none | 863 0x00, // Flags: none |
881 0x00, 0x00, 0x00, 0x02, // Stream: 2 | 864 0x00, 0x00, 0x00, 0x02, // Stream: 2 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
937 0x80u, 0x00, 0x04, 0x00, // Incr: 1024 (plus R bit) | 920 0x80u, 0x00, 0x04, 0x00, // Incr: 1024 (plus R bit) |
938 0x00, // Too much | 921 0x00, // Too much |
939 }; | 922 }; |
940 Http2FrameHeader header(5, Http2FrameType::WINDOW_UPDATE, 0, 1); | 923 Http2FrameHeader header(5, Http2FrameType::WINDOW_UPDATE, 0, 1); |
941 EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header)); | 924 EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header)); |
942 } | 925 } |
943 | 926 |
944 } // namespace | 927 } // namespace |
945 } // namespace test | 928 } // namespace test |
946 } // namespace net | 929 } // namespace net |
OLD | NEW |