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

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

Issue 23691073: Land Recent QUIC changes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Compiler/unittests fix Created 7 years, 3 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 | Annotate | Revision Log
« no previous file with comments | « net/quic/quic_session.cc ('k') | net/quic/reliable_quic_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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/quic/quic_session.h" 5 #include "net/quic/quic_session.h"
6 6
7 #include <set> 7 #include <set>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/containers/hash_tables.h" 10 #include "base/containers/hash_tables.h"
11 #include "net/quic/crypto/crypto_handshake.h" 11 #include "net/quic/crypto/crypto_handshake.h"
12 #include "net/quic/quic_connection.h" 12 #include "net/quic/quic_connection.h"
13 #include "net/quic/quic_protocol.h" 13 #include "net/quic/quic_protocol.h"
14 #include "net/quic/test_tools/quic_connection_peer.h" 14 #include "net/quic/test_tools/quic_connection_peer.h"
15 #include "net/quic/test_tools/quic_test_utils.h" 15 #include "net/quic/test_tools/quic_test_utils.h"
16 #include "net/quic/test_tools/reliable_quic_stream_peer.h" 16 #include "net/quic/test_tools/reliable_quic_stream_peer.h"
17 #include "net/spdy/spdy_framer.h" 17 #include "net/spdy/spdy_framer.h"
18 #include "testing/gmock/include/gmock/gmock.h" 18 #include "testing/gmock/include/gmock/gmock.h"
19 #include "testing/gtest/include/gtest/gtest.h" 19 #include "testing/gtest/include/gtest/gtest.h"
20 20
21 using base::hash_map; 21 using base::hash_map;
22 using std::set; 22 using std::set;
23 using std::vector; 23 using std::vector;
24 using testing::_; 24 using testing::_;
25 using testing::InSequence; 25 using testing::InSequence;
26 using testing::InvokeWithoutArgs;
26 using testing::StrictMock; 27 using testing::StrictMock;
27 28
28 namespace net { 29 namespace net {
29 namespace test { 30 namespace test {
30 namespace { 31 namespace {
31 32
33 const QuicPriority kSomeMiddlePriority = 2;
34
32 class TestCryptoStream : public QuicCryptoStream { 35 class TestCryptoStream : public QuicCryptoStream {
33 public: 36 public:
34 explicit TestCryptoStream(QuicSession* session) 37 explicit TestCryptoStream(QuicSession* session)
35 : QuicCryptoStream(session) { 38 : QuicCryptoStream(session) {
36 } 39 }
37 40
38 virtual void OnHandshakeMessage( 41 virtual void OnHandshakeMessage(
39 const CryptoHandshakeMessage& message) OVERRIDE { 42 const CryptoHandshakeMessage& message) OVERRIDE {
40 encryption_established_ = true; 43 encryption_established_ = true;
41 handshake_confirmed_ = true; 44 handshake_confirmed_ = true;
42 CryptoHandshakeMessage msg; 45 CryptoHandshakeMessage msg;
43 string error_details; 46 string error_details;
44 session()->config()->ToHandshakeMessage(&msg); 47 session()->config()->ToHandshakeMessage(&msg);
45 const QuicErrorCode error = session()->config()->ProcessClientHello( 48 const QuicErrorCode error = session()->config()->ProcessClientHello(
46 msg, &error_details); 49 msg, &error_details);
47 EXPECT_EQ(QUIC_NO_ERROR, error); 50 EXPECT_EQ(QUIC_NO_ERROR, error);
48 session()->OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED); 51 session()->OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED);
49 } 52 }
53
54 MOCK_METHOD0(OnCanWrite, void());
50 }; 55 };
51 56
52 class TestStream : public ReliableQuicStream { 57 class TestStream : public ReliableQuicStream {
53 public: 58 public:
54 TestStream(QuicStreamId id, QuicSession* session) 59 TestStream(QuicStreamId id, QuicSession* session)
55 : ReliableQuicStream(id, session) { 60 : ReliableQuicStream(id, session) {
56 } 61 }
57 62
58 using ReliableQuicStream::CloseWriteSide; 63 using ReliableQuicStream::CloseWriteSide;
59 64
60 virtual uint32 ProcessData(const char* data, uint32 data_len) { 65 virtual uint32 ProcessData(const char* data, uint32 data_len) {
61 return data_len; 66 return data_len;
62 } 67 }
63 68
64 MOCK_METHOD0(OnCanWrite, void()); 69 MOCK_METHOD0(OnCanWrite, void());
65 }; 70 };
66 71
72 // Poor man's functor for use as callback in a mock.
73 class StreamBlocker {
74 public:
75 StreamBlocker(QuicSession* session, QuicStreamId stream_id)
76 : session_(session),
77 stream_id_(stream_id) {
78 }
79
80 void MarkWriteBlocked() {
81 session_->MarkWriteBlocked(stream_id_, kSomeMiddlePriority);
82 }
83
84 private:
85 QuicSession* const session_;
86 const QuicStreamId stream_id_;
87 };
88
67 class TestSession : public QuicSession { 89 class TestSession : public QuicSession {
68 public: 90 public:
69 TestSession(QuicConnection* connection, bool is_server) 91 TestSession(QuicConnection* connection, bool is_server)
70 : QuicSession(connection, DefaultQuicConfig(), is_server), 92 : QuicSession(connection, DefaultQuicConfig(), is_server),
71 crypto_stream_(this) { 93 crypto_stream_(this) {
72 } 94 }
73 95
74 virtual QuicCryptoStream* GetCryptoStream() OVERRIDE { 96 virtual TestCryptoStream* GetCryptoStream() OVERRIDE {
75 return &crypto_stream_; 97 return &crypto_stream_;
76 } 98 }
77 99
78 virtual TestStream* CreateOutgoingReliableStream() OVERRIDE { 100 virtual TestStream* CreateOutgoingReliableStream() OVERRIDE {
79 TestStream* stream = new TestStream(GetNextStreamId(), this); 101 TestStream* stream = new TestStream(GetNextStreamId(), this);
80 ActivateStream(stream); 102 ActivateStream(stream);
81 return stream; 103 return stream;
82 } 104 }
83 105
84 virtual TestStream* CreateIncomingReliableStream(QuicStreamId id) OVERRIDE { 106 virtual TestStream* CreateIncomingReliableStream(QuicStreamId id) OVERRIDE {
85 return new TestStream(id, this); 107 return new TestStream(id, this);
86 } 108 }
87 109
88 bool IsClosedStream(QuicStreamId id) { 110 bool IsClosedStream(QuicStreamId id) {
89 return QuicSession::IsClosedStream(id); 111 return QuicSession::IsClosedStream(id);
90 } 112 }
91 113
92 ReliableQuicStream* GetIncomingReliableStream(QuicStreamId stream_id) { 114 ReliableQuicStream* GetIncomingReliableStream(QuicStreamId stream_id) {
93 return QuicSession::GetIncomingReliableStream(stream_id); 115 return QuicSession::GetIncomingReliableStream(stream_id);
94 } 116 }
95 117
96 // Helper method for gmock
97 void MarkTwoWriteBlocked() {
98 this->MarkWriteBlocked(2, 0);
99 }
100
101 TestCryptoStream crypto_stream_; 118 TestCryptoStream crypto_stream_;
102 }; 119 };
103 120
104 class QuicSessionTest : public ::testing::Test { 121 class QuicSessionTest : public ::testing::Test {
105 protected: 122 protected:
106 QuicSessionTest() 123 QuicSessionTest()
107 : guid_(1), 124 : guid_(1),
108 connection_(new MockConnection(guid_, IPEndPoint(), false)), 125 connection_(new MockConnection(guid_, IPEndPoint(), false)),
109 session_(connection_, true) { 126 session_(connection_, true) {
110 headers_[":host"] = "www.google.com"; 127 headers_[":host"] = "www.google.com";
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 "\0\0\0\4" // length 250 "\0\0\0\4" // length
234 "abcd"; // invalid compressed data 251 "abcd"; // invalid compressed data
235 stream->ProcessRawData(data, arraysize(data)); 252 stream->ProcessRawData(data, arraysize(data));
236 } 253 }
237 254
238 TEST_F(QuicSessionTest, OnCanWrite) { 255 TEST_F(QuicSessionTest, OnCanWrite) {
239 TestStream* stream2 = session_.CreateOutgoingReliableStream(); 256 TestStream* stream2 = session_.CreateOutgoingReliableStream();
240 TestStream* stream4 = session_.CreateOutgoingReliableStream(); 257 TestStream* stream4 = session_.CreateOutgoingReliableStream();
241 TestStream* stream6 = session_.CreateOutgoingReliableStream(); 258 TestStream* stream6 = session_.CreateOutgoingReliableStream();
242 259
243 session_.MarkWriteBlocked(2, 0); 260 session_.MarkWriteBlocked(stream2->id(), kSomeMiddlePriority);
244 session_.MarkWriteBlocked(6, 0); 261 session_.MarkWriteBlocked(stream6->id(), kSomeMiddlePriority);
245 session_.MarkWriteBlocked(4, 0); 262 session_.MarkWriteBlocked(stream4->id(), kSomeMiddlePriority);
246 263
247 InSequence s; 264 InSequence s;
265 StreamBlocker stream2_blocker(&session_, stream2->id());
248 EXPECT_CALL(*stream2, OnCanWrite()).WillOnce( 266 EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(
249 // Reregister, to test the loop limit. 267 // Reregister, to test the loop limit.
250 testing::InvokeWithoutArgs(&session_, &TestSession::MarkTwoWriteBlocked)); 268 InvokeWithoutArgs(&stream2_blocker, &StreamBlocker::MarkWriteBlocked));
251 EXPECT_CALL(*stream6, OnCanWrite()); 269 EXPECT_CALL(*stream6, OnCanWrite());
252 EXPECT_CALL(*stream4, OnCanWrite()); 270 EXPECT_CALL(*stream4, OnCanWrite());
253 271
254 EXPECT_FALSE(session_.OnCanWrite()); 272 EXPECT_FALSE(session_.OnCanWrite());
255 } 273 }
256 274
275 TEST_F(QuicSessionTest, BufferedHandshake) {
276 EXPECT_FALSE(session_.HasPendingHandshake()); // Default value.
277
278 // Test that blocking other streams does not change our status.
279 TestStream* stream2 = session_.CreateOutgoingReliableStream();
280 StreamBlocker stream2_blocker(&session_, stream2->id());
281 stream2_blocker.MarkWriteBlocked();
282 EXPECT_FALSE(session_.HasPendingHandshake());
283
284 TestStream* stream3 = session_.CreateOutgoingReliableStream();
285 StreamBlocker stream3_blocker(&session_, stream3->id());
286 stream3_blocker.MarkWriteBlocked();
287 EXPECT_FALSE(session_.HasPendingHandshake());
288
289 // Blocking (due to buffering of) the Crypto stream is detected.
290 session_.MarkWriteBlocked(kCryptoStreamId, kSomeMiddlePriority);
291 EXPECT_TRUE(session_.HasPendingHandshake());
292
293 TestStream* stream4 = session_.CreateOutgoingReliableStream();
294 StreamBlocker stream4_blocker(&session_, stream4->id());
295 stream4_blocker.MarkWriteBlocked();
296 EXPECT_TRUE(session_.HasPendingHandshake());
297
298 InSequence s;
299 // Force most streams to re-register, which is common scenario when we block
300 // the Crypto stream, and only the crypto stream can "really" write.
301
302 // Due to prioritization, we *should* be asked to write the crypto stream
303 // first.
304 // Don't re-register the crypto stream (which signals complete writing).
305 TestCryptoStream* crypto_stream = session_.GetCryptoStream();
306 EXPECT_CALL(*crypto_stream, OnCanWrite());
307
308 // Re-register all other streams, to show they weren't able to proceed.
309 EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(
310 InvokeWithoutArgs(&stream2_blocker, &StreamBlocker::MarkWriteBlocked));
311
312 EXPECT_CALL(*stream3, OnCanWrite()).WillOnce(
313 InvokeWithoutArgs(&stream3_blocker, &StreamBlocker::MarkWriteBlocked));
314
315 EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(
316 InvokeWithoutArgs(&stream4_blocker, &StreamBlocker::MarkWriteBlocked));
317
318 EXPECT_FALSE(session_.OnCanWrite());
319 EXPECT_FALSE(session_.HasPendingHandshake()); // Crypto stream wrote.
320 }
321
257 TEST_F(QuicSessionTest, OnCanWriteWithClosedStream) { 322 TEST_F(QuicSessionTest, OnCanWriteWithClosedStream) {
258 TestStream* stream2 = session_.CreateOutgoingReliableStream(); 323 TestStream* stream2 = session_.CreateOutgoingReliableStream();
259 TestStream* stream4 = session_.CreateOutgoingReliableStream(); 324 TestStream* stream4 = session_.CreateOutgoingReliableStream();
260 session_.CreateOutgoingReliableStream(); // stream 6 325 TestStream* stream6 = session_.CreateOutgoingReliableStream();
261 326
262 session_.MarkWriteBlocked(2, 0); 327 session_.MarkWriteBlocked(stream2->id(), kSomeMiddlePriority);
263 session_.MarkWriteBlocked(6, 0); 328 session_.MarkWriteBlocked(stream6->id(), kSomeMiddlePriority);
264 session_.MarkWriteBlocked(4, 0); 329 session_.MarkWriteBlocked(stream4->id(), kSomeMiddlePriority);
265 CloseStream(6); 330 CloseStream(stream6->id());
266 331
267 InSequence s; 332 InSequence s;
268 EXPECT_CALL(*stream2, OnCanWrite()); 333 EXPECT_CALL(*stream2, OnCanWrite());
269 EXPECT_CALL(*stream4, OnCanWrite()); 334 EXPECT_CALL(*stream4, OnCanWrite());
270 EXPECT_TRUE(session_.OnCanWrite()); 335 EXPECT_TRUE(session_.OnCanWrite());
271 } 336 }
272 337
273 // Regression test for http://crbug.com/248737 338 // Regression test for http://crbug.com/248737
274 TEST_F(QuicSessionTest, OutOfOrderHeaders) { 339 TEST_F(QuicSessionTest, OutOfOrderHeaders) {
275 QuicSpdyCompressor compressor; 340 QuicSpdyCompressor compressor;
(...skipping 10 matching lines...) Expand all
286 string compressed_headers1 = compressor.CompressHeaders(headers_); 351 string compressed_headers1 = compressor.CompressHeaders(headers_);
287 QuicStreamFrame frame1(stream2->id(), false, 0, compressed_headers1); 352 QuicStreamFrame frame1(stream2->id(), false, 0, compressed_headers1);
288 353
289 // Create frame with headers for stream4. 354 // Create frame with headers for stream4.
290 string compressed_headers2 = compressor.CompressHeaders(headers_); 355 string compressed_headers2 = compressor.CompressHeaders(headers_);
291 QuicStreamFrame frame2(stream4->id(), true, 0, compressed_headers2); 356 QuicStreamFrame frame2(stream4->id(), true, 0, compressed_headers2);
292 357
293 // Process the second frame first. This will cause the headers to 358 // Process the second frame first. This will cause the headers to
294 // be queued up and processed after the first frame is processed. 359 // be queued up and processed after the first frame is processed.
295 frames.push_back(frame2); 360 frames.push_back(frame2);
296 session_.OnPacket(IPEndPoint(), IPEndPoint(), header, frames); 361 session_.OnStreamFrames(frames);
297 362
298 // Process the first frame, and un-cork the buffered headers. 363 // Process the first frame, and un-cork the buffered headers.
299 frames[0] = frame1; 364 frames[0] = frame1;
300 session_.OnPacket(IPEndPoint(), IPEndPoint(), header, frames); 365 session_.OnStreamFrames(frames);
301 366
302 // Ensure that the streams actually close and we don't DCHECK. 367 // Ensure that the streams actually close and we don't DCHECK.
303 connection_->CloseConnection(QUIC_CONNECTION_TIMED_OUT, true); 368 connection_->CloseConnection(QUIC_CONNECTION_TIMED_OUT, true);
304 } 369 }
305 370
306 TEST_F(QuicSessionTest, SendGoAway) { 371 TEST_F(QuicSessionTest, SendGoAway) {
307 // After sending a GoAway, ensure new incoming streams cannot be created and 372 // After sending a GoAway, ensure new incoming streams cannot be created and
308 // result in a RST being sent. 373 // result in a RST being sent.
309 EXPECT_CALL(*connection_, 374 EXPECT_CALL(*connection_,
310 SendGoAway(QUIC_PEER_GOING_AWAY, 0u, "Going Away.")); 375 SendGoAway(QUIC_PEER_GOING_AWAY, 0u, "Going Away."));
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 414
350 // Create frame with headers for stream2. 415 // Create frame with headers for stream2.
351 QuicSpdyCompressor compressor; 416 QuicSpdyCompressor compressor;
352 string compressed_headers1 = compressor.CompressHeaders(headers_); 417 string compressed_headers1 = compressor.CompressHeaders(headers_);
353 QuicStreamFrame frame1(stream3->id(), false, 0, compressed_headers1); 418 QuicStreamFrame frame1(stream3->id(), false, 0, compressed_headers1);
354 419
355 // Process the second frame first. This will cause the headers to 420 // Process the second frame first. This will cause the headers to
356 // be queued up and processed after the first frame is processed. 421 // be queued up and processed after the first frame is processed.
357 frames.push_back(frame1); 422 frames.push_back(frame1);
358 EXPECT_FALSE(stream3->headers_decompressed()); 423 EXPECT_FALSE(stream3->headers_decompressed());
359 session.OnPacket(IPEndPoint(), IPEndPoint(), header, frames); 424
425 session.OnStreamFrames(frames);
360 EXPECT_EQ(1u, session.GetNumOpenStreams()); 426 EXPECT_EQ(1u, session.GetNumOpenStreams());
361 427
362 EXPECT_TRUE(connection->connected()); 428 EXPECT_TRUE(connection->connected());
363 } 429 }
364 430
365 TEST_F(QuicSessionTest, ZombieStreamConnectionClose) { 431 TEST_F(QuicSessionTest, ZombieStreamConnectionClose) {
366 StrictMock<MockConnection>* connection = 432 StrictMock<MockConnection>* connection =
367 new StrictMock<MockConnection>(guid_, IPEndPoint(), false); 433 new StrictMock<MockConnection>(guid_, IPEndPoint(), false);
368 TestSession session(connection, /*is_server=*/ false); 434 TestSession session(connection, /*is_server=*/ false);
369 435
(...skipping 13 matching lines...) Expand all
383 EXPECT_EQ(1u, session.GetNumOpenStreams()); 449 EXPECT_EQ(1u, session.GetNumOpenStreams());
384 450
385 connection->CloseConnection(QUIC_CONNECTION_TIMED_OUT, false); 451 connection->CloseConnection(QUIC_CONNECTION_TIMED_OUT, false);
386 452
387 EXPECT_EQ(0u, session.GetNumOpenStreams()); 453 EXPECT_EQ(0u, session.GetNumOpenStreams());
388 } 454 }
389 455
390 } // namespace 456 } // namespace
391 } // namespace test 457 } // namespace test
392 } // namespace net 458 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/quic_session.cc ('k') | net/quic/reliable_quic_stream.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698