1 // Copyright 2020 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/decoder/payload_decoders/priority_update_payload_decoder.h"
6
7 #include <stddef.h>
8
9 #include <string>
10
11 #include "quiche/http2/decoder/http2_frame_decoder_listener.h"
12 #include "quiche/http2/http2_constants.h"
13 #include "quiche/http2/test_tools/frame_parts.h"
14 #include "quiche/http2/test_tools/frame_parts_collector.h"
15 #include "quiche/http2/test_tools/http2_frame_builder.h"
16 #include "quiche/http2/test_tools/http2_random.h"
17 #include "quiche/http2/test_tools/http2_structures_test_util.h"
18 #include "quiche/http2/test_tools/payload_decoder_base_test_util.h"
19 #include "quiche/http2/test_tools/random_decoder_test_base.h"
20 #include "quiche/common/platform/api/quiche_logging.h"
21 #include "quiche/common/platform/api/quiche_test.h"
22
23 namespace http2 {
24 namespace test {
25
26 class PriorityUpdatePayloadDecoderPeer {
27 public:
FrameType()28 static constexpr Http2FrameType FrameType() {
29 return Http2FrameType::PRIORITY_UPDATE;
30 }
31
32 // Returns the mask of flags that affect the decoding of the payload (i.e.
33 // flags that that indicate the presence of certain fields or padding).
FlagsAffectingPayloadDecoding()34 static constexpr uint8_t FlagsAffectingPayloadDecoding() { return 0; }
35 };
36
37 namespace {
38
39 struct Listener : public FramePartsCollector {
OnPriorityUpdateStarthttp2::test::__anon9c52c85f0111::Listener40 void OnPriorityUpdateStart(
41 const Http2FrameHeader& header,
42 const Http2PriorityUpdateFields& priority_update) override {
43 QUICHE_VLOG(1) << "OnPriorityUpdateStart header: " << header
44 << "; priority_update: " << priority_update;
45 StartFrame(header)->OnPriorityUpdateStart(header, priority_update);
46 }
47
OnPriorityUpdatePayloadhttp2::test::__anon9c52c85f0111::Listener48 void OnPriorityUpdatePayload(const char* data, size_t len) override {
49 QUICHE_VLOG(1) << "OnPriorityUpdatePayload: len=" << len;
50 CurrentFrame()->OnPriorityUpdatePayload(data, len);
51 }
52
OnPriorityUpdateEndhttp2::test::__anon9c52c85f0111::Listener53 void OnPriorityUpdateEnd() override {
54 QUICHE_VLOG(1) << "OnPriorityUpdateEnd";
55 EndFrame()->OnPriorityUpdateEnd();
56 }
57
OnFrameSizeErrorhttp2::test::__anon9c52c85f0111::Listener58 void OnFrameSizeError(const Http2FrameHeader& header) override {
59 QUICHE_VLOG(1) << "OnFrameSizeError: " << header;
60 FrameError(header)->OnFrameSizeError(header);
61 }
62 };
63
64 class PriorityUpdatePayloadDecoderTest
65 : public AbstractPayloadDecoderTest<PriorityUpdatePayloadDecoder,
66 PriorityUpdatePayloadDecoderPeer,
67 Listener> {};
68
69 // Confirm we get an error if the payload is not long enough to hold
70 // Http2PriorityUpdateFields.
TEST_F(PriorityUpdatePayloadDecoderTest,Truncated)71 TEST_F(PriorityUpdatePayloadDecoderTest, Truncated) {
72 auto approve_size = [](size_t size) {
73 return size != Http2PriorityUpdateFields::EncodedSize();
74 };
75 Http2FrameBuilder fb;
76 fb.Append(Http2PriorityUpdateFields(123));
77 EXPECT_TRUE(VerifyDetectsFrameSizeError(0, fb.buffer(), approve_size));
78 }
79
80 class PriorityUpdatePayloadLengthTests
81 : public AbstractPayloadDecoderTest<PriorityUpdatePayloadDecoder,
82 PriorityUpdatePayloadDecoderPeer,
83 Listener>,
84 public ::testing::WithParamInterface<uint32_t> {
85 protected:
PriorityUpdatePayloadLengthTests()86 PriorityUpdatePayloadLengthTests() : length_(GetParam()) {
87 QUICHE_VLOG(1) << "################ length_=" << length_
88 << " ################";
89 }
90
91 const uint32_t length_;
92 };
93
94 INSTANTIATE_TEST_SUITE_P(VariousLengths, PriorityUpdatePayloadLengthTests,
95 ::testing::Values(0, 1, 2, 3, 4, 5, 6));
96
TEST_P(PriorityUpdatePayloadLengthTests,ValidLength)97 TEST_P(PriorityUpdatePayloadLengthTests, ValidLength) {
98 Http2PriorityUpdateFields priority_update;
99 Randomize(&priority_update, RandomPtr());
100 std::string priority_field_value = Random().RandString(length_);
101 Http2FrameBuilder fb;
102 fb.Append(priority_update);
103 fb.Append(priority_field_value);
104 Http2FrameHeader header(fb.size(), Http2FrameType::PRIORITY_UPDATE,
105 RandFlags(), RandStreamId());
106 set_frame_header(header);
107 FrameParts expected(header, priority_field_value);
108 expected.SetOptPriorityUpdate(Http2PriorityUpdateFields{priority_update});
109 ASSERT_TRUE(DecodePayloadAndValidateSeveralWays(fb.buffer(), expected));
110 }
111
112 } // namespace
113 } // namespace test
114 } // namespace http2
115