Call InvalidationController#refreshRegisteredTypes() on Chrome startup
[chromium-blink-merge.git] / net / tools / quic / quic_spdy_server_stream_test.cc
blob9290a79a212b1cb995d2c2487c887d3edfbef611
1 // Copyright (c) 2013 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.
5 #include "net/tools/quic/quic_spdy_server_stream.h"
7 #include "base/strings/string_number_conversions.h"
8 #include "base/strings/string_piece.h"
9 #include "net/quic/quic_connection.h"
10 #include "net/quic/quic_protocol.h"
11 #include "net/quic/quic_utils.h"
12 #include "net/quic/spdy_utils.h"
13 #include "net/quic/test_tools/quic_test_utils.h"
14 #include "net/tools/epoll_server/epoll_server.h"
15 #include "net/tools/quic/quic_in_memory_cache.h"
16 #include "net/tools/quic/spdy_balsa_utils.h"
17 #include "net/tools/quic/test_tools/quic_in_memory_cache_peer.h"
18 #include "testing/gmock/include/gmock/gmock.h"
19 #include "testing/gtest/include/gtest/gtest.h"
21 using base::StringPiece;
22 using net::test::MockConnection;
23 using net::test::MockSession;
24 using net::test::SupportedVersions;
25 using net::test::kInitialSessionFlowControlWindowForTest;
26 using net::test::kInitialStreamFlowControlWindowForTest;
27 using std::string;
28 using testing::_;
29 using testing::AnyNumber;
30 using testing::Invoke;
31 using testing::InvokeArgument;
32 using testing::InSequence;
33 using testing::Return;
34 using testing::StrictMock;
35 using testing::WithArgs;
37 namespace net {
38 namespace tools {
39 namespace test {
41 class QuicSpdyServerStreamPeer : public QuicSpdyServerStream {
42 public:
43 QuicSpdyServerStreamPeer(QuicStreamId stream_id, QuicSession* session)
44 : QuicSpdyServerStream(stream_id, session) {
47 using QuicSpdyServerStream::SendResponse;
48 using QuicSpdyServerStream::SendErrorResponse;
50 SpdyHeaderBlock* mutable_headers() {
51 return &request_headers_;
54 static void SendResponse(QuicSpdyServerStream* stream) {
55 stream->SendResponse();
58 static void SendErrorResponse(QuicSpdyServerStream* stream) {
59 stream->SendResponse();
62 static const string& body(QuicSpdyServerStream* stream) {
63 return stream->body_;
66 static const SpdyHeaderBlock& headers(QuicSpdyServerStream* stream) {
67 return stream->request_headers_;
71 namespace {
73 class QuicSpdyServerStreamTest : public ::testing::TestWithParam<QuicVersion> {
74 public:
75 QuicSpdyServerStreamTest()
76 : connection_(
77 new StrictMock<MockConnection>(Perspective::IS_SERVER,
78 SupportedVersions(GetParam()))),
79 session_(connection_),
80 body_("hello world") {
81 SpdyHeaderBlock request_headers;
82 request_headers[":host"] = "";
83 request_headers[":path"] = "/";
84 request_headers[":method"] = "POST";
85 request_headers[":version"] = "HTTP/1.1";
86 request_headers["content-length"] = "11";
88 headers_string_ = net::SpdyUtils::SerializeUncompressedHeaders(
89 request_headers, GetParam());
91 // New streams rely on having the peer's flow control receive window
92 // negotiated in the config.
93 session_.config()->SetInitialStreamFlowControlWindowToSend(
94 kInitialStreamFlowControlWindowForTest);
95 session_.config()->SetInitialSessionFlowControlWindowToSend(
96 kInitialSessionFlowControlWindowForTest);
97 stream_.reset(new QuicSpdyServerStreamPeer(3, &session_));
99 QuicInMemoryCachePeer::ResetForTests();
101 string host = "";
102 string path = "/foo";
103 SpdyHeaderBlock response_headers;
104 StringPiece body("Yum");
105 QuicInMemoryCache::GetInstance()->AddResponse(host, path, response_headers,
106 body);
109 ~QuicSpdyServerStreamTest() override {
110 QuicInMemoryCachePeer::ResetForTests();
113 const string& StreamBody() {
114 return QuicSpdyServerStreamPeer::body(stream_.get());
117 const string& StreamHeadersValue(const string& key) {
118 return (*stream_->mutable_headers())[key];
121 SpdyHeaderBlock response_headers_;
122 StrictMock<MockConnection>* connection_;
123 StrictMock<MockSession> session_;
124 scoped_ptr<QuicSpdyServerStreamPeer> stream_;
125 string headers_string_;
126 string body_;
129 QuicConsumedData ConsumeAllData(
130 QuicStreamId id,
131 const IOVector& data,
132 QuicStreamOffset offset,
133 bool fin,
134 FecProtection /*fec_protection_*/,
135 QuicAckNotifier::DelegateInterface* /*ack_notifier_delegate*/) {
136 return QuicConsumedData(data.TotalBufferSize(), fin);
139 INSTANTIATE_TEST_CASE_P(Tests, QuicSpdyServerStreamTest,
140 ::testing::ValuesIn(QuicSupportedVersions()));
142 TEST_P(QuicSpdyServerStreamTest, TestFraming) {
143 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)).Times(AnyNumber()).
144 WillRepeatedly(Invoke(ConsumeAllData));
145 stream_->OnStreamHeaders(headers_string_);
146 stream_->OnStreamHeadersComplete(false, headers_string_.size());
147 EXPECT_EQ(body_.size(), stream_->ProcessData(body_.c_str(), body_.size()));
148 EXPECT_EQ("11", StreamHeadersValue("content-length"));
149 EXPECT_EQ("/", StreamHeadersValue(":path"));
150 EXPECT_EQ("POST", StreamHeadersValue(":method"));
151 EXPECT_EQ(body_, StreamBody());
154 TEST_P(QuicSpdyServerStreamTest, TestFramingOnePacket) {
155 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)).Times(AnyNumber()).
156 WillRepeatedly(Invoke(ConsumeAllData));
158 stream_->OnStreamHeaders(headers_string_);
159 stream_->OnStreamHeadersComplete(false, headers_string_.size());
160 EXPECT_EQ(body_.size(), stream_->ProcessData(body_.c_str(), body_.size()));
161 EXPECT_EQ("11", StreamHeadersValue("content-length"));
162 EXPECT_EQ("/", StreamHeadersValue(":path"));
163 EXPECT_EQ("POST", StreamHeadersValue(":method"));
164 EXPECT_EQ(body_, StreamBody());
167 TEST_P(QuicSpdyServerStreamTest, TestFramingExtraData) {
168 string large_body = "hello world!!!!!!";
170 // We'll automatically write out an error (headers + body)
171 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)).Times(AnyNumber()).
172 WillRepeatedly(Invoke(ConsumeAllData));
174 stream_->OnStreamHeaders(headers_string_);
175 stream_->OnStreamHeadersComplete(false, headers_string_.size());
176 EXPECT_EQ(body_.size(), stream_->ProcessData(body_.c_str(), body_.size()));
177 // Content length is still 11. This will register as an error and we won't
178 // accept the bytes.
179 stream_->ProcessData(large_body.c_str(), large_body.size());
180 EXPECT_EQ("11", StreamHeadersValue("content-length"));
181 EXPECT_EQ("/", StreamHeadersValue(":path"));
182 EXPECT_EQ("POST", StreamHeadersValue(":method"));
185 TEST_P(QuicSpdyServerStreamTest, TestSendResponse) {
186 SpdyHeaderBlock* request_headers = stream_->mutable_headers();
187 (*request_headers)[":path"] = "/foo";
188 (*request_headers)[":host"] = "";
189 (*request_headers)[":version"] = "HTTP/1.1";
190 (*request_headers)[":method"] = "GET";
192 response_headers_[":version"] = "HTTP/1.1";
193 response_headers_[":status"] = "200 OK";
194 response_headers_["content-length"] = "3";
196 InSequence s;
197 EXPECT_CALL(session_, WritevData(kHeadersStreamId, _, 0, false, _, nullptr));
198 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)).Times(1).
199 WillOnce(Return(QuicConsumedData(3, true)));
201 QuicSpdyServerStreamPeer::SendResponse(stream_.get());
202 EXPECT_TRUE(stream_->read_side_closed());
203 EXPECT_TRUE(stream_->write_side_closed());
206 TEST_P(QuicSpdyServerStreamTest, TestSendErrorResponse) {
207 response_headers_[":version"] = "HTTP/1.1";
208 response_headers_[":status"] = "500 Server Error";
209 response_headers_["content-length"] = "3";
211 InSequence s;
212 EXPECT_CALL(session_, WritevData(kHeadersStreamId, _, 0, false, _, nullptr));
213 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)).Times(1).
214 WillOnce(Return(QuicConsumedData(3, true)));
216 QuicSpdyServerStreamPeer::SendErrorResponse(stream_.get());
217 EXPECT_TRUE(stream_->read_side_closed());
218 EXPECT_TRUE(stream_->write_side_closed());
221 TEST_P(QuicSpdyServerStreamTest, InvalidHeadersWithFin) {
222 char arr[] = {
223 0x3a, 0x68, 0x6f, 0x73, // :hos
224 0x74, 0x00, 0x00, 0x00, // t...
225 0x00, 0x00, 0x00, 0x00, // ....
226 0x07, 0x3a, 0x6d, 0x65, // .:me
227 0x74, 0x68, 0x6f, 0x64, // thod
228 0x00, 0x00, 0x00, 0x03, // ....
229 0x47, 0x45, 0x54, 0x00, // GET.
230 0x00, 0x00, 0x05, 0x3a, // ...:
231 0x70, 0x61, 0x74, 0x68, // path
232 0x00, 0x00, 0x00, 0x04, // ....
233 0x2f, 0x66, 0x6f, 0x6f, // /foo
234 0x00, 0x00, 0x00, 0x07, // ....
235 0x3a, 0x73, 0x63, 0x68, // :sch
236 0x65, 0x6d, 0x65, 0x00, // eme.
237 0x00, 0x00, 0x00, 0x00, // ....
238 0x00, 0x00, 0x08, 0x3a, // ...:
239 0x76, 0x65, 0x72, 0x73, // vers
240 '\x96', 0x6f, 0x6e, 0x00, // <i(69)>on.
241 0x00, 0x00, 0x08, 0x48, // ...H
242 0x54, 0x54, 0x50, 0x2f, // TTP/
243 0x31, 0x2e, 0x31, // 1.1
245 StringPiece data(arr, arraysize(arr));
246 QuicStreamFrame frame(stream_->id(), true, 0, data);
247 // Verify that we don't crash when we get a invalid headers in stream frame.
248 stream_->OnStreamFrame(frame);
251 } // namespace
252 } // namespace test
253 } // namespace tools
254 } // namespace net