blob: ab155697d5d4806439eecea8eb178dc05042b982 [file] [log] [blame]
QUICHE team85c4fe32021-04-16 15:43:46 -07001#include "http2/adapter/oghttp2_session.h"
2
3#include "http2/adapter/mock_http2_visitor.h"
4#include "http2/adapter/test_frame_sequence.h"
5#include "common/platform/api/quiche_test.h"
6
7namespace http2 {
8namespace adapter {
9namespace test {
QUICHE team2121bae2021-04-30 13:05:38 -070010namespace {
11
12using testing::_;
13
14enum FrameType {
15 DATA,
16 HEADERS,
17 PRIORITY,
18 RST_STREAM,
19 SETTINGS,
20 PUSH_PROMISE,
21 PING,
22 GOAWAY,
23 WINDOW_UPDATE,
24};
25
26} // namespace
QUICHE team85c4fe32021-04-16 15:43:46 -070027
28TEST(OgHttp2SessionTest, ClientConstruction) {
29 testing::StrictMock<MockHttp2Visitor> visitor;
30 OgHttp2Session session(
31 visitor, OgHttp2Session::Options{.perspective = Perspective::kClient});
32 EXPECT_TRUE(session.want_read());
33 EXPECT_FALSE(session.want_write());
34 EXPECT_EQ(session.GetRemoteWindowSize(), kDefaultInitialStreamWindowSize);
35}
36
37TEST(OgHttp2SessionTest, ClientHandlesFrames) {
38 testing::StrictMock<MockHttp2Visitor> visitor;
39 OgHttp2Session session(
40 visitor, OgHttp2Session::Options{.perspective = Perspective::kClient});
41
42 const std::string initial_frames = TestFrameSequence()
43 .ServerPreface()
44 .Ping(42)
45 .WindowUpdate(0, 1000)
46 .Serialize();
47 testing::InSequence s;
48
49 // Server preface (empty SETTINGS)
QUICHE team2121bae2021-04-30 13:05:38 -070050 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
QUICHE team85c4fe32021-04-16 15:43:46 -070051 EXPECT_CALL(visitor, OnSettingsStart());
52 EXPECT_CALL(visitor, OnSettingsEnd());
53
QUICHE team2121bae2021-04-30 13:05:38 -070054 EXPECT_CALL(visitor, OnFrameHeader(0, 8, PING, 0));
QUICHE team85c4fe32021-04-16 15:43:46 -070055 EXPECT_CALL(visitor, OnPing(42, false));
QUICHE team2121bae2021-04-30 13:05:38 -070056 EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
QUICHE team85c4fe32021-04-16 15:43:46 -070057 EXPECT_CALL(visitor, OnWindowUpdate(0, 1000));
58
59 const ssize_t initial_result = session.ProcessBytes(initial_frames);
60 EXPECT_EQ(initial_frames.size(), initial_result);
61
62 EXPECT_EQ(session.GetRemoteWindowSize(),
63 kDefaultInitialStreamWindowSize + 1000);
64
65 // Should OgHttp2Session require that streams 1 and 3 have been created?
66
67 const std::string stream_frames =
68 TestFrameSequence()
69 .Headers(1,
70 {{":status", "200"},
71 {"server", "my-fake-server"},
72 {"date", "Tue, 6 Apr 2021 12:54:01 GMT"}},
73 /*fin=*/false)
74 .Data(1, "This is the response body.")
75 .RstStream(3, Http2ErrorCode::INTERNAL_ERROR)
76 .GoAway(5, Http2ErrorCode::ENHANCE_YOUR_CALM, "calm down!!")
77 .Serialize();
78
QUICHE team2121bae2021-04-30 13:05:38 -070079 EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
QUICHE team85c4fe32021-04-16 15:43:46 -070080 EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
81 EXPECT_CALL(visitor, OnHeaderForStream(1, ":status", "200"));
82 EXPECT_CALL(visitor, OnHeaderForStream(1, "server", "my-fake-server"));
83 EXPECT_CALL(visitor,
84 OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT"));
85 EXPECT_CALL(visitor, OnEndHeadersForStream(1));
QUICHE team2121bae2021-04-30 13:05:38 -070086 EXPECT_CALL(visitor, OnFrameHeader(1, 26, DATA, 0));
QUICHE team85c4fe32021-04-16 15:43:46 -070087 EXPECT_CALL(visitor, OnBeginDataForStream(1, 26));
88 EXPECT_CALL(visitor, OnDataForStream(1, "This is the response body."));
QUICHE team2121bae2021-04-30 13:05:38 -070089 EXPECT_CALL(visitor, OnFrameHeader(3, 4, RST_STREAM, 0));
QUICHE team85c4fe32021-04-16 15:43:46 -070090 EXPECT_CALL(visitor, OnRstStream(3, Http2ErrorCode::INTERNAL_ERROR));
QUICHE teamd9050872021-04-27 09:12:49 -070091 EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::INTERNAL_ERROR));
QUICHE team2121bae2021-04-30 13:05:38 -070092 EXPECT_CALL(visitor, OnFrameHeader(0, 19, GOAWAY, 0));
QUICHE team85c4fe32021-04-16 15:43:46 -070093 EXPECT_CALL(visitor, OnGoAway(5, Http2ErrorCode::ENHANCE_YOUR_CALM, ""));
94 const ssize_t stream_result = session.ProcessBytes(stream_frames);
95 EXPECT_EQ(stream_frames.size(), stream_result);
96}
97
98TEST(OgHttp2SessionTest, ServerConstruction) {
99 testing::StrictMock<MockHttp2Visitor> visitor;
100 OgHttp2Session session(
101 visitor, OgHttp2Session::Options{.perspective = Perspective::kServer});
102 EXPECT_TRUE(session.want_read());
103 EXPECT_FALSE(session.want_write());
104 EXPECT_EQ(session.GetRemoteWindowSize(), kDefaultInitialStreamWindowSize);
105}
106
107TEST(OgHttp2SessionTest, ServerHandlesFrames) {
108 testing::StrictMock<MockHttp2Visitor> visitor;
109 OgHttp2Session session(
110 visitor, OgHttp2Session::Options{.perspective = Perspective::kServer});
111
112 const std::string frames = TestFrameSequence()
113 .ClientPreface()
114 .Ping(42)
115 .WindowUpdate(0, 1000)
116 .Headers(1,
117 {{":method", "POST"},
118 {":scheme", "https"},
119 {":authority", "example.com"},
120 {":path", "/this/is/request/one"}},
121 /*fin=*/false)
122 .WindowUpdate(1, 2000)
123 .Data(1, "This is the request body.")
124 .Headers(3,
125 {{":method", "GET"},
126 {":scheme", "http"},
127 {":authority", "example.com"},
128 {":path", "/this/is/request/two"}},
129 /*fin=*/true)
130 .RstStream(3, Http2ErrorCode::CANCEL)
131 .Ping(47)
132 .Serialize();
133 testing::InSequence s;
134
135 // Client preface (empty SETTINGS)
QUICHE team2121bae2021-04-30 13:05:38 -0700136 EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0));
QUICHE team85c4fe32021-04-16 15:43:46 -0700137 EXPECT_CALL(visitor, OnSettingsStart());
138 EXPECT_CALL(visitor, OnSettingsEnd());
139
QUICHE team2121bae2021-04-30 13:05:38 -0700140 EXPECT_CALL(visitor, OnFrameHeader(0, 8, PING, 0));
QUICHE team85c4fe32021-04-16 15:43:46 -0700141 EXPECT_CALL(visitor, OnPing(42, false));
QUICHE team2121bae2021-04-30 13:05:38 -0700142 EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
QUICHE team85c4fe32021-04-16 15:43:46 -0700143 EXPECT_CALL(visitor, OnWindowUpdate(0, 1000));
QUICHE team2121bae2021-04-30 13:05:38 -0700144 EXPECT_CALL(visitor, OnFrameHeader(1, _, HEADERS, 4));
QUICHE team85c4fe32021-04-16 15:43:46 -0700145 EXPECT_CALL(visitor, OnBeginHeadersForStream(1));
146 EXPECT_CALL(visitor, OnHeaderForStream(1, ":method", "POST"));
147 EXPECT_CALL(visitor, OnHeaderForStream(1, ":scheme", "https"));
148 EXPECT_CALL(visitor, OnHeaderForStream(1, ":authority", "example.com"));
149 EXPECT_CALL(visitor, OnHeaderForStream(1, ":path", "/this/is/request/one"));
150 EXPECT_CALL(visitor, OnEndHeadersForStream(1));
QUICHE team2121bae2021-04-30 13:05:38 -0700151 EXPECT_CALL(visitor, OnFrameHeader(1, 4, WINDOW_UPDATE, 0));
QUICHE team85c4fe32021-04-16 15:43:46 -0700152 EXPECT_CALL(visitor, OnWindowUpdate(1, 2000));
QUICHE team2121bae2021-04-30 13:05:38 -0700153 EXPECT_CALL(visitor, OnFrameHeader(1, 25, DATA, 0));
QUICHE team85c4fe32021-04-16 15:43:46 -0700154 EXPECT_CALL(visitor, OnBeginDataForStream(1, 25));
155 EXPECT_CALL(visitor, OnDataForStream(1, "This is the request body."));
QUICHE team2121bae2021-04-30 13:05:38 -0700156 EXPECT_CALL(visitor, OnFrameHeader(3, _, HEADERS, 5));
QUICHE team85c4fe32021-04-16 15:43:46 -0700157 EXPECT_CALL(visitor, OnBeginHeadersForStream(3));
158 EXPECT_CALL(visitor, OnHeaderForStream(3, ":method", "GET"));
159 EXPECT_CALL(visitor, OnHeaderForStream(3, ":scheme", "http"));
160 EXPECT_CALL(visitor, OnHeaderForStream(3, ":authority", "example.com"));
161 EXPECT_CALL(visitor, OnHeaderForStream(3, ":path", "/this/is/request/two"));
162 EXPECT_CALL(visitor, OnEndHeadersForStream(3));
163 EXPECT_CALL(visitor, OnEndStream(3));
QUICHE team2121bae2021-04-30 13:05:38 -0700164 EXPECT_CALL(visitor, OnFrameHeader(3, 4, RST_STREAM, 0));
QUICHE team85c4fe32021-04-16 15:43:46 -0700165 EXPECT_CALL(visitor, OnRstStream(3, Http2ErrorCode::CANCEL));
QUICHE teamd9050872021-04-27 09:12:49 -0700166 EXPECT_CALL(visitor, OnCloseStream(3, Http2ErrorCode::CANCEL));
QUICHE team2121bae2021-04-30 13:05:38 -0700167 EXPECT_CALL(visitor, OnFrameHeader(0, 8, PING, 0));
QUICHE team85c4fe32021-04-16 15:43:46 -0700168 EXPECT_CALL(visitor, OnPing(47, false));
169
170 const ssize_t result = session.ProcessBytes(frames);
171 EXPECT_EQ(frames.size(), result);
172
173 EXPECT_EQ(session.GetRemoteWindowSize(),
174 kDefaultInitialStreamWindowSize + 1000);
175}
176
177} // namespace test
178} // namespace adapter
179} // namespace http2