Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(411)

Side by Side Diff: net/quic/quic_headers_stream_test.cc

Issue 992733002: Remove //net (except for Android test stuff) and sdch (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/quic/quic_headers_stream.cc ('k') | net/quic/quic_http_stream.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 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.
4
5 #include "net/quic/quic_headers_stream.h"
6
7 #include "net/quic/quic_utils.h"
8 #include "net/quic/spdy_utils.h"
9 #include "net/quic/test_tools/quic_connection_peer.h"
10 #include "net/quic/test_tools/quic_session_peer.h"
11 #include "net/quic/test_tools/quic_test_utils.h"
12 #include "net/quic/test_tools/reliable_quic_stream_peer.h"
13 #include "net/spdy/spdy_protocol.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15
16 using base::StringPiece;
17 using std::ostream;
18 using std::string;
19 using std::vector;
20 using testing::Invoke;
21 using testing::StrictMock;
22 using testing::WithArgs;
23 using testing::_;
24
25 namespace net {
26 namespace test {
27 namespace {
28
29 class MockVisitor : public SpdyFramerVisitorInterface {
30 public:
31 MOCK_METHOD1(OnError, void(SpdyFramer* framer));
32 MOCK_METHOD3(OnDataFrameHeader, void(SpdyStreamId stream_id,
33 size_t length,
34 bool fin));
35 MOCK_METHOD4(OnStreamFrameData, void(SpdyStreamId stream_id,
36 const char* data,
37 size_t len,
38 bool fin));
39 MOCK_METHOD3(OnControlFrameHeaderData, bool(SpdyStreamId stream_id,
40 const char* header_data,
41 size_t len));
42 MOCK_METHOD5(OnSynStream, void(SpdyStreamId stream_id,
43 SpdyStreamId associated_stream_id,
44 SpdyPriority priority,
45 bool fin,
46 bool unidirectional));
47 MOCK_METHOD2(OnSynReply, void(SpdyStreamId stream_id, bool fin));
48 MOCK_METHOD2(OnRstStream, void(SpdyStreamId stream_id,
49 SpdyRstStreamStatus status));
50 MOCK_METHOD1(OnSettings, void(bool clear_persisted));
51 MOCK_METHOD3(OnSetting, void(SpdySettingsIds id, uint8 flags, uint32 value));
52 MOCK_METHOD0(OnSettingsAck, void());
53 MOCK_METHOD0(OnSettingsEnd, void());
54 MOCK_METHOD2(OnPing, void(SpdyPingId unique_id, bool is_ack));
55 MOCK_METHOD2(OnGoAway, void(SpdyStreamId last_accepted_stream_id,
56 SpdyGoAwayStatus status));
57 MOCK_METHOD5(OnHeaders, void(SpdyStreamId stream_id, bool has_priority,
58 SpdyPriority priority, bool fin, bool end));
59 MOCK_METHOD2(OnWindowUpdate, void(SpdyStreamId stream_id,
60 uint32 delta_window_size));
61 MOCK_METHOD2(OnCredentialFrameData, bool(const char* credential_data,
62 size_t len));
63 MOCK_METHOD1(OnBlocked, void(SpdyStreamId stream_id));
64 MOCK_METHOD3(OnPushPromise, void(SpdyStreamId stream_id,
65 SpdyStreamId promised_stream_id,
66 bool end));
67 MOCK_METHOD2(OnContinuation, void(SpdyStreamId stream_id, bool end));
68 MOCK_METHOD6(OnAltSvc, void(SpdyStreamId stream_id,
69 uint32 max_age,
70 uint16 port,
71 StringPiece protocol_id,
72 StringPiece host,
73 StringPiece origin));
74 MOCK_METHOD2(OnUnknownFrame, bool(SpdyStreamId stream_id, int frame_type));
75 };
76
77 // Run all tests with each version, and client or server
78 struct TestParams {
79 TestParams(QuicVersion version, bool is_server)
80 : version(version), is_server(is_server) {}
81
82 friend ostream& operator<<(ostream& os, const TestParams& p) {
83 os << "{ version: " << QuicVersionToString(p.version);
84 os << ", is_server: " << p.is_server << " }";
85 return os;
86 }
87
88 QuicVersion version;
89 bool is_server;
90 };
91
92 // Constructs various test permutations.
93 vector<TestParams> GetTestParams() {
94 vector<TestParams> params;
95 QuicVersionVector all_supported_versions = QuicSupportedVersions();
96 for (const QuicVersion version : all_supported_versions) {
97 params.push_back(TestParams(version, false));
98 params.push_back(TestParams(version, true));
99 }
100 return params;
101 }
102
103 class QuicHeadersStreamTest : public ::testing::TestWithParam<TestParams> {
104 public:
105 QuicHeadersStreamTest()
106 : connection_(new StrictMock<MockConnection>(is_server(), GetVersion())),
107 session_(connection_),
108 headers_stream_(QuicSessionPeer::GetHeadersStream(&session_)),
109 body_("hello world"),
110 framer_(version() > QUIC_VERSION_23 ? SPDY4 : SPDY3) {
111 headers_[":version"] = "HTTP/1.1";
112 headers_[":status"] = "200 Ok";
113 headers_["content-length"] = "11";
114 framer_.set_visitor(&visitor_);
115 EXPECT_EQ(version(), session_.connection()->version());
116 EXPECT_TRUE(headers_stream_ != nullptr);
117 VLOG(1) << GetParam();
118 }
119
120 QuicConsumedData SaveIov(const IOVector& data) {
121 const iovec* iov = data.iovec();
122 int count = data.Capacity();
123 for (int i = 0 ; i < count; ++i) {
124 saved_data_.append(static_cast<char*>(iov[i].iov_base), iov[i].iov_len);
125 }
126 return QuicConsumedData(saved_data_.length(), false);
127 }
128
129 bool SaveHeaderData(const char* data, int len) {
130 saved_header_data_.append(data, len);
131 return true;
132 }
133
134 void SaveHeaderDataStringPiece(StringPiece data) {
135 saved_header_data_.append(data.data(), data.length());
136 }
137
138 void WriteHeadersAndExpectSynStream(QuicStreamId stream_id,
139 bool fin,
140 QuicPriority priority) {
141 WriteHeadersAndCheckData(stream_id, fin, priority, SYN_STREAM);
142 }
143
144 void WriteHeadersAndExpectSynReply(QuicStreamId stream_id,
145 bool fin) {
146 WriteHeadersAndCheckData(stream_id, fin, 0, SYN_REPLY);
147 }
148
149 void WriteHeadersAndCheckData(QuicStreamId stream_id,
150 bool fin,
151 QuicPriority priority,
152 SpdyFrameType type) {
153 // Write the headers and capture the outgoing data
154 EXPECT_CALL(session_, WritevData(kHeadersStreamId, _, _, false, _, nullptr))
155 .WillOnce(WithArgs<1>(Invoke(this, &QuicHeadersStreamTest::SaveIov)));
156 headers_stream_->WriteHeaders(stream_id, headers_, fin, priority, nullptr);
157
158 // Parse the outgoing data and check that it matches was was written.
159 if (type == SYN_STREAM) {
160 if (version() > QUIC_VERSION_23) {
161 EXPECT_CALL(visitor_, OnHeaders(stream_id, kHasPriority, priority, fin,
162 kFrameComplete));
163 } else {
164 EXPECT_CALL(visitor_,
165 OnSynStream(stream_id, kNoAssociatedStream,
166 /*priority=*/0, fin, kNotUnidirectional));
167 }
168 } else {
169 if (version() > QUIC_VERSION_23) {
170 EXPECT_CALL(visitor_, OnHeaders(stream_id, !kHasPriority,
171 /*priority=*/0, fin, kFrameComplete));
172 } else {
173 EXPECT_CALL(visitor_, OnSynReply(stream_id, fin));
174 }
175 }
176 EXPECT_CALL(visitor_, OnControlFrameHeaderData(stream_id, _, _))
177 .WillRepeatedly(WithArgs<1, 2>(
178 Invoke(this, &QuicHeadersStreamTest::SaveHeaderData)));
179 if (fin) {
180 EXPECT_CALL(visitor_, OnStreamFrameData(stream_id, nullptr, 0, true));
181 }
182 framer_.ProcessInput(saved_data_.data(), saved_data_.length());
183 EXPECT_FALSE(framer_.HasError())
184 << SpdyFramer::ErrorCodeToString(framer_.error_code());
185
186 CheckHeaders();
187 saved_data_.clear();
188 }
189
190 void CheckHeaders() {
191 SpdyHeaderBlock headers;
192 EXPECT_EQ(saved_header_data_.length(),
193 framer_.ParseHeaderBlockInBuffer(saved_header_data_.data(),
194 saved_header_data_.length(),
195 &headers));
196 EXPECT_EQ(headers_, headers);
197 saved_header_data_.clear();
198 }
199
200 bool is_server() { return GetParam().is_server; }
201
202 QuicVersion version() { return GetParam().version; }
203
204 QuicVersionVector GetVersion() {
205 QuicVersionVector versions;
206 versions.push_back(version());
207 return versions;
208 }
209
210 void CloseConnection() {
211 QuicConnectionPeer::CloseConnection(connection_);
212 }
213
214 static const bool kFrameComplete = true;
215 static const bool kHasPriority = true;
216 static const bool kNotUnidirectional = false;
217 static const bool kNoAssociatedStream = false;
218
219 StrictMock<MockConnection>* connection_;
220 StrictMock<MockSession> session_;
221 QuicHeadersStream* headers_stream_;
222 SpdyHeaderBlock headers_;
223 string body_;
224 string saved_data_;
225 string saved_header_data_;
226 SpdyFramer framer_;
227 StrictMock<MockVisitor> visitor_;
228 };
229
230 INSTANTIATE_TEST_CASE_P(Tests,
231 QuicHeadersStreamTest,
232 ::testing::ValuesIn(GetTestParams()));
233
234 TEST_P(QuicHeadersStreamTest, StreamId) {
235 EXPECT_EQ(3u, headers_stream_->id());
236 }
237
238 TEST_P(QuicHeadersStreamTest, EffectivePriority) {
239 EXPECT_EQ(0u, headers_stream_->EffectivePriority());
240 }
241
242 TEST_P(QuicHeadersStreamTest, WriteHeaders) {
243 for (QuicStreamId stream_id = kClientDataStreamId1;
244 stream_id < kClientDataStreamId3; stream_id += 2) {
245 for (int count = 0; count < 2; ++count) {
246 bool fin = (count == 0);
247 if (is_server()) {
248 WriteHeadersAndExpectSynReply(stream_id, fin);
249 } else {
250 for (QuicPriority priority = 0; priority < 7; ++priority) {
251 // TODO(rch): implement priorities correctly.
252 WriteHeadersAndExpectSynStream(stream_id, fin, 0);
253 }
254 }
255 }
256 }
257 }
258
259 TEST_P(QuicHeadersStreamTest, ProcessRawData) {
260 for (QuicStreamId stream_id = kClientDataStreamId1;
261 stream_id < kClientDataStreamId3; stream_id += 2) {
262 for (int count = 0; count < 2; ++count) {
263 bool fin = (count == 0);
264 for (QuicPriority priority = 0; priority < 7; ++priority) {
265 // Replace with "WriteHeadersAndSaveData"
266 scoped_ptr<SpdySerializedFrame> frame;
267 if (is_server()) {
268 if (version() > QUIC_VERSION_23) {
269 SpdyHeadersIR headers_frame(stream_id);
270 headers_frame.set_name_value_block(headers_);
271 headers_frame.set_fin(fin);
272 headers_frame.set_has_priority(true);
273 frame.reset(framer_.SerializeFrame(headers_frame));
274 } else {
275 SpdySynStreamIR syn_stream(stream_id);
276 syn_stream.set_name_value_block(headers_);
277 syn_stream.set_fin(fin);
278 frame.reset(framer_.SerializeSynStream(syn_stream));
279 }
280 EXPECT_CALL(session_, OnStreamHeadersPriority(stream_id, 0));
281 } else {
282 if (version() > QUIC_VERSION_23) {
283 SpdyHeadersIR headers_frame(stream_id);
284 headers_frame.set_name_value_block(headers_);
285 headers_frame.set_fin(fin);
286 frame.reset(framer_.SerializeFrame(headers_frame));
287 } else {
288 SpdySynReplyIR syn_reply(stream_id);
289 syn_reply.set_name_value_block(headers_);
290 syn_reply.set_fin(fin);
291 frame.reset(framer_.SerializeSynReply(syn_reply));
292 }
293 }
294 EXPECT_CALL(session_, OnStreamHeaders(stream_id, _))
295 .WillRepeatedly(WithArgs<1>(
296 Invoke(this,
297 &QuicHeadersStreamTest::SaveHeaderDataStringPiece)));
298 EXPECT_CALL(session_,
299 OnStreamHeadersComplete(stream_id, fin, frame->size()));
300 headers_stream_->ProcessRawData(frame->data(), frame->size());
301 CheckHeaders();
302 }
303 }
304 }
305 }
306
307 TEST_P(QuicHeadersStreamTest, ProcessLargeRawData) {
308 // We want to create a frame that is more than the SPDY Framer's max control
309 // frame size, which is 16K, but less than the HPACK decoders max decode
310 // buffer size, which is 32K.
311 headers_["key0"] = string(1 << 13, '.');
312 headers_["key1"] = string(1 << 13, '.');
313 headers_["key2"] = string(1 << 13, '.');
314 for (QuicStreamId stream_id = kClientDataStreamId1;
315 stream_id < kClientDataStreamId3; stream_id += 2) {
316 for (int count = 0; count < 2; ++count) {
317 bool fin = (count == 0);
318 for (QuicPriority priority = 0; priority < 7; ++priority) {
319 // Replace with "WriteHeadersAndSaveData"
320 scoped_ptr<SpdySerializedFrame> frame;
321 if (is_server()) {
322 if (version() > QUIC_VERSION_23) {
323 SpdyHeadersIR headers_frame(stream_id);
324 headers_frame.set_name_value_block(headers_);
325 headers_frame.set_fin(fin);
326 headers_frame.set_has_priority(true);
327 frame.reset(framer_.SerializeFrame(headers_frame));
328 } else {
329 SpdySynStreamIR syn_stream(stream_id);
330 syn_stream.set_name_value_block(headers_);
331 syn_stream.set_fin(fin);
332 frame.reset(framer_.SerializeSynStream(syn_stream));
333 }
334 EXPECT_CALL(session_, OnStreamHeadersPriority(stream_id, 0));
335 } else {
336 if (version() > QUIC_VERSION_23) {
337 SpdyHeadersIR headers_frame(stream_id);
338 headers_frame.set_name_value_block(headers_);
339 headers_frame.set_fin(fin);
340 frame.reset(framer_.SerializeFrame(headers_frame));
341 } else {
342 SpdySynReplyIR syn_reply(stream_id);
343 syn_reply.set_name_value_block(headers_);
344 syn_reply.set_fin(fin);
345 frame.reset(framer_.SerializeSynReply(syn_reply));
346 }
347 }
348 EXPECT_CALL(session_, OnStreamHeaders(stream_id, _))
349 .WillRepeatedly(WithArgs<1>(Invoke(
350 this, &QuicHeadersStreamTest::SaveHeaderDataStringPiece)));
351 EXPECT_CALL(session_,
352 OnStreamHeadersComplete(stream_id, fin, frame->size()));
353 headers_stream_->ProcessRawData(frame->data(), frame->size());
354 CheckHeaders();
355 }
356 }
357 }
358 }
359
360 TEST_P(QuicHeadersStreamTest, ProcessBadData) {
361 const char kBadData[] = "blah blah blah";
362 EXPECT_CALL(*connection_, SendConnectionCloseWithDetails(
363 QUIC_INVALID_HEADERS_STREAM_DATA, _))
364 .Times(::testing::AnyNumber());
365 headers_stream_->ProcessRawData(kBadData, strlen(kBadData));
366 }
367
368 TEST_P(QuicHeadersStreamTest, ProcessSpdyDataFrame) {
369 SpdyDataIR data(2, "");
370 scoped_ptr<SpdySerializedFrame> frame(framer_.SerializeFrame(data));
371 EXPECT_CALL(*connection_,
372 SendConnectionCloseWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
373 "SPDY DATA frame received."))
374 .WillOnce(InvokeWithoutArgs(this,
375 &QuicHeadersStreamTest::CloseConnection));
376 headers_stream_->ProcessRawData(frame->data(), frame->size());
377 }
378
379 TEST_P(QuicHeadersStreamTest, ProcessSpdyRstStreamFrame) {
380 SpdyRstStreamIR data(2, RST_STREAM_PROTOCOL_ERROR, "");
381 scoped_ptr<SpdySerializedFrame> frame(framer_.SerializeFrame(data));
382 EXPECT_CALL(*connection_,
383 SendConnectionCloseWithDetails(
384 QUIC_INVALID_HEADERS_STREAM_DATA,
385 "SPDY RST_STREAM frame received."))
386 .WillOnce(InvokeWithoutArgs(this,
387 &QuicHeadersStreamTest::CloseConnection));
388 headers_stream_->ProcessRawData(frame->data(), frame->size());
389 }
390
391 TEST_P(QuicHeadersStreamTest, ProcessSpdySettingsFrame) {
392 SpdySettingsIR data;
393 if (version() > QUIC_VERSION_23) {
394 data.AddSetting(SETTINGS_HEADER_TABLE_SIZE, true, true, 0);
395 } else {
396 data.AddSetting(SETTINGS_UPLOAD_BANDWIDTH, true, true, 0);
397 }
398 scoped_ptr<SpdySerializedFrame> frame(framer_.SerializeFrame(data));
399 EXPECT_CALL(*connection_,
400 SendConnectionCloseWithDetails(
401 QUIC_INVALID_HEADERS_STREAM_DATA,
402 "SPDY SETTINGS frame received."))
403 .WillOnce(InvokeWithoutArgs(this,
404 &QuicHeadersStreamTest::CloseConnection));
405 headers_stream_->ProcessRawData(frame->data(), frame->size());
406 }
407
408 TEST_P(QuicHeadersStreamTest, ProcessSpdyPingFrame) {
409 SpdyPingIR data(1);
410 scoped_ptr<SpdySerializedFrame> frame(framer_.SerializeFrame(data));
411 EXPECT_CALL(*connection_,
412 SendConnectionCloseWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
413 "SPDY PING frame received."))
414 .WillOnce(InvokeWithoutArgs(this,
415 &QuicHeadersStreamTest::CloseConnection));
416 headers_stream_->ProcessRawData(frame->data(), frame->size());
417 }
418
419 TEST_P(QuicHeadersStreamTest, ProcessSpdyGoAwayFrame) {
420 SpdyGoAwayIR data(1, GOAWAY_PROTOCOL_ERROR, "go away");
421 scoped_ptr<SpdySerializedFrame> frame(framer_.SerializeFrame(data));
422 EXPECT_CALL(*connection_,
423 SendConnectionCloseWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
424 "SPDY GOAWAY frame received."))
425 .WillOnce(InvokeWithoutArgs(this,
426 &QuicHeadersStreamTest::CloseConnection));
427 headers_stream_->ProcessRawData(frame->data(), frame->size());
428 }
429
430 TEST_P(QuicHeadersStreamTest, ProcessSpdyHeadersFrame) {
431 if (version() > QUIC_VERSION_23) {
432 // HEADERS frames are an error when using SPDY/3, but
433 // when using SPDY/4 they're the "normal" way of sending headers
434 // so we test their handling in the ProcessRawData test.
435 return;
436 }
437 SpdyHeadersIR data(1);
438 scoped_ptr<SpdySerializedFrame> frame(framer_.SerializeFrame(data));
439 EXPECT_CALL(*connection_,
440 SendConnectionCloseWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
441 "SPDY HEADERS frame received."))
442 .WillOnce(InvokeWithoutArgs(this,
443 &QuicHeadersStreamTest::CloseConnection));
444 headers_stream_->ProcessRawData(frame->data(), frame->size());
445 }
446
447 TEST_P(QuicHeadersStreamTest, ProcessSpdyWindowUpdateFrame) {
448 SpdyWindowUpdateIR data(1, 1);
449 scoped_ptr<SpdySerializedFrame> frame(framer_.SerializeFrame(data));
450 EXPECT_CALL(*connection_,
451 SendConnectionCloseWithDetails(
452 QUIC_INVALID_HEADERS_STREAM_DATA,
453 "SPDY WINDOW_UPDATE frame received."))
454 .WillOnce(InvokeWithoutArgs(this,
455 &QuicHeadersStreamTest::CloseConnection));
456 headers_stream_->ProcessRawData(frame->data(), frame->size());
457 }
458
459 TEST_P(QuicHeadersStreamTest, NoConnectionLevelFlowControl) {
460 EXPECT_TRUE(headers_stream_->flow_controller()->IsEnabled());
461 EXPECT_FALSE(ReliableQuicStreamPeer::StreamContributesToConnectionFlowControl(
462 headers_stream_));
463 }
464
465 } // namespace
466 } // namespace test
467 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/quic_headers_stream.cc ('k') | net/quic/quic_http_stream.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698