1 #include "quiche/http2/adapter/recording_http2_visitor.h"
2
3 #include <list>
4
5 #include "quiche/http2/adapter/http2_protocol.h"
6 #include "quiche/http2/adapter/http2_visitor_interface.h"
7 #include "quiche/http2/test_tools/http2_random.h"
8 #include "quiche/common/platform/api/quiche_test.h"
9
10 namespace http2 {
11 namespace adapter {
12 namespace test {
13 namespace {
14
15 using ::testing::IsEmpty;
16
TEST(RecordingHttp2VisitorTest,EmptySequence)17 TEST(RecordingHttp2VisitorTest, EmptySequence) {
18 RecordingHttp2Visitor chocolate_visitor;
19 RecordingHttp2Visitor vanilla_visitor;
20
21 EXPECT_THAT(chocolate_visitor.GetEventSequence(), IsEmpty());
22 EXPECT_THAT(vanilla_visitor.GetEventSequence(), IsEmpty());
23 EXPECT_EQ(chocolate_visitor.GetEventSequence(),
24 vanilla_visitor.GetEventSequence());
25
26 chocolate_visitor.OnSettingsStart();
27
28 EXPECT_THAT(chocolate_visitor.GetEventSequence(), testing::Not(IsEmpty()));
29 EXPECT_THAT(vanilla_visitor.GetEventSequence(), IsEmpty());
30 EXPECT_NE(chocolate_visitor.GetEventSequence(),
31 vanilla_visitor.GetEventSequence());
32
33 chocolate_visitor.Clear();
34
35 EXPECT_THAT(chocolate_visitor.GetEventSequence(), IsEmpty());
36 EXPECT_THAT(vanilla_visitor.GetEventSequence(), IsEmpty());
37 EXPECT_EQ(chocolate_visitor.GetEventSequence(),
38 vanilla_visitor.GetEventSequence());
39 }
40
TEST(RecordingHttp2VisitorTest,SameEventsProduceSameSequence)41 TEST(RecordingHttp2VisitorTest, SameEventsProduceSameSequence) {
42 RecordingHttp2Visitor chocolate_visitor;
43 RecordingHttp2Visitor vanilla_visitor;
44
45 // Prepare some random values to deliver with the events.
46 http2::test::Http2Random random;
47 const Http2StreamId stream_id = random.Uniform(kMaxStreamId);
48 const Http2StreamId another_stream_id = random.Uniform(kMaxStreamId);
49 const size_t length = random.Rand16();
50 const uint8_t type = random.Rand8();
51 const uint8_t flags = random.Rand8();
52 const Http2ErrorCode error_code = static_cast<Http2ErrorCode>(
53 random.Uniform(static_cast<int>(Http2ErrorCode::MAX_ERROR_CODE)));
54 const Http2Setting setting = {random.Rand16(), random.Rand32()};
55 const absl::string_view alphabet = "abcdefghijklmnopqrstuvwxyz0123456789-";
56 const std::string some_string =
57 random.RandStringWithAlphabet(random.Rand8(), alphabet);
58 const std::string another_string =
59 random.RandStringWithAlphabet(random.Rand8(), alphabet);
60 const uint16_t some_int = random.Rand16();
61 const bool some_bool = random.OneIn(2);
62
63 // Send the same arbitrary sequence of events to both visitors.
64 std::list<RecordingHttp2Visitor*> visitors = {&chocolate_visitor,
65 &vanilla_visitor};
66 for (RecordingHttp2Visitor* visitor : visitors) {
67 visitor->OnConnectionError(
68 Http2VisitorInterface::ConnectionError::kSendError);
69 visitor->OnFrameHeader(stream_id, length, type, flags);
70 visitor->OnSettingsStart();
71 visitor->OnSetting(setting);
72 visitor->OnSettingsEnd();
73 visitor->OnSettingsAck();
74 visitor->OnBeginHeadersForStream(stream_id);
75 visitor->OnHeaderForStream(stream_id, some_string, another_string);
76 visitor->OnEndHeadersForStream(stream_id);
77 visitor->OnBeginDataForStream(stream_id, length);
78 visitor->OnDataForStream(stream_id, some_string);
79 visitor->OnDataForStream(stream_id, another_string);
80 visitor->OnEndStream(stream_id);
81 visitor->OnRstStream(stream_id, error_code);
82 visitor->OnCloseStream(stream_id, error_code);
83 visitor->OnPriorityForStream(stream_id, another_stream_id, some_int,
84 some_bool);
85 visitor->OnPing(some_int, some_bool);
86 visitor->OnPushPromiseForStream(stream_id, another_stream_id);
87 visitor->OnGoAway(stream_id, error_code, some_string);
88 visitor->OnWindowUpdate(stream_id, some_int);
89 visitor->OnBeginMetadataForStream(stream_id, length);
90 visitor->OnMetadataForStream(stream_id, some_string);
91 visitor->OnMetadataForStream(stream_id, another_string);
92 visitor->OnMetadataEndForStream(stream_id);
93 }
94
95 EXPECT_EQ(chocolate_visitor.GetEventSequence(),
96 vanilla_visitor.GetEventSequence());
97 }
98
TEST(RecordingHttp2VisitorTest,DifferentEventsProduceDifferentSequence)99 TEST(RecordingHttp2VisitorTest, DifferentEventsProduceDifferentSequence) {
100 RecordingHttp2Visitor chocolate_visitor;
101 RecordingHttp2Visitor vanilla_visitor;
102 EXPECT_EQ(chocolate_visitor.GetEventSequence(),
103 vanilla_visitor.GetEventSequence());
104
105 const Http2StreamId stream_id = 1;
106 const size_t length = 42;
107
108 // Different events with the same method arguments should produce different
109 // event sequences.
110 chocolate_visitor.OnBeginDataForStream(stream_id, length);
111 vanilla_visitor.OnBeginMetadataForStream(stream_id, length);
112 EXPECT_NE(chocolate_visitor.GetEventSequence(),
113 vanilla_visitor.GetEventSequence());
114
115 chocolate_visitor.Clear();
116 vanilla_visitor.Clear();
117 EXPECT_EQ(chocolate_visitor.GetEventSequence(),
118 vanilla_visitor.GetEventSequence());
119
120 // The same events with different method arguments should produce different
121 // event sequences.
122 chocolate_visitor.OnBeginHeadersForStream(stream_id);
123 vanilla_visitor.OnBeginHeadersForStream(stream_id + 2);
124 EXPECT_NE(chocolate_visitor.GetEventSequence(),
125 vanilla_visitor.GetEventSequence());
126 }
127
128 } // namespace
129 } // namespace test
130 } // namespace adapter
131 } // namespace http2
132