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

Side by Side Diff: trunk/src/net/spdy/spdy_session_unittest.cc

Issue 310563002: Revert 273680 "Defer SpdySession destruction to support closing ..." (Closed) Base URL: svn://svn.chromium.org/chrome/
Patch Set: Created 6 years, 6 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 | « trunk/src/net/spdy/spdy_session_pool_unittest.cc ('k') | no next file » | 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/spdy/spdy_session.h" 5 #include "net/spdy/spdy_session.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/callback.h" 8 #include "base/callback.h"
9 #include "base/memory/scoped_ptr.h" 9 #include "base/memory/scoped_ptr.h"
10 #include "base/run_loop.h" 10 #include "base/run_loop.h"
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 BoundNetLog(), 275 BoundNetLog(),
276 callback2.callback())); 276 callback2.callback()));
277 277
278 callback1.SetRequestToDestroy(request2.Pass()); 278 callback1.SetRequestToDestroy(request2.Pass());
279 279
280 session->CloseSessionOnError(ERR_ABORTED, "Aborting session"); 280 session->CloseSessionOnError(ERR_ABORTED, "Aborting session");
281 281
282 EXPECT_EQ(ERR_ABORTED, callback1.WaitForResult()); 282 EXPECT_EQ(ERR_ABORTED, callback1.WaitForResult());
283 } 283 }
284 284
285 // A session receiving a GOAWAY frame with no active streams should close. 285 // A session receiving a GOAWAY frame with no active streams should
286 // immediately close.
286 TEST_P(SpdySessionTest, GoAwayWithNoActiveStreams) { 287 TEST_P(SpdySessionTest, GoAwayWithNoActiveStreams) {
287 session_deps_.host_resolver->set_synchronous_mode(true); 288 session_deps_.host_resolver->set_synchronous_mode(true);
288 289
289 MockConnect connect_data(SYNCHRONOUS, OK); 290 MockConnect connect_data(SYNCHRONOUS, OK);
290 scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1)); 291 scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1));
291 MockRead reads[] = { 292 MockRead reads[] = {
292 CreateMockRead(*goaway, 0), 293 CreateMockRead(*goaway, 0),
293 }; 294 };
294 DeterministicSocketData data(reads, arraysize(reads), NULL, 0); 295 DeterministicSocketData data(reads, arraysize(reads), NULL, 0);
295 data.set_connect_data(connect_data); 296 data.set_connect_data(connect_data);
296 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 297 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
297 298
298 CreateDeterministicNetworkSession(); 299 CreateDeterministicNetworkSession();
299 300
300 base::WeakPtr<SpdySession> session = 301 base::WeakPtr<SpdySession> session =
301 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 302 CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
302 303
303 EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion()); 304 EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion());
304 305
305 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); 306 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
306 307
307 // Read and process the GOAWAY frame. 308 // Read and process the GOAWAY frame.
308 data.RunFor(1); 309 data.RunFor(1);
310
309 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); 311 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
310 base::RunLoop().RunUntilIdle(); 312
311 EXPECT_TRUE(session == NULL); 313 EXPECT_TRUE(session == NULL);
312 } 314 }
313 315
314 // A session receiving a GOAWAY frame immediately with no active 316 // A session receiving a GOAWAY frame immediately with no active
315 // streams should then close. 317 // streams should then close.
316 TEST_P(SpdySessionTest, GoAwayImmediatelyWithNoActiveStreams) { 318 TEST_P(SpdySessionTest, GoAwayImmediatelyWithNoActiveStreams) {
317 session_deps_.host_resolver->set_synchronous_mode(true); 319 session_deps_.host_resolver->set_synchronous_mode(true);
318 320
319 MockConnect connect_data(SYNCHRONOUS, OK); 321 MockConnect connect_data(SYNCHRONOUS, OK);
320 scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1)); 322 scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1));
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 402
401 // Read and process the GOAWAY frame. 403 // Read and process the GOAWAY frame.
402 data.RunFor(1); 404 data.RunFor(1);
403 405
404 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); 406 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
405 407
406 EXPECT_FALSE(session->IsStreamActive(3)); 408 EXPECT_FALSE(session->IsStreamActive(3));
407 EXPECT_EQ(NULL, spdy_stream2.get()); 409 EXPECT_EQ(NULL, spdy_stream2.get());
408 EXPECT_TRUE(session->IsStreamActive(1)); 410 EXPECT_TRUE(session->IsStreamActive(1));
409 411
410 EXPECT_TRUE(session->IsGoingAway()); 412 EXPECT_FALSE(session->IsClosed());
411 413
412 // Should close the session. 414 // Should close the session.
413 spdy_stream1->Close(); 415 spdy_stream1->Close();
414 EXPECT_EQ(NULL, spdy_stream1.get()); 416 EXPECT_EQ(NULL, spdy_stream1.get());
415 417
416 base::MessageLoop::current()->RunUntilIdle();
417 EXPECT_TRUE(session == NULL); 418 EXPECT_TRUE(session == NULL);
418 } 419 }
419 420
420 // Have a session receive two GOAWAY frames, with the last one causing 421 // Have a session receive two GOAWAY frames, with the last one causing
421 // the last active stream to be closed. The session should then be 422 // the last active stream to be closed. The session should then be
422 // closed after the second GOAWAY frame. 423 // closed after the second GOAWAY frame.
423 TEST_P(SpdySessionTest, GoAwayTwice) { 424 TEST_P(SpdySessionTest, GoAwayTwice) {
424 session_deps_.host_resolver->set_synchronous_mode(true); 425 session_deps_.host_resolver->set_synchronous_mode(true);
425 426
426 MockConnect connect_data(SYNCHRONOUS, OK); 427 MockConnect connect_data(SYNCHRONOUS, OK);
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
481 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); 482 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
482 483
483 // Read and process the first GOAWAY frame. 484 // Read and process the first GOAWAY frame.
484 data.RunFor(1); 485 data.RunFor(1);
485 486
486 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); 487 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
487 488
488 EXPECT_FALSE(session->IsStreamActive(3)); 489 EXPECT_FALSE(session->IsStreamActive(3));
489 EXPECT_EQ(NULL, spdy_stream2.get()); 490 EXPECT_EQ(NULL, spdy_stream2.get());
490 EXPECT_TRUE(session->IsStreamActive(1)); 491 EXPECT_TRUE(session->IsStreamActive(1));
491 EXPECT_TRUE(session->IsGoingAway()); 492
493 EXPECT_FALSE(session->IsClosed());
492 494
493 // Read and process the second GOAWAY frame, which should close the 495 // Read and process the second GOAWAY frame, which should close the
494 // session. 496 // session.
495 data.RunFor(1); 497 data.RunFor(1);
496 base::MessageLoop::current()->RunUntilIdle(); 498
497 EXPECT_TRUE(session == NULL); 499 EXPECT_TRUE(session == NULL);
498 } 500 }
499 501
500 // Have a session with active streams receive a GOAWAY frame and then 502 // Have a session with active streams receive a GOAWAY frame and then
501 // close it. It should handle the close properly (i.e., not try to 503 // close it. It should handle the close properly (i.e., not try to
502 // make itself unavailable in its pool twice). 504 // make itself unavailable in its pool twice).
503 TEST_P(SpdySessionTest, GoAwayWithActiveStreamsThenClose) { 505 TEST_P(SpdySessionTest, GoAwayWithActiveStreamsThenClose) {
504 session_deps_.host_resolver->set_synchronous_mode(true); 506 session_deps_.host_resolver->set_synchronous_mode(true);
505 507
506 MockConnect connect_data(SYNCHRONOUS, OK); 508 MockConnect connect_data(SYNCHRONOUS, OK);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); 561 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
560 562
561 // Read and process the GOAWAY frame. 563 // Read and process the GOAWAY frame.
562 data.RunFor(1); 564 data.RunFor(1);
563 565
564 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); 566 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
565 567
566 EXPECT_FALSE(session->IsStreamActive(3)); 568 EXPECT_FALSE(session->IsStreamActive(3));
567 EXPECT_EQ(NULL, spdy_stream2.get()); 569 EXPECT_EQ(NULL, spdy_stream2.get());
568 EXPECT_TRUE(session->IsStreamActive(1)); 570 EXPECT_TRUE(session->IsStreamActive(1));
569 EXPECT_TRUE(session->IsGoingAway()); 571
572 EXPECT_FALSE(session->IsClosed());
570 573
571 session->CloseSessionOnError(ERR_ABORTED, "Aborting session"); 574 session->CloseSessionOnError(ERR_ABORTED, "Aborting session");
575
572 EXPECT_EQ(NULL, spdy_stream1.get()); 576 EXPECT_EQ(NULL, spdy_stream1.get());
573
574 base::MessageLoop::current()->RunUntilIdle();
575 EXPECT_TRUE(session == NULL); 577 EXPECT_TRUE(session == NULL);
576 } 578 }
577 579
578 // Try to create a stream after receiving a GOAWAY frame. It should 580 // Try to create a stream after receiving a GOAWAY frame. It should
579 // fail. 581 // fail.
580 TEST_P(SpdySessionTest, CreateStreamAfterGoAway) { 582 TEST_P(SpdySessionTest, CreateStreamAfterGoAway) {
581 session_deps_.host_resolver->set_synchronous_mode(true); 583 session_deps_.host_resolver->set_synchronous_mode(true);
582 584
583 MockConnect connect_data(SYNCHRONOUS, OK); 585 MockConnect connect_data(SYNCHRONOUS, OK);
584 scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1)); 586 scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1));
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
693 695
694 // Read and process the GOAWAY frame. 696 // Read and process the GOAWAY frame.
695 data.RunFor(1); 697 data.RunFor(1);
696 698
697 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); 699 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
698 EXPECT_TRUE(session->IsStreamActive(1)); 700 EXPECT_TRUE(session->IsStreamActive(1));
699 701
700 // Read and process the SYN_STREAM frame, the subsequent RST_STREAM, 702 // Read and process the SYN_STREAM frame, the subsequent RST_STREAM,
701 // and EOF. 703 // and EOF.
702 data.RunFor(3); 704 data.RunFor(3);
703 base::MessageLoop::current()->RunUntilIdle(); 705
704 EXPECT_TRUE(session == NULL); 706 EXPECT_TRUE(session == NULL);
705 } 707 }
706 708
707 // A session observing a network change with active streams should close 709 // A session observing a network change with active streams should close
708 // when the last active stream is closed. 710 // when the last active stream is closed.
709 TEST_P(SpdySessionTest, NetworkChangeWithActiveStreams) { 711 TEST_P(SpdySessionTest, NetworkChangeWithActiveStreams) {
710 session_deps_.host_resolver->set_synchronous_mode(true); 712 session_deps_.host_resolver->set_synchronous_mode(true);
711 713
712 MockConnect connect_data(SYNCHRONOUS, OK); 714 MockConnect connect_data(SYNCHRONOUS, OK);
713 MockRead reads[] = { 715 MockRead reads[] = {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
752 754
753 // The SpdySessionPool behavior differs based on how the OSs reacts to 755 // The SpdySessionPool behavior differs based on how the OSs reacts to
754 // network changes; see comment in SpdySessionPool::OnIPAddressChanged(). 756 // network changes; see comment in SpdySessionPool::OnIPAddressChanged().
755 #if defined(OS_ANDROID) || defined(OS_WIN) || defined(OS_IOS) 757 #if defined(OS_ANDROID) || defined(OS_WIN) || defined(OS_IOS)
756 // For OSs where the TCP connections will close upon relevant network 758 // For OSs where the TCP connections will close upon relevant network
757 // changes, SpdySessionPool doesn't need to force them to close, so in these 759 // changes, SpdySessionPool doesn't need to force them to close, so in these
758 // cases verify the session has become unavailable but remains open and the 760 // cases verify the session has become unavailable but remains open and the
759 // pre-existing stream is still active. 761 // pre-existing stream is still active.
760 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); 762 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
761 763
762 EXPECT_TRUE(session->IsGoingAway()); 764 EXPECT_FALSE(session->IsClosed());
763 765
764 EXPECT_TRUE(session->IsStreamActive(1)); 766 EXPECT_TRUE(session->IsStreamActive(1));
765 767
766 // Should close the session. 768 // Should close the session.
767 spdy_stream->Close(); 769 spdy_stream->Close();
768 #endif 770 #endif
769 EXPECT_EQ(NULL, spdy_stream.get()); 771 EXPECT_EQ(NULL, spdy_stream.get());
770 772
771 base::MessageLoop::current()->RunUntilIdle();
772 EXPECT_TRUE(session == NULL); 773 EXPECT_TRUE(session == NULL);
773 } 774 }
774 775
775 TEST_P(SpdySessionTest, ClientPing) { 776 TEST_P(SpdySessionTest, ClientPing) {
776 session_deps_.enable_ping = true; 777 session_deps_.enable_ping = true;
777 session_deps_.host_resolver->set_synchronous_mode(true); 778 session_deps_.host_resolver->set_synchronous_mode(true);
778 779
779 MockConnect connect_data(SYNCHRONOUS, OK); 780 MockConnect connect_data(SYNCHRONOUS, OK);
780 scoped_ptr<SpdyFrame> read_ping(spdy_util_.ConstructSpdyPing(1, true)); 781 scoped_ptr<SpdyFrame> read_ping(spdy_util_.ConstructSpdyPing(1, true));
781 MockRead reads[] = { 782 MockRead reads[] = {
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
1034 EXPECT_EQ(0u, session->pending_create_stream_queue_size(MEDIUM)); 1035 EXPECT_EQ(0u, session->pending_create_stream_queue_size(MEDIUM));
1035 1036
1036 // Read responses on remaining active streams. 1037 // Read responses on remaining active streams.
1037 data.RunFor(4); 1038 data.RunFor(4);
1038 EXPECT_EQ(OK, delegate1.WaitForClose()); 1039 EXPECT_EQ(OK, delegate1.WaitForClose());
1039 EXPECT_EQ(kUploadData, delegate1.TakeReceivedData()); 1040 EXPECT_EQ(kUploadData, delegate1.TakeReceivedData());
1040 EXPECT_EQ(OK, delegate2.WaitForClose()); 1041 EXPECT_EQ(OK, delegate2.WaitForClose());
1041 EXPECT_EQ(kUploadData, delegate2.TakeReceivedData()); 1042 EXPECT_EQ(kUploadData, delegate2.TakeReceivedData());
1042 1043
1043 // Session was destroyed. 1044 // Session was destroyed.
1044 base::MessageLoop::current()->RunUntilIdle();
1045 EXPECT_FALSE(session.get()); 1045 EXPECT_FALSE(session.get());
1046 } 1046 }
1047 1047
1048 // Verifies that an unstalled pending stream creation racing with a new stream 1048 // Verifies that an unstalled pending stream creation racing with a new stream
1049 // creation doesn't violate the maximum stream concurrency. Regression test for 1049 // creation doesn't violate the maximum stream concurrency. Regression test for
1050 // crbug.com/373858. 1050 // crbug.com/373858.
1051 TEST_P(SpdySessionTest, UnstallRacesWithStreamCreation) { 1051 TEST_P(SpdySessionTest, UnstallRacesWithStreamCreation) {
1052 session_deps_.host_resolver->set_synchronous_mode(true); 1052 session_deps_.host_resolver->set_synchronous_mode(true);
1053 1053
1054 MockRead reads[] = { 1054 MockRead reads[] = {
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
1188 if (session->flow_control_state_ == 1188 if (session->flow_control_state_ ==
1189 SpdySession::FLOW_CONTROL_STREAM_AND_SESSION) { 1189 SpdySession::FLOW_CONTROL_STREAM_AND_SESSION) {
1190 // Verify that the session window reclaimed the evicted stream body. 1190 // Verify that the session window reclaimed the evicted stream body.
1191 EXPECT_EQ(kSpdySessionInitialWindowSize, 1191 EXPECT_EQ(kSpdySessionInitialWindowSize,
1192 session->session_recv_window_size_); 1192 session->session_recv_window_size_);
1193 EXPECT_EQ(kUploadDataSize, session->session_unacked_recv_window_bytes_); 1193 EXPECT_EQ(kUploadDataSize, session->session_unacked_recv_window_bytes_);
1194 } 1194 }
1195 1195
1196 // Read and process EOF. 1196 // Read and process EOF.
1197 data.RunFor(1); 1197 data.RunFor(1);
1198 base::MessageLoop::current()->RunUntilIdle();
1199 EXPECT_TRUE(session == NULL); 1198 EXPECT_TRUE(session == NULL);
1200 } 1199 }
1201 1200
1202 TEST_P(SpdySessionTest, FailedPing) { 1201 TEST_P(SpdySessionTest, FailedPing) {
1203 session_deps_.host_resolver->set_synchronous_mode(true); 1202 session_deps_.host_resolver->set_synchronous_mode(true);
1204 1203
1205 MockConnect connect_data(SYNCHRONOUS, OK); 1204 MockConnect connect_data(SYNCHRONOUS, OK);
1206 MockRead reads[] = { 1205 MockRead reads[] = {
1207 MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. 1206 MockRead(ASYNC, 0, 0, 0) // EOF
1208 }; 1207 };
1209 scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(1, false)); 1208 scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(1, false));
1210 MockWrite writes[] = { 1209 DeterministicSocketData data(reads, arraysize(reads), NULL, 0);
1211 CreateMockWrite(*write_ping),
1212 };
1213 StaticSocketDataProvider data(
1214 reads, arraysize(reads), writes, arraysize(writes));
1215 data.set_connect_data(connect_data); 1210 data.set_connect_data(connect_data);
1216 session_deps_.socket_factory->AddSocketDataProvider(&data); 1211 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
1217 1212
1218 CreateNetworkSession(); 1213 CreateDeterministicNetworkSession();
1219 1214
1220 base::WeakPtr<SpdySession> session = 1215 base::WeakPtr<SpdySession> session =
1221 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 1216 CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
1222 1217
1223 base::WeakPtr<SpdyStream> spdy_stream1 = 1218 base::WeakPtr<SpdyStream> spdy_stream1 =
1224 CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, 1219 CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
1225 session, test_url_, MEDIUM, BoundNetLog()); 1220 session, test_url_, MEDIUM, BoundNetLog());
1226 ASSERT_TRUE(spdy_stream1.get() != NULL); 1221 ASSERT_TRUE(spdy_stream1.get() != NULL);
1227 test::StreamDelegateSendImmediate delegate(spdy_stream1, NULL); 1222 test::StreamDelegateSendImmediate delegate(spdy_stream1, NULL);
1228 spdy_stream1->SetDelegate(&delegate); 1223 spdy_stream1->SetDelegate(&delegate);
1229 1224
1230 session->set_connection_at_risk_of_loss_time(base::TimeDelta::FromSeconds(0)); 1225 session->set_connection_at_risk_of_loss_time(base::TimeDelta::FromSeconds(0));
1231 session->set_hung_interval(base::TimeDelta::FromSeconds(0)); 1226 session->set_hung_interval(base::TimeDelta::FromSeconds(0));
1232 1227
1233 // Send a PING frame. 1228 // Send a PING frame.
1234 session->WritePingFrame(1, false); 1229 session->WritePingFrame(1, false);
1235 EXPECT_LT(0, session->pings_in_flight()); 1230 EXPECT_LT(0, session->pings_in_flight());
1236 EXPECT_GE(session->next_ping_id(), static_cast<uint32>(1)); 1231 EXPECT_GE(session->next_ping_id(), static_cast<uint32>(1));
1237 EXPECT_TRUE(session->check_ping_status_pending()); 1232 EXPECT_TRUE(session->check_ping_status_pending());
1238 1233
1239 // Assert session is not closed. 1234 // Assert session is not closed.
1240 EXPECT_TRUE(session->IsAvailable()); 1235 EXPECT_FALSE(session->IsClosed());
1241 EXPECT_LT(0u, session->num_active_streams() + session->num_created_streams()); 1236 EXPECT_LT(0u, session->num_active_streams() + session->num_created_streams());
1242 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); 1237 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
1243 1238
1244 // We set last time we have received any data in 1 sec less than now. 1239 // We set last time we have received any data in 1 sec less than now.
1245 // CheckPingStatus will trigger timeout because hung interval is zero. 1240 // CheckPingStatus will trigger timeout because hung interval is zero.
1246 base::TimeTicks now = base::TimeTicks::Now(); 1241 base::TimeTicks now = base::TimeTicks::Now();
1247 session->last_activity_time_ = now - base::TimeDelta::FromSeconds(1); 1242 session->last_activity_time_ = now - base::TimeDelta::FromSeconds(1);
1248 session->CheckPingStatus(now); 1243 session->CheckPingStatus(now);
1249 base::MessageLoop::current()->RunUntilIdle();
1250 1244
1251 EXPECT_TRUE(session == NULL); 1245 EXPECT_TRUE(session == NULL);
1252 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); 1246 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
1253 EXPECT_EQ(NULL, spdy_stream1.get()); 1247 EXPECT_EQ(NULL, spdy_stream1.get());
1254 } 1248 }
1255 1249
1256 // Request kInitialMaxConcurrentStreams + 1 streams. Receive a 1250 // Request kInitialMaxConcurrentStreams + 1 streams. Receive a
1257 // settings frame increasing the max concurrent streams by 1. Make 1251 // settings frame increasing the max concurrent streams by 1. Make
1258 // sure nothing blows up. This is a regression test for 1252 // sure nothing blows up. This is a regression test for
1259 // http://crbug.com/57331 . 1253 // http://crbug.com/57331 .
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1303 request.StartRequest( 1297 request.StartRequest(
1304 SPDY_BIDIRECTIONAL_STREAM, session, test_url_, MEDIUM, 1298 SPDY_BIDIRECTIONAL_STREAM, session, test_url_, MEDIUM,
1305 BoundNetLog(), 1299 BoundNetLog(),
1306 stream_releaser.MakeCallback(&request))); 1300 stream_releaser.MakeCallback(&request)));
1307 1301
1308 data.RunFor(1); 1302 data.RunFor(1);
1309 1303
1310 EXPECT_EQ(OK, stream_releaser.WaitForResult()); 1304 EXPECT_EQ(OK, stream_releaser.WaitForResult());
1311 1305
1312 data.RunFor(1); 1306 data.RunFor(1);
1313 if (spdy_util_.spdy_version() >= SPDY4) {
1314 // Allow the SETTINGS+ACK to write, so the session finishes draining.
1315 data.RunFor(1);
1316 }
1317 base::MessageLoop::current()->RunUntilIdle();
1318 EXPECT_TRUE(session == NULL); 1307 EXPECT_TRUE(session == NULL);
1319 } 1308 }
1320 1309
1321 // Start with a persisted value for max concurrent streams. Receive a 1310 // Start with a persisted value for max concurrent streams. Receive a
1322 // settings frame increasing the max concurrent streams by 1 and which 1311 // settings frame increasing the max concurrent streams by 1 and which
1323 // also clears the persisted data. Verify that persisted data is 1312 // also clears the persisted data. Verify that persisted data is
1324 // correct. 1313 // correct.
1325 TEST_P(SpdySessionTest, ClearSettings) { 1314 TEST_P(SpdySessionTest, ClearSettings) {
1326 if (spdy_util_.spdy_version() >= SPDY4) { 1315 if (spdy_util_.spdy_version() >= SPDY4) {
1327 // SPDY4 doesn't include settings persistence, or a CLEAR_SETTINGS flag. 1316 // SPDY4 doesn't include settings persistence, or a CLEAR_SETTINGS flag.
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
1587 EXPECT_LT(0, pos); 1576 EXPECT_LT(0, pos);
1588 1577
1589 CapturingNetLog::CapturedEntry entry = entries[pos]; 1578 CapturingNetLog::CapturedEntry entry = entries[pos];
1590 NetLog::Source socket_source; 1579 NetLog::Source socket_source;
1591 EXPECT_TRUE(NetLog::Source::FromEventParameters(entry.params.get(), 1580 EXPECT_TRUE(NetLog::Source::FromEventParameters(entry.params.get(),
1592 &socket_source)); 1581 &socket_source));
1593 EXPECT_TRUE(socket_source.IsValid()); 1582 EXPECT_TRUE(socket_source.IsValid());
1594 EXPECT_NE(log.bound().source().id, socket_source.id); 1583 EXPECT_NE(log.bound().source().id, socket_source.id);
1595 } 1584 }
1596 1585
1597 TEST_P(SpdySessionTest, NetLogOnSessionGoaway) { 1586 TEST_P(SpdySessionTest, CloseSessionOnError) {
1598 session_deps_.host_resolver->set_synchronous_mode(true); 1587 session_deps_.host_resolver->set_synchronous_mode(true);
1599 1588
1600 MockConnect connect_data(SYNCHRONOUS, OK); 1589 MockConnect connect_data(SYNCHRONOUS, OK);
1601 scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway()); 1590 scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway());
1602 MockRead reads[] = { 1591 MockRead reads[] = {
1603 CreateMockRead(*goaway), 1592 CreateMockRead(*goaway),
1604 MockRead(SYNCHRONOUS, 0, 0) // EOF 1593 MockRead(SYNCHRONOUS, 0, 0) // EOF
1605 }; 1594 };
1606 1595
1607 StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0); 1596 StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
(...skipping 21 matching lines...) Expand all
1629 // Check that we logged SPDY_SESSION_CLOSE correctly. 1618 // Check that we logged SPDY_SESSION_CLOSE correctly.
1630 int pos = net::ExpectLogContainsSomewhere( 1619 int pos = net::ExpectLogContainsSomewhere(
1631 entries, 0, 1620 entries, 0,
1632 net::NetLog::TYPE_SPDY_SESSION_CLOSE, 1621 net::NetLog::TYPE_SPDY_SESSION_CLOSE,
1633 net::NetLog::PHASE_NONE); 1622 net::NetLog::PHASE_NONE);
1634 1623
1635 if (pos < static_cast<int>(entries.size())) { 1624 if (pos < static_cast<int>(entries.size())) {
1636 CapturingNetLog::CapturedEntry entry = entries[pos]; 1625 CapturingNetLog::CapturedEntry entry = entries[pos];
1637 int error_code = 0; 1626 int error_code = 0;
1638 ASSERT_TRUE(entry.GetNetErrorCode(&error_code)); 1627 ASSERT_TRUE(entry.GetNetErrorCode(&error_code));
1639 EXPECT_EQ(OK, error_code);
1640 } else {
1641 ADD_FAILURE();
1642 }
1643 }
1644
1645 TEST_P(SpdySessionTest, NetLogOnSessionEOF) {
1646 session_deps_.host_resolver->set_synchronous_mode(true);
1647
1648 MockConnect connect_data(SYNCHRONOUS, OK);
1649 MockRead reads[] = {
1650 MockRead(SYNCHRONOUS, 0, 0) // EOF
1651 };
1652
1653 StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
1654 data.set_connect_data(connect_data);
1655 session_deps_.socket_factory->AddSocketDataProvider(&data);
1656
1657 CreateNetworkSession();
1658
1659 CapturingBoundNetLog log;
1660 base::WeakPtr<SpdySession> session =
1661 CreateInsecureSpdySession(http_session_, key_, log.bound());
1662 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
1663
1664 // Flush the read completion task.
1665 base::MessageLoop::current()->RunUntilIdle();
1666
1667 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
1668 EXPECT_TRUE(session == NULL);
1669
1670 // Check that the NetLog was filled reasonably.
1671 net::CapturingNetLog::CapturedEntryList entries;
1672 log.GetEntries(&entries);
1673 EXPECT_LT(0u, entries.size());
1674
1675 // Check that we logged SPDY_SESSION_CLOSE correctly.
1676 int pos =
1677 net::ExpectLogContainsSomewhere(entries,
1678 0,
1679 net::NetLog::TYPE_SPDY_SESSION_CLOSE,
1680 net::NetLog::PHASE_NONE);
1681
1682 if (pos < static_cast<int>(entries.size())) {
1683 CapturingNetLog::CapturedEntry entry = entries[pos];
1684 int error_code = 0;
1685 ASSERT_TRUE(entry.GetNetErrorCode(&error_code));
1686 EXPECT_EQ(ERR_CONNECTION_CLOSED, error_code); 1628 EXPECT_EQ(ERR_CONNECTION_CLOSED, error_code);
1687 } else { 1629 } else {
1688 ADD_FAILURE(); 1630 ADD_FAILURE();
1689 } 1631 }
1690 } 1632 }
1691 1633
1692 // Queue up a low-priority SYN_STREAM followed by a high-priority 1634 // Queue up a low-priority SYN_STREAM followed by a high-priority
1693 // one. The high priority one should still send first and receive 1635 // one. The high priority one should still send first and receive
1694 // first. 1636 // first.
1695 TEST_P(SpdySessionTest, OutOfOrderSynStreams) { 1637 TEST_P(SpdySessionTest, OutOfOrderSynStreams) {
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
1908 1850
1909 // Ensure we don't crash while closing the session. 1851 // Ensure we don't crash while closing the session.
1910 session->CloseSessionOnError(ERR_ABORTED, std::string()); 1852 session->CloseSessionOnError(ERR_ABORTED, std::string());
1911 1853
1912 EXPECT_EQ(NULL, spdy_stream1.get()); 1854 EXPECT_EQ(NULL, spdy_stream1.get());
1913 EXPECT_EQ(NULL, spdy_stream2.get()); 1855 EXPECT_EQ(NULL, spdy_stream2.get());
1914 1856
1915 EXPECT_TRUE(delegate1.StreamIsClosed()); 1857 EXPECT_TRUE(delegate1.StreamIsClosed());
1916 EXPECT_TRUE(delegate2.StreamIsClosed()); 1858 EXPECT_TRUE(delegate2.StreamIsClosed());
1917 1859
1918 base::MessageLoop::current()->RunUntilIdle();
1919 EXPECT_TRUE(session == NULL); 1860 EXPECT_TRUE(session == NULL);
1920 } 1861 }
1921 1862
1922 // Create two streams that are set to close each other on close, and 1863 // Create two streams that are set to close each other on close, and
1923 // then close the session. Nothing should blow up. 1864 // then close the session. Nothing should blow up.
1924 TEST_P(SpdySessionTest, CloseSessionWithTwoCreatedMutuallyClosingStreams) { 1865 TEST_P(SpdySessionTest, CloseSessionWithTwoCreatedMutuallyClosingStreams) {
1925 session_deps_.host_resolver->set_synchronous_mode(true); 1866 session_deps_.host_resolver->set_synchronous_mode(true);
1926 1867
1927 MockConnect connect_data(SYNCHRONOUS, OK); 1868 MockConnect connect_data(SYNCHRONOUS, OK);
1928 1869
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1982 1923
1983 // Ensure we don't crash while closing the session. 1924 // Ensure we don't crash while closing the session.
1984 session->CloseSessionOnError(ERR_ABORTED, std::string()); 1925 session->CloseSessionOnError(ERR_ABORTED, std::string());
1985 1926
1986 EXPECT_EQ(NULL, spdy_stream1.get()); 1927 EXPECT_EQ(NULL, spdy_stream1.get());
1987 EXPECT_EQ(NULL, spdy_stream2.get()); 1928 EXPECT_EQ(NULL, spdy_stream2.get());
1988 1929
1989 EXPECT_TRUE(delegate1.StreamIsClosed()); 1930 EXPECT_TRUE(delegate1.StreamIsClosed());
1990 EXPECT_TRUE(delegate2.StreamIsClosed()); 1931 EXPECT_TRUE(delegate2.StreamIsClosed());
1991 1932
1992 base::MessageLoop::current()->RunUntilIdle();
1993 EXPECT_TRUE(session == NULL); 1933 EXPECT_TRUE(session == NULL);
1994 } 1934 }
1995 1935
1996 // Create two streams that are set to re-close themselves on close, 1936 // Create two streams that are set to re-close themselves on close,
1997 // activate them, and then close the session. Nothing should blow up. 1937 // activate them, and then close the session. Nothing should blow up.
1998 TEST_P(SpdySessionTest, CloseSessionWithTwoActivatedSelfClosingStreams) { 1938 TEST_P(SpdySessionTest, CloseSessionWithTwoActivatedSelfClosingStreams) {
1999 session_deps_.host_resolver->set_synchronous_mode(true); 1939 session_deps_.host_resolver->set_synchronous_mode(true);
2000 1940
2001 MockConnect connect_data(SYNCHRONOUS, OK); 1941 MockConnect connect_data(SYNCHRONOUS, OK);
2002 1942
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
2064 2004
2065 // Ensure we don't crash while closing the session. 2005 // Ensure we don't crash while closing the session.
2066 session->CloseSessionOnError(ERR_ABORTED, std::string()); 2006 session->CloseSessionOnError(ERR_ABORTED, std::string());
2067 2007
2068 EXPECT_EQ(NULL, spdy_stream1.get()); 2008 EXPECT_EQ(NULL, spdy_stream1.get());
2069 EXPECT_EQ(NULL, spdy_stream2.get()); 2009 EXPECT_EQ(NULL, spdy_stream2.get());
2070 2010
2071 EXPECT_TRUE(delegate1.StreamIsClosed()); 2011 EXPECT_TRUE(delegate1.StreamIsClosed());
2072 EXPECT_TRUE(delegate2.StreamIsClosed()); 2012 EXPECT_TRUE(delegate2.StreamIsClosed());
2073 2013
2074 base::MessageLoop::current()->RunUntilIdle();
2075 EXPECT_TRUE(session == NULL); 2014 EXPECT_TRUE(session == NULL);
2076 } 2015 }
2077 2016
2078 // Create two streams that are set to close each other on close, 2017 // Create two streams that are set to close each other on close,
2079 // activate them, and then close the session. Nothing should blow up. 2018 // activate them, and then close the session. Nothing should blow up.
2080 TEST_P(SpdySessionTest, CloseSessionWithTwoActivatedMutuallyClosingStreams) { 2019 TEST_P(SpdySessionTest, CloseSessionWithTwoActivatedMutuallyClosingStreams) {
2081 session_deps_.host_resolver->set_synchronous_mode(true); 2020 session_deps_.host_resolver->set_synchronous_mode(true);
2082 2021
2083 MockConnect connect_data(SYNCHRONOUS, OK); 2022 MockConnect connect_data(SYNCHRONOUS, OK);
2084 2023
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
2148 2087
2149 // Ensure we don't crash while closing the session. 2088 // Ensure we don't crash while closing the session.
2150 session->CloseSessionOnError(ERR_ABORTED, std::string()); 2089 session->CloseSessionOnError(ERR_ABORTED, std::string());
2151 2090
2152 EXPECT_EQ(NULL, spdy_stream1.get()); 2091 EXPECT_EQ(NULL, spdy_stream1.get());
2153 EXPECT_EQ(NULL, spdy_stream2.get()); 2092 EXPECT_EQ(NULL, spdy_stream2.get());
2154 2093
2155 EXPECT_TRUE(delegate1.StreamIsClosed()); 2094 EXPECT_TRUE(delegate1.StreamIsClosed());
2156 EXPECT_TRUE(delegate2.StreamIsClosed()); 2095 EXPECT_TRUE(delegate2.StreamIsClosed());
2157 2096
2158 base::MessageLoop::current()->RunUntilIdle();
2159 EXPECT_TRUE(session == NULL); 2097 EXPECT_TRUE(session == NULL);
2160 } 2098 }
2161 2099
2162 // Delegate that closes a given session when the stream is closed. 2100 // Delegate that closes a given session when the stream is closed.
2163 class SessionClosingDelegate : public test::StreamDelegateDoNothing { 2101 class SessionClosingDelegate : public test::StreamDelegateDoNothing {
2164 public: 2102 public:
2165 SessionClosingDelegate(const base::WeakPtr<SpdyStream>& stream, 2103 SessionClosingDelegate(const base::WeakPtr<SpdyStream>& stream,
2166 const base::WeakPtr<SpdySession>& session_to_close) 2104 const base::WeakPtr<SpdySession>& session_to_close)
2167 : StreamDelegateDoNothing(stream), 2105 : StreamDelegateDoNothing(stream),
2168 session_to_close_(session_to_close) {} 2106 session_to_close_(session_to_close) {}
(...skipping 10 matching lines...) Expand all
2179 2117
2180 // Close an activated stream that closes its session. Nothing should 2118 // Close an activated stream that closes its session. Nothing should
2181 // blow up. This is a regression test for http://crbug.com/263691 . 2119 // blow up. This is a regression test for http://crbug.com/263691 .
2182 TEST_P(SpdySessionTest, CloseActivatedStreamThatClosesSession) { 2120 TEST_P(SpdySessionTest, CloseActivatedStreamThatClosesSession) {
2183 session_deps_.host_resolver->set_synchronous_mode(true); 2121 session_deps_.host_resolver->set_synchronous_mode(true);
2184 2122
2185 MockConnect connect_data(SYNCHRONOUS, OK); 2123 MockConnect connect_data(SYNCHRONOUS, OK);
2186 2124
2187 scoped_ptr<SpdyFrame> req( 2125 scoped_ptr<SpdyFrame> req(
2188 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); 2126 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
2189 scoped_ptr<SpdyFrame> rst(
2190 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
2191 MockWrite writes[] = { 2127 MockWrite writes[] = {
2192 CreateMockWrite(*req, 0), CreateMockWrite(*rst, 1), 2128 CreateMockWrite(*req, 0),
2193 }; 2129 };
2194 2130
2195 MockRead reads[] = { 2131 MockRead reads[] = {
2196 MockRead(ASYNC, 0, 2) // EOF 2132 MockRead(ASYNC, 0, 1) // EOF
2197 }; 2133 };
2198 DeterministicSocketData data(reads, arraysize(reads), 2134 DeterministicSocketData data(reads, arraysize(reads),
2199 writes, arraysize(writes)); 2135 writes, arraysize(writes));
2200 data.set_connect_data(connect_data); 2136 data.set_connect_data(connect_data);
2201 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 2137 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
2202 2138
2203 CreateDeterministicNetworkSession(); 2139 CreateDeterministicNetworkSession();
2204 2140
2205 base::WeakPtr<SpdySession> session = 2141 base::WeakPtr<SpdySession> session =
2206 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); 2142 CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
(...skipping 16 matching lines...) Expand all
2223 EXPECT_EQ(0u, spdy_stream->stream_id()); 2159 EXPECT_EQ(0u, spdy_stream->stream_id());
2224 2160
2225 data.RunFor(1); 2161 data.RunFor(1);
2226 2162
2227 EXPECT_EQ(1u, spdy_stream->stream_id()); 2163 EXPECT_EQ(1u, spdy_stream->stream_id());
2228 2164
2229 // Ensure we don't crash while closing the stream (which closes the 2165 // Ensure we don't crash while closing the stream (which closes the
2230 // session). 2166 // session).
2231 spdy_stream->Cancel(); 2167 spdy_stream->Cancel();
2232 2168
2233 data.RunFor(1);
2234 base::MessageLoop::current()->RunUntilIdle();
2235
2236 EXPECT_EQ(NULL, spdy_stream.get()); 2169 EXPECT_EQ(NULL, spdy_stream.get());
2237 EXPECT_TRUE(delegate.StreamIsClosed()); 2170 EXPECT_TRUE(delegate.StreamIsClosed());
2238
2239 EXPECT_TRUE(session == NULL); 2171 EXPECT_TRUE(session == NULL);
2240 } 2172 }
2241 2173
2242 TEST_P(SpdySessionTest, VerifyDomainAuthentication) { 2174 TEST_P(SpdySessionTest, VerifyDomainAuthentication) {
2243 session_deps_.host_resolver->set_synchronous_mode(true); 2175 session_deps_.host_resolver->set_synchronous_mode(true);
2244 2176
2245 MockConnect connect_data(SYNCHRONOUS, OK); 2177 MockConnect connect_data(SYNCHRONOUS, OK);
2246 2178
2247 // No actual data will be sent. 2179 // No actual data will be sent.
2248 MockWrite writes[] = { 2180 MockWrite writes[] = {
(...skipping 2120 matching lines...) Expand 10 before | Expand all | Expand 10 after
4369 EXPECT_TRUE(stream2->send_stalled_by_flow_control()); 4301 EXPECT_TRUE(stream2->send_stalled_by_flow_control());
4370 4302
4371 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); 4303 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
4372 4304
4373 // Unstall stream1. 4305 // Unstall stream1.
4374 UnstallSessionSend(session.get(), kBodyDataSize); 4306 UnstallSessionSend(session.get(), kBodyDataSize);
4375 4307
4376 // Close the session (since we can't do it from within the delegate 4308 // Close the session (since we can't do it from within the delegate
4377 // method, since it's in the stream's loop). 4309 // method, since it's in the stream's loop).
4378 session->CloseSessionOnError(ERR_CONNECTION_CLOSED, "Closing session"); 4310 session->CloseSessionOnError(ERR_CONNECTION_CLOSED, "Closing session");
4379 base::RunLoop().RunUntilIdle();
4380 EXPECT_TRUE(session == NULL); 4311 EXPECT_TRUE(session == NULL);
4381 4312
4382 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); 4313 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
4383 4314
4384 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate1.WaitForClose()); 4315 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate1.WaitForClose());
4385 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate2.WaitForClose()); 4316 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate2.WaitForClose());
4386 4317
4387 EXPECT_TRUE(delegate1.send_headers_completed()); 4318 EXPECT_TRUE(delegate1.send_headers_completed());
4388 EXPECT_EQ(std::string(), delegate1.TakeReceivedData()); 4319 EXPECT_EQ(std::string(), delegate1.TakeReceivedData());
4389 4320
(...skipping 24 matching lines...) Expand all
4414 RST_STREAM_PROTOCOL_ERROR)); 4345 RST_STREAM_PROTOCOL_ERROR));
4415 CHECK_EQ(STATUS_CODE_FRAME_SIZE_ERROR, 4346 CHECK_EQ(STATUS_CODE_FRAME_SIZE_ERROR,
4416 MapRstStreamStatusToProtocolError( 4347 MapRstStreamStatusToProtocolError(
4417 RST_STREAM_FRAME_SIZE_ERROR)); 4348 RST_STREAM_FRAME_SIZE_ERROR));
4418 CHECK_EQ(STATUS_CODE_ENHANCE_YOUR_CALM, 4349 CHECK_EQ(STATUS_CODE_ENHANCE_YOUR_CALM,
4419 MapRstStreamStatusToProtocolError( 4350 MapRstStreamStatusToProtocolError(
4420 RST_STREAM_ENHANCE_YOUR_CALM)); 4351 RST_STREAM_ENHANCE_YOUR_CALM));
4421 } 4352 }
4422 4353
4423 } // namespace net 4354 } // namespace net
OLDNEW
« no previous file with comments | « trunk/src/net/spdy/spdy_session_pool_unittest.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698