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