| OLD | NEW |
| 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/base64.h" | 7 #include "base/base64.h" |
| 8 #include "base/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/callback.h" | 9 #include "base/callback.h" |
| 10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 100 } | 100 } |
| 101 | 101 |
| 102 protected: | 102 protected: |
| 103 SpdySessionTest() | 103 SpdySessionTest() |
| 104 : old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group( | 104 : old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group( |
| 105 HttpNetworkSession::NORMAL_SOCKET_POOL)), | 105 HttpNetworkSession::NORMAL_SOCKET_POOL)), |
| 106 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool( | 106 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool( |
| 107 HttpNetworkSession::NORMAL_SOCKET_POOL)), | 107 HttpNetworkSession::NORMAL_SOCKET_POOL)), |
| 108 spdy_util_(GetParam()), | 108 spdy_util_(GetParam()), |
| 109 session_deps_(GetParam()), | 109 session_deps_(GetParam()), |
| 110 spdy_session_pool_(NULL), | 110 spdy_session_pool_(nullptr), |
| 111 test_url_(kTestUrl), | 111 test_url_(kTestUrl), |
| 112 test_host_port_pair_(kTestHost, kTestPort), | 112 test_host_port_pair_(kTestHost, kTestPort), |
| 113 key_(test_host_port_pair_, ProxyServer::Direct(), | 113 key_(test_host_port_pair_, |
| 114 PRIVACY_MODE_DISABLED) { | 114 ProxyServer::Direct(), |
| 115 } | 115 PRIVACY_MODE_DISABLED) {} |
| 116 | 116 |
| 117 virtual ~SpdySessionTest() { | 117 virtual ~SpdySessionTest() { |
| 118 // Important to restore the per-pool limit first, since the pool limit must | 118 // Important to restore the per-pool limit first, since the pool limit must |
| 119 // always be greater than group limit, and the tests reduce both limits. | 119 // always be greater than group limit, and the tests reduce both limits. |
| 120 ClientSocketPoolManager::set_max_sockets_per_pool( | 120 ClientSocketPoolManager::set_max_sockets_per_pool( |
| 121 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_); | 121 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_); |
| 122 ClientSocketPoolManager::set_max_sockets_per_group( | 122 ClientSocketPoolManager::set_max_sockets_per_group( |
| 123 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_); | 123 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_); |
| 124 } | 124 } |
| 125 | 125 |
| 126 void SetUp() override { g_time_delta = base::TimeDelta(); } | 126 void SetUp() override { g_time_delta = base::TimeDelta(); } |
| 127 | 127 |
| 128 void CreateDeterministicNetworkSession() { | |
| 129 http_session_ = | |
| 130 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_); | |
| 131 spdy_session_pool_ = http_session_->spdy_session_pool(); | |
| 132 } | |
| 133 | |
| 134 void CreateNetworkSession() { | 128 void CreateNetworkSession() { |
| 135 http_session_ = | 129 http_session_ = |
| 136 SpdySessionDependencies::SpdyCreateSession(&session_deps_); | 130 SpdySessionDependencies::SpdyCreateSession(&session_deps_); |
| 137 spdy_session_pool_ = http_session_->spdy_session_pool(); | 131 spdy_session_pool_ = http_session_->spdy_session_pool(); |
| 138 } | 132 } |
| 139 | 133 |
| 140 void StallSessionSend(SpdySession* session) { | 134 void StallSessionSend(SpdySession* session) { |
| 141 // Reduce the send window size to 0 to stall. | 135 // Reduce the send window size to 0 to stall. |
| 142 while (session->session_send_window_size_ > 0) { | 136 while (session->session_send_window_size_ > 0) { |
| 143 session->DecreaseSendWindowSize( | 137 session->DecreaseSendWindowSize( |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 182 | 176 |
| 183 INSTANTIATE_TEST_CASE_P(NextProto, | 177 INSTANTIATE_TEST_CASE_P(NextProto, |
| 184 SpdySessionTest, | 178 SpdySessionTest, |
| 185 testing::Values(kProtoSPDY31, | 179 testing::Values(kProtoSPDY31, |
| 186 kProtoSPDY4_14, | 180 kProtoSPDY4_14, |
| 187 kProtoSPDY4)); | 181 kProtoSPDY4)); |
| 188 | 182 |
| 189 // Try to create a SPDY session that will fail during | 183 // Try to create a SPDY session that will fail during |
| 190 // initialization. Nothing should blow up. | 184 // initialization. Nothing should blow up. |
| 191 TEST_P(SpdySessionTest, InitialReadError) { | 185 TEST_P(SpdySessionTest, InitialReadError) { |
| 192 CreateDeterministicNetworkSession(); | 186 CreateNetworkSession(); |
| 193 | 187 |
| 194 base::WeakPtr<SpdySession> session = TryCreateFakeSpdySessionExpectingFailure( | 188 base::WeakPtr<SpdySession> session = TryCreateFakeSpdySessionExpectingFailure( |
| 195 spdy_session_pool_, key_, ERR_CONNECTION_CLOSED); | 189 spdy_session_pool_, key_, ERR_CONNECTION_CLOSED); |
| 196 EXPECT_TRUE(session); | 190 EXPECT_TRUE(session); |
| 197 // Flush the read. | 191 // Flush the read. |
| 198 base::RunLoop().RunUntilIdle(); | 192 base::RunLoop().RunUntilIdle(); |
| 199 EXPECT_FALSE(session); | 193 EXPECT_FALSE(session); |
| 200 } | 194 } |
| 201 | 195 |
| 202 namespace { | 196 namespace { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 231 | 225 |
| 232 // Request kInitialMaxConcurrentStreams streams. Request two more | 226 // Request kInitialMaxConcurrentStreams streams. Request two more |
| 233 // streams, but have the callback for one destroy the second stream | 227 // streams, but have the callback for one destroy the second stream |
| 234 // request. Close the session. Nothing should blow up. This is a | 228 // request. Close the session. Nothing should blow up. This is a |
| 235 // regression test for http://crbug.com/250841 . | 229 // regression test for http://crbug.com/250841 . |
| 236 TEST_P(SpdySessionTest, PendingStreamCancellingAnother) { | 230 TEST_P(SpdySessionTest, PendingStreamCancellingAnother) { |
| 237 session_deps_.host_resolver->set_synchronous_mode(true); | 231 session_deps_.host_resolver->set_synchronous_mode(true); |
| 238 | 232 |
| 239 MockRead reads[] = {MockRead(ASYNC, 0, 0), }; | 233 MockRead reads[] = {MockRead(ASYNC, 0, 0), }; |
| 240 | 234 |
| 241 DeterministicSocketData data(reads, arraysize(reads), NULL, 0); | 235 SequencedSocketData data(reads, arraysize(reads), nullptr, 0); |
| 242 MockConnect connect_data(SYNCHRONOUS, OK); | 236 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 243 data.set_connect_data(connect_data); | |
| 244 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 245 | 237 |
| 246 CreateDeterministicNetworkSession(); | 238 CreateNetworkSession(); |
| 247 | 239 |
| 248 base::WeakPtr<SpdySession> session = | 240 base::WeakPtr<SpdySession> session = |
| 249 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 241 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 250 | 242 |
| 251 // Create the maximum number of concurrent streams. | 243 // Create the maximum number of concurrent streams. |
| 252 for (size_t i = 0; i < kInitialMaxConcurrentStreams; ++i) { | 244 for (size_t i = 0; i < kInitialMaxConcurrentStreams; ++i) { |
| 253 base::WeakPtr<SpdyStream> spdy_stream = CreateStreamSynchronously( | 245 base::WeakPtr<SpdyStream> spdy_stream = CreateStreamSynchronously( |
| 254 SPDY_BIDIRECTIONAL_STREAM, session, test_url_, MEDIUM, BoundNetLog()); | 246 SPDY_BIDIRECTIONAL_STREAM, session, test_url_, MEDIUM, BoundNetLog()); |
| 255 ASSERT_TRUE(spdy_stream != NULL); | 247 ASSERT_TRUE(spdy_stream != nullptr); |
| 256 } | 248 } |
| 257 | 249 |
| 258 SpdyStreamRequest request1; | 250 SpdyStreamRequest request1; |
| 259 scoped_ptr<SpdyStreamRequest> request2(new SpdyStreamRequest); | 251 scoped_ptr<SpdyStreamRequest> request2(new SpdyStreamRequest); |
| 260 | 252 |
| 261 StreamRequestDestroyingCallback callback1; | 253 StreamRequestDestroyingCallback callback1; |
| 262 ASSERT_EQ(ERR_IO_PENDING, | 254 ASSERT_EQ(ERR_IO_PENDING, |
| 263 request1.StartRequest(SPDY_BIDIRECTIONAL_STREAM, | 255 request1.StartRequest(SPDY_BIDIRECTIONAL_STREAM, |
| 264 session, | 256 session, |
| 265 test_url_, | 257 test_url_, |
| (...skipping 15 matching lines...) Expand all Loading... |
| 281 | 273 |
| 282 session->CloseSessionOnError(ERR_ABORTED, "Aborting session"); | 274 session->CloseSessionOnError(ERR_ABORTED, "Aborting session"); |
| 283 | 275 |
| 284 EXPECT_EQ(ERR_ABORTED, callback1.WaitForResult()); | 276 EXPECT_EQ(ERR_ABORTED, callback1.WaitForResult()); |
| 285 } | 277 } |
| 286 | 278 |
| 287 // A session receiving a GOAWAY frame with no active streams should close. | 279 // A session receiving a GOAWAY frame with no active streams should close. |
| 288 TEST_P(SpdySessionTest, GoAwayWithNoActiveStreams) { | 280 TEST_P(SpdySessionTest, GoAwayWithNoActiveStreams) { |
| 289 session_deps_.host_resolver->set_synchronous_mode(true); | 281 session_deps_.host_resolver->set_synchronous_mode(true); |
| 290 | 282 |
| 291 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 292 scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1)); | 283 scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1)); |
| 293 MockRead reads[] = { | 284 MockRead reads[] = { |
| 294 CreateMockRead(*goaway, 0), | 285 CreateMockRead(*goaway, 0), |
| 295 }; | 286 }; |
| 296 DeterministicSocketData data(reads, arraysize(reads), NULL, 0); | 287 SequencedSocketData data(reads, arraysize(reads), nullptr, 0); |
| 297 data.set_connect_data(connect_data); | 288 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 298 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 299 | 289 |
| 300 CreateDeterministicNetworkSession(); | 290 CreateNetworkSession(); |
| 301 | 291 |
| 302 base::WeakPtr<SpdySession> session = | 292 base::WeakPtr<SpdySession> session = |
| 303 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 293 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 304 | 294 |
| 305 EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion()); | 295 EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion()); |
| 306 | 296 |
| 307 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); | 297 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); |
| 308 | 298 |
| 309 // Read and process the GOAWAY frame. | 299 // Read and process the GOAWAY frame. |
| 310 data.RunFor(1); | 300 base::RunLoop().RunUntilIdle(); |
| 311 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); | 301 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); |
| 312 base::RunLoop().RunUntilIdle(); | 302 EXPECT_FALSE(session); |
| 313 EXPECT_TRUE(session == NULL); | |
| 314 } | 303 } |
| 315 | 304 |
| 316 // A session receiving a GOAWAY frame immediately with no active | 305 // A session receiving a GOAWAY frame immediately with no active |
| 317 // streams should then close. | 306 // streams should then close. |
| 318 TEST_P(SpdySessionTest, GoAwayImmediatelyWithNoActiveStreams) { | 307 TEST_P(SpdySessionTest, GoAwayImmediatelyWithNoActiveStreams) { |
| 319 session_deps_.host_resolver->set_synchronous_mode(true); | 308 session_deps_.host_resolver->set_synchronous_mode(true); |
| 320 | 309 |
| 321 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 322 scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1)); | 310 scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1)); |
| 323 MockRead reads[] = { | 311 MockRead reads[] = { |
| 324 CreateMockRead(*goaway, 0, SYNCHRONOUS), | 312 CreateMockRead(*goaway, 0, SYNCHRONOUS), MockRead(ASYNC, 0, 1) // EOF |
| 325 }; | 313 }; |
| 326 DeterministicSocketData data(reads, arraysize(reads), NULL, 0); | 314 SequencedSocketData data(reads, arraysize(reads), nullptr, 0); |
| 327 data.set_connect_data(connect_data); | 315 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 328 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 329 | 316 |
| 330 CreateDeterministicNetworkSession(); | 317 CreateNetworkSession(); |
| 331 | |
| 332 data.StopAfter(1); | |
| 333 | 318 |
| 334 base::WeakPtr<SpdySession> session = | 319 base::WeakPtr<SpdySession> session = |
| 335 TryCreateInsecureSpdySessionExpectingFailure( | 320 TryCreateInsecureSpdySessionExpectingFailure( |
| 336 http_session_, key_, ERR_CONNECTION_CLOSED, BoundNetLog()); | 321 http_session_, key_, ERR_CONNECTION_CLOSED, BoundNetLog()); |
| 337 base::RunLoop().RunUntilIdle(); | 322 base::RunLoop().RunUntilIdle(); |
| 338 | 323 |
| 339 EXPECT_FALSE(session); | 324 EXPECT_FALSE(session); |
| 340 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); | 325 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); |
| 326 EXPECT_FALSE(data.AllReadDataConsumed()); |
| 341 } | 327 } |
| 342 | 328 |
| 343 // A session receiving a GOAWAY frame with active streams should close | 329 // A session receiving a GOAWAY frame with active streams should close |
| 344 // when the last active stream is closed. | 330 // when the last active stream is closed. |
| 345 TEST_P(SpdySessionTest, GoAwayWithActiveStreams) { | 331 TEST_P(SpdySessionTest, GoAwayWithActiveStreams) { |
| 346 session_deps_.host_resolver->set_synchronous_mode(true); | 332 session_deps_.host_resolver->set_synchronous_mode(true); |
| 347 | 333 |
| 348 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 349 scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1)); | 334 scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1)); |
| 350 MockRead reads[] = { | 335 MockRead reads[] = { |
| 351 CreateMockRead(*goaway, 2), | 336 MockRead(ASYNC, ERR_IO_PENDING, 2), |
| 352 MockRead(ASYNC, 0, 3) // EOF | 337 CreateMockRead(*goaway, 3), |
| 338 MockRead(ASYNC, ERR_IO_PENDING, 4), |
| 339 MockRead(ASYNC, 0, 5) // EOF |
| 353 }; | 340 }; |
| 354 scoped_ptr<SpdyFrame> req1( | 341 scoped_ptr<SpdyFrame> req1( |
| 355 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); | 342 spdy_util_.ConstructSpdyGet(nullptr, 0, false, 1, MEDIUM, true)); |
| 356 scoped_ptr<SpdyFrame> req2( | 343 scoped_ptr<SpdyFrame> req2( |
| 357 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, MEDIUM, true)); | 344 spdy_util_.ConstructSpdyGet(nullptr, 0, false, 3, MEDIUM, true)); |
| 358 MockWrite writes[] = { | 345 MockWrite writes[] = { |
| 359 CreateMockWrite(*req1, 0), | 346 CreateMockWrite(*req1, 0), |
| 360 CreateMockWrite(*req2, 1), | 347 CreateMockWrite(*req2, 1), |
| 361 }; | 348 }; |
| 362 DeterministicSocketData data(reads, arraysize(reads), | 349 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); |
| 363 writes, arraysize(writes)); | 350 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 364 data.set_connect_data(connect_data); | |
| 365 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 366 | 351 |
| 367 CreateDeterministicNetworkSession(); | 352 CreateNetworkSession(); |
| 368 | 353 |
| 369 base::WeakPtr<SpdySession> session = | 354 base::WeakPtr<SpdySession> session = |
| 370 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 355 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 371 | 356 |
| 372 EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion()); | 357 EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion()); |
| 373 | 358 |
| 374 GURL url(kDefaultURL); | 359 GURL url(kDefaultURL); |
| 375 base::WeakPtr<SpdyStream> spdy_stream1 = | 360 base::WeakPtr<SpdyStream> spdy_stream1 = |
| 376 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, | 361 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, |
| 377 session, url, MEDIUM, BoundNetLog()); | 362 session, url, MEDIUM, BoundNetLog()); |
| 378 test::StreamDelegateDoNothing delegate1(spdy_stream1); | 363 test::StreamDelegateDoNothing delegate1(spdy_stream1); |
| 379 spdy_stream1->SetDelegate(&delegate1); | 364 spdy_stream1->SetDelegate(&delegate1); |
| 380 | 365 |
| 381 base::WeakPtr<SpdyStream> spdy_stream2 = | 366 base::WeakPtr<SpdyStream> spdy_stream2 = |
| 382 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, | 367 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, |
| 383 session, url, MEDIUM, BoundNetLog()); | 368 session, url, MEDIUM, BoundNetLog()); |
| 384 test::StreamDelegateDoNothing delegate2(spdy_stream2); | 369 test::StreamDelegateDoNothing delegate2(spdy_stream2); |
| 385 spdy_stream2->SetDelegate(&delegate2); | 370 spdy_stream2->SetDelegate(&delegate2); |
| 386 | 371 |
| 387 scoped_ptr<SpdyHeaderBlock> headers( | 372 scoped_ptr<SpdyHeaderBlock> headers( |
| 388 spdy_util_.ConstructGetHeaderBlock(url.spec())); | 373 spdy_util_.ConstructGetHeaderBlock(url.spec())); |
| 389 scoped_ptr<SpdyHeaderBlock> headers2(new SpdyHeaderBlock(*headers)); | 374 scoped_ptr<SpdyHeaderBlock> headers2(new SpdyHeaderBlock(*headers)); |
| 390 | 375 |
| 391 spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); | 376 spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); |
| 392 EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); | 377 EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); |
| 393 spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND); | 378 spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND); |
| 394 EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders()); | 379 EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders()); |
| 395 | 380 |
| 396 data.RunFor(2); | 381 base::RunLoop().RunUntilIdle(); |
| 397 | 382 |
| 398 EXPECT_EQ(1u, spdy_stream1->stream_id()); | 383 EXPECT_EQ(1u, spdy_stream1->stream_id()); |
| 399 EXPECT_EQ(3u, spdy_stream2->stream_id()); | 384 EXPECT_EQ(3u, spdy_stream2->stream_id()); |
| 400 | 385 |
| 401 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); | 386 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); |
| 402 | 387 |
| 403 // Read and process the GOAWAY frame. | 388 // Read and process the GOAWAY frame. |
| 404 data.RunFor(1); | 389 data.CompleteRead(); |
| 390 base::RunLoop().RunUntilIdle(); |
| 405 | 391 |
| 406 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); | 392 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); |
| 407 | 393 |
| 408 EXPECT_FALSE(session->IsStreamActive(3)); | 394 EXPECT_FALSE(session->IsStreamActive(3)); |
| 409 EXPECT_EQ(NULL, spdy_stream2.get()); | 395 EXPECT_FALSE(spdy_stream2); |
| 410 EXPECT_TRUE(session->IsStreamActive(1)); | 396 EXPECT_TRUE(session->IsStreamActive(1)); |
| 411 | 397 |
| 412 EXPECT_TRUE(session->IsGoingAway()); | 398 EXPECT_TRUE(session->IsGoingAway()); |
| 413 | 399 |
| 414 // Should close the session. | 400 // Should close the session. |
| 415 spdy_stream1->Close(); | 401 spdy_stream1->Close(); |
| 416 EXPECT_EQ(NULL, spdy_stream1.get()); | 402 EXPECT_FALSE(spdy_stream1); |
| 417 | 403 |
| 418 base::MessageLoop::current()->RunUntilIdle(); | 404 EXPECT_TRUE(session); |
| 419 EXPECT_TRUE(session == NULL); | 405 data.CompleteRead(); |
| 406 base::RunLoop().RunUntilIdle(); |
| 407 EXPECT_FALSE(session); |
| 420 } | 408 } |
| 421 | 409 |
| 422 // Have a session receive two GOAWAY frames, with the last one causing | 410 // Have a session receive two GOAWAY frames, with the last one causing |
| 423 // the last active stream to be closed. The session should then be | 411 // the last active stream to be closed. The session should then be |
| 424 // closed after the second GOAWAY frame. | 412 // closed after the second GOAWAY frame. |
| 425 TEST_P(SpdySessionTest, GoAwayTwice) { | 413 TEST_P(SpdySessionTest, GoAwayTwice) { |
| 426 session_deps_.host_resolver->set_synchronous_mode(true); | 414 session_deps_.host_resolver->set_synchronous_mode(true); |
| 427 | 415 |
| 428 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 429 scoped_ptr<SpdyFrame> goaway1(spdy_util_.ConstructSpdyGoAway(1)); | 416 scoped_ptr<SpdyFrame> goaway1(spdy_util_.ConstructSpdyGoAway(1)); |
| 430 scoped_ptr<SpdyFrame> goaway2(spdy_util_.ConstructSpdyGoAway(0)); | 417 scoped_ptr<SpdyFrame> goaway2(spdy_util_.ConstructSpdyGoAway(0)); |
| 431 MockRead reads[] = { | 418 MockRead reads[] = { |
| 432 CreateMockRead(*goaway1, 2), | 419 MockRead(ASYNC, ERR_IO_PENDING, 2), |
| 433 CreateMockRead(*goaway2, 3), | 420 CreateMockRead(*goaway1, 3), |
| 434 MockRead(ASYNC, 0, 4) // EOF | 421 MockRead(ASYNC, ERR_IO_PENDING, 4), |
| 422 CreateMockRead(*goaway2, 5), |
| 423 MockRead(ASYNC, ERR_IO_PENDING, 6), |
| 424 MockRead(ASYNC, 0, 7) // EOF |
| 435 }; | 425 }; |
| 436 scoped_ptr<SpdyFrame> req1( | 426 scoped_ptr<SpdyFrame> req1( |
| 437 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); | 427 spdy_util_.ConstructSpdyGet(nullptr, 0, false, 1, MEDIUM, true)); |
| 438 scoped_ptr<SpdyFrame> req2( | 428 scoped_ptr<SpdyFrame> req2( |
| 439 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, MEDIUM, true)); | 429 spdy_util_.ConstructSpdyGet(nullptr, 0, false, 3, MEDIUM, true)); |
| 440 MockWrite writes[] = { | 430 MockWrite writes[] = { |
| 441 CreateMockWrite(*req1, 0), | 431 CreateMockWrite(*req1, 0), |
| 442 CreateMockWrite(*req2, 1), | 432 CreateMockWrite(*req2, 1), |
| 443 }; | 433 }; |
| 444 DeterministicSocketData data(reads, arraysize(reads), | 434 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); |
| 445 writes, arraysize(writes)); | 435 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 446 data.set_connect_data(connect_data); | |
| 447 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 448 | 436 |
| 449 CreateDeterministicNetworkSession(); | 437 CreateNetworkSession(); |
| 450 | 438 |
| 451 base::WeakPtr<SpdySession> session = | 439 base::WeakPtr<SpdySession> session = |
| 452 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 440 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 453 | 441 |
| 454 EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion()); | 442 EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion()); |
| 455 | 443 |
| 456 GURL url(kDefaultURL); | 444 GURL url(kDefaultURL); |
| 457 base::WeakPtr<SpdyStream> spdy_stream1 = | 445 base::WeakPtr<SpdyStream> spdy_stream1 = |
| 458 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, | 446 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, |
| 459 session, url, MEDIUM, BoundNetLog()); | 447 session, url, MEDIUM, BoundNetLog()); |
| 460 test::StreamDelegateDoNothing delegate1(spdy_stream1); | 448 test::StreamDelegateDoNothing delegate1(spdy_stream1); |
| 461 spdy_stream1->SetDelegate(&delegate1); | 449 spdy_stream1->SetDelegate(&delegate1); |
| 462 | 450 |
| 463 base::WeakPtr<SpdyStream> spdy_stream2 = | 451 base::WeakPtr<SpdyStream> spdy_stream2 = |
| 464 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, | 452 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, |
| 465 session, url, MEDIUM, BoundNetLog()); | 453 session, url, MEDIUM, BoundNetLog()); |
| 466 test::StreamDelegateDoNothing delegate2(spdy_stream2); | 454 test::StreamDelegateDoNothing delegate2(spdy_stream2); |
| 467 spdy_stream2->SetDelegate(&delegate2); | 455 spdy_stream2->SetDelegate(&delegate2); |
| 468 | 456 |
| 469 scoped_ptr<SpdyHeaderBlock> headers( | 457 scoped_ptr<SpdyHeaderBlock> headers( |
| 470 spdy_util_.ConstructGetHeaderBlock(url.spec())); | 458 spdy_util_.ConstructGetHeaderBlock(url.spec())); |
| 471 scoped_ptr<SpdyHeaderBlock> headers2(new SpdyHeaderBlock(*headers)); | 459 scoped_ptr<SpdyHeaderBlock> headers2(new SpdyHeaderBlock(*headers)); |
| 472 | 460 |
| 473 spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); | 461 spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); |
| 474 EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); | 462 EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); |
| 475 spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND); | 463 spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND); |
| 476 EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders()); | 464 EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders()); |
| 477 | 465 |
| 478 data.RunFor(2); | 466 base::RunLoop().RunUntilIdle(); |
| 479 | 467 |
| 480 EXPECT_EQ(1u, spdy_stream1->stream_id()); | 468 EXPECT_EQ(1u, spdy_stream1->stream_id()); |
| 481 EXPECT_EQ(3u, spdy_stream2->stream_id()); | 469 EXPECT_EQ(3u, spdy_stream2->stream_id()); |
| 482 | 470 |
| 483 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); | 471 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); |
| 484 | 472 |
| 485 // Read and process the first GOAWAY frame. | 473 // Read and process the first GOAWAY frame. |
| 486 data.RunFor(1); | 474 data.CompleteRead(); |
| 475 base::RunLoop().RunUntilIdle(); |
| 487 | 476 |
| 488 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); | 477 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); |
| 489 | 478 |
| 490 EXPECT_FALSE(session->IsStreamActive(3)); | 479 EXPECT_FALSE(session->IsStreamActive(3)); |
| 491 EXPECT_EQ(NULL, spdy_stream2.get()); | 480 EXPECT_FALSE(spdy_stream2); |
| 492 EXPECT_TRUE(session->IsStreamActive(1)); | 481 EXPECT_TRUE(session->IsStreamActive(1)); |
| 493 EXPECT_TRUE(session->IsGoingAway()); | 482 EXPECT_TRUE(session->IsGoingAway()); |
| 494 | 483 |
| 495 // Read and process the second GOAWAY frame, which should close the | 484 // Read and process the second GOAWAY frame, which should close the |
| 496 // session. | 485 // session. |
| 497 data.RunFor(1); | 486 data.CompleteRead(); |
| 498 base::MessageLoop::current()->RunUntilIdle(); | 487 base::RunLoop().RunUntilIdle(); |
| 499 EXPECT_TRUE(session == NULL); | 488 EXPECT_FALSE(session); |
| 500 } | 489 } |
| 501 | 490 |
| 502 // Have a session with active streams receive a GOAWAY frame and then | 491 // Have a session with active streams receive a GOAWAY frame and then |
| 503 // close it. It should handle the close properly (i.e., not try to | 492 // close it. It should handle the close properly (i.e., not try to |
| 504 // make itself unavailable in its pool twice). | 493 // make itself unavailable in its pool twice). |
| 505 TEST_P(SpdySessionTest, GoAwayWithActiveStreamsThenClose) { | 494 TEST_P(SpdySessionTest, GoAwayWithActiveStreamsThenClose) { |
| 506 session_deps_.host_resolver->set_synchronous_mode(true); | 495 session_deps_.host_resolver->set_synchronous_mode(true); |
| 507 | 496 |
| 508 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 509 scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1)); | 497 scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1)); |
| 510 MockRead reads[] = { | 498 MockRead reads[] = { |
| 511 CreateMockRead(*goaway, 2), | 499 MockRead(ASYNC, ERR_IO_PENDING, 2), |
| 512 MockRead(ASYNC, 0, 3) // EOF | 500 CreateMockRead(*goaway, 3), |
| 501 MockRead(ASYNC, ERR_IO_PENDING, 4), |
| 502 MockRead(ASYNC, 0, 5) // EOF |
| 513 }; | 503 }; |
| 514 scoped_ptr<SpdyFrame> req1( | 504 scoped_ptr<SpdyFrame> req1( |
| 515 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); | 505 spdy_util_.ConstructSpdyGet(nullptr, 0, false, 1, MEDIUM, true)); |
| 516 scoped_ptr<SpdyFrame> req2( | 506 scoped_ptr<SpdyFrame> req2( |
| 517 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, MEDIUM, true)); | 507 spdy_util_.ConstructSpdyGet(nullptr, 0, false, 3, MEDIUM, true)); |
| 518 MockWrite writes[] = { | 508 MockWrite writes[] = { |
| 519 CreateMockWrite(*req1, 0), | 509 CreateMockWrite(*req1, 0), |
| 520 CreateMockWrite(*req2, 1), | 510 CreateMockWrite(*req2, 1), |
| 521 }; | 511 }; |
| 522 DeterministicSocketData data(reads, arraysize(reads), | 512 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); |
| 523 writes, arraysize(writes)); | 513 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 524 data.set_connect_data(connect_data); | |
| 525 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 526 | 514 |
| 527 CreateDeterministicNetworkSession(); | 515 CreateNetworkSession(); |
| 528 | 516 |
| 529 base::WeakPtr<SpdySession> session = | 517 base::WeakPtr<SpdySession> session = |
| 530 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 518 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 531 | 519 |
| 532 EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion()); | 520 EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion()); |
| 533 | 521 |
| 534 GURL url(kDefaultURL); | 522 GURL url(kDefaultURL); |
| 535 base::WeakPtr<SpdyStream> spdy_stream1 = | 523 base::WeakPtr<SpdyStream> spdy_stream1 = |
| 536 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, | 524 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, |
| 537 session, url, MEDIUM, BoundNetLog()); | 525 session, url, MEDIUM, BoundNetLog()); |
| 538 test::StreamDelegateDoNothing delegate1(spdy_stream1); | 526 test::StreamDelegateDoNothing delegate1(spdy_stream1); |
| 539 spdy_stream1->SetDelegate(&delegate1); | 527 spdy_stream1->SetDelegate(&delegate1); |
| 540 | 528 |
| 541 base::WeakPtr<SpdyStream> spdy_stream2 = | 529 base::WeakPtr<SpdyStream> spdy_stream2 = |
| 542 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, | 530 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, |
| 543 session, url, MEDIUM, BoundNetLog()); | 531 session, url, MEDIUM, BoundNetLog()); |
| 544 test::StreamDelegateDoNothing delegate2(spdy_stream2); | 532 test::StreamDelegateDoNothing delegate2(spdy_stream2); |
| 545 spdy_stream2->SetDelegate(&delegate2); | 533 spdy_stream2->SetDelegate(&delegate2); |
| 546 | 534 |
| 547 scoped_ptr<SpdyHeaderBlock> headers( | 535 scoped_ptr<SpdyHeaderBlock> headers( |
| 548 spdy_util_.ConstructGetHeaderBlock(url.spec())); | 536 spdy_util_.ConstructGetHeaderBlock(url.spec())); |
| 549 scoped_ptr<SpdyHeaderBlock> headers2(new SpdyHeaderBlock(*headers)); | 537 scoped_ptr<SpdyHeaderBlock> headers2(new SpdyHeaderBlock(*headers)); |
| 550 | 538 |
| 551 spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); | 539 spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); |
| 552 EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); | 540 EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); |
| 553 spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND); | 541 spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND); |
| 554 EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders()); | 542 EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders()); |
| 555 | 543 |
| 556 data.RunFor(2); | 544 base::RunLoop().RunUntilIdle(); |
| 557 | 545 |
| 558 EXPECT_EQ(1u, spdy_stream1->stream_id()); | 546 EXPECT_EQ(1u, spdy_stream1->stream_id()); |
| 559 EXPECT_EQ(3u, spdy_stream2->stream_id()); | 547 EXPECT_EQ(3u, spdy_stream2->stream_id()); |
| 560 | 548 |
| 561 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); | 549 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); |
| 562 | 550 |
| 563 // Read and process the GOAWAY frame. | 551 // Read and process the GOAWAY frame. |
| 564 data.RunFor(1); | 552 data.CompleteRead(); |
| 553 base::RunLoop().RunUntilIdle(); |
| 565 | 554 |
| 566 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); | 555 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); |
| 567 | 556 |
| 568 EXPECT_FALSE(session->IsStreamActive(3)); | 557 EXPECT_FALSE(session->IsStreamActive(3)); |
| 569 EXPECT_EQ(NULL, spdy_stream2.get()); | 558 EXPECT_FALSE(spdy_stream2); |
| 570 EXPECT_TRUE(session->IsStreamActive(1)); | 559 EXPECT_TRUE(session->IsStreamActive(1)); |
| 571 EXPECT_TRUE(session->IsGoingAway()); | 560 EXPECT_TRUE(session->IsGoingAway()); |
| 572 | 561 |
| 573 session->CloseSessionOnError(ERR_ABORTED, "Aborting session"); | 562 session->CloseSessionOnError(ERR_ABORTED, "Aborting session"); |
| 574 EXPECT_EQ(NULL, spdy_stream1.get()); | 563 EXPECT_FALSE(spdy_stream1); |
| 575 | 564 |
| 576 base::MessageLoop::current()->RunUntilIdle(); | 565 data.CompleteRead(); |
| 577 EXPECT_TRUE(session == NULL); | 566 base::RunLoop().RunUntilIdle(); |
| 567 EXPECT_FALSE(session); |
| 578 } | 568 } |
| 579 | 569 |
| 580 // Process a joint read buffer which causes the session to begin draining, and | 570 // Process a joint read buffer which causes the session to begin draining, and |
| 581 // then processes a GOAWAY. The session should gracefully drain. Regression test | 571 // then processes a GOAWAY. The session should gracefully drain. Regression test |
| 582 // for crbug.com/379469 | 572 // for crbug.com/379469 |
| 583 TEST_P(SpdySessionTest, GoAwayWhileDraining) { | 573 TEST_P(SpdySessionTest, GoAwayWhileDraining) { |
| 584 session_deps_.host_resolver->set_synchronous_mode(true); | 574 session_deps_.host_resolver->set_synchronous_mode(true); |
| 585 | 575 |
| 586 scoped_ptr<SpdyFrame> req( | 576 scoped_ptr<SpdyFrame> req( |
| 587 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); | 577 spdy_util_.ConstructSpdyGet(nullptr, 0, false, 1, MEDIUM, true)); |
| 588 MockWrite writes[] = { | 578 MockWrite writes[] = { |
| 589 CreateMockWrite(*req, 0), | 579 CreateMockWrite(*req, 0), |
| 590 }; | 580 }; |
| 591 | 581 |
| 592 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); | 582 scoped_ptr<SpdyFrame> resp( |
| 583 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); |
| 593 scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1)); | 584 scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1)); |
| 594 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); | 585 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); |
| 595 size_t joint_size = goaway->size() * 2 + body->size(); | 586 size_t joint_size = goaway->size() * 2 + body->size(); |
| 596 | 587 |
| 597 // Compose interleaved |goaway| and |body| frames into a single read. | 588 // Compose interleaved |goaway| and |body| frames into a single read. |
| 598 scoped_ptr<char[]> buffer(new char[joint_size]); | 589 scoped_ptr<char[]> buffer(new char[joint_size]); |
| 599 { | 590 { |
| 600 size_t out = 0; | 591 size_t out = 0; |
| 601 memcpy(&buffer[out], goaway->data(), goaway->size()); | 592 memcpy(&buffer[out], goaway->data(), goaway->size()); |
| 602 out += goaway->size(); | 593 out += goaway->size(); |
| 603 memcpy(&buffer[out], body->data(), body->size()); | 594 memcpy(&buffer[out], body->data(), body->size()); |
| 604 out += body->size(); | 595 out += body->size(); |
| 605 memcpy(&buffer[out], goaway->data(), goaway->size()); | 596 memcpy(&buffer[out], goaway->data(), goaway->size()); |
| 606 out += goaway->size(); | 597 out += goaway->size(); |
| 607 ASSERT_EQ(out, joint_size); | 598 ASSERT_EQ(out, joint_size); |
| 608 } | 599 } |
| 609 SpdyFrame joint_frames(buffer.get(), joint_size, false); | 600 SpdyFrame joint_frames(buffer.get(), joint_size, false); |
| 610 | 601 |
| 611 MockRead reads[] = { | 602 MockRead reads[] = { |
| 612 CreateMockRead(*resp, 1), CreateMockRead(joint_frames, 2), | 603 CreateMockRead(*resp, 1), CreateMockRead(joint_frames, 2), |
| 613 MockRead(ASYNC, 0, 3) // EOF | 604 MockRead(ASYNC, 0, 3) // EOF |
| 614 }; | 605 }; |
| 615 | 606 |
| 616 MockConnect connect_data(SYNCHRONOUS, OK); | 607 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); |
| 617 DeterministicSocketData data( | 608 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 618 reads, arraysize(reads), writes, arraysize(writes)); | |
| 619 data.set_connect_data(connect_data); | |
| 620 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 621 | 609 |
| 622 CreateDeterministicNetworkSession(); | 610 CreateNetworkSession(); |
| 623 base::WeakPtr<SpdySession> session = | 611 base::WeakPtr<SpdySession> session = |
| 624 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 612 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 625 | 613 |
| 626 GURL url(kDefaultURL); | 614 GURL url(kDefaultURL); |
| 627 base::WeakPtr<SpdyStream> spdy_stream = CreateStreamSynchronously( | 615 base::WeakPtr<SpdyStream> spdy_stream = CreateStreamSynchronously( |
| 628 SPDY_REQUEST_RESPONSE_STREAM, session, url, MEDIUM, BoundNetLog()); | 616 SPDY_REQUEST_RESPONSE_STREAM, session, url, MEDIUM, BoundNetLog()); |
| 629 test::StreamDelegateDoNothing delegate(spdy_stream); | 617 test::StreamDelegateDoNothing delegate(spdy_stream); |
| 630 spdy_stream->SetDelegate(&delegate); | 618 spdy_stream->SetDelegate(&delegate); |
| 631 | 619 |
| 632 scoped_ptr<SpdyHeaderBlock> headers( | 620 scoped_ptr<SpdyHeaderBlock> headers( |
| 633 spdy_util_.ConstructGetHeaderBlock(url.spec())); | 621 spdy_util_.ConstructGetHeaderBlock(url.spec())); |
| 634 spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); | 622 spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); |
| 635 EXPECT_TRUE(spdy_stream->HasUrlFromHeaders()); | 623 EXPECT_TRUE(spdy_stream->HasUrlFromHeaders()); |
| 636 | 624 |
| 637 data.RunFor(3); | 625 base::RunLoop().RunUntilIdle(); |
| 638 base::MessageLoop::current()->RunUntilIdle(); | |
| 639 | 626 |
| 640 // Stream and session closed gracefully. | 627 // Stream and session closed gracefully. |
| 641 EXPECT_TRUE(delegate.StreamIsClosed()); | 628 EXPECT_TRUE(delegate.StreamIsClosed()); |
| 642 EXPECT_EQ(OK, delegate.WaitForClose()); | 629 EXPECT_EQ(OK, delegate.WaitForClose()); |
| 643 EXPECT_EQ(kUploadData, delegate.TakeReceivedData()); | 630 EXPECT_EQ(kUploadData, delegate.TakeReceivedData()); |
| 644 EXPECT_TRUE(session == NULL); | 631 EXPECT_FALSE(session); |
| 645 } | 632 } |
| 646 | 633 |
| 647 // Try to create a stream after receiving a GOAWAY frame. It should | 634 // Try to create a stream after receiving a GOAWAY frame. It should |
| 648 // fail. | 635 // fail. |
| 649 TEST_P(SpdySessionTest, CreateStreamAfterGoAway) { | 636 TEST_P(SpdySessionTest, CreateStreamAfterGoAway) { |
| 650 session_deps_.host_resolver->set_synchronous_mode(true); | 637 session_deps_.host_resolver->set_synchronous_mode(true); |
| 651 | 638 |
| 652 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 653 scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1)); | 639 scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1)); |
| 654 MockRead reads[] = { | 640 MockRead reads[] = { |
| 655 CreateMockRead(*goaway, 1), | 641 MockRead(ASYNC, ERR_IO_PENDING, 1), |
| 656 MockRead(ASYNC, 0, 2) // EOF | 642 CreateMockRead(*goaway, 2), |
| 643 MockRead(ASYNC, ERR_IO_PENDING, 3), |
| 644 MockRead(ASYNC, 0, 4) // EOF |
| 657 }; | 645 }; |
| 658 scoped_ptr<SpdyFrame> req( | 646 scoped_ptr<SpdyFrame> req( |
| 659 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); | 647 spdy_util_.ConstructSpdyGet(nullptr, 0, false, 1, MEDIUM, true)); |
| 660 MockWrite writes[] = { | 648 MockWrite writes[] = { |
| 661 CreateMockWrite(*req, 0), | 649 CreateMockWrite(*req, 0), |
| 662 }; | 650 }; |
| 663 DeterministicSocketData data(reads, arraysize(reads), | 651 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); |
| 664 writes, arraysize(writes)); | 652 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 665 data.set_connect_data(connect_data); | |
| 666 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 667 | 653 |
| 668 CreateDeterministicNetworkSession(); | 654 CreateNetworkSession(); |
| 669 | 655 |
| 670 base::WeakPtr<SpdySession> session = | 656 base::WeakPtr<SpdySession> session = |
| 671 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 657 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 672 | 658 |
| 673 EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion()); | 659 EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion()); |
| 674 | 660 |
| 675 GURL url(kDefaultURL); | 661 GURL url(kDefaultURL); |
| 676 base::WeakPtr<SpdyStream> spdy_stream = | 662 base::WeakPtr<SpdyStream> spdy_stream = |
| 677 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, | 663 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, |
| 678 session, url, MEDIUM, BoundNetLog()); | 664 session, url, MEDIUM, BoundNetLog()); |
| 679 test::StreamDelegateDoNothing delegate(spdy_stream); | 665 test::StreamDelegateDoNothing delegate(spdy_stream); |
| 680 spdy_stream->SetDelegate(&delegate); | 666 spdy_stream->SetDelegate(&delegate); |
| 681 | 667 |
| 682 scoped_ptr<SpdyHeaderBlock> headers( | 668 scoped_ptr<SpdyHeaderBlock> headers( |
| 683 spdy_util_.ConstructGetHeaderBlock(url.spec())); | 669 spdy_util_.ConstructGetHeaderBlock(url.spec())); |
| 684 spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); | 670 spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); |
| 685 EXPECT_TRUE(spdy_stream->HasUrlFromHeaders()); | 671 EXPECT_TRUE(spdy_stream->HasUrlFromHeaders()); |
| 686 | 672 |
| 687 data.RunFor(1); | 673 base::RunLoop().RunUntilIdle(); |
| 688 | 674 |
| 689 EXPECT_EQ(1u, spdy_stream->stream_id()); | 675 EXPECT_EQ(1u, spdy_stream->stream_id()); |
| 690 | 676 |
| 691 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); | 677 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); |
| 692 | 678 |
| 693 // Read and process the GOAWAY frame. | 679 // Read and process the GOAWAY frame. |
| 694 data.RunFor(1); | 680 data.CompleteRead(); |
| 681 base::RunLoop().RunUntilIdle(); |
| 695 | 682 |
| 696 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); | 683 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); |
| 697 EXPECT_TRUE(session->IsStreamActive(1)); | 684 EXPECT_TRUE(session->IsStreamActive(1)); |
| 698 | 685 |
| 699 SpdyStreamRequest stream_request; | 686 SpdyStreamRequest stream_request; |
| 700 int rv = stream_request.StartRequest( | 687 int rv = stream_request.StartRequest( |
| 701 SPDY_REQUEST_RESPONSE_STREAM, session, url, MEDIUM, BoundNetLog(), | 688 SPDY_REQUEST_RESPONSE_STREAM, session, url, MEDIUM, BoundNetLog(), |
| 702 CompletionCallback()); | 689 CompletionCallback()); |
| 703 EXPECT_EQ(ERR_FAILED, rv); | 690 EXPECT_EQ(ERR_FAILED, rv); |
| 704 | 691 |
| 705 // Read and process EOF. | 692 EXPECT_TRUE(session); |
| 706 data.RunFor(1); | 693 data.CompleteRead(); |
| 707 | 694 base::RunLoop().RunUntilIdle(); |
| 708 EXPECT_TRUE(session == NULL); | 695 EXPECT_FALSE(session); |
| 709 } | 696 } |
| 710 | 697 |
| 711 // Receiving a SYN_STREAM frame after a GOAWAY frame should result in | 698 // Receiving a SYN_STREAM frame after a GOAWAY frame should result in |
| 712 // the stream being refused. | 699 // the stream being refused. |
| 713 TEST_P(SpdySessionTest, SynStreamAfterGoAway) { | 700 TEST_P(SpdySessionTest, SynStreamAfterGoAway) { |
| 714 session_deps_.host_resolver->set_synchronous_mode(true); | 701 session_deps_.host_resolver->set_synchronous_mode(true); |
| 715 | 702 |
| 716 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 717 scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1)); | 703 scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1)); |
| 718 scoped_ptr<SpdyFrame> | 704 scoped_ptr<SpdyFrame> push( |
| 719 push(spdy_util_.ConstructSpdyPush(NULL, 0, 2, 1, kDefaultURL)); | 705 spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, kDefaultURL)); |
| 720 MockRead reads[] = { | 706 MockRead reads[] = { |
| 721 CreateMockRead(*goaway, 1), | 707 MockRead(ASYNC, ERR_IO_PENDING, 1), |
| 722 CreateMockRead(*push, 2), | 708 CreateMockRead(*goaway, 2), |
| 723 MockRead(ASYNC, 0, 4) // EOF | 709 MockRead(ASYNC, ERR_IO_PENDING, 3), |
| 710 CreateMockRead(*push, 4), |
| 711 MockRead(ASYNC, 0, 6) // EOF |
| 724 }; | 712 }; |
| 725 scoped_ptr<SpdyFrame> req( | 713 scoped_ptr<SpdyFrame> req( |
| 726 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); | 714 spdy_util_.ConstructSpdyGet(nullptr, 0, false, 1, MEDIUM, true)); |
| 727 scoped_ptr<SpdyFrame> rst( | 715 scoped_ptr<SpdyFrame> rst( |
| 728 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM)); | 716 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM)); |
| 729 MockWrite writes[] = { | 717 MockWrite writes[] = {CreateMockWrite(*req, 0), CreateMockWrite(*rst, 5)}; |
| 730 CreateMockWrite(*req, 0), | 718 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); |
| 731 CreateMockWrite(*rst, 3) | 719 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 732 }; | |
| 733 DeterministicSocketData data(reads, arraysize(reads), | |
| 734 writes, arraysize(writes)); | |
| 735 data.set_connect_data(connect_data); | |
| 736 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 737 | 720 |
| 738 CreateDeterministicNetworkSession(); | 721 CreateNetworkSession(); |
| 739 | 722 |
| 740 base::WeakPtr<SpdySession> session = | 723 base::WeakPtr<SpdySession> session = |
| 741 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 724 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 742 | 725 |
| 743 EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion()); | 726 EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion()); |
| 744 | 727 |
| 745 GURL url(kDefaultURL); | 728 GURL url(kDefaultURL); |
| 746 base::WeakPtr<SpdyStream> spdy_stream = | 729 base::WeakPtr<SpdyStream> spdy_stream = |
| 747 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, | 730 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, |
| 748 session, url, MEDIUM, BoundNetLog()); | 731 session, url, MEDIUM, BoundNetLog()); |
| 749 test::StreamDelegateDoNothing delegate(spdy_stream); | 732 test::StreamDelegateDoNothing delegate(spdy_stream); |
| 750 spdy_stream->SetDelegate(&delegate); | 733 spdy_stream->SetDelegate(&delegate); |
| 751 | 734 |
| 752 scoped_ptr<SpdyHeaderBlock> headers( | 735 scoped_ptr<SpdyHeaderBlock> headers( |
| 753 spdy_util_.ConstructGetHeaderBlock(url.spec())); | 736 spdy_util_.ConstructGetHeaderBlock(url.spec())); |
| 754 spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); | 737 spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); |
| 755 EXPECT_TRUE(spdy_stream->HasUrlFromHeaders()); | 738 EXPECT_TRUE(spdy_stream->HasUrlFromHeaders()); |
| 756 | 739 |
| 757 data.RunFor(1); | 740 base::RunLoop().RunUntilIdle(); |
| 758 | 741 |
| 759 EXPECT_EQ(1u, spdy_stream->stream_id()); | 742 EXPECT_EQ(1u, spdy_stream->stream_id()); |
| 760 | 743 |
| 761 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); | 744 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); |
| 762 | 745 |
| 763 // Read and process the GOAWAY frame. | 746 // Read and process the GOAWAY frame. |
| 764 data.RunFor(1); | 747 data.CompleteRead(); |
| 748 base::RunLoop().RunUntilIdle(); |
| 765 | 749 |
| 766 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); | 750 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); |
| 767 EXPECT_TRUE(session->IsStreamActive(1)); | 751 EXPECT_TRUE(session->IsStreamActive(1)); |
| 768 | 752 |
| 769 // Read and process the SYN_STREAM frame, the subsequent RST_STREAM, | 753 // Read and process the SYN_STREAM frame, the subsequent RST_STREAM, |
| 770 // and EOF. | 754 // and EOF. |
| 771 data.RunFor(3); | 755 data.CompleteRead(); |
| 772 base::MessageLoop::current()->RunUntilIdle(); | 756 base::RunLoop().RunUntilIdle(); |
| 773 EXPECT_TRUE(session == NULL); | 757 EXPECT_FALSE(session); |
| 774 } | 758 } |
| 775 | 759 |
| 776 // A session observing a network change with active streams should close | 760 // A session observing a network change with active streams should close |
| 777 // when the last active stream is closed. | 761 // when the last active stream is closed. |
| 778 TEST_P(SpdySessionTest, NetworkChangeWithActiveStreams) { | 762 TEST_P(SpdySessionTest, NetworkChangeWithActiveStreams) { |
| 779 session_deps_.host_resolver->set_synchronous_mode(true); | 763 session_deps_.host_resolver->set_synchronous_mode(true); |
| 780 | 764 |
| 781 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 782 MockRead reads[] = { | 765 MockRead reads[] = { |
| 783 MockRead(ASYNC, 0, 1) // EOF | 766 MockRead(ASYNC, ERR_IO_PENDING, 1), MockRead(ASYNC, 0, 2) // EOF |
| 784 }; | 767 }; |
| 785 scoped_ptr<SpdyFrame> req1( | 768 scoped_ptr<SpdyFrame> req1( |
| 786 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); | 769 spdy_util_.ConstructSpdyGet(nullptr, 0, false, 1, MEDIUM, true)); |
| 787 MockWrite writes[] = { | 770 MockWrite writes[] = { |
| 788 CreateMockWrite(*req1, 0), | 771 CreateMockWrite(*req1, 0), |
| 789 }; | 772 }; |
| 790 DeterministicSocketData data(reads, arraysize(reads), | 773 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); |
| 791 writes, arraysize(writes)); | 774 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 792 data.set_connect_data(connect_data); | |
| 793 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 794 | 775 |
| 795 CreateDeterministicNetworkSession(); | 776 CreateNetworkSession(); |
| 796 | 777 |
| 797 base::WeakPtr<SpdySession> session = | 778 base::WeakPtr<SpdySession> session = |
| 798 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 779 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 799 | 780 |
| 800 EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion()); | 781 EXPECT_EQ(spdy_util_.spdy_version(), session->GetProtocolVersion()); |
| 801 | 782 |
| 802 base::WeakPtr<SpdyStream> spdy_stream = | 783 base::WeakPtr<SpdyStream> spdy_stream = |
| 803 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session, | 784 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session, |
| 804 GURL(kDefaultURL), MEDIUM, BoundNetLog()); | 785 GURL(kDefaultURL), MEDIUM, BoundNetLog()); |
| 805 test::StreamDelegateDoNothing delegate(spdy_stream); | 786 test::StreamDelegateDoNothing delegate(spdy_stream); |
| 806 spdy_stream->SetDelegate(&delegate); | 787 spdy_stream->SetDelegate(&delegate); |
| 807 | 788 |
| 808 scoped_ptr<SpdyHeaderBlock> headers( | 789 scoped_ptr<SpdyHeaderBlock> headers( |
| 809 spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); | 790 spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); |
| 810 | 791 |
| 811 spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); | 792 spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); |
| 812 EXPECT_TRUE(spdy_stream->HasUrlFromHeaders()); | 793 EXPECT_TRUE(spdy_stream->HasUrlFromHeaders()); |
| 813 | 794 |
| 814 data.RunFor(1); | 795 base::RunLoop().RunUntilIdle(); |
| 815 | 796 |
| 816 EXPECT_EQ(1u, spdy_stream->stream_id()); | 797 EXPECT_EQ(1u, spdy_stream->stream_id()); |
| 817 | 798 |
| 818 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); | 799 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); |
| 819 | 800 |
| 820 spdy_session_pool_->OnIPAddressChanged(); | 801 spdy_session_pool_->OnIPAddressChanged(); |
| 821 | 802 |
| 822 // The SpdySessionPool behavior differs based on how the OSs reacts to | 803 // The SpdySessionPool behavior differs based on how the OSs reacts to |
| 823 // network changes; see comment in SpdySessionPool::OnIPAddressChanged(). | 804 // network changes; see comment in SpdySessionPool::OnIPAddressChanged(). |
| 824 #if defined(OS_ANDROID) || defined(OS_WIN) || defined(OS_IOS) | 805 #if defined(OS_ANDROID) || defined(OS_WIN) || defined(OS_IOS) |
| 825 // For OSs where the TCP connections will close upon relevant network | 806 // For OSs where the TCP connections will close upon relevant network |
| 826 // changes, SpdySessionPool doesn't need to force them to close, so in these | 807 // changes, SpdySessionPool doesn't need to force them to close, so in these |
| 827 // cases verify the session has become unavailable but remains open and the | 808 // cases verify the session has become unavailable but remains open and the |
| 828 // pre-existing stream is still active. | 809 // pre-existing stream is still active. |
| 829 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); | 810 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); |
| 830 | 811 |
| 831 EXPECT_TRUE(session->IsGoingAway()); | 812 EXPECT_TRUE(session->IsGoingAway()); |
| 832 | 813 |
| 833 EXPECT_TRUE(session->IsStreamActive(1)); | 814 EXPECT_TRUE(session->IsStreamActive(1)); |
| 834 | 815 |
| 835 // Should close the session. | 816 // Should close the session. |
| 836 spdy_stream->Close(); | 817 spdy_stream->Close(); |
| 837 #endif | 818 #endif |
| 838 EXPECT_EQ(NULL, spdy_stream.get()); | 819 EXPECT_FALSE(spdy_stream); |
| 839 | 820 |
| 840 base::MessageLoop::current()->RunUntilIdle(); | 821 data.CompleteRead(); |
| 841 EXPECT_TRUE(session == NULL); | 822 base::RunLoop().RunUntilIdle(); |
| 823 EXPECT_FALSE(session); |
| 842 } | 824 } |
| 843 | 825 |
| 844 TEST_P(SpdySessionTest, ClientPing) { | 826 TEST_P(SpdySessionTest, ClientPing) { |
| 845 session_deps_.enable_ping = true; | 827 session_deps_.enable_ping = true; |
| 846 session_deps_.host_resolver->set_synchronous_mode(true); | 828 session_deps_.host_resolver->set_synchronous_mode(true); |
| 847 | 829 |
| 848 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 849 scoped_ptr<SpdyFrame> read_ping(spdy_util_.ConstructSpdyPing(1, true)); | 830 scoped_ptr<SpdyFrame> read_ping(spdy_util_.ConstructSpdyPing(1, true)); |
| 850 MockRead reads[] = { | 831 MockRead reads[] = { |
| 851 CreateMockRead(*read_ping, 1), | 832 CreateMockRead(*read_ping, 1), |
| 852 MockRead(ASYNC, 0, 0, 2) // EOF | 833 MockRead(ASYNC, ERR_IO_PENDING, 2), |
| 834 MockRead(ASYNC, 0, 3) // EOF |
| 853 }; | 835 }; |
| 854 scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(1, false)); | 836 scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(1, false)); |
| 855 MockWrite writes[] = { | 837 MockWrite writes[] = { |
| 856 CreateMockWrite(*write_ping, 0), | 838 CreateMockWrite(*write_ping, 0), |
| 857 }; | 839 }; |
| 858 DeterministicSocketData data( | 840 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); |
| 859 reads, arraysize(reads), writes, arraysize(writes)); | 841 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 860 data.set_connect_data(connect_data); | |
| 861 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 862 | 842 |
| 863 CreateDeterministicNetworkSession(); | 843 CreateNetworkSession(); |
| 864 | 844 |
| 865 base::WeakPtr<SpdySession> session = | 845 base::WeakPtr<SpdySession> session = |
| 866 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 846 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 867 | 847 |
| 868 base::WeakPtr<SpdyStream> spdy_stream1 = | 848 base::WeakPtr<SpdyStream> spdy_stream1 = |
| 869 CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, | 849 CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, |
| 870 session, test_url_, MEDIUM, BoundNetLog()); | 850 session, test_url_, MEDIUM, BoundNetLog()); |
| 871 ASSERT_TRUE(spdy_stream1.get() != NULL); | 851 ASSERT_TRUE(spdy_stream1.get() != nullptr); |
| 872 test::StreamDelegateSendImmediate delegate(spdy_stream1, NULL); | 852 test::StreamDelegateSendImmediate delegate(spdy_stream1, nullptr); |
| 873 spdy_stream1->SetDelegate(&delegate); | 853 spdy_stream1->SetDelegate(&delegate); |
| 874 | 854 |
| 875 base::TimeTicks before_ping_time = base::TimeTicks::Now(); | 855 base::TimeTicks before_ping_time = base::TimeTicks::Now(); |
| 876 | 856 |
| 877 session->set_connection_at_risk_of_loss_time( | 857 session->set_connection_at_risk_of_loss_time( |
| 878 base::TimeDelta::FromSeconds(-1)); | 858 base::TimeDelta::FromSeconds(-1)); |
| 879 session->set_hung_interval(base::TimeDelta::FromMilliseconds(50)); | 859 session->set_hung_interval(base::TimeDelta::FromMilliseconds(50)); |
| 880 | 860 |
| 881 session->SendPrefacePingIfNoneInFlight(); | 861 session->SendPrefacePingIfNoneInFlight(); |
| 882 | 862 |
| 883 data.RunFor(2); | 863 base::RunLoop().RunUntilIdle(); |
| 884 | 864 |
| 885 session->CheckPingStatus(before_ping_time); | 865 session->CheckPingStatus(before_ping_time); |
| 886 | 866 |
| 887 EXPECT_EQ(0, session->pings_in_flight()); | 867 EXPECT_EQ(0, session->pings_in_flight()); |
| 888 EXPECT_GE(session->next_ping_id(), 1U); | 868 EXPECT_GE(session->next_ping_id(), 1U); |
| 889 EXPECT_FALSE(session->check_ping_status_pending()); | 869 EXPECT_FALSE(session->check_ping_status_pending()); |
| 890 EXPECT_GE(session->last_activity_time(), before_ping_time); | 870 EXPECT_GE(session->last_activity_time(), before_ping_time); |
| 891 | 871 |
| 892 data.RunFor(1); | 872 data.CompleteRead(); |
| 873 base::RunLoop().RunUntilIdle(); |
| 893 | 874 |
| 894 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate.WaitForClose()); | 875 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate.WaitForClose()); |
| 895 | 876 |
| 896 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); | 877 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); |
| 897 EXPECT_TRUE(session == NULL); | 878 EXPECT_FALSE(session); |
| 898 } | 879 } |
| 899 | 880 |
| 900 TEST_P(SpdySessionTest, ServerPing) { | 881 TEST_P(SpdySessionTest, ServerPing) { |
| 901 session_deps_.host_resolver->set_synchronous_mode(true); | 882 session_deps_.host_resolver->set_synchronous_mode(true); |
| 902 | 883 |
| 903 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 904 scoped_ptr<SpdyFrame> read_ping(spdy_util_.ConstructSpdyPing(2, false)); | 884 scoped_ptr<SpdyFrame> read_ping(spdy_util_.ConstructSpdyPing(2, false)); |
| 905 MockRead reads[] = { | 885 MockRead reads[] = { |
| 906 CreateMockRead(*read_ping), | 886 CreateMockRead(*read_ping), |
| 907 MockRead(SYNCHRONOUS, 0, 0) // EOF | 887 MockRead(SYNCHRONOUS, 0, 0) // EOF |
| 908 }; | 888 }; |
| 909 scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(2, true)); | 889 scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(2, true)); |
| 910 MockWrite writes[] = { | 890 MockWrite writes[] = { |
| 911 CreateMockWrite(*write_ping), | 891 CreateMockWrite(*write_ping), |
| 912 }; | 892 }; |
| 913 StaticSocketDataProvider data( | 893 StaticSocketDataProvider data( |
| 914 reads, arraysize(reads), writes, arraysize(writes)); | 894 reads, arraysize(reads), writes, arraysize(writes)); |
| 915 data.set_connect_data(connect_data); | |
| 916 session_deps_.socket_factory->AddSocketDataProvider(&data); | 895 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 917 | 896 |
| 918 CreateNetworkSession(); | 897 CreateNetworkSession(); |
| 919 | 898 |
| 920 base::WeakPtr<SpdySession> session = | 899 base::WeakPtr<SpdySession> session = |
| 921 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 900 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 922 | 901 |
| 923 base::WeakPtr<SpdyStream> spdy_stream1 = | 902 base::WeakPtr<SpdyStream> spdy_stream1 = |
| 924 CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, | 903 CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, |
| 925 session, test_url_, MEDIUM, BoundNetLog()); | 904 session, test_url_, MEDIUM, BoundNetLog()); |
| 926 ASSERT_TRUE(spdy_stream1.get() != NULL); | 905 ASSERT_TRUE(spdy_stream1.get() != nullptr); |
| 927 test::StreamDelegateSendImmediate delegate(spdy_stream1, NULL); | 906 test::StreamDelegateSendImmediate delegate(spdy_stream1, nullptr); |
| 928 spdy_stream1->SetDelegate(&delegate); | 907 spdy_stream1->SetDelegate(&delegate); |
| 929 | 908 |
| 930 // Flush the read completion task. | 909 // Flush the read completion task. |
| 931 base::MessageLoop::current()->RunUntilIdle(); | 910 base::RunLoop().RunUntilIdle(); |
| 932 | 911 |
| 933 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); | 912 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); |
| 934 | 913 |
| 935 EXPECT_TRUE(session == NULL); | 914 EXPECT_FALSE(session); |
| 936 EXPECT_EQ(NULL, spdy_stream1.get()); | 915 EXPECT_FALSE(spdy_stream1); |
| 937 } | 916 } |
| 938 | 917 |
| 939 // Cause a ping to be sent out while producing a write. The write loop | 918 // Cause a ping to be sent out while producing a write. The write loop |
| 940 // should handle this properly, i.e. another DoWriteLoop task should | 919 // should handle this properly, i.e. another DoWriteLoop task should |
| 941 // not be posted. This is a regression test for | 920 // not be posted. This is a regression test for |
| 942 // http://crbug.com/261043 . | 921 // http://crbug.com/261043 . |
| 943 TEST_P(SpdySessionTest, PingAndWriteLoop) { | 922 TEST_P(SpdySessionTest, PingAndWriteLoop) { |
| 944 session_deps_.enable_ping = true; | 923 session_deps_.enable_ping = true; |
| 945 session_deps_.time_func = TheNearFuture; | 924 session_deps_.time_func = TheNearFuture; |
| 946 | 925 |
| 947 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 948 scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(1, false)); | 926 scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(1, false)); |
| 949 scoped_ptr<SpdyFrame> req( | 927 scoped_ptr<SpdyFrame> req( |
| 950 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); | 928 spdy_util_.ConstructSpdyGet(nullptr, 0, false, 1, LOWEST, true)); |
| 951 MockWrite writes[] = { | 929 MockWrite writes[] = { |
| 952 CreateMockWrite(*req, 0), | 930 CreateMockWrite(*req, 0), |
| 953 CreateMockWrite(*write_ping, 1), | 931 CreateMockWrite(*write_ping, 1), |
| 954 }; | 932 }; |
| 955 | 933 |
| 956 MockRead reads[] = { | 934 MockRead reads[] = { |
| 957 MockRead(ASYNC, 0, 2) // EOF | 935 MockRead(ASYNC, ERR_IO_PENDING, 2), MockRead(ASYNC, 0, 3) // EOF |
| 958 }; | 936 }; |
| 959 | 937 |
| 960 session_deps_.host_resolver->set_synchronous_mode(true); | 938 session_deps_.host_resolver->set_synchronous_mode(true); |
| 961 | 939 |
| 962 DeterministicSocketData data(reads, arraysize(reads), | 940 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); |
| 963 writes, arraysize(writes)); | 941 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 964 data.set_connect_data(connect_data); | |
| 965 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 966 | 942 |
| 967 CreateDeterministicNetworkSession(); | 943 CreateNetworkSession(); |
| 968 | 944 |
| 969 base::WeakPtr<SpdySession> session = | 945 base::WeakPtr<SpdySession> session = |
| 970 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 946 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 971 | 947 |
| 972 GURL url(kDefaultURL); | 948 GURL url(kDefaultURL); |
| 973 base::WeakPtr<SpdyStream> spdy_stream = | 949 base::WeakPtr<SpdyStream> spdy_stream = |
| 974 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, | 950 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, |
| 975 session, url, LOWEST, BoundNetLog()); | 951 session, url, LOWEST, BoundNetLog()); |
| 976 test::StreamDelegateDoNothing delegate(spdy_stream); | 952 test::StreamDelegateDoNothing delegate(spdy_stream); |
| 977 spdy_stream->SetDelegate(&delegate); | 953 spdy_stream->SetDelegate(&delegate); |
| 978 | 954 |
| 979 scoped_ptr<SpdyHeaderBlock> headers( | 955 scoped_ptr<SpdyHeaderBlock> headers( |
| 980 spdy_util_.ConstructGetHeaderBlock(url.spec())); | 956 spdy_util_.ConstructGetHeaderBlock(url.spec())); |
| 981 spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); | 957 spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); |
| 982 | 958 |
| 983 // Shift time so that a ping will be sent out. | 959 // Shift time so that a ping will be sent out. |
| 984 g_time_delta = base::TimeDelta::FromSeconds(11); | 960 g_time_delta = base::TimeDelta::FromSeconds(11); |
| 985 | 961 |
| 986 data.RunFor(2); | 962 base::RunLoop().RunUntilIdle(); |
| 963 session->CloseSessionOnError(ERR_ABORTED, "Aborting"); |
| 987 | 964 |
| 988 session->CloseSessionOnError(ERR_ABORTED, "Aborting"); | 965 data.CompleteRead(); |
| 966 base::RunLoop().RunUntilIdle(); |
| 967 EXPECT_FALSE(session); |
| 989 } | 968 } |
| 990 | 969 |
| 991 TEST_P(SpdySessionTest, StreamIdSpaceExhausted) { | 970 TEST_P(SpdySessionTest, StreamIdSpaceExhausted) { |
| 992 const SpdyStreamId kLastStreamId = 0x7fffffff; | 971 const SpdyStreamId kLastStreamId = 0x7fffffff; |
| 993 session_deps_.host_resolver->set_synchronous_mode(true); | 972 session_deps_.host_resolver->set_synchronous_mode(true); |
| 994 | 973 |
| 995 // Test setup: |stream_hi_water_mark_| and |max_concurrent_streams_| are | 974 // Test setup: |stream_hi_water_mark_| and |max_concurrent_streams_| are |
| 996 // fixed to allow for two stream ID assignments, and three concurrent | 975 // fixed to allow for two stream ID assignments, and three concurrent |
| 997 // streams. Four streams are started, and two are activated. Verify the | 976 // streams. Four streams are started, and two are activated. Verify the |
| 998 // session goes away, and that the created (but not activated) and | 977 // session goes away, and that the created (but not activated) and |
| 999 // stalled streams are aborted. Also verify the activated streams complete, | 978 // stalled streams are aborted. Also verify the activated streams complete, |
| 1000 // at which point the session closes. | 979 // at which point the session closes. |
| 1001 | 980 |
| 1002 scoped_ptr<SpdyFrame> req1(spdy_util_.ConstructSpdyGet( | 981 scoped_ptr<SpdyFrame> req1(spdy_util_.ConstructSpdyGet( |
| 1003 NULL, 0, false, kLastStreamId - 2, MEDIUM, true)); | 982 nullptr, 0, false, kLastStreamId - 2, MEDIUM, true)); |
| 1004 scoped_ptr<SpdyFrame> req2( | 983 scoped_ptr<SpdyFrame> req2(spdy_util_.ConstructSpdyGet( |
| 1005 spdy_util_.ConstructSpdyGet(NULL, 0, false, kLastStreamId, MEDIUM, true)); | 984 nullptr, 0, false, kLastStreamId, MEDIUM, true)); |
| 1006 | 985 |
| 1007 MockWrite writes[] = { | 986 MockWrite writes[] = { |
| 1008 CreateMockWrite(*req1, 0), CreateMockWrite(*req2, 1), | 987 CreateMockWrite(*req1, 0), CreateMockWrite(*req2, 1), |
| 1009 }; | 988 }; |
| 1010 | 989 |
| 1011 scoped_ptr<SpdyFrame> resp1( | 990 scoped_ptr<SpdyFrame> resp1( |
| 1012 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, kLastStreamId - 2)); | 991 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, kLastStreamId - 2)); |
| 1013 scoped_ptr<SpdyFrame> resp2( | 992 scoped_ptr<SpdyFrame> resp2( |
| 1014 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, kLastStreamId)); | 993 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, kLastStreamId)); |
| 1015 | 994 |
| 1016 scoped_ptr<SpdyFrame> body1( | 995 scoped_ptr<SpdyFrame> body1( |
| 1017 spdy_util_.ConstructSpdyBodyFrame(kLastStreamId - 2, true)); | 996 spdy_util_.ConstructSpdyBodyFrame(kLastStreamId - 2, true)); |
| 1018 scoped_ptr<SpdyFrame> body2( | 997 scoped_ptr<SpdyFrame> body2( |
| 1019 spdy_util_.ConstructSpdyBodyFrame(kLastStreamId, true)); | 998 spdy_util_.ConstructSpdyBodyFrame(kLastStreamId, true)); |
| 1020 | 999 |
| 1021 MockRead reads[] = { | 1000 MockRead reads[] = { |
| 1022 CreateMockRead(*resp1, 2), CreateMockRead(*resp2, 3), | 1001 CreateMockRead(*resp1, 2), |
| 1023 CreateMockRead(*body1, 4), CreateMockRead(*body2, 5), | 1002 CreateMockRead(*resp2, 3), |
| 1024 MockRead(ASYNC, 0, 6) // EOF | 1003 MockRead(ASYNC, ERR_IO_PENDING, 4), |
| 1004 CreateMockRead(*body1, 5), |
| 1005 CreateMockRead(*body2, 6), |
| 1006 MockRead(ASYNC, 0, 7) // EOF |
| 1025 }; | 1007 }; |
| 1026 | 1008 |
| 1027 DeterministicSocketData data( | 1009 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); |
| 1028 reads, arraysize(reads), writes, arraysize(writes)); | 1010 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 1029 | 1011 |
| 1030 MockConnect connect_data(SYNCHRONOUS, OK); | 1012 CreateNetworkSession(); |
| 1031 data.set_connect_data(connect_data); | |
| 1032 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 1033 | |
| 1034 CreateDeterministicNetworkSession(); | |
| 1035 base::WeakPtr<SpdySession> session = | 1013 base::WeakPtr<SpdySession> session = |
| 1036 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 1014 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 1037 | 1015 |
| 1038 // Fix stream_hi_water_mark_ to allow for two stream activations. | 1016 // Fix stream_hi_water_mark_ to allow for two stream activations. |
| 1039 session->stream_hi_water_mark_ = kLastStreamId - 2; | 1017 session->stream_hi_water_mark_ = kLastStreamId - 2; |
| 1040 // Fix max_concurrent_streams to allow for three stream creations. | 1018 // Fix max_concurrent_streams to allow for three stream creations. |
| 1041 session->max_concurrent_streams_ = 3; | 1019 session->max_concurrent_streams_ = 3; |
| 1042 | 1020 |
| 1043 // Create three streams synchronously, and begin a fourth (which is stalled). | 1021 // Create three streams synchronously, and begin a fourth (which is stalled). |
| 1044 GURL url(kDefaultURL); | 1022 GURL url(kDefaultURL); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1070 // Streams 1-3 were created. 4th is stalled. No streams are active yet. | 1048 // Streams 1-3 were created. 4th is stalled. No streams are active yet. |
| 1071 EXPECT_EQ(0u, session->num_active_streams()); | 1049 EXPECT_EQ(0u, session->num_active_streams()); |
| 1072 EXPECT_EQ(3u, session->num_created_streams()); | 1050 EXPECT_EQ(3u, session->num_created_streams()); |
| 1073 EXPECT_EQ(1u, session->pending_create_stream_queue_size(MEDIUM)); | 1051 EXPECT_EQ(1u, session->pending_create_stream_queue_size(MEDIUM)); |
| 1074 | 1052 |
| 1075 // Activate stream 1. One ID remains available. | 1053 // Activate stream 1. One ID remains available. |
| 1076 stream1->SendRequestHeaders( | 1054 stream1->SendRequestHeaders( |
| 1077 scoped_ptr<SpdyHeaderBlock>( | 1055 scoped_ptr<SpdyHeaderBlock>( |
| 1078 spdy_util_.ConstructGetHeaderBlock(url.spec())), | 1056 spdy_util_.ConstructGetHeaderBlock(url.spec())), |
| 1079 NO_MORE_DATA_TO_SEND); | 1057 NO_MORE_DATA_TO_SEND); |
| 1080 data.RunFor(1); | 1058 base::RunLoop().RunUntilIdle(); |
| 1081 | 1059 |
| 1082 EXPECT_EQ(kLastStreamId - 2u, stream1->stream_id()); | 1060 EXPECT_EQ(kLastStreamId - 2u, stream1->stream_id()); |
| 1083 EXPECT_EQ(1u, session->num_active_streams()); | 1061 EXPECT_EQ(1u, session->num_active_streams()); |
| 1084 EXPECT_EQ(2u, session->num_created_streams()); | 1062 EXPECT_EQ(2u, session->num_created_streams()); |
| 1085 EXPECT_EQ(1u, session->pending_create_stream_queue_size(MEDIUM)); | 1063 EXPECT_EQ(1u, session->pending_create_stream_queue_size(MEDIUM)); |
| 1086 | 1064 |
| 1087 // Activate stream 2. ID space is exhausted. | 1065 // Activate stream 2. ID space is exhausted. |
| 1088 stream2->SendRequestHeaders( | 1066 stream2->SendRequestHeaders( |
| 1089 scoped_ptr<SpdyHeaderBlock>( | 1067 scoped_ptr<SpdyHeaderBlock>( |
| 1090 spdy_util_.ConstructGetHeaderBlock(url.spec())), | 1068 spdy_util_.ConstructGetHeaderBlock(url.spec())), |
| 1091 NO_MORE_DATA_TO_SEND); | 1069 NO_MORE_DATA_TO_SEND); |
| 1092 data.RunFor(1); | 1070 base::RunLoop().RunUntilIdle(); |
| 1093 | 1071 |
| 1094 // Active streams remain active. | 1072 // Active streams remain active. |
| 1095 EXPECT_EQ(kLastStreamId, stream2->stream_id()); | 1073 EXPECT_EQ(kLastStreamId, stream2->stream_id()); |
| 1096 EXPECT_EQ(2u, session->num_active_streams()); | 1074 EXPECT_EQ(2u, session->num_active_streams()); |
| 1097 | 1075 |
| 1098 // Session is going away. Created and stalled streams were aborted. | 1076 // Session is going away. Created and stalled streams were aborted. |
| 1099 EXPECT_EQ(SpdySession::STATE_GOING_AWAY, session->availability_state_); | 1077 EXPECT_EQ(SpdySession::STATE_GOING_AWAY, session->availability_state_); |
| 1100 EXPECT_EQ(ERR_ABORTED, delegate3.WaitForClose()); | 1078 EXPECT_EQ(ERR_ABORTED, delegate3.WaitForClose()); |
| 1101 EXPECT_EQ(ERR_ABORTED, callback4.WaitForResult()); | 1079 EXPECT_EQ(ERR_ABORTED, callback4.WaitForResult()); |
| 1102 EXPECT_EQ(0u, session->num_created_streams()); | 1080 EXPECT_EQ(0u, session->num_created_streams()); |
| 1103 EXPECT_EQ(0u, session->pending_create_stream_queue_size(MEDIUM)); | 1081 EXPECT_EQ(0u, session->pending_create_stream_queue_size(MEDIUM)); |
| 1104 | 1082 |
| 1105 // Read responses on remaining active streams. | 1083 // Read responses on remaining active streams. |
| 1106 data.RunFor(4); | 1084 data.CompleteRead(); |
| 1085 base::RunLoop().RunUntilIdle(); |
| 1107 EXPECT_EQ(OK, delegate1.WaitForClose()); | 1086 EXPECT_EQ(OK, delegate1.WaitForClose()); |
| 1108 EXPECT_EQ(kUploadData, delegate1.TakeReceivedData()); | 1087 EXPECT_EQ(kUploadData, delegate1.TakeReceivedData()); |
| 1109 EXPECT_EQ(OK, delegate2.WaitForClose()); | 1088 EXPECT_EQ(OK, delegate2.WaitForClose()); |
| 1110 EXPECT_EQ(kUploadData, delegate2.TakeReceivedData()); | 1089 EXPECT_EQ(kUploadData, delegate2.TakeReceivedData()); |
| 1111 | 1090 |
| 1112 // Session was destroyed. | 1091 // Session was destroyed. |
| 1113 base::MessageLoop::current()->RunUntilIdle(); | 1092 EXPECT_FALSE(session); |
| 1114 EXPECT_FALSE(session.get()); | |
| 1115 } | 1093 } |
| 1116 | 1094 |
| 1117 // Verifies that an unstalled pending stream creation racing with a new stream | 1095 // Verifies that an unstalled pending stream creation racing with a new stream |
| 1118 // creation doesn't violate the maximum stream concurrency. Regression test for | 1096 // creation doesn't violate the maximum stream concurrency. Regression test for |
| 1119 // crbug.com/373858. | 1097 // crbug.com/373858. |
| 1120 TEST_P(SpdySessionTest, UnstallRacesWithStreamCreation) { | 1098 TEST_P(SpdySessionTest, UnstallRacesWithStreamCreation) { |
| 1121 session_deps_.host_resolver->set_synchronous_mode(true); | 1099 session_deps_.host_resolver->set_synchronous_mode(true); |
| 1122 | 1100 |
| 1123 MockRead reads[] = { | 1101 MockRead reads[] = { |
| 1124 MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. | 1102 MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. |
| 1125 }; | 1103 }; |
| 1126 | 1104 |
| 1127 StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0); | 1105 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0); |
| 1128 | |
| 1129 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 1130 data.set_connect_data(connect_data); | |
| 1131 session_deps_.socket_factory->AddSocketDataProvider(&data); | 1106 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 1132 | 1107 |
| 1133 CreateNetworkSession(); | 1108 CreateNetworkSession(); |
| 1134 base::WeakPtr<SpdySession> session = | 1109 base::WeakPtr<SpdySession> session = |
| 1135 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 1110 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 1136 | 1111 |
| 1137 // Fix max_concurrent_streams to allow for one open stream. | 1112 // Fix max_concurrent_streams to allow for one open stream. |
| 1138 session->max_concurrent_streams_ = 1; | 1113 session->max_concurrent_streams_ = 1; |
| 1139 | 1114 |
| 1140 // Create two streams: one synchronously, and one which stalls. | 1115 // Create two streams: one synchronously, and one which stalls. |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1162 EXPECT_EQ(0u, session->num_created_streams()); | 1137 EXPECT_EQ(0u, session->num_created_streams()); |
| 1163 EXPECT_EQ(0u, session->pending_create_stream_queue_size(MEDIUM)); | 1138 EXPECT_EQ(0u, session->pending_create_stream_queue_size(MEDIUM)); |
| 1164 | 1139 |
| 1165 // Create a third stream prior to the second stream's callback. | 1140 // Create a third stream prior to the second stream's callback. |
| 1166 base::WeakPtr<SpdyStream> stream3 = CreateStreamSynchronously( | 1141 base::WeakPtr<SpdyStream> stream3 = CreateStreamSynchronously( |
| 1167 SPDY_REQUEST_RESPONSE_STREAM, session, url, MEDIUM, BoundNetLog()); | 1142 SPDY_REQUEST_RESPONSE_STREAM, session, url, MEDIUM, BoundNetLog()); |
| 1168 | 1143 |
| 1169 EXPECT_EQ(1u, session->num_created_streams()); | 1144 EXPECT_EQ(1u, session->num_created_streams()); |
| 1170 EXPECT_EQ(0u, session->pending_create_stream_queue_size(MEDIUM)); | 1145 EXPECT_EQ(0u, session->pending_create_stream_queue_size(MEDIUM)); |
| 1171 | 1146 |
| 1172 // NOW run the message loop. The unstalled stream will re-stall itself. | 1147 // Now run the message loop. The unstalled stream will re-stall itself. |
| 1173 base::MessageLoop::current()->RunUntilIdle(); | 1148 base::RunLoop().RunUntilIdle(); |
| 1174 EXPECT_EQ(1u, session->num_created_streams()); | 1149 EXPECT_EQ(1u, session->num_created_streams()); |
| 1175 EXPECT_EQ(1u, session->pending_create_stream_queue_size(MEDIUM)); | 1150 EXPECT_EQ(1u, session->pending_create_stream_queue_size(MEDIUM)); |
| 1176 | 1151 |
| 1177 // Cancel the third stream and run the message loop. Verify that the second | 1152 // Cancel the third stream and run the message loop. Verify that the second |
| 1178 // stream creation now completes. | 1153 // stream creation now completes. |
| 1179 stream3->Cancel(); | 1154 stream3->Cancel(); |
| 1180 base::MessageLoop::current()->RunUntilIdle(); | 1155 base::RunLoop().RunUntilIdle(); |
| 1181 | 1156 |
| 1182 EXPECT_EQ(1u, session->num_created_streams()); | 1157 EXPECT_EQ(1u, session->num_created_streams()); |
| 1183 EXPECT_EQ(0u, session->pending_create_stream_queue_size(MEDIUM)); | 1158 EXPECT_EQ(0u, session->pending_create_stream_queue_size(MEDIUM)); |
| 1184 EXPECT_EQ(OK, callback2.WaitForResult()); | 1159 EXPECT_EQ(OK, callback2.WaitForResult()); |
| 1185 } | 1160 } |
| 1186 | 1161 |
| 1187 TEST_P(SpdySessionTest, DeleteExpiredPushStreams) { | 1162 TEST_P(SpdySessionTest, DeleteExpiredPushStreams) { |
| 1188 session_deps_.host_resolver->set_synchronous_mode(true); | 1163 session_deps_.host_resolver->set_synchronous_mode(true); |
| 1189 session_deps_.time_func = TheNearFuture; | 1164 session_deps_.time_func = TheNearFuture; |
| 1190 | 1165 |
| 1191 scoped_ptr<SpdyFrame> req( | 1166 scoped_ptr<SpdyFrame> req( |
| 1192 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); | 1167 spdy_util_.ConstructSpdyGet(nullptr, 0, false, 1, MEDIUM, true)); |
| 1193 scoped_ptr<SpdyFrame> rst( | 1168 scoped_ptr<SpdyFrame> rst( |
| 1194 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM)); | 1169 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM)); |
| 1170 MockWrite writes[] = {CreateMockWrite(*req, 0), CreateMockWrite(*rst, 5)}; |
| 1195 | 1171 |
| 1196 scoped_ptr<SpdyFrame> push_a(spdy_util_.ConstructSpdyPush( | 1172 scoped_ptr<SpdyFrame> push_a(spdy_util_.ConstructSpdyPush( |
| 1197 NULL, 0, 2, 1, "http://www.example.org/a.dat")); | 1173 nullptr, 0, 2, 1, "http://www.example.org/a.dat")); |
| 1198 scoped_ptr<SpdyFrame> push_a_body( | 1174 scoped_ptr<SpdyFrame> push_a_body( |
| 1199 spdy_util_.ConstructSpdyBodyFrame(2, false)); | 1175 spdy_util_.ConstructSpdyBodyFrame(2, false)); |
| 1200 // In ascii "0" < "a". We use it to verify that we properly handle std::map | 1176 // In ascii "0" < "a". We use it to verify that we properly handle std::map |
| 1201 // iterators inside. See http://crbug.com/443490 | 1177 // iterators inside. See http://crbug.com/443490 |
| 1202 scoped_ptr<SpdyFrame> push_b(spdy_util_.ConstructSpdyPush( | 1178 scoped_ptr<SpdyFrame> push_b(spdy_util_.ConstructSpdyPush( |
| 1203 NULL, 0, 4, 1, "http://www.example.org/0.dat")); | 1179 nullptr, 0, 4, 1, "http://www.example.org/0.dat")); |
| 1204 MockWrite writes[] = {CreateMockWrite(*req, 0), CreateMockWrite(*rst, 4)}; | |
| 1205 MockRead reads[] = { | 1180 MockRead reads[] = { |
| 1206 CreateMockRead(*push_a, 1), CreateMockRead(*push_a_body, 2), | 1181 CreateMockRead(*push_a, 1), |
| 1207 CreateMockRead(*push_b, 3), MockRead(ASYNC, 0, 5), // EOF | 1182 CreateMockRead(*push_a_body, 2), |
| 1183 MockRead(ASYNC, ERR_IO_PENDING, 3), |
| 1184 CreateMockRead(*push_b, 4), |
| 1185 MockRead(ASYNC, ERR_IO_PENDING, 6), |
| 1186 MockRead(ASYNC, 0, 7) // EOF |
| 1208 }; | 1187 }; |
| 1209 DeterministicSocketData data( | |
| 1210 reads, arraysize(reads), writes, arraysize(writes)); | |
| 1211 | 1188 |
| 1212 MockConnect connect_data(SYNCHRONOUS, OK); | 1189 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); |
| 1213 data.set_connect_data(connect_data); | 1190 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 1214 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 1215 | 1191 |
| 1216 CreateDeterministicNetworkSession(); | 1192 CreateNetworkSession(); |
| 1217 base::WeakPtr<SpdySession> session = | 1193 base::WeakPtr<SpdySession> session = |
| 1218 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 1194 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 1219 | 1195 |
| 1220 // Process the principal request, and the first push stream request & body. | 1196 // Process the principal request, and the first push stream request & body. |
| 1221 GURL url(kDefaultURL); | 1197 GURL url(kDefaultURL); |
| 1222 base::WeakPtr<SpdyStream> spdy_stream = CreateStreamSynchronously( | 1198 base::WeakPtr<SpdyStream> spdy_stream = CreateStreamSynchronously( |
| 1223 SPDY_REQUEST_RESPONSE_STREAM, session, url, MEDIUM, BoundNetLog()); | 1199 SPDY_REQUEST_RESPONSE_STREAM, session, url, MEDIUM, BoundNetLog()); |
| 1224 test::StreamDelegateDoNothing delegate(spdy_stream); | 1200 test::StreamDelegateDoNothing delegate(spdy_stream); |
| 1225 spdy_stream->SetDelegate(&delegate); | 1201 spdy_stream->SetDelegate(&delegate); |
| 1226 | 1202 |
| 1227 scoped_ptr<SpdyHeaderBlock> headers( | 1203 scoped_ptr<SpdyHeaderBlock> headers( |
| 1228 spdy_util_.ConstructGetHeaderBlock(url.spec())); | 1204 spdy_util_.ConstructGetHeaderBlock(url.spec())); |
| 1229 spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); | 1205 spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); |
| 1230 | 1206 |
| 1231 data.RunFor(3); | 1207 base::RunLoop().RunUntilIdle(); |
| 1232 | 1208 |
| 1233 // Verify that there is one unclaimed push stream. | 1209 // Verify that there is one unclaimed push stream. |
| 1234 EXPECT_EQ(1u, session->num_unclaimed_pushed_streams()); | 1210 EXPECT_EQ(1u, session->num_unclaimed_pushed_streams()); |
| 1235 SpdySession::PushedStreamMap::iterator iter = | 1211 SpdySession::PushedStreamMap::iterator iter = |
| 1236 session->unclaimed_pushed_streams_.find( | 1212 session->unclaimed_pushed_streams_.find( |
| 1237 GURL("http://www.example.org/a.dat")); | 1213 GURL("http://www.example.org/a.dat")); |
| 1238 EXPECT_TRUE(session->unclaimed_pushed_streams_.end() != iter); | 1214 EXPECT_TRUE(session->unclaimed_pushed_streams_.end() != iter); |
| 1239 | 1215 |
| 1240 if (session->flow_control_state_ == | 1216 if (session->flow_control_state_ == |
| 1241 SpdySession::FLOW_CONTROL_STREAM_AND_SESSION) { | 1217 SpdySession::FLOW_CONTROL_STREAM_AND_SESSION) { |
| 1242 // Unclaimed push body consumed bytes from the session window. | 1218 // Unclaimed push body consumed bytes from the session window. |
| 1243 EXPECT_EQ( | 1219 EXPECT_EQ( |
| 1244 SpdySession::GetDefaultInitialWindowSize(GetParam()) - kUploadDataSize, | 1220 SpdySession::GetDefaultInitialWindowSize(GetParam()) - kUploadDataSize, |
| 1245 session->session_recv_window_size_); | 1221 session->session_recv_window_size_); |
| 1246 EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); | 1222 EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); |
| 1247 } | 1223 } |
| 1248 | 1224 |
| 1249 // Shift time to expire the push stream. Read the second SYN_STREAM, | 1225 // Shift time to expire the push stream. Read the second SYN_STREAM, |
| 1250 // and verify a RST_STREAM was written. | 1226 // and verify a RST_STREAM was written. |
| 1251 g_time_delta = base::TimeDelta::FromSeconds(301); | 1227 g_time_delta = base::TimeDelta::FromSeconds(301); |
| 1252 data.RunFor(2); | 1228 data.CompleteRead(); |
| 1229 base::RunLoop().RunUntilIdle(); |
| 1253 | 1230 |
| 1254 // Verify that the second pushed stream evicted the first pushed stream. | 1231 // Verify that the second pushed stream evicted the first pushed stream. |
| 1255 EXPECT_EQ(1u, session->num_unclaimed_pushed_streams()); | 1232 EXPECT_EQ(1u, session->num_unclaimed_pushed_streams()); |
| 1256 iter = session->unclaimed_pushed_streams_.find( | 1233 iter = session->unclaimed_pushed_streams_.find( |
| 1257 GURL("http://www.example.org/0.dat")); | 1234 GURL("http://www.example.org/0.dat")); |
| 1258 EXPECT_TRUE(session->unclaimed_pushed_streams_.end() != iter); | 1235 EXPECT_TRUE(session->unclaimed_pushed_streams_.end() != iter); |
| 1259 | 1236 |
| 1260 if (session->flow_control_state_ == | 1237 if (session->flow_control_state_ == |
| 1261 SpdySession::FLOW_CONTROL_STREAM_AND_SESSION) { | 1238 SpdySession::FLOW_CONTROL_STREAM_AND_SESSION) { |
| 1262 // Verify that the session window reclaimed the evicted stream body. | 1239 // Verify that the session window reclaimed the evicted stream body. |
| 1263 EXPECT_EQ(SpdySession::GetDefaultInitialWindowSize(GetParam()), | 1240 EXPECT_EQ(SpdySession::GetDefaultInitialWindowSize(GetParam()), |
| 1264 session->session_recv_window_size_); | 1241 session->session_recv_window_size_); |
| 1265 EXPECT_EQ(kUploadDataSize, session->session_unacked_recv_window_bytes_); | 1242 EXPECT_EQ(kUploadDataSize, session->session_unacked_recv_window_bytes_); |
| 1266 } | 1243 } |
| 1267 | 1244 |
| 1268 // Read and process EOF. | 1245 // Read and process EOF. |
| 1269 data.RunFor(1); | 1246 EXPECT_TRUE(session); |
| 1270 base::MessageLoop::current()->RunUntilIdle(); | 1247 data.CompleteRead(); |
| 1271 EXPECT_TRUE(session == NULL); | 1248 base::RunLoop().RunUntilIdle(); |
| 1249 EXPECT_FALSE(session); |
| 1272 } | 1250 } |
| 1273 | 1251 |
| 1274 TEST_P(SpdySessionTest, FailedPing) { | 1252 TEST_P(SpdySessionTest, FailedPing) { |
| 1275 session_deps_.host_resolver->set_synchronous_mode(true); | 1253 session_deps_.host_resolver->set_synchronous_mode(true); |
| 1276 | 1254 |
| 1277 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 1278 MockRead reads[] = { | 1255 MockRead reads[] = { |
| 1279 MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. | 1256 MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. |
| 1280 }; | 1257 }; |
| 1281 scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(1, false)); | 1258 scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(1, false)); |
| 1282 scoped_ptr<SpdyFrame> goaway( | 1259 scoped_ptr<SpdyFrame> goaway( |
| 1283 spdy_util_.ConstructSpdyGoAway(0, GOAWAY_PROTOCOL_ERROR, "Failed ping.")); | 1260 spdy_util_.ConstructSpdyGoAway(0, GOAWAY_PROTOCOL_ERROR, "Failed ping.")); |
| 1284 MockWrite writes[] = {CreateMockWrite(*write_ping), CreateMockWrite(*goaway)}; | 1261 MockWrite writes[] = {CreateMockWrite(*write_ping), CreateMockWrite(*goaway)}; |
| 1262 |
| 1285 StaticSocketDataProvider data( | 1263 StaticSocketDataProvider data( |
| 1286 reads, arraysize(reads), writes, arraysize(writes)); | 1264 reads, arraysize(reads), writes, arraysize(writes)); |
| 1287 data.set_connect_data(connect_data); | |
| 1288 session_deps_.socket_factory->AddSocketDataProvider(&data); | 1265 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 1289 | 1266 |
| 1290 CreateNetworkSession(); | 1267 CreateNetworkSession(); |
| 1291 | 1268 |
| 1292 base::WeakPtr<SpdySession> session = | 1269 base::WeakPtr<SpdySession> session = |
| 1293 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 1270 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 1294 | 1271 |
| 1295 base::WeakPtr<SpdyStream> spdy_stream1 = | 1272 base::WeakPtr<SpdyStream> spdy_stream1 = |
| 1296 CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, | 1273 CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, |
| 1297 session, test_url_, MEDIUM, BoundNetLog()); | 1274 session, test_url_, MEDIUM, BoundNetLog()); |
| 1298 ASSERT_TRUE(spdy_stream1.get() != NULL); | 1275 ASSERT_TRUE(spdy_stream1.get() != nullptr); |
| 1299 test::StreamDelegateSendImmediate delegate(spdy_stream1, NULL); | 1276 test::StreamDelegateSendImmediate delegate(spdy_stream1, nullptr); |
| 1300 spdy_stream1->SetDelegate(&delegate); | 1277 spdy_stream1->SetDelegate(&delegate); |
| 1301 | 1278 |
| 1302 session->set_connection_at_risk_of_loss_time(base::TimeDelta::FromSeconds(0)); | 1279 session->set_connection_at_risk_of_loss_time(base::TimeDelta::FromSeconds(0)); |
| 1303 session->set_hung_interval(base::TimeDelta::FromSeconds(0)); | 1280 session->set_hung_interval(base::TimeDelta::FromSeconds(0)); |
| 1304 | 1281 |
| 1305 // Send a PING frame. | 1282 // Send a PING frame. |
| 1306 session->WritePingFrame(1, false); | 1283 session->WritePingFrame(1, false); |
| 1307 EXPECT_LT(0, session->pings_in_flight()); | 1284 EXPECT_LT(0, session->pings_in_flight()); |
| 1308 EXPECT_GE(session->next_ping_id(), 1U); | 1285 EXPECT_GE(session->next_ping_id(), 1U); |
| 1309 EXPECT_TRUE(session->check_ping_status_pending()); | 1286 EXPECT_TRUE(session->check_ping_status_pending()); |
| 1310 | 1287 |
| 1311 // Assert session is not closed. | 1288 // Assert session is not closed. |
| 1312 EXPECT_TRUE(session->IsAvailable()); | 1289 EXPECT_TRUE(session->IsAvailable()); |
| 1313 EXPECT_LT(0u, session->num_active_streams() + session->num_created_streams()); | 1290 EXPECT_LT(0u, session->num_active_streams() + session->num_created_streams()); |
| 1314 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); | 1291 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); |
| 1315 | 1292 |
| 1316 // We set last time we have received any data in 1 sec less than now. | 1293 // We set last time we have received any data in 1 sec less than now. |
| 1317 // CheckPingStatus will trigger timeout because hung interval is zero. | 1294 // CheckPingStatus will trigger timeout because hung interval is zero. |
| 1318 base::TimeTicks now = base::TimeTicks::Now(); | 1295 base::TimeTicks now = base::TimeTicks::Now(); |
| 1319 session->last_activity_time_ = now - base::TimeDelta::FromSeconds(1); | 1296 session->last_activity_time_ = now - base::TimeDelta::FromSeconds(1); |
| 1320 session->CheckPingStatus(now); | 1297 session->CheckPingStatus(now); |
| 1321 base::MessageLoop::current()->RunUntilIdle(); | 1298 base::RunLoop().RunUntilIdle(); |
| 1322 | 1299 |
| 1323 EXPECT_TRUE(session == NULL); | 1300 EXPECT_FALSE(session); |
| 1324 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); | 1301 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); |
| 1325 EXPECT_EQ(NULL, spdy_stream1.get()); | 1302 EXPECT_FALSE(spdy_stream1); |
| 1326 } | 1303 } |
| 1327 | 1304 |
| 1328 // Request kInitialMaxConcurrentStreams + 1 streams. Receive a | 1305 // Request kInitialMaxConcurrentStreams + 1 streams. Receive a |
| 1329 // settings frame increasing the max concurrent streams by 1. Make | 1306 // settings frame increasing the max concurrent streams by 1. Make |
| 1330 // sure nothing blows up. This is a regression test for | 1307 // sure nothing blows up. This is a regression test for |
| 1331 // http://crbug.com/57331 . | 1308 // http://crbug.com/57331 . |
| 1332 TEST_P(SpdySessionTest, OnSettings) { | 1309 TEST_P(SpdySessionTest, OnSettings) { |
| 1333 session_deps_.host_resolver->set_synchronous_mode(true); | 1310 session_deps_.host_resolver->set_synchronous_mode(true); |
| 1334 | 1311 |
| 1335 const SpdySettingsIds kSpdySettingsIds = SETTINGS_MAX_CONCURRENT_STREAMS; | 1312 const SpdySettingsIds kSpdySettingsIds = SETTINGS_MAX_CONCURRENT_STREAMS; |
| 1336 | 1313 |
| 1314 int seq = 0; |
| 1315 std::vector<MockWrite> writes; |
| 1316 scoped_ptr<SpdyFrame> settings_ack(spdy_util_.ConstructSpdySettingsAck()); |
| 1317 if (GetParam() >= kProtoSPDY4MinimumVersion) { |
| 1318 writes.push_back(CreateMockWrite(*settings_ack, ++seq)); |
| 1319 } |
| 1320 |
| 1337 SettingsMap new_settings; | 1321 SettingsMap new_settings; |
| 1338 const uint32 max_concurrent_streams = kInitialMaxConcurrentStreams + 1; | 1322 const uint32 max_concurrent_streams = kInitialMaxConcurrentStreams + 1; |
| 1339 new_settings[kSpdySettingsIds] = | 1323 new_settings[kSpdySettingsIds] = |
| 1340 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams); | 1324 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams); |
| 1341 scoped_ptr<SpdyFrame> settings_frame( | 1325 scoped_ptr<SpdyFrame> settings_frame( |
| 1342 spdy_util_.ConstructSpdySettings(new_settings)); | 1326 spdy_util_.ConstructSpdySettings(new_settings)); |
| 1343 MockRead reads[] = { | 1327 MockRead reads[] = { |
| 1344 CreateMockRead(*settings_frame, 0), | 1328 CreateMockRead(*settings_frame, 0), |
| 1345 MockRead(ASYNC, 0, 1), | 1329 MockRead(ASYNC, ERR_IO_PENDING, ++seq), |
| 1330 MockRead(ASYNC, 0, ++seq), |
| 1346 }; | 1331 }; |
| 1347 | 1332 |
| 1348 scoped_ptr<SpdyFrame> settings_ack(spdy_util_.ConstructSpdySettingsAck()); | 1333 SequencedSocketData data(reads, arraysize(reads), vector_as_array(&writes), |
| 1349 MockWrite writes[] = { | 1334 writes.size()); |
| 1350 CreateMockWrite(*settings_ack, 2), | 1335 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 1351 }; | |
| 1352 | 1336 |
| 1353 DeterministicSocketData data(reads, arraysize(reads), | 1337 CreateNetworkSession(); |
| 1354 writes, arraysize(writes)); | |
| 1355 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 1356 data.set_connect_data(connect_data); | |
| 1357 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 1358 | |
| 1359 CreateDeterministicNetworkSession(); | |
| 1360 | 1338 |
| 1361 base::WeakPtr<SpdySession> session = | 1339 base::WeakPtr<SpdySession> session = |
| 1362 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 1340 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 1363 | 1341 |
| 1364 // Create the maximum number of concurrent streams. | 1342 // Create the maximum number of concurrent streams. |
| 1365 for (size_t i = 0; i < kInitialMaxConcurrentStreams; ++i) { | 1343 for (size_t i = 0; i < kInitialMaxConcurrentStreams; ++i) { |
| 1366 base::WeakPtr<SpdyStream> spdy_stream = | 1344 base::WeakPtr<SpdyStream> spdy_stream = |
| 1367 CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, | 1345 CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, |
| 1368 session, test_url_, MEDIUM, BoundNetLog()); | 1346 session, test_url_, MEDIUM, BoundNetLog()); |
| 1369 ASSERT_TRUE(spdy_stream != NULL); | 1347 ASSERT_TRUE(spdy_stream != nullptr); |
| 1370 } | 1348 } |
| 1371 | 1349 |
| 1372 StreamReleaserCallback stream_releaser; | 1350 StreamReleaserCallback stream_releaser; |
| 1373 SpdyStreamRequest request; | 1351 SpdyStreamRequest request; |
| 1374 ASSERT_EQ(ERR_IO_PENDING, | 1352 ASSERT_EQ(ERR_IO_PENDING, |
| 1375 request.StartRequest( | 1353 request.StartRequest( |
| 1376 SPDY_BIDIRECTIONAL_STREAM, session, test_url_, MEDIUM, | 1354 SPDY_BIDIRECTIONAL_STREAM, session, test_url_, MEDIUM, |
| 1377 BoundNetLog(), | 1355 BoundNetLog(), |
| 1378 stream_releaser.MakeCallback(&request))); | 1356 stream_releaser.MakeCallback(&request))); |
| 1379 | 1357 |
| 1380 data.RunFor(1); | 1358 base::RunLoop().RunUntilIdle(); |
| 1381 | 1359 |
| 1382 EXPECT_EQ(OK, stream_releaser.WaitForResult()); | 1360 EXPECT_EQ(OK, stream_releaser.WaitForResult()); |
| 1383 | 1361 |
| 1384 data.RunFor(1); | 1362 data.CompleteRead(); |
| 1385 if (spdy_util_.spdy_version() >= SPDY4) { | 1363 base::RunLoop().RunUntilIdle(); |
| 1386 // Allow the SETTINGS+ACK to write, so the session finishes draining. | 1364 EXPECT_FALSE(session); |
| 1387 data.RunFor(1); | 1365 |
| 1388 } | 1366 EXPECT_TRUE(data.AllWriteDataConsumed()); |
| 1389 base::MessageLoop::current()->RunUntilIdle(); | 1367 EXPECT_TRUE(data.AllReadDataConsumed()); |
| 1390 EXPECT_TRUE(session == NULL); | |
| 1391 } | 1368 } |
| 1392 | 1369 |
| 1393 // Start with a persisted value for max concurrent streams. Receive a | 1370 // Start with a persisted value for max concurrent streams. Receive a |
| 1394 // settings frame increasing the max concurrent streams by 1 and which | 1371 // settings frame increasing the max concurrent streams by 1 and which |
| 1395 // also clears the persisted data. Verify that persisted data is | 1372 // also clears the persisted data. Verify that persisted data is |
| 1396 // correct. | 1373 // correct. |
| 1397 TEST_P(SpdySessionTest, ClearSettings) { | 1374 TEST_P(SpdySessionTest, ClearSettings) { |
| 1398 if (spdy_util_.spdy_version() >= SPDY4) { | 1375 if (spdy_util_.spdy_version() >= SPDY4) { |
| 1399 // SPDY4 doesn't include settings persistence, or a CLEAR_SETTINGS flag. | 1376 // SPDY4 doesn't include settings persistence, or a CLEAR_SETTINGS flag. |
| 1400 // Flag 0x1, CLEAR_SETTINGS in SPDY3, is instead settings ACK in SPDY4. | 1377 // Flag 0x1, CLEAR_SETTINGS in SPDY3, is instead settings ACK in SPDY4. |
| 1401 return; | 1378 return; |
| 1402 } | 1379 } |
| 1403 session_deps_.host_resolver->set_synchronous_mode(true); | 1380 session_deps_.host_resolver->set_synchronous_mode(true); |
| 1404 | 1381 |
| 1405 SettingsMap new_settings; | 1382 SettingsMap new_settings; |
| 1406 const uint32 max_concurrent_streams = kInitialMaxConcurrentStreams + 1; | 1383 const uint32 max_concurrent_streams = kInitialMaxConcurrentStreams + 1; |
| 1407 new_settings[SETTINGS_MAX_CONCURRENT_STREAMS] = | 1384 new_settings[SETTINGS_MAX_CONCURRENT_STREAMS] = |
| 1408 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams); | 1385 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams); |
| 1409 scoped_ptr<SpdyFrame> settings_frame( | 1386 scoped_ptr<SpdyFrame> settings_frame( |
| 1410 spdy_util_.ConstructSpdySettings(new_settings)); | 1387 spdy_util_.ConstructSpdySettings(new_settings)); |
| 1411 uint8 flags = SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS; | 1388 uint8 flags = SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS; |
| 1412 test::SetFrameFlags(settings_frame.get(), flags, spdy_util_.spdy_version()); | 1389 test::SetFrameFlags(settings_frame.get(), flags, spdy_util_.spdy_version()); |
| 1413 MockRead reads[] = { | 1390 MockRead reads[] = { |
| 1414 CreateMockRead(*settings_frame, 0), | 1391 CreateMockRead(*settings_frame, 0), |
| 1415 MockRead(ASYNC, 0, 1), | 1392 MockRead(ASYNC, ERR_IO_PENDING, 1), |
| 1393 MockRead(ASYNC, 0, 2), |
| 1416 }; | 1394 }; |
| 1417 | 1395 |
| 1418 DeterministicSocketData data(reads, arraysize(reads), NULL, 0); | 1396 SequencedSocketData data(reads, arraysize(reads), nullptr, 0); |
| 1419 MockConnect connect_data(SYNCHRONOUS, OK); | 1397 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 1420 data.set_connect_data(connect_data); | |
| 1421 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 1422 | 1398 |
| 1423 CreateDeterministicNetworkSession(); | 1399 CreateNetworkSession(); |
| 1424 | 1400 |
| 1425 // Initialize the SpdySetting with the default. | 1401 // Initialize the SpdySetting with the default. |
| 1426 spdy_session_pool_->http_server_properties()->SetSpdySetting( | 1402 spdy_session_pool_->http_server_properties()->SetSpdySetting( |
| 1427 test_host_port_pair_, | 1403 test_host_port_pair_, |
| 1428 SETTINGS_MAX_CONCURRENT_STREAMS, | 1404 SETTINGS_MAX_CONCURRENT_STREAMS, |
| 1429 SETTINGS_FLAG_PLEASE_PERSIST, | 1405 SETTINGS_FLAG_PLEASE_PERSIST, |
| 1430 kInitialMaxConcurrentStreams); | 1406 kInitialMaxConcurrentStreams); |
| 1431 | 1407 |
| 1432 EXPECT_FALSE( | 1408 EXPECT_FALSE( |
| 1433 spdy_session_pool_->http_server_properties()->GetSpdySettings( | 1409 spdy_session_pool_->http_server_properties()->GetSpdySettings( |
| 1434 test_host_port_pair_).empty()); | 1410 test_host_port_pair_).empty()); |
| 1435 | 1411 |
| 1436 base::WeakPtr<SpdySession> session = | 1412 base::WeakPtr<SpdySession> session = |
| 1437 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 1413 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 1438 | 1414 |
| 1439 // Create the maximum number of concurrent streams. | 1415 // Create the maximum number of concurrent streams. |
| 1440 for (size_t i = 0; i < kInitialMaxConcurrentStreams; ++i) { | 1416 for (size_t i = 0; i < kInitialMaxConcurrentStreams; ++i) { |
| 1441 base::WeakPtr<SpdyStream> spdy_stream = | 1417 base::WeakPtr<SpdyStream> spdy_stream = |
| 1442 CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, | 1418 CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, |
| 1443 session, test_url_, MEDIUM, BoundNetLog()); | 1419 session, test_url_, MEDIUM, BoundNetLog()); |
| 1444 ASSERT_TRUE(spdy_stream != NULL); | 1420 ASSERT_TRUE(spdy_stream != nullptr); |
| 1445 } | 1421 } |
| 1446 | 1422 |
| 1447 StreamReleaserCallback stream_releaser; | 1423 StreamReleaserCallback stream_releaser; |
| 1448 | 1424 |
| 1449 SpdyStreamRequest request; | 1425 SpdyStreamRequest request; |
| 1450 ASSERT_EQ(ERR_IO_PENDING, | 1426 ASSERT_EQ(ERR_IO_PENDING, |
| 1451 request.StartRequest( | 1427 request.StartRequest( |
| 1452 SPDY_BIDIRECTIONAL_STREAM, session, test_url_, MEDIUM, | 1428 SPDY_BIDIRECTIONAL_STREAM, session, test_url_, MEDIUM, |
| 1453 BoundNetLog(), | 1429 BoundNetLog(), |
| 1454 stream_releaser.MakeCallback(&request))); | 1430 stream_releaser.MakeCallback(&request))); |
| 1455 | 1431 |
| 1456 data.RunFor(1); | 1432 base::RunLoop().RunUntilIdle(); |
| 1457 | 1433 |
| 1458 EXPECT_EQ(OK, stream_releaser.WaitForResult()); | 1434 EXPECT_EQ(OK, stream_releaser.WaitForResult()); |
| 1459 | 1435 |
| 1460 // Make sure that persisted data is cleared. | 1436 // Make sure that persisted data is cleared. |
| 1461 EXPECT_TRUE( | 1437 EXPECT_TRUE( |
| 1462 spdy_session_pool_->http_server_properties()->GetSpdySettings( | 1438 spdy_session_pool_->http_server_properties()->GetSpdySettings( |
| 1463 test_host_port_pair_).empty()); | 1439 test_host_port_pair_).empty()); |
| 1464 | 1440 |
| 1465 // Make sure session's max_concurrent_streams is correct. | 1441 // Make sure session's max_concurrent_streams is correct. |
| 1466 EXPECT_EQ(kInitialMaxConcurrentStreams + 1, | 1442 EXPECT_EQ(kInitialMaxConcurrentStreams + 1, |
| 1467 session->max_concurrent_streams()); | 1443 session->max_concurrent_streams()); |
| 1468 | 1444 |
| 1469 data.RunFor(1); | 1445 data.CompleteRead(); |
| 1470 EXPECT_TRUE(session == NULL); | 1446 base::RunLoop().RunUntilIdle(); |
| 1447 EXPECT_FALSE(session); |
| 1471 } | 1448 } |
| 1472 | 1449 |
| 1473 // Start with max concurrent streams set to 1. Request two streams. | 1450 // Start with max concurrent streams set to 1. Request two streams. |
| 1474 // When the first completes, have the callback close its stream, which | 1451 // When the first completes, have the callback close its stream, which |
| 1475 // should trigger the second stream creation. Then cancel that one | 1452 // should trigger the second stream creation. Then cancel that one |
| 1476 // immediately. Don't crash. This is a regression test for | 1453 // immediately. Don't crash. This is a regression test for |
| 1477 // http://crbug.com/63532 . | 1454 // http://crbug.com/63532 . |
| 1478 TEST_P(SpdySessionTest, CancelPendingCreateStream) { | 1455 TEST_P(SpdySessionTest, CancelPendingCreateStream) { |
| 1479 session_deps_.host_resolver->set_synchronous_mode(true); | 1456 session_deps_.host_resolver->set_synchronous_mode(true); |
| 1480 | 1457 |
| 1481 MockRead reads[] = { | 1458 MockRead reads[] = { |
| 1482 MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. | 1459 MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. |
| 1483 }; | 1460 }; |
| 1484 | 1461 |
| 1485 StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0); | 1462 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0); |
| 1486 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 1487 | |
| 1488 data.set_connect_data(connect_data); | |
| 1489 session_deps_.socket_factory->AddSocketDataProvider(&data); | 1463 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 1490 | 1464 |
| 1491 CreateNetworkSession(); | 1465 CreateNetworkSession(); |
| 1492 | 1466 |
| 1493 // Initialize the SpdySetting with 1 max concurrent streams. | 1467 // Initialize the SpdySetting with 1 max concurrent streams. |
| 1494 spdy_session_pool_->http_server_properties()->SetSpdySetting( | 1468 spdy_session_pool_->http_server_properties()->SetSpdySetting( |
| 1495 test_host_port_pair_, | 1469 test_host_port_pair_, |
| 1496 SETTINGS_MAX_CONCURRENT_STREAMS, | 1470 SETTINGS_MAX_CONCURRENT_STREAMS, |
| 1497 SETTINGS_FLAG_PLEASE_PERSIST, | 1471 SETTINGS_FLAG_PLEASE_PERSIST, |
| 1498 1); | 1472 1); |
| 1499 | 1473 |
| 1500 base::WeakPtr<SpdySession> session = | 1474 base::WeakPtr<SpdySession> session = |
| 1501 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 1475 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 1502 | 1476 |
| 1503 // Leave room for only one more stream to be created. | 1477 // Leave room for only one more stream to be created. |
| 1504 for (size_t i = 0; i < kInitialMaxConcurrentStreams - 1; ++i) { | 1478 for (size_t i = 0; i < kInitialMaxConcurrentStreams - 1; ++i) { |
| 1505 base::WeakPtr<SpdyStream> spdy_stream = | 1479 base::WeakPtr<SpdyStream> spdy_stream = |
| 1506 CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, | 1480 CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, |
| 1507 session, test_url_, MEDIUM, BoundNetLog()); | 1481 session, test_url_, MEDIUM, BoundNetLog()); |
| 1508 ASSERT_TRUE(spdy_stream != NULL); | 1482 ASSERT_TRUE(spdy_stream != nullptr); |
| 1509 } | 1483 } |
| 1510 | 1484 |
| 1511 // Create 2 more streams. First will succeed. Second will be pending. | 1485 // Create 2 more streams. First will succeed. Second will be pending. |
| 1512 base::WeakPtr<SpdyStream> spdy_stream1 = | 1486 base::WeakPtr<SpdyStream> spdy_stream1 = |
| 1513 CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, | 1487 CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, |
| 1514 session, test_url_, MEDIUM, BoundNetLog()); | 1488 session, test_url_, MEDIUM, BoundNetLog()); |
| 1515 ASSERT_TRUE(spdy_stream1.get() != NULL); | 1489 ASSERT_TRUE(spdy_stream1.get() != nullptr); |
| 1516 | 1490 |
| 1517 // Use scoped_ptr to let us invalidate the memory when we want to, to trigger | 1491 // Use scoped_ptr to let us invalidate the memory when we want to, to trigger |
| 1518 // a valgrind error if the callback is invoked when it's not supposed to be. | 1492 // a valgrind error if the callback is invoked when it's not supposed to be. |
| 1519 scoped_ptr<TestCompletionCallback> callback(new TestCompletionCallback); | 1493 scoped_ptr<TestCompletionCallback> callback(new TestCompletionCallback); |
| 1520 | 1494 |
| 1521 SpdyStreamRequest request; | 1495 SpdyStreamRequest request; |
| 1522 ASSERT_EQ(ERR_IO_PENDING, | 1496 ASSERT_EQ(ERR_IO_PENDING, |
| 1523 request.StartRequest( | 1497 request.StartRequest( |
| 1524 SPDY_BIDIRECTIONAL_STREAM, session, test_url_, MEDIUM, | 1498 SPDY_BIDIRECTIONAL_STREAM, session, test_url_, MEDIUM, |
| 1525 BoundNetLog(), | 1499 BoundNetLog(), |
| 1526 callback->callback())); | 1500 callback->callback())); |
| 1527 | 1501 |
| 1528 // Release the first one, this will allow the second to be created. | 1502 // Release the first one, this will allow the second to be created. |
| 1529 spdy_stream1->Cancel(); | 1503 spdy_stream1->Cancel(); |
| 1530 EXPECT_EQ(NULL, spdy_stream1.get()); | 1504 EXPECT_FALSE(spdy_stream1); |
| 1531 | 1505 |
| 1532 request.CancelRequest(); | 1506 request.CancelRequest(); |
| 1533 callback.reset(); | 1507 callback.reset(); |
| 1534 | 1508 |
| 1535 // Should not crash when running the pending callback. | 1509 // Should not crash when running the pending callback. |
| 1536 base::MessageLoop::current()->RunUntilIdle(); | 1510 base::RunLoop().RunUntilIdle(); |
| 1537 } | 1511 } |
| 1538 | 1512 |
| 1539 TEST_P(SpdySessionTest, SendInitialDataOnNewSession) { | 1513 TEST_P(SpdySessionTest, SendInitialDataOnNewSession) { |
| 1540 session_deps_.host_resolver->set_synchronous_mode(true); | 1514 session_deps_.host_resolver->set_synchronous_mode(true); |
| 1541 | 1515 |
| 1542 MockRead reads[] = { | 1516 MockRead reads[] = { |
| 1543 MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. | 1517 MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. |
| 1544 }; | 1518 }; |
| 1545 | 1519 |
| 1546 SettingsMap settings; | 1520 SettingsMap settings; |
| 1547 settings[SETTINGS_MAX_CONCURRENT_STREAMS] = | 1521 settings[SETTINGS_MAX_CONCURRENT_STREAMS] = |
| 1548 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kMaxConcurrentPushedStreams); | 1522 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kMaxConcurrentPushedStreams); |
| 1549 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 1550 scoped_ptr<SpdyFrame> settings_frame( | 1523 scoped_ptr<SpdyFrame> settings_frame( |
| 1551 spdy_util_.ConstructSpdySettings(settings)); | 1524 spdy_util_.ConstructSpdySettings(settings)); |
| 1552 std::vector<MockWrite> writes; | 1525 std::vector<MockWrite> writes; |
| 1553 if ((GetParam() >= kProtoSPDY4MinimumVersion) && | 1526 if ((GetParam() >= kProtoSPDY4MinimumVersion) && |
| 1554 (GetParam() <= kProtoSPDY4MaximumVersion)) { | 1527 (GetParam() <= kProtoSPDY4MaximumVersion)) { |
| 1555 writes.push_back( | 1528 writes.push_back( |
| 1556 MockWrite(ASYNC, | 1529 MockWrite(ASYNC, |
| 1557 kHttp2ConnectionHeaderPrefix, | 1530 kHttp2ConnectionHeaderPrefix, |
| 1558 kHttp2ConnectionHeaderPrefixSize)); | 1531 kHttp2ConnectionHeaderPrefixSize)); |
| 1559 } | 1532 } |
| 1560 writes.push_back(CreateMockWrite(*settings_frame)); | 1533 writes.push_back(CreateMockWrite(*settings_frame)); |
| 1561 | 1534 |
| 1562 SettingsMap server_settings; | 1535 SettingsMap server_settings; |
| 1563 const uint32 initial_max_concurrent_streams = 1; | 1536 const uint32 initial_max_concurrent_streams = 1; |
| 1564 server_settings[SETTINGS_MAX_CONCURRENT_STREAMS] = | 1537 server_settings[SETTINGS_MAX_CONCURRENT_STREAMS] = |
| 1565 SettingsFlagsAndValue(SETTINGS_FLAG_PERSISTED, | 1538 SettingsFlagsAndValue(SETTINGS_FLAG_PERSISTED, |
| 1566 initial_max_concurrent_streams); | 1539 initial_max_concurrent_streams); |
| 1567 scoped_ptr<SpdyFrame> server_settings_frame( | 1540 scoped_ptr<SpdyFrame> server_settings_frame( |
| 1568 spdy_util_.ConstructSpdySettings(server_settings)); | 1541 spdy_util_.ConstructSpdySettings(server_settings)); |
| 1569 if (GetParam() <= kProtoSPDY31) { | 1542 if (GetParam() <= kProtoSPDY31) { |
| 1570 writes.push_back(CreateMockWrite(*server_settings_frame)); | 1543 writes.push_back(CreateMockWrite(*server_settings_frame)); |
| 1571 } | 1544 } |
| 1572 | 1545 |
| 1573 StaticSocketDataProvider data(reads, arraysize(reads), | 1546 StaticSocketDataProvider data(reads, arraysize(reads), |
| 1574 vector_as_array(&writes), writes.size()); | 1547 vector_as_array(&writes), writes.size()); |
| 1575 data.set_connect_data(connect_data); | |
| 1576 session_deps_.socket_factory->AddSocketDataProvider(&data); | 1548 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 1577 | 1549 |
| 1578 CreateNetworkSession(); | 1550 CreateNetworkSession(); |
| 1579 | 1551 |
| 1580 spdy_session_pool_->http_server_properties()->SetSpdySetting( | 1552 spdy_session_pool_->http_server_properties()->SetSpdySetting( |
| 1581 test_host_port_pair_, | 1553 test_host_port_pair_, |
| 1582 SETTINGS_MAX_CONCURRENT_STREAMS, | 1554 SETTINGS_MAX_CONCURRENT_STREAMS, |
| 1583 SETTINGS_FLAG_PLEASE_PERSIST, | 1555 SETTINGS_FLAG_PLEASE_PERSIST, |
| 1584 initial_max_concurrent_streams); | 1556 initial_max_concurrent_streams); |
| 1585 | 1557 |
| 1586 SpdySessionPoolPeer pool_peer(spdy_session_pool_); | 1558 SpdySessionPoolPeer pool_peer(spdy_session_pool_); |
| 1587 pool_peer.SetEnableSendingInitialData(true); | 1559 pool_peer.SetEnableSendingInitialData(true); |
| 1588 | 1560 |
| 1589 base::WeakPtr<SpdySession> session = | 1561 base::WeakPtr<SpdySession> session = |
| 1590 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 1562 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 1591 | 1563 |
| 1592 base::MessageLoop::current()->RunUntilIdle(); | 1564 base::RunLoop().RunUntilIdle(); |
| 1593 EXPECT_TRUE(data.AllWriteDataConsumed()); | 1565 EXPECT_TRUE(data.AllWriteDataConsumed()); |
| 1594 } | 1566 } |
| 1595 | 1567 |
| 1596 TEST_P(SpdySessionTest, ClearSettingsStorageOnIPAddressChanged) { | 1568 TEST_P(SpdySessionTest, ClearSettingsStorageOnIPAddressChanged) { |
| 1597 CreateNetworkSession(); | 1569 CreateNetworkSession(); |
| 1598 | 1570 |
| 1599 base::WeakPtr<HttpServerProperties> test_http_server_properties = | 1571 base::WeakPtr<HttpServerProperties> test_http_server_properties = |
| 1600 spdy_session_pool_->http_server_properties(); | 1572 spdy_session_pool_->http_server_properties(); |
| 1601 SettingsFlagsAndValue flags_and_value1(SETTINGS_FLAG_PLEASE_PERSIST, 2); | 1573 SettingsFlagsAndValue flags_and_value1(SETTINGS_FLAG_PLEASE_PERSIST, 2); |
| 1602 test_http_server_properties->SetSpdySetting( | 1574 test_http_server_properties->SetSpdySetting( |
| 1603 test_host_port_pair_, | 1575 test_host_port_pair_, |
| 1604 SETTINGS_MAX_CONCURRENT_STREAMS, | 1576 SETTINGS_MAX_CONCURRENT_STREAMS, |
| 1605 SETTINGS_FLAG_PLEASE_PERSIST, | 1577 SETTINGS_FLAG_PLEASE_PERSIST, |
| 1606 2); | 1578 2); |
| 1607 EXPECT_NE(0u, test_http_server_properties->GetSpdySettings( | 1579 EXPECT_NE(0u, test_http_server_properties->GetSpdySettings( |
| 1608 test_host_port_pair_).size()); | 1580 test_host_port_pair_).size()); |
| 1609 spdy_session_pool_->OnIPAddressChanged(); | 1581 spdy_session_pool_->OnIPAddressChanged(); |
| 1610 EXPECT_EQ(0u, test_http_server_properties->GetSpdySettings( | 1582 EXPECT_EQ(0u, test_http_server_properties->GetSpdySettings( |
| 1611 test_host_port_pair_).size()); | 1583 test_host_port_pair_).size()); |
| 1612 } | 1584 } |
| 1613 | 1585 |
| 1614 TEST_P(SpdySessionTest, Initialize) { | 1586 TEST_P(SpdySessionTest, Initialize) { |
| 1615 BoundTestNetLog log; | 1587 BoundTestNetLog log; |
| 1616 session_deps_.net_log = log.bound().net_log(); | 1588 session_deps_.net_log = log.bound().net_log(); |
| 1617 session_deps_.host_resolver->set_synchronous_mode(true); | 1589 session_deps_.host_resolver->set_synchronous_mode(true); |
| 1618 | 1590 |
| 1619 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 1620 MockRead reads[] = { | 1591 MockRead reads[] = { |
| 1621 MockRead(ASYNC, 0, 0) // EOF | 1592 MockRead(ASYNC, 0, 0) // EOF |
| 1622 }; | 1593 }; |
| 1623 | 1594 |
| 1624 StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0); | 1595 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0); |
| 1625 data.set_connect_data(connect_data); | |
| 1626 session_deps_.socket_factory->AddSocketDataProvider(&data); | 1596 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 1627 | 1597 |
| 1628 CreateNetworkSession(); | 1598 CreateNetworkSession(); |
| 1629 | 1599 |
| 1630 base::WeakPtr<SpdySession> session = | 1600 base::WeakPtr<SpdySession> session = |
| 1631 CreateInsecureSpdySession(http_session_, key_, log.bound()); | 1601 CreateInsecureSpdySession(http_session_, key_, log.bound()); |
| 1632 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); | 1602 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); |
| 1633 | 1603 |
| 1634 // Flush the read completion task. | 1604 // Flush the read completion task. |
| 1635 base::MessageLoop::current()->RunUntilIdle(); | 1605 base::RunLoop().RunUntilIdle(); |
| 1636 | 1606 |
| 1637 TestNetLogEntry::List entries; | 1607 TestNetLogEntry::List entries; |
| 1638 log.GetEntries(&entries); | 1608 log.GetEntries(&entries); |
| 1639 EXPECT_LT(0u, entries.size()); | 1609 EXPECT_LT(0u, entries.size()); |
| 1640 | 1610 |
| 1641 // Check that we logged TYPE_HTTP2_SESSION_INITIALIZED correctly. | 1611 // Check that we logged TYPE_HTTP2_SESSION_INITIALIZED correctly. |
| 1642 int pos = ExpectLogContainsSomewhere( | 1612 int pos = ExpectLogContainsSomewhere( |
| 1643 entries, 0, NetLog::TYPE_HTTP2_SESSION_INITIALIZED, NetLog::PHASE_NONE); | 1613 entries, 0, NetLog::TYPE_HTTP2_SESSION_INITIALIZED, NetLog::PHASE_NONE); |
| 1644 EXPECT_LT(0, pos); | 1614 EXPECT_LT(0, pos); |
| 1645 | 1615 |
| 1646 TestNetLogEntry entry = entries[pos]; | 1616 TestNetLogEntry entry = entries[pos]; |
| 1647 NetLog::Source socket_source; | 1617 NetLog::Source socket_source; |
| 1648 EXPECT_TRUE(NetLog::Source::FromEventParameters(entry.params.get(), | 1618 EXPECT_TRUE(NetLog::Source::FromEventParameters(entry.params.get(), |
| 1649 &socket_source)); | 1619 &socket_source)); |
| 1650 EXPECT_TRUE(socket_source.IsValid()); | 1620 EXPECT_TRUE(socket_source.IsValid()); |
| 1651 EXPECT_NE(log.bound().source().id, socket_source.id); | 1621 EXPECT_NE(log.bound().source().id, socket_source.id); |
| 1652 } | 1622 } |
| 1653 | 1623 |
| 1654 TEST_P(SpdySessionTest, NetLogOnSessionGoaway) { | 1624 TEST_P(SpdySessionTest, NetLogOnSessionGoaway) { |
| 1655 session_deps_.host_resolver->set_synchronous_mode(true); | 1625 session_deps_.host_resolver->set_synchronous_mode(true); |
| 1656 | 1626 |
| 1657 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 1658 scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway()); | 1627 scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway()); |
| 1659 MockRead reads[] = { | 1628 MockRead reads[] = { |
| 1660 CreateMockRead(*goaway), | 1629 CreateMockRead(*goaway), |
| 1661 MockRead(SYNCHRONOUS, 0, 0) // EOF | 1630 MockRead(SYNCHRONOUS, 0, 0) // EOF |
| 1662 }; | 1631 }; |
| 1663 | 1632 |
| 1664 StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0); | 1633 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0); |
| 1665 data.set_connect_data(connect_data); | |
| 1666 session_deps_.socket_factory->AddSocketDataProvider(&data); | 1634 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 1667 | 1635 |
| 1668 CreateNetworkSession(); | 1636 CreateNetworkSession(); |
| 1669 | 1637 |
| 1670 BoundTestNetLog log; | 1638 BoundTestNetLog log; |
| 1671 base::WeakPtr<SpdySession> session = | 1639 base::WeakPtr<SpdySession> session = |
| 1672 CreateInsecureSpdySession(http_session_, key_, log.bound()); | 1640 CreateInsecureSpdySession(http_session_, key_, log.bound()); |
| 1673 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); | 1641 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); |
| 1674 | 1642 |
| 1675 // Flush the read completion task. | 1643 // Flush the read completion task. |
| 1676 base::MessageLoop::current()->RunUntilIdle(); | 1644 base::RunLoop().RunUntilIdle(); |
| 1677 | 1645 |
| 1678 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); | 1646 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); |
| 1679 EXPECT_TRUE(session == NULL); | 1647 EXPECT_FALSE(session); |
| 1680 | 1648 |
| 1681 // Check that the NetLog was filled reasonably. | 1649 // Check that the NetLog was filled reasonably. |
| 1682 TestNetLogEntry::List entries; | 1650 TestNetLogEntry::List entries; |
| 1683 log.GetEntries(&entries); | 1651 log.GetEntries(&entries); |
| 1684 EXPECT_LT(0u, entries.size()); | 1652 EXPECT_LT(0u, entries.size()); |
| 1685 | 1653 |
| 1686 // Check that we logged SPDY_SESSION_CLOSE correctly. | 1654 // Check that we logged SPDY_SESSION_CLOSE correctly. |
| 1687 int pos = ExpectLogContainsSomewhere( | 1655 int pos = ExpectLogContainsSomewhere( |
| 1688 entries, 0, NetLog::TYPE_HTTP2_SESSION_CLOSE, NetLog::PHASE_NONE); | 1656 entries, 0, NetLog::TYPE_HTTP2_SESSION_CLOSE, NetLog::PHASE_NONE); |
| 1689 | 1657 |
| 1690 if (pos < static_cast<int>(entries.size())) { | 1658 if (pos < static_cast<int>(entries.size())) { |
| 1691 TestNetLogEntry entry = entries[pos]; | 1659 TestNetLogEntry entry = entries[pos]; |
| 1692 int error_code = 0; | 1660 int error_code = 0; |
| 1693 ASSERT_TRUE(entry.GetNetErrorCode(&error_code)); | 1661 ASSERT_TRUE(entry.GetNetErrorCode(&error_code)); |
| 1694 EXPECT_EQ(OK, error_code); | 1662 EXPECT_EQ(OK, error_code); |
| 1695 } else { | 1663 } else { |
| 1696 ADD_FAILURE(); | 1664 ADD_FAILURE(); |
| 1697 } | 1665 } |
| 1698 } | 1666 } |
| 1699 | 1667 |
| 1700 TEST_P(SpdySessionTest, NetLogOnSessionEOF) { | 1668 TEST_P(SpdySessionTest, NetLogOnSessionEOF) { |
| 1701 session_deps_.host_resolver->set_synchronous_mode(true); | 1669 session_deps_.host_resolver->set_synchronous_mode(true); |
| 1702 | 1670 |
| 1703 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 1704 MockRead reads[] = { | 1671 MockRead reads[] = { |
| 1705 MockRead(SYNCHRONOUS, 0, 0) // EOF | 1672 MockRead(SYNCHRONOUS, 0, 0) // EOF |
| 1706 }; | 1673 }; |
| 1707 | 1674 |
| 1708 StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0); | 1675 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0); |
| 1709 data.set_connect_data(connect_data); | |
| 1710 session_deps_.socket_factory->AddSocketDataProvider(&data); | 1676 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 1711 | 1677 |
| 1712 CreateNetworkSession(); | 1678 CreateNetworkSession(); |
| 1713 | 1679 |
| 1714 BoundTestNetLog log; | 1680 BoundTestNetLog log; |
| 1715 base::WeakPtr<SpdySession> session = | 1681 base::WeakPtr<SpdySession> session = |
| 1716 CreateInsecureSpdySession(http_session_, key_, log.bound()); | 1682 CreateInsecureSpdySession(http_session_, key_, log.bound()); |
| 1717 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); | 1683 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); |
| 1718 | 1684 |
| 1719 // Flush the read completion task. | 1685 // Flush the read completion task. |
| 1720 base::MessageLoop::current()->RunUntilIdle(); | 1686 base::RunLoop().RunUntilIdle(); |
| 1721 | 1687 |
| 1722 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); | 1688 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); |
| 1723 EXPECT_TRUE(session == NULL); | 1689 EXPECT_FALSE(session); |
| 1724 | 1690 |
| 1725 // Check that the NetLog was filled reasonably. | 1691 // Check that the NetLog was filled reasonably. |
| 1726 TestNetLogEntry::List entries; | 1692 TestNetLogEntry::List entries; |
| 1727 log.GetEntries(&entries); | 1693 log.GetEntries(&entries); |
| 1728 EXPECT_LT(0u, entries.size()); | 1694 EXPECT_LT(0u, entries.size()); |
| 1729 | 1695 |
| 1730 // Check that we logged SPDY_SESSION_CLOSE correctly. | 1696 // Check that we logged SPDY_SESSION_CLOSE correctly. |
| 1731 int pos = ExpectLogContainsSomewhere( | 1697 int pos = ExpectLogContainsSomewhere( |
| 1732 entries, 0, NetLog::TYPE_HTTP2_SESSION_CLOSE, NetLog::PHASE_NONE); | 1698 entries, 0, NetLog::TYPE_HTTP2_SESSION_CLOSE, NetLog::PHASE_NONE); |
| 1733 | 1699 |
| 1734 if (pos < static_cast<int>(entries.size())) { | 1700 if (pos < static_cast<int>(entries.size())) { |
| 1735 TestNetLogEntry entry = entries[pos]; | 1701 TestNetLogEntry entry = entries[pos]; |
| 1736 int error_code = 0; | 1702 int error_code = 0; |
| 1737 ASSERT_TRUE(entry.GetNetErrorCode(&error_code)); | 1703 ASSERT_TRUE(entry.GetNetErrorCode(&error_code)); |
| 1738 EXPECT_EQ(ERR_CONNECTION_CLOSED, error_code); | 1704 EXPECT_EQ(ERR_CONNECTION_CLOSED, error_code); |
| 1739 } else { | 1705 } else { |
| 1740 ADD_FAILURE(); | 1706 ADD_FAILURE(); |
| 1741 } | 1707 } |
| 1742 } | 1708 } |
| 1743 | 1709 |
| 1744 TEST_P(SpdySessionTest, SynCompressionHistograms) { | 1710 TEST_P(SpdySessionTest, SynCompressionHistograms) { |
| 1745 session_deps_.enable_compression = true; | 1711 session_deps_.enable_compression = true; |
| 1746 | 1712 |
| 1747 scoped_ptr<SpdyFrame> req( | 1713 scoped_ptr<SpdyFrame> req( |
| 1748 spdy_util_.ConstructSpdyGet(NULL, 0, true, 1, MEDIUM, true)); | 1714 spdy_util_.ConstructSpdyGet(nullptr, 0, true, 1, MEDIUM, true)); |
| 1749 MockWrite writes[] = { | 1715 MockWrite writes[] = { |
| 1750 CreateMockWrite(*req, 0), | 1716 CreateMockWrite(*req, 0), |
| 1751 }; | 1717 }; |
| 1752 MockRead reads[] = { | 1718 MockRead reads[] = { |
| 1753 MockRead(ASYNC, 0, 1) // EOF | 1719 MockRead(ASYNC, ERR_IO_PENDING, 1), MockRead(ASYNC, 0, 2) // EOF |
| 1754 }; | 1720 }; |
| 1755 DeterministicSocketData data(reads, arraysize(reads), | 1721 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); |
| 1756 writes, arraysize(writes)); | 1722 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 1757 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 1758 data.set_connect_data(connect_data); | |
| 1759 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 1760 | 1723 |
| 1761 CreateDeterministicNetworkSession(); | 1724 CreateNetworkSession(); |
| 1762 base::WeakPtr<SpdySession> session = | 1725 base::WeakPtr<SpdySession> session = |
| 1763 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 1726 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 1764 | 1727 |
| 1765 GURL url(kDefaultURL); | 1728 GURL url(kDefaultURL); |
| 1766 base::WeakPtr<SpdyStream> spdy_stream = | 1729 base::WeakPtr<SpdyStream> spdy_stream = |
| 1767 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, | 1730 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, |
| 1768 session, url, MEDIUM, BoundNetLog()); | 1731 session, url, MEDIUM, BoundNetLog()); |
| 1769 test::StreamDelegateDoNothing delegate(spdy_stream); | 1732 test::StreamDelegateDoNothing delegate(spdy_stream); |
| 1770 spdy_stream->SetDelegate(&delegate); | 1733 spdy_stream->SetDelegate(&delegate); |
| 1771 | 1734 |
| 1772 scoped_ptr<SpdyHeaderBlock> headers( | 1735 scoped_ptr<SpdyHeaderBlock> headers( |
| 1773 spdy_util_.ConstructGetHeaderBlock(url.spec())); | 1736 spdy_util_.ConstructGetHeaderBlock(url.spec())); |
| 1774 spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); | 1737 spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); |
| 1775 EXPECT_TRUE(spdy_stream->HasUrlFromHeaders()); | 1738 EXPECT_TRUE(spdy_stream->HasUrlFromHeaders()); |
| 1776 | 1739 |
| 1777 // Write request headers & capture resulting histogram update. | 1740 // Write request headers & capture resulting histogram update. |
| 1778 base::HistogramTester histogram_tester; | 1741 base::HistogramTester histogram_tester; |
| 1779 | 1742 |
| 1780 data.RunFor(1); | 1743 base::RunLoop().RunUntilIdle(); |
| 1781 // Regression test of compression performance under the request fixture. | 1744 // Regression test of compression performance under the request fixture. |
| 1782 switch (spdy_util_.spdy_version()) { | 1745 switch (spdy_util_.spdy_version()) { |
| 1783 case SPDY3: | 1746 case SPDY3: |
| 1784 histogram_tester.ExpectBucketCount( | 1747 histogram_tester.ExpectBucketCount( |
| 1785 "Net.SpdySynStreamCompressionPercentage", 30, 1); | 1748 "Net.SpdySynStreamCompressionPercentage", 30, 1); |
| 1786 break; | 1749 break; |
| 1787 case SPDY4: | 1750 case SPDY4: |
| 1788 histogram_tester.ExpectBucketCount( | 1751 histogram_tester.ExpectBucketCount( |
| 1789 "Net.SpdySynStreamCompressionPercentage", 81, 1); | 1752 "Net.SpdySynStreamCompressionPercentage", 81, 1); |
| 1790 break; | 1753 break; |
| 1791 default: | 1754 default: |
| 1792 NOTREACHED(); | 1755 NOTREACHED(); |
| 1793 } | 1756 } |
| 1794 | 1757 |
| 1795 // Read and process EOF. | 1758 // Read and process EOF. |
| 1796 data.RunFor(1); | 1759 EXPECT_TRUE(session); |
| 1797 base::MessageLoop::current()->RunUntilIdle(); | 1760 data.CompleteRead(); |
| 1798 EXPECT_TRUE(session == NULL); | 1761 base::RunLoop().RunUntilIdle(); |
| 1762 EXPECT_FALSE(session); |
| 1799 } | 1763 } |
| 1800 | 1764 |
| 1801 // Queue up a low-priority SYN_STREAM followed by a high-priority | 1765 // Queue up a low-priority SYN_STREAM followed by a high-priority |
| 1802 // one. The high priority one should still send first and receive | 1766 // one. The high priority one should still send first and receive |
| 1803 // first. | 1767 // first. |
| 1804 TEST_P(SpdySessionTest, OutOfOrderSynStreams) { | 1768 TEST_P(SpdySessionTest, OutOfOrderSynStreams) { |
| 1805 // Construct the request. | 1769 // Construct the request. |
| 1806 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 1807 scoped_ptr<SpdyFrame> req_highest( | 1770 scoped_ptr<SpdyFrame> req_highest( |
| 1808 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, HIGHEST, true)); | 1771 spdy_util_.ConstructSpdyGet(nullptr, 0, false, 1, HIGHEST, true)); |
| 1809 scoped_ptr<SpdyFrame> req_lowest( | 1772 scoped_ptr<SpdyFrame> req_lowest( |
| 1810 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true)); | 1773 spdy_util_.ConstructSpdyGet(nullptr, 0, false, 3, LOWEST, true)); |
| 1811 MockWrite writes[] = { | 1774 MockWrite writes[] = { |
| 1812 CreateMockWrite(*req_highest, 0), | 1775 CreateMockWrite(*req_highest, 0), |
| 1813 CreateMockWrite(*req_lowest, 1), | 1776 CreateMockWrite(*req_lowest, 1), |
| 1814 }; | 1777 }; |
| 1815 | 1778 |
| 1816 scoped_ptr<SpdyFrame> resp_highest( | 1779 scoped_ptr<SpdyFrame> resp_highest( |
| 1817 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); | 1780 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); |
| 1818 scoped_ptr<SpdyFrame> body_highest( | 1781 scoped_ptr<SpdyFrame> body_highest( |
| 1819 spdy_util_.ConstructSpdyBodyFrame(1, true)); | 1782 spdy_util_.ConstructSpdyBodyFrame(1, true)); |
| 1820 scoped_ptr<SpdyFrame> resp_lowest( | 1783 scoped_ptr<SpdyFrame> resp_lowest( |
| 1821 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); | 1784 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 3)); |
| 1822 scoped_ptr<SpdyFrame> body_lowest( | 1785 scoped_ptr<SpdyFrame> body_lowest( |
| 1823 spdy_util_.ConstructSpdyBodyFrame(3, true)); | 1786 spdy_util_.ConstructSpdyBodyFrame(3, true)); |
| 1824 MockRead reads[] = { | 1787 MockRead reads[] = { |
| 1825 CreateMockRead(*resp_highest, 2), | 1788 CreateMockRead(*resp_highest, 2), |
| 1826 CreateMockRead(*body_highest, 3), | 1789 CreateMockRead(*body_highest, 3), |
| 1827 CreateMockRead(*resp_lowest, 4), | 1790 CreateMockRead(*resp_lowest, 4), |
| 1828 CreateMockRead(*body_lowest, 5), | 1791 CreateMockRead(*body_lowest, 5), |
| 1829 MockRead(ASYNC, 0, 6) // EOF | 1792 MockRead(ASYNC, 0, 6) // EOF |
| 1830 }; | 1793 }; |
| 1831 | 1794 |
| 1832 session_deps_.host_resolver->set_synchronous_mode(true); | 1795 session_deps_.host_resolver->set_synchronous_mode(true); |
| 1833 | 1796 |
| 1834 DeterministicSocketData data(reads, arraysize(reads), | 1797 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); |
| 1835 writes, arraysize(writes)); | 1798 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 1836 data.set_connect_data(connect_data); | |
| 1837 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 1838 | 1799 |
| 1839 CreateDeterministicNetworkSession(); | 1800 CreateNetworkSession(); |
| 1840 | 1801 |
| 1841 base::WeakPtr<SpdySession> session = | 1802 base::WeakPtr<SpdySession> session = |
| 1842 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 1803 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 1843 | 1804 |
| 1844 GURL url(kDefaultURL); | 1805 GURL url(kDefaultURL); |
| 1845 | 1806 |
| 1846 base::WeakPtr<SpdyStream> spdy_stream_lowest = | 1807 base::WeakPtr<SpdyStream> spdy_stream_lowest = |
| 1847 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, | 1808 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, |
| 1848 session, url, LOWEST, BoundNetLog()); | 1809 session, url, LOWEST, BoundNetLog()); |
| 1849 ASSERT_TRUE(spdy_stream_lowest); | 1810 ASSERT_TRUE(spdy_stream_lowest); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1866 spdy_stream_lowest->SendRequestHeaders( | 1827 spdy_stream_lowest->SendRequestHeaders( |
| 1867 headers_lowest.Pass(), NO_MORE_DATA_TO_SEND); | 1828 headers_lowest.Pass(), NO_MORE_DATA_TO_SEND); |
| 1868 EXPECT_TRUE(spdy_stream_lowest->HasUrlFromHeaders()); | 1829 EXPECT_TRUE(spdy_stream_lowest->HasUrlFromHeaders()); |
| 1869 | 1830 |
| 1870 scoped_ptr<SpdyHeaderBlock> headers_highest( | 1831 scoped_ptr<SpdyHeaderBlock> headers_highest( |
| 1871 spdy_util_.ConstructGetHeaderBlock(url.spec())); | 1832 spdy_util_.ConstructGetHeaderBlock(url.spec())); |
| 1872 spdy_stream_highest->SendRequestHeaders( | 1833 spdy_stream_highest->SendRequestHeaders( |
| 1873 headers_highest.Pass(), NO_MORE_DATA_TO_SEND); | 1834 headers_highest.Pass(), NO_MORE_DATA_TO_SEND); |
| 1874 EXPECT_TRUE(spdy_stream_highest->HasUrlFromHeaders()); | 1835 EXPECT_TRUE(spdy_stream_highest->HasUrlFromHeaders()); |
| 1875 | 1836 |
| 1876 data.RunFor(7); | 1837 base::RunLoop().RunUntilIdle(); |
| 1877 | 1838 |
| 1878 EXPECT_FALSE(spdy_stream_lowest); | 1839 EXPECT_FALSE(spdy_stream_lowest); |
| 1879 EXPECT_FALSE(spdy_stream_highest); | 1840 EXPECT_FALSE(spdy_stream_highest); |
| 1880 EXPECT_EQ(3u, delegate_lowest.stream_id()); | 1841 EXPECT_EQ(3u, delegate_lowest.stream_id()); |
| 1881 EXPECT_EQ(1u, delegate_highest.stream_id()); | 1842 EXPECT_EQ(1u, delegate_highest.stream_id()); |
| 1882 } | 1843 } |
| 1883 | 1844 |
| 1884 TEST_P(SpdySessionTest, CancelStream) { | 1845 TEST_P(SpdySessionTest, CancelStream) { |
| 1885 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 1886 // Request 1, at HIGHEST priority, will be cancelled before it writes data. | 1846 // Request 1, at HIGHEST priority, will be cancelled before it writes data. |
| 1887 // Request 2, at LOWEST priority, will be a full request and will be id 1. | 1847 // Request 2, at LOWEST priority, will be a full request and will be id 1. |
| 1888 scoped_ptr<SpdyFrame> req2( | 1848 scoped_ptr<SpdyFrame> req2( |
| 1889 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); | 1849 spdy_util_.ConstructSpdyGet(nullptr, 0, false, 1, LOWEST, true)); |
| 1890 MockWrite writes[] = { | 1850 MockWrite writes[] = { |
| 1891 CreateMockWrite(*req2, 0), | 1851 CreateMockWrite(*req2, 0), |
| 1892 }; | 1852 }; |
| 1893 | 1853 |
| 1894 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); | 1854 scoped_ptr<SpdyFrame> resp2( |
| 1855 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); |
| 1895 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true)); | 1856 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true)); |
| 1896 MockRead reads[] = { | 1857 MockRead reads[] = { |
| 1897 CreateMockRead(*resp2, 1), | 1858 CreateMockRead(*resp2, 1), |
| 1898 CreateMockRead(*body2, 2), | 1859 MockRead(ASYNC, ERR_IO_PENDING, 2), |
| 1899 MockRead(ASYNC, 0, 3) // EOF | 1860 CreateMockRead(*body2, 3), |
| 1861 MockRead(ASYNC, 0, 4) // EOF |
| 1900 }; | 1862 }; |
| 1901 | 1863 |
| 1902 session_deps_.host_resolver->set_synchronous_mode(true); | 1864 session_deps_.host_resolver->set_synchronous_mode(true); |
| 1903 | 1865 |
| 1904 DeterministicSocketData data(reads, arraysize(reads), | 1866 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); |
| 1905 writes, arraysize(writes)); | 1867 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 1906 data.set_connect_data(connect_data); | |
| 1907 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 1908 | 1868 |
| 1909 CreateDeterministicNetworkSession(); | 1869 CreateNetworkSession(); |
| 1910 | 1870 |
| 1911 base::WeakPtr<SpdySession> session = | 1871 base::WeakPtr<SpdySession> session = |
| 1912 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 1872 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 1913 | 1873 |
| 1914 GURL url1(kDefaultURL); | 1874 GURL url1(kDefaultURL); |
| 1915 base::WeakPtr<SpdyStream> spdy_stream1 = | 1875 base::WeakPtr<SpdyStream> spdy_stream1 = |
| 1916 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, | 1876 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, |
| 1917 session, url1, HIGHEST, BoundNetLog()); | 1877 session, url1, HIGHEST, BoundNetLog()); |
| 1918 ASSERT_TRUE(spdy_stream1.get() != NULL); | 1878 ASSERT_TRUE(spdy_stream1.get() != nullptr); |
| 1919 EXPECT_EQ(0u, spdy_stream1->stream_id()); | 1879 EXPECT_EQ(0u, spdy_stream1->stream_id()); |
| 1920 test::StreamDelegateDoNothing delegate1(spdy_stream1); | 1880 test::StreamDelegateDoNothing delegate1(spdy_stream1); |
| 1921 spdy_stream1->SetDelegate(&delegate1); | 1881 spdy_stream1->SetDelegate(&delegate1); |
| 1922 | 1882 |
| 1923 GURL url2(kDefaultURL); | 1883 GURL url2(kDefaultURL); |
| 1924 base::WeakPtr<SpdyStream> spdy_stream2 = | 1884 base::WeakPtr<SpdyStream> spdy_stream2 = |
| 1925 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, | 1885 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, |
| 1926 session, url2, LOWEST, BoundNetLog()); | 1886 session, url2, LOWEST, BoundNetLog()); |
| 1927 ASSERT_TRUE(spdy_stream2.get() != NULL); | 1887 ASSERT_TRUE(spdy_stream2.get() != nullptr); |
| 1928 EXPECT_EQ(0u, spdy_stream2->stream_id()); | 1888 EXPECT_EQ(0u, spdy_stream2->stream_id()); |
| 1929 test::StreamDelegateDoNothing delegate2(spdy_stream2); | 1889 test::StreamDelegateDoNothing delegate2(spdy_stream2); |
| 1930 spdy_stream2->SetDelegate(&delegate2); | 1890 spdy_stream2->SetDelegate(&delegate2); |
| 1931 | 1891 |
| 1932 scoped_ptr<SpdyHeaderBlock> headers( | 1892 scoped_ptr<SpdyHeaderBlock> headers( |
| 1933 spdy_util_.ConstructGetHeaderBlock(url1.spec())); | 1893 spdy_util_.ConstructGetHeaderBlock(url1.spec())); |
| 1934 spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); | 1894 spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); |
| 1935 EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); | 1895 EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); |
| 1936 | 1896 |
| 1937 scoped_ptr<SpdyHeaderBlock> headers2( | 1897 scoped_ptr<SpdyHeaderBlock> headers2( |
| 1938 spdy_util_.ConstructGetHeaderBlock(url2.spec())); | 1898 spdy_util_.ConstructGetHeaderBlock(url2.spec())); |
| 1939 spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND); | 1899 spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND); |
| 1940 EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders()); | 1900 EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders()); |
| 1941 | 1901 |
| 1942 EXPECT_EQ(0u, spdy_stream1->stream_id()); | 1902 EXPECT_EQ(0u, spdy_stream1->stream_id()); |
| 1943 | 1903 |
| 1944 spdy_stream1->Cancel(); | 1904 spdy_stream1->Cancel(); |
| 1945 EXPECT_EQ(NULL, spdy_stream1.get()); | 1905 EXPECT_FALSE(spdy_stream1); |
| 1946 | 1906 |
| 1947 EXPECT_EQ(0u, delegate1.stream_id()); | 1907 EXPECT_EQ(0u, delegate1.stream_id()); |
| 1948 | 1908 |
| 1949 data.RunFor(1); | 1909 base::RunLoop().RunUntilIdle(); |
| 1950 | 1910 |
| 1951 EXPECT_EQ(0u, delegate1.stream_id()); | 1911 EXPECT_EQ(0u, delegate1.stream_id()); |
| 1952 EXPECT_EQ(1u, delegate2.stream_id()); | 1912 EXPECT_EQ(1u, delegate2.stream_id()); |
| 1953 | 1913 |
| 1954 spdy_stream2->Cancel(); | 1914 spdy_stream2->Cancel(); |
| 1955 EXPECT_EQ(NULL, spdy_stream2.get()); | 1915 EXPECT_FALSE(spdy_stream2); |
| 1956 } | 1916 } |
| 1957 | 1917 |
| 1958 // Create two streams that are set to re-close themselves on close, | 1918 // Create two streams that are set to re-close themselves on close, |
| 1959 // and then close the session. Nothing should blow up. Also a | 1919 // and then close the session. Nothing should blow up. Also a |
| 1960 // regression test for http://crbug.com/139518 . | 1920 // regression test for http://crbug.com/139518 . |
| 1961 TEST_P(SpdySessionTest, CloseSessionWithTwoCreatedSelfClosingStreams) { | 1921 TEST_P(SpdySessionTest, CloseSessionWithTwoCreatedSelfClosingStreams) { |
| 1962 session_deps_.host_resolver->set_synchronous_mode(true); | 1922 session_deps_.host_resolver->set_synchronous_mode(true); |
| 1963 | 1923 |
| 1964 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 1965 | 1924 |
| 1966 // No actual data will be sent. | 1925 // No actual data will be sent. |
| 1967 MockWrite writes[] = { | 1926 MockWrite writes[] = { |
| 1968 MockWrite(ASYNC, 0, 1) // EOF | 1927 MockWrite(ASYNC, 0, 1) // EOF |
| 1969 }; | 1928 }; |
| 1970 | 1929 |
| 1971 MockRead reads[] = { | 1930 MockRead reads[] = { |
| 1972 MockRead(ASYNC, 0, 0) // EOF | 1931 MockRead(ASYNC, 0, 0) // EOF |
| 1973 }; | 1932 }; |
| 1974 DeterministicSocketData data(reads, arraysize(reads), | 1933 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); |
| 1975 writes, arraysize(writes)); | 1934 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 1976 data.set_connect_data(connect_data); | |
| 1977 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 1978 | 1935 |
| 1979 CreateDeterministicNetworkSession(); | 1936 CreateNetworkSession(); |
| 1980 | 1937 |
| 1981 base::WeakPtr<SpdySession> session = | 1938 base::WeakPtr<SpdySession> session = |
| 1982 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 1939 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 1983 | 1940 |
| 1984 GURL url1(kDefaultURL); | 1941 GURL url1(kDefaultURL); |
| 1985 base::WeakPtr<SpdyStream> spdy_stream1 = | 1942 base::WeakPtr<SpdyStream> spdy_stream1 = |
| 1986 CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, | 1943 CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, |
| 1987 session, url1, HIGHEST, BoundNetLog()); | 1944 session, url1, HIGHEST, BoundNetLog()); |
| 1988 ASSERT_TRUE(spdy_stream1.get() != NULL); | 1945 ASSERT_TRUE(spdy_stream1.get() != nullptr); |
| 1989 EXPECT_EQ(0u, spdy_stream1->stream_id()); | 1946 EXPECT_EQ(0u, spdy_stream1->stream_id()); |
| 1990 | 1947 |
| 1991 GURL url2(kDefaultURL); | 1948 GURL url2(kDefaultURL); |
| 1992 base::WeakPtr<SpdyStream> spdy_stream2 = | 1949 base::WeakPtr<SpdyStream> spdy_stream2 = |
| 1993 CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, | 1950 CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, |
| 1994 session, url2, LOWEST, BoundNetLog()); | 1951 session, url2, LOWEST, BoundNetLog()); |
| 1995 ASSERT_TRUE(spdy_stream2.get() != NULL); | 1952 ASSERT_TRUE(spdy_stream2.get() != nullptr); |
| 1996 EXPECT_EQ(0u, spdy_stream2->stream_id()); | 1953 EXPECT_EQ(0u, spdy_stream2->stream_id()); |
| 1997 | 1954 |
| 1998 test::ClosingDelegate delegate1(spdy_stream1); | 1955 test::ClosingDelegate delegate1(spdy_stream1); |
| 1999 spdy_stream1->SetDelegate(&delegate1); | 1956 spdy_stream1->SetDelegate(&delegate1); |
| 2000 | 1957 |
| 2001 test::ClosingDelegate delegate2(spdy_stream2); | 1958 test::ClosingDelegate delegate2(spdy_stream2); |
| 2002 spdy_stream2->SetDelegate(&delegate2); | 1959 spdy_stream2->SetDelegate(&delegate2); |
| 2003 | 1960 |
| 2004 scoped_ptr<SpdyHeaderBlock> headers( | 1961 scoped_ptr<SpdyHeaderBlock> headers( |
| 2005 spdy_util_.ConstructGetHeaderBlock(url1.spec())); | 1962 spdy_util_.ConstructGetHeaderBlock(url1.spec())); |
| 2006 spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); | 1963 spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); |
| 2007 EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); | 1964 EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); |
| 2008 | 1965 |
| 2009 scoped_ptr<SpdyHeaderBlock> headers2( | 1966 scoped_ptr<SpdyHeaderBlock> headers2( |
| 2010 spdy_util_.ConstructGetHeaderBlock(url2.spec())); | 1967 spdy_util_.ConstructGetHeaderBlock(url2.spec())); |
| 2011 spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND); | 1968 spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND); |
| 2012 EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders()); | 1969 EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders()); |
| 2013 | 1970 |
| 2014 // Ensure that the streams have not yet been activated and assigned an id. | 1971 // Ensure that the streams have not yet been activated and assigned an id. |
| 2015 EXPECT_EQ(0u, spdy_stream1->stream_id()); | 1972 EXPECT_EQ(0u, spdy_stream1->stream_id()); |
| 2016 EXPECT_EQ(0u, spdy_stream2->stream_id()); | 1973 EXPECT_EQ(0u, spdy_stream2->stream_id()); |
| 2017 | 1974 |
| 2018 // Ensure we don't crash while closing the session. | 1975 // Ensure we don't crash while closing the session. |
| 2019 session->CloseSessionOnError(ERR_ABORTED, std::string()); | 1976 session->CloseSessionOnError(ERR_ABORTED, std::string()); |
| 2020 | 1977 |
| 2021 EXPECT_EQ(NULL, spdy_stream1.get()); | 1978 EXPECT_FALSE(spdy_stream1); |
| 2022 EXPECT_EQ(NULL, spdy_stream2.get()); | 1979 EXPECT_FALSE(spdy_stream2); |
| 2023 | 1980 |
| 2024 EXPECT_TRUE(delegate1.StreamIsClosed()); | 1981 EXPECT_TRUE(delegate1.StreamIsClosed()); |
| 2025 EXPECT_TRUE(delegate2.StreamIsClosed()); | 1982 EXPECT_TRUE(delegate2.StreamIsClosed()); |
| 2026 | 1983 |
| 2027 base::MessageLoop::current()->RunUntilIdle(); | 1984 base::RunLoop().RunUntilIdle(); |
| 2028 EXPECT_TRUE(session == NULL); | 1985 EXPECT_FALSE(session); |
| 2029 } | 1986 } |
| 2030 | 1987 |
| 2031 // Create two streams that are set to close each other on close, and | 1988 // Create two streams that are set to close each other on close, and |
| 2032 // then close the session. Nothing should blow up. | 1989 // then close the session. Nothing should blow up. |
| 2033 TEST_P(SpdySessionTest, CloseSessionWithTwoCreatedMutuallyClosingStreams) { | 1990 TEST_P(SpdySessionTest, CloseSessionWithTwoCreatedMutuallyClosingStreams) { |
| 2034 session_deps_.host_resolver->set_synchronous_mode(true); | 1991 session_deps_.host_resolver->set_synchronous_mode(true); |
| 2035 | 1992 |
| 2036 MockConnect connect_data(SYNCHRONOUS, OK); | 1993 SequencedSocketData data(nullptr, 0, nullptr, 0); |
| 1994 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 2037 | 1995 |
| 2038 // No actual data will be sent. | 1996 CreateNetworkSession(); |
| 2039 MockWrite writes[] = { | |
| 2040 MockWrite(ASYNC, 0, 1) // EOF | |
| 2041 }; | |
| 2042 | |
| 2043 MockRead reads[] = { | |
| 2044 MockRead(ASYNC, 0, 0) // EOF | |
| 2045 }; | |
| 2046 DeterministicSocketData data(reads, arraysize(reads), | |
| 2047 writes, arraysize(writes)); | |
| 2048 data.set_connect_data(connect_data); | |
| 2049 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 2050 | |
| 2051 CreateDeterministicNetworkSession(); | |
| 2052 | 1997 |
| 2053 base::WeakPtr<SpdySession> session = | 1998 base::WeakPtr<SpdySession> session = |
| 2054 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 1999 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 2055 | 2000 |
| 2056 GURL url1(kDefaultURL); | 2001 GURL url1(kDefaultURL); |
| 2057 base::WeakPtr<SpdyStream> spdy_stream1 = | 2002 base::WeakPtr<SpdyStream> spdy_stream1 = |
| 2058 CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, | 2003 CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, |
| 2059 session, url1, HIGHEST, BoundNetLog()); | 2004 session, url1, HIGHEST, BoundNetLog()); |
| 2060 ASSERT_TRUE(spdy_stream1.get() != NULL); | 2005 ASSERT_TRUE(spdy_stream1); |
| 2061 EXPECT_EQ(0u, spdy_stream1->stream_id()); | 2006 EXPECT_EQ(0u, spdy_stream1->stream_id()); |
| 2062 | 2007 |
| 2063 GURL url2(kDefaultURL); | 2008 GURL url2(kDefaultURL); |
| 2064 base::WeakPtr<SpdyStream> spdy_stream2 = | 2009 base::WeakPtr<SpdyStream> spdy_stream2 = |
| 2065 CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, | 2010 CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, |
| 2066 session, url2, LOWEST, BoundNetLog()); | 2011 session, url2, LOWEST, BoundNetLog()); |
| 2067 ASSERT_TRUE(spdy_stream2.get() != NULL); | 2012 ASSERT_TRUE(spdy_stream2); |
| 2068 EXPECT_EQ(0u, spdy_stream2->stream_id()); | 2013 EXPECT_EQ(0u, spdy_stream2->stream_id()); |
| 2069 | 2014 |
| 2070 // Make |spdy_stream1| close |spdy_stream2|. | 2015 // Make |spdy_stream1| close |spdy_stream2|. |
| 2071 test::ClosingDelegate delegate1(spdy_stream2); | 2016 test::ClosingDelegate delegate1(spdy_stream2); |
| 2072 spdy_stream1->SetDelegate(&delegate1); | 2017 spdy_stream1->SetDelegate(&delegate1); |
| 2073 | 2018 |
| 2074 // Make |spdy_stream2| close |spdy_stream1|. | 2019 // Make |spdy_stream2| close |spdy_stream1|. |
| 2075 test::ClosingDelegate delegate2(spdy_stream1); | 2020 test::ClosingDelegate delegate2(spdy_stream1); |
| 2076 spdy_stream2->SetDelegate(&delegate2); | 2021 spdy_stream2->SetDelegate(&delegate2); |
| 2077 | 2022 |
| 2078 scoped_ptr<SpdyHeaderBlock> headers( | 2023 scoped_ptr<SpdyHeaderBlock> headers( |
| 2079 spdy_util_.ConstructGetHeaderBlock(url1.spec())); | 2024 spdy_util_.ConstructGetHeaderBlock(url1.spec())); |
| 2080 spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); | 2025 spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); |
| 2081 EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); | 2026 EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); |
| 2082 | 2027 |
| 2083 scoped_ptr<SpdyHeaderBlock> headers2( | 2028 scoped_ptr<SpdyHeaderBlock> headers2( |
| 2084 spdy_util_.ConstructGetHeaderBlock(url2.spec())); | 2029 spdy_util_.ConstructGetHeaderBlock(url2.spec())); |
| 2085 spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND); | 2030 spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND); |
| 2086 EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders()); | 2031 EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders()); |
| 2087 | 2032 |
| 2088 // Ensure that the streams have not yet been activated and assigned an id. | 2033 // Ensure that the streams have not yet been activated and assigned an id. |
| 2089 EXPECT_EQ(0u, spdy_stream1->stream_id()); | 2034 EXPECT_EQ(0u, spdy_stream1->stream_id()); |
| 2090 EXPECT_EQ(0u, spdy_stream2->stream_id()); | 2035 EXPECT_EQ(0u, spdy_stream2->stream_id()); |
| 2091 | 2036 |
| 2092 // Ensure we don't crash while closing the session. | 2037 // Ensure we don't crash while closing the session. |
| 2093 session->CloseSessionOnError(ERR_ABORTED, std::string()); | 2038 session->CloseSessionOnError(ERR_ABORTED, std::string()); |
| 2094 | 2039 |
| 2095 EXPECT_EQ(NULL, spdy_stream1.get()); | 2040 EXPECT_FALSE(spdy_stream1); |
| 2096 EXPECT_EQ(NULL, spdy_stream2.get()); | 2041 EXPECT_FALSE(spdy_stream2); |
| 2097 | 2042 |
| 2098 EXPECT_TRUE(delegate1.StreamIsClosed()); | 2043 EXPECT_TRUE(delegate1.StreamIsClosed()); |
| 2099 EXPECT_TRUE(delegate2.StreamIsClosed()); | 2044 EXPECT_TRUE(delegate2.StreamIsClosed()); |
| 2100 | 2045 |
| 2101 base::MessageLoop::current()->RunUntilIdle(); | 2046 base::RunLoop().RunUntilIdle(); |
| 2102 EXPECT_TRUE(session == NULL); | 2047 EXPECT_FALSE(session); |
| 2103 } | 2048 } |
| 2104 | 2049 |
| 2105 // Create two streams that are set to re-close themselves on close, | 2050 // Create two streams that are set to re-close themselves on close, |
| 2106 // activate them, and then close the session. Nothing should blow up. | 2051 // activate them, and then close the session. Nothing should blow up. |
| 2107 TEST_P(SpdySessionTest, CloseSessionWithTwoActivatedSelfClosingStreams) { | 2052 TEST_P(SpdySessionTest, CloseSessionWithTwoActivatedSelfClosingStreams) { |
| 2108 session_deps_.host_resolver->set_synchronous_mode(true); | 2053 session_deps_.host_resolver->set_synchronous_mode(true); |
| 2109 | 2054 |
| 2110 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 2111 | |
| 2112 scoped_ptr<SpdyFrame> req1( | 2055 scoped_ptr<SpdyFrame> req1( |
| 2113 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); | 2056 spdy_util_.ConstructSpdyGet(nullptr, 0, false, 1, MEDIUM, true)); |
| 2114 scoped_ptr<SpdyFrame> req2( | 2057 scoped_ptr<SpdyFrame> req2( |
| 2115 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, MEDIUM, true)); | 2058 spdy_util_.ConstructSpdyGet(nullptr, 0, false, 3, MEDIUM, true)); |
| 2116 MockWrite writes[] = { | 2059 MockWrite writes[] = { |
| 2117 CreateMockWrite(*req1, 0), | 2060 CreateMockWrite(*req1, 0), |
| 2118 CreateMockWrite(*req2, 1), | 2061 CreateMockWrite(*req2, 1), |
| 2119 }; | 2062 }; |
| 2120 | 2063 |
| 2121 MockRead reads[] = { | 2064 MockRead reads[] = { |
| 2122 MockRead(ASYNC, 0, 2) // EOF | 2065 MockRead(ASYNC, ERR_IO_PENDING, 2), MockRead(ASYNC, 0, 3) // EOF |
| 2123 }; | 2066 }; |
| 2124 | 2067 |
| 2125 DeterministicSocketData data(reads, arraysize(reads), | 2068 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); |
| 2126 writes, arraysize(writes)); | 2069 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 2127 data.set_connect_data(connect_data); | |
| 2128 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 2129 | 2070 |
| 2130 CreateDeterministicNetworkSession(); | 2071 CreateNetworkSession(); |
| 2131 | 2072 |
| 2132 base::WeakPtr<SpdySession> session = | 2073 base::WeakPtr<SpdySession> session = |
| 2133 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 2074 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 2134 | 2075 |
| 2135 GURL url1(kDefaultURL); | 2076 GURL url1(kDefaultURL); |
| 2136 base::WeakPtr<SpdyStream> spdy_stream1 = | 2077 base::WeakPtr<SpdyStream> spdy_stream1 = |
| 2137 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, | 2078 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, |
| 2138 session, url1, MEDIUM, BoundNetLog()); | 2079 session, url1, MEDIUM, BoundNetLog()); |
| 2139 ASSERT_TRUE(spdy_stream1.get() != NULL); | 2080 ASSERT_TRUE(spdy_stream1.get() != nullptr); |
| 2140 EXPECT_EQ(0u, spdy_stream1->stream_id()); | 2081 EXPECT_EQ(0u, spdy_stream1->stream_id()); |
| 2141 | 2082 |
| 2142 GURL url2(kDefaultURL); | 2083 GURL url2(kDefaultURL); |
| 2143 base::WeakPtr<SpdyStream> spdy_stream2 = | 2084 base::WeakPtr<SpdyStream> spdy_stream2 = |
| 2144 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, | 2085 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, |
| 2145 session, url2, MEDIUM, BoundNetLog()); | 2086 session, url2, MEDIUM, BoundNetLog()); |
| 2146 ASSERT_TRUE(spdy_stream2.get() != NULL); | 2087 ASSERT_TRUE(spdy_stream2.get() != nullptr); |
| 2147 EXPECT_EQ(0u, spdy_stream2->stream_id()); | 2088 EXPECT_EQ(0u, spdy_stream2->stream_id()); |
| 2148 | 2089 |
| 2149 test::ClosingDelegate delegate1(spdy_stream1); | 2090 test::ClosingDelegate delegate1(spdy_stream1); |
| 2150 spdy_stream1->SetDelegate(&delegate1); | 2091 spdy_stream1->SetDelegate(&delegate1); |
| 2151 | 2092 |
| 2152 test::ClosingDelegate delegate2(spdy_stream2); | 2093 test::ClosingDelegate delegate2(spdy_stream2); |
| 2153 spdy_stream2->SetDelegate(&delegate2); | 2094 spdy_stream2->SetDelegate(&delegate2); |
| 2154 | 2095 |
| 2155 scoped_ptr<SpdyHeaderBlock> headers( | 2096 scoped_ptr<SpdyHeaderBlock> headers( |
| 2156 spdy_util_.ConstructGetHeaderBlock(url1.spec())); | 2097 spdy_util_.ConstructGetHeaderBlock(url1.spec())); |
| 2157 spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); | 2098 spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); |
| 2158 EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); | 2099 EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); |
| 2159 | 2100 |
| 2160 scoped_ptr<SpdyHeaderBlock> headers2( | 2101 scoped_ptr<SpdyHeaderBlock> headers2( |
| 2161 spdy_util_.ConstructGetHeaderBlock(url2.spec())); | 2102 spdy_util_.ConstructGetHeaderBlock(url2.spec())); |
| 2162 spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND); | 2103 spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND); |
| 2163 EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders()); | 2104 EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders()); |
| 2164 | 2105 |
| 2165 // Ensure that the streams have not yet been activated and assigned an id. | 2106 // Ensure that the streams have not yet been activated and assigned an id. |
| 2166 EXPECT_EQ(0u, spdy_stream1->stream_id()); | 2107 EXPECT_EQ(0u, spdy_stream1->stream_id()); |
| 2167 EXPECT_EQ(0u, spdy_stream2->stream_id()); | 2108 EXPECT_EQ(0u, spdy_stream2->stream_id()); |
| 2168 | 2109 |
| 2169 data.RunFor(2); | 2110 base::RunLoop().RunUntilIdle(); |
| 2170 | 2111 |
| 2171 EXPECT_EQ(1u, spdy_stream1->stream_id()); | 2112 EXPECT_EQ(1u, spdy_stream1->stream_id()); |
| 2172 EXPECT_EQ(3u, spdy_stream2->stream_id()); | 2113 EXPECT_EQ(3u, spdy_stream2->stream_id()); |
| 2173 | 2114 |
| 2174 // Ensure we don't crash while closing the session. | 2115 // Ensure we don't crash while closing the session. |
| 2175 session->CloseSessionOnError(ERR_ABORTED, std::string()); | 2116 session->CloseSessionOnError(ERR_ABORTED, std::string()); |
| 2176 | 2117 |
| 2177 EXPECT_EQ(NULL, spdy_stream1.get()); | 2118 EXPECT_FALSE(spdy_stream1); |
| 2178 EXPECT_EQ(NULL, spdy_stream2.get()); | 2119 EXPECT_FALSE(spdy_stream2); |
| 2179 | 2120 |
| 2180 EXPECT_TRUE(delegate1.StreamIsClosed()); | 2121 EXPECT_TRUE(delegate1.StreamIsClosed()); |
| 2181 EXPECT_TRUE(delegate2.StreamIsClosed()); | 2122 EXPECT_TRUE(delegate2.StreamIsClosed()); |
| 2182 | 2123 |
| 2183 base::MessageLoop::current()->RunUntilIdle(); | 2124 EXPECT_TRUE(session); |
| 2184 EXPECT_TRUE(session == NULL); | 2125 data.CompleteRead(); |
| 2126 base::RunLoop().RunUntilIdle(); |
| 2127 EXPECT_FALSE(session); |
| 2185 } | 2128 } |
| 2186 | 2129 |
| 2187 // Create two streams that are set to close each other on close, | 2130 // Create two streams that are set to close each other on close, |
| 2188 // activate them, and then close the session. Nothing should blow up. | 2131 // activate them, and then close the session. Nothing should blow up. |
| 2189 TEST_P(SpdySessionTest, CloseSessionWithTwoActivatedMutuallyClosingStreams) { | 2132 TEST_P(SpdySessionTest, CloseSessionWithTwoActivatedMutuallyClosingStreams) { |
| 2190 session_deps_.host_resolver->set_synchronous_mode(true); | 2133 session_deps_.host_resolver->set_synchronous_mode(true); |
| 2191 | 2134 |
| 2192 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 2193 | |
| 2194 scoped_ptr<SpdyFrame> req1( | 2135 scoped_ptr<SpdyFrame> req1( |
| 2195 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); | 2136 spdy_util_.ConstructSpdyGet(nullptr, 0, false, 1, MEDIUM, true)); |
| 2196 scoped_ptr<SpdyFrame> req2( | 2137 scoped_ptr<SpdyFrame> req2( |
| 2197 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, MEDIUM, true)); | 2138 spdy_util_.ConstructSpdyGet(nullptr, 0, false, 3, MEDIUM, true)); |
| 2198 MockWrite writes[] = { | 2139 MockWrite writes[] = { |
| 2199 CreateMockWrite(*req1, 0), | 2140 CreateMockWrite(*req1, 0), |
| 2200 CreateMockWrite(*req2, 1), | 2141 CreateMockWrite(*req2, 1), |
| 2201 }; | 2142 }; |
| 2202 | 2143 |
| 2203 MockRead reads[] = { | 2144 MockRead reads[] = { |
| 2204 MockRead(ASYNC, 0, 2) // EOF | 2145 MockRead(ASYNC, ERR_IO_PENDING, 2), MockRead(ASYNC, 0, 3) // EOF |
| 2205 }; | 2146 }; |
| 2206 | 2147 |
| 2207 DeterministicSocketData data(reads, arraysize(reads), | 2148 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); |
| 2208 writes, arraysize(writes)); | 2149 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 2209 data.set_connect_data(connect_data); | |
| 2210 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 2211 | 2150 |
| 2212 CreateDeterministicNetworkSession(); | 2151 CreateNetworkSession(); |
| 2213 | 2152 |
| 2214 base::WeakPtr<SpdySession> session = | 2153 base::WeakPtr<SpdySession> session = |
| 2215 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 2154 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 2216 | 2155 |
| 2217 GURL url1(kDefaultURL); | 2156 GURL url1(kDefaultURL); |
| 2218 base::WeakPtr<SpdyStream> spdy_stream1 = | 2157 base::WeakPtr<SpdyStream> spdy_stream1 = |
| 2219 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, | 2158 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, |
| 2220 session, url1, MEDIUM, BoundNetLog()); | 2159 session, url1, MEDIUM, BoundNetLog()); |
| 2221 ASSERT_TRUE(spdy_stream1.get() != NULL); | 2160 ASSERT_TRUE(spdy_stream1); |
| 2222 EXPECT_EQ(0u, spdy_stream1->stream_id()); | 2161 EXPECT_EQ(0u, spdy_stream1->stream_id()); |
| 2223 | 2162 |
| 2224 GURL url2(kDefaultURL); | 2163 GURL url2(kDefaultURL); |
| 2225 base::WeakPtr<SpdyStream> spdy_stream2 = | 2164 base::WeakPtr<SpdyStream> spdy_stream2 = |
| 2226 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, | 2165 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, |
| 2227 session, url2, MEDIUM, BoundNetLog()); | 2166 session, url2, MEDIUM, BoundNetLog()); |
| 2228 ASSERT_TRUE(spdy_stream2.get() != NULL); | 2167 ASSERT_TRUE(spdy_stream2); |
| 2229 EXPECT_EQ(0u, spdy_stream2->stream_id()); | 2168 EXPECT_EQ(0u, spdy_stream2->stream_id()); |
| 2230 | 2169 |
| 2231 // Make |spdy_stream1| close |spdy_stream2|. | 2170 // Make |spdy_stream1| close |spdy_stream2|. |
| 2232 test::ClosingDelegate delegate1(spdy_stream2); | 2171 test::ClosingDelegate delegate1(spdy_stream2); |
| 2233 spdy_stream1->SetDelegate(&delegate1); | 2172 spdy_stream1->SetDelegate(&delegate1); |
| 2234 | 2173 |
| 2235 // Make |spdy_stream2| close |spdy_stream1|. | 2174 // Make |spdy_stream2| close |spdy_stream1|. |
| 2236 test::ClosingDelegate delegate2(spdy_stream1); | 2175 test::ClosingDelegate delegate2(spdy_stream1); |
| 2237 spdy_stream2->SetDelegate(&delegate2); | 2176 spdy_stream2->SetDelegate(&delegate2); |
| 2238 | 2177 |
| 2239 scoped_ptr<SpdyHeaderBlock> headers( | 2178 scoped_ptr<SpdyHeaderBlock> headers( |
| 2240 spdy_util_.ConstructGetHeaderBlock(url1.spec())); | 2179 spdy_util_.ConstructGetHeaderBlock(url1.spec())); |
| 2241 spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); | 2180 spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); |
| 2242 EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); | 2181 EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); |
| 2243 | 2182 |
| 2244 scoped_ptr<SpdyHeaderBlock> headers2( | 2183 scoped_ptr<SpdyHeaderBlock> headers2( |
| 2245 spdy_util_.ConstructGetHeaderBlock(url2.spec())); | 2184 spdy_util_.ConstructGetHeaderBlock(url2.spec())); |
| 2246 spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND); | 2185 spdy_stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND); |
| 2247 EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders()); | 2186 EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders()); |
| 2248 | 2187 |
| 2249 // Ensure that the streams have not yet been activated and assigned an id. | 2188 // Ensure that the streams have not yet been activated and assigned an id. |
| 2250 EXPECT_EQ(0u, spdy_stream1->stream_id()); | 2189 EXPECT_EQ(0u, spdy_stream1->stream_id()); |
| 2251 EXPECT_EQ(0u, spdy_stream2->stream_id()); | 2190 EXPECT_EQ(0u, spdy_stream2->stream_id()); |
| 2252 | 2191 |
| 2253 data.RunFor(2); | 2192 base::RunLoop().RunUntilIdle(); |
| 2254 | 2193 |
| 2255 EXPECT_EQ(1u, spdy_stream1->stream_id()); | 2194 EXPECT_EQ(1u, spdy_stream1->stream_id()); |
| 2256 EXPECT_EQ(3u, spdy_stream2->stream_id()); | 2195 EXPECT_EQ(3u, spdy_stream2->stream_id()); |
| 2257 | 2196 |
| 2258 // Ensure we don't crash while closing the session. | 2197 // Ensure we don't crash while closing the session. |
| 2259 session->CloseSessionOnError(ERR_ABORTED, std::string()); | 2198 session->CloseSessionOnError(ERR_ABORTED, std::string()); |
| 2260 | 2199 |
| 2261 EXPECT_EQ(NULL, spdy_stream1.get()); | 2200 EXPECT_FALSE(spdy_stream1); |
| 2262 EXPECT_EQ(NULL, spdy_stream2.get()); | 2201 EXPECT_FALSE(spdy_stream2); |
| 2263 | 2202 |
| 2264 EXPECT_TRUE(delegate1.StreamIsClosed()); | 2203 EXPECT_TRUE(delegate1.StreamIsClosed()); |
| 2265 EXPECT_TRUE(delegate2.StreamIsClosed()); | 2204 EXPECT_TRUE(delegate2.StreamIsClosed()); |
| 2266 | 2205 |
| 2267 base::MessageLoop::current()->RunUntilIdle(); | 2206 EXPECT_TRUE(session); |
| 2268 EXPECT_TRUE(session == NULL); | 2207 data.CompleteRead(); |
| 2208 base::RunLoop().RunUntilIdle(); |
| 2209 EXPECT_FALSE(session); |
| 2269 } | 2210 } |
| 2270 | 2211 |
| 2271 // Delegate that closes a given session when the stream is closed. | 2212 // Delegate that closes a given session when the stream is closed. |
| 2272 class SessionClosingDelegate : public test::StreamDelegateDoNothing { | 2213 class SessionClosingDelegate : public test::StreamDelegateDoNothing { |
| 2273 public: | 2214 public: |
| 2274 SessionClosingDelegate(const base::WeakPtr<SpdyStream>& stream, | 2215 SessionClosingDelegate(const base::WeakPtr<SpdyStream>& stream, |
| 2275 const base::WeakPtr<SpdySession>& session_to_close) | 2216 const base::WeakPtr<SpdySession>& session_to_close) |
| 2276 : StreamDelegateDoNothing(stream), | 2217 : StreamDelegateDoNothing(stream), |
| 2277 session_to_close_(session_to_close) {} | 2218 session_to_close_(session_to_close) {} |
| 2278 | 2219 |
| 2279 ~SessionClosingDelegate() override {} | 2220 ~SessionClosingDelegate() override {} |
| 2280 | 2221 |
| 2281 void OnClose(int status) override { | 2222 void OnClose(int status) override { |
| 2282 session_to_close_->CloseSessionOnError(ERR_SPDY_PROTOCOL_ERROR, "Error"); | 2223 session_to_close_->CloseSessionOnError(ERR_SPDY_PROTOCOL_ERROR, "Error"); |
| 2283 } | 2224 } |
| 2284 | 2225 |
| 2285 private: | 2226 private: |
| 2286 base::WeakPtr<SpdySession> session_to_close_; | 2227 base::WeakPtr<SpdySession> session_to_close_; |
| 2287 }; | 2228 }; |
| 2288 | 2229 |
| 2289 // Close an activated stream that closes its session. Nothing should | 2230 // Close an activated stream that closes its session. Nothing should |
| 2290 // blow up. This is a regression test for http://crbug.com/263691 . | 2231 // blow up. This is a regression test for https://crbug.com/263691. |
| 2291 TEST_P(SpdySessionTest, CloseActivatedStreamThatClosesSession) { | 2232 TEST_P(SpdySessionTest, CloseActivatedStreamThatClosesSession) { |
| 2292 session_deps_.host_resolver->set_synchronous_mode(true); | 2233 session_deps_.host_resolver->set_synchronous_mode(true); |
| 2293 | 2234 |
| 2294 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 2295 | |
| 2296 scoped_ptr<SpdyFrame> req( | 2235 scoped_ptr<SpdyFrame> req( |
| 2297 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); | 2236 spdy_util_.ConstructSpdyGet(nullptr, 0, false, 1, MEDIUM, true)); |
| 2298 scoped_ptr<SpdyFrame> rst( | 2237 scoped_ptr<SpdyFrame> rst( |
| 2299 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL)); | 2238 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL)); |
| 2300 scoped_ptr<SpdyFrame> goaway( | 2239 scoped_ptr<SpdyFrame> goaway( |
| 2301 spdy_util_.ConstructSpdyGoAway(0, GOAWAY_PROTOCOL_ERROR, "Error")); | 2240 spdy_util_.ConstructSpdyGoAway(0, GOAWAY_PROTOCOL_ERROR, "Error")); |
| 2302 // The GOAWAY has higher-priority than the RST_STREAM, and is written first | 2241 // The GOAWAY has higher-priority than the RST_STREAM, and is written first |
| 2303 // despite being queued second. | 2242 // despite being queued second. |
| 2304 MockWrite writes[] = { | 2243 MockWrite writes[] = { |
| 2305 CreateMockWrite(*req, 0), CreateMockWrite(*goaway, 1), | 2244 CreateMockWrite(*req, 0), |
| 2306 CreateMockWrite(*rst, 2), | 2245 CreateMockWrite(*goaway, 1), |
| 2246 CreateMockWrite(*rst, 3), |
| 2307 }; | 2247 }; |
| 2308 | 2248 |
| 2309 MockRead reads[] = { | 2249 MockRead reads[] = { |
| 2310 MockRead(ASYNC, 0, 3) // EOF | 2250 MockRead(ASYNC, 0, 2) // EOF |
| 2311 }; | 2251 }; |
| 2312 DeterministicSocketData data(reads, arraysize(reads), | 2252 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); |
| 2313 writes, arraysize(writes)); | 2253 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 2314 data.set_connect_data(connect_data); | |
| 2315 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 2316 | 2254 |
| 2317 CreateDeterministicNetworkSession(); | 2255 CreateNetworkSession(); |
| 2318 | 2256 |
| 2319 base::WeakPtr<SpdySession> session = | 2257 base::WeakPtr<SpdySession> session = |
| 2320 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 2258 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 2321 | 2259 |
| 2322 GURL url(kDefaultURL); | 2260 GURL url(kDefaultURL); |
| 2323 base::WeakPtr<SpdyStream> spdy_stream = | 2261 base::WeakPtr<SpdyStream> spdy_stream = |
| 2324 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, | 2262 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, |
| 2325 session, url, MEDIUM, BoundNetLog()); | 2263 session, url, MEDIUM, BoundNetLog()); |
| 2326 ASSERT_TRUE(spdy_stream.get() != NULL); | 2264 ASSERT_TRUE(spdy_stream.get() != nullptr); |
| 2327 EXPECT_EQ(0u, spdy_stream->stream_id()); | 2265 EXPECT_EQ(0u, spdy_stream->stream_id()); |
| 2328 | 2266 |
| 2329 SessionClosingDelegate delegate(spdy_stream, session); | 2267 SessionClosingDelegate delegate(spdy_stream, session); |
| 2330 spdy_stream->SetDelegate(&delegate); | 2268 spdy_stream->SetDelegate(&delegate); |
| 2331 | 2269 |
| 2332 scoped_ptr<SpdyHeaderBlock> headers( | 2270 scoped_ptr<SpdyHeaderBlock> headers( |
| 2333 spdy_util_.ConstructGetHeaderBlock(url.spec())); | 2271 spdy_util_.ConstructGetHeaderBlock(url.spec())); |
| 2334 spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); | 2272 spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); |
| 2335 EXPECT_TRUE(spdy_stream->HasUrlFromHeaders()); | 2273 EXPECT_TRUE(spdy_stream->HasUrlFromHeaders()); |
| 2336 | 2274 |
| 2337 EXPECT_EQ(0u, spdy_stream->stream_id()); | 2275 EXPECT_EQ(0u, spdy_stream->stream_id()); |
| 2338 | 2276 |
| 2339 data.RunFor(1); | 2277 base::RunLoop().RunUntilIdle(); |
| 2340 | 2278 |
| 2341 EXPECT_EQ(1u, spdy_stream->stream_id()); | 2279 EXPECT_EQ(1u, spdy_stream->stream_id()); |
| 2342 | 2280 |
| 2343 // Ensure we don't crash while closing the stream (which closes the | 2281 // Ensure we don't crash while closing the stream (which closes the |
| 2344 // session). | 2282 // session). |
| 2345 spdy_stream->Cancel(); | 2283 spdy_stream->Cancel(); |
| 2346 | 2284 |
| 2347 EXPECT_EQ(NULL, spdy_stream.get()); | 2285 EXPECT_FALSE(spdy_stream); |
| 2348 EXPECT_TRUE(delegate.StreamIsClosed()); | 2286 EXPECT_TRUE(delegate.StreamIsClosed()); |
| 2349 | 2287 |
| 2350 data.RunFor(2); // Write the RST_STREAM & GOAWAY. | 2288 // Write the RST_STREAM & GOAWAY. |
| 2351 base::MessageLoop::current()->RunUntilIdle(); | 2289 base::RunLoop().RunUntilIdle(); |
| 2352 EXPECT_TRUE(session == NULL); | 2290 EXPECT_TRUE(data.AllWriteDataConsumed()); |
| 2291 EXPECT_TRUE(data.AllReadDataConsumed()); |
| 2353 } | 2292 } |
| 2354 | 2293 |
| 2355 TEST_P(SpdySessionTest, VerifyDomainAuthentication) { | 2294 TEST_P(SpdySessionTest, VerifyDomainAuthentication) { |
| 2356 session_deps_.host_resolver->set_synchronous_mode(true); | 2295 session_deps_.host_resolver->set_synchronous_mode(true); |
| 2357 | 2296 |
| 2358 MockConnect connect_data(SYNCHRONOUS, OK); | 2297 SequencedSocketData data(nullptr, 0, nullptr, 0); |
| 2359 | 2298 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 2360 // No actual data will be sent. | |
| 2361 MockWrite writes[] = { | |
| 2362 MockWrite(ASYNC, 0, 1) // EOF | |
| 2363 }; | |
| 2364 | |
| 2365 MockRead reads[] = { | |
| 2366 MockRead(ASYNC, 0, 0) // EOF | |
| 2367 }; | |
| 2368 DeterministicSocketData data(reads, arraysize(reads), | |
| 2369 writes, arraysize(writes)); | |
| 2370 data.set_connect_data(connect_data); | |
| 2371 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 2372 | 2299 |
| 2373 // Load a cert that is valid for: | 2300 // Load a cert that is valid for: |
| 2374 // www.example.org | 2301 // www.example.org |
| 2375 // mail.example.org | 2302 // mail.example.org |
| 2376 // www.example.com | 2303 // www.example.com |
| 2377 base::FilePath certs_dir = GetTestCertsDirectory(); | 2304 base::FilePath certs_dir = GetTestCertsDirectory(); |
| 2378 scoped_refptr<X509Certificate> test_cert( | 2305 scoped_refptr<X509Certificate> test_cert( |
| 2379 ImportCertFromFile(certs_dir, "spdy_pooling.pem")); | 2306 ImportCertFromFile(certs_dir, "spdy_pooling.pem")); |
| 2380 ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert.get()); | 2307 ASSERT_NE(static_cast<X509Certificate*>(nullptr), test_cert.get()); |
| 2381 | 2308 |
| 2382 SSLSocketDataProvider ssl(SYNCHRONOUS, OK); | 2309 SSLSocketDataProvider ssl(SYNCHRONOUS, OK); |
| 2383 ssl.cert = test_cert; | 2310 ssl.cert = test_cert; |
| 2384 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); | 2311 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); |
| 2385 | 2312 |
| 2386 CreateDeterministicNetworkSession(); | 2313 CreateNetworkSession(); |
| 2387 | 2314 |
| 2388 base::WeakPtr<SpdySession> session = | 2315 base::WeakPtr<SpdySession> session = |
| 2389 CreateSecureSpdySession(http_session_, key_, BoundNetLog()); | 2316 CreateSecureSpdySession(http_session_, key_, BoundNetLog()); |
| 2390 | 2317 |
| 2391 EXPECT_TRUE(session->VerifyDomainAuthentication("www.example.org")); | 2318 EXPECT_TRUE(session->VerifyDomainAuthentication("www.example.org")); |
| 2392 EXPECT_TRUE(session->VerifyDomainAuthentication("mail.example.org")); | 2319 EXPECT_TRUE(session->VerifyDomainAuthentication("mail.example.org")); |
| 2393 EXPECT_TRUE(session->VerifyDomainAuthentication("mail.example.com")); | 2320 EXPECT_TRUE(session->VerifyDomainAuthentication("mail.example.com")); |
| 2394 EXPECT_FALSE(session->VerifyDomainAuthentication("mail.google.com")); | 2321 EXPECT_FALSE(session->VerifyDomainAuthentication("mail.google.com")); |
| 2395 } | 2322 } |
| 2396 | 2323 |
| 2397 TEST_P(SpdySessionTest, ConnectionPooledWithTlsChannelId) { | 2324 TEST_P(SpdySessionTest, ConnectionPooledWithTlsChannelId) { |
| 2398 session_deps_.host_resolver->set_synchronous_mode(true); | 2325 session_deps_.host_resolver->set_synchronous_mode(true); |
| 2399 | 2326 |
| 2400 MockConnect connect_data(SYNCHRONOUS, OK); | 2327 SequencedSocketData data(nullptr, 0, nullptr, 0); |
| 2401 | 2328 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 2402 // No actual data will be sent. | |
| 2403 MockWrite writes[] = { | |
| 2404 MockWrite(ASYNC, 0, 1) // EOF | |
| 2405 }; | |
| 2406 | |
| 2407 MockRead reads[] = { | |
| 2408 MockRead(ASYNC, 0, 0) // EOF | |
| 2409 }; | |
| 2410 DeterministicSocketData data(reads, arraysize(reads), | |
| 2411 writes, arraysize(writes)); | |
| 2412 data.set_connect_data(connect_data); | |
| 2413 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 2414 | 2329 |
| 2415 // Load a cert that is valid for: | 2330 // Load a cert that is valid for: |
| 2416 // www.example.org | 2331 // www.example.org |
| 2417 // mail.example.org | 2332 // mail.example.org |
| 2418 // www.example.com | 2333 // www.example.com |
| 2419 base::FilePath certs_dir = GetTestCertsDirectory(); | 2334 base::FilePath certs_dir = GetTestCertsDirectory(); |
| 2420 scoped_refptr<X509Certificate> test_cert( | 2335 scoped_refptr<X509Certificate> test_cert( |
| 2421 ImportCertFromFile(certs_dir, "spdy_pooling.pem")); | 2336 ImportCertFromFile(certs_dir, "spdy_pooling.pem")); |
| 2422 ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert.get()); | 2337 ASSERT_NE(static_cast<X509Certificate*>(nullptr), test_cert.get()); |
| 2423 | 2338 |
| 2424 SSLSocketDataProvider ssl(SYNCHRONOUS, OK); | 2339 SSLSocketDataProvider ssl(SYNCHRONOUS, OK); |
| 2425 ssl.channel_id_sent = true; | 2340 ssl.channel_id_sent = true; |
| 2426 ssl.cert = test_cert; | 2341 ssl.cert = test_cert; |
| 2427 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl); | 2342 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); |
| 2428 | 2343 |
| 2429 CreateDeterministicNetworkSession(); | 2344 CreateNetworkSession(); |
| 2430 | 2345 |
| 2431 base::WeakPtr<SpdySession> session = | 2346 base::WeakPtr<SpdySession> session = |
| 2432 CreateSecureSpdySession(http_session_, key_, BoundNetLog()); | 2347 CreateSecureSpdySession(http_session_, key_, BoundNetLog()); |
| 2433 | 2348 |
| 2434 EXPECT_TRUE(session->VerifyDomainAuthentication("www.example.org")); | 2349 EXPECT_TRUE(session->VerifyDomainAuthentication("www.example.org")); |
| 2435 EXPECT_TRUE(session->VerifyDomainAuthentication("mail.example.org")); | 2350 EXPECT_TRUE(session->VerifyDomainAuthentication("mail.example.org")); |
| 2436 EXPECT_FALSE(session->VerifyDomainAuthentication("mail.example.com")); | 2351 EXPECT_FALSE(session->VerifyDomainAuthentication("mail.example.com")); |
| 2437 EXPECT_FALSE(session->VerifyDomainAuthentication("mail.google.com")); | 2352 EXPECT_FALSE(session->VerifyDomainAuthentication("mail.google.com")); |
| 2438 } | 2353 } |
| 2439 | 2354 |
| 2440 TEST_P(SpdySessionTest, CloseTwoStalledCreateStream) { | 2355 TEST_P(SpdySessionTest, CloseTwoStalledCreateStream) { |
| 2441 // TODO(rtenneti): Define a helper class/methods and move the common code in | 2356 // TODO(rtenneti): Define a helper class/methods and move the common code in |
| 2442 // this file. | 2357 // this file. |
| 2443 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 2444 | |
| 2445 SettingsMap new_settings; | 2358 SettingsMap new_settings; |
| 2446 const SpdySettingsIds kSpdySettingsIds1 = SETTINGS_MAX_CONCURRENT_STREAMS; | 2359 const SpdySettingsIds kSpdySettingsIds1 = SETTINGS_MAX_CONCURRENT_STREAMS; |
| 2447 const uint32 max_concurrent_streams = 1; | 2360 const uint32 max_concurrent_streams = 1; |
| 2448 new_settings[kSpdySettingsIds1] = | 2361 new_settings[kSpdySettingsIds1] = |
| 2449 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams); | 2362 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams); |
| 2450 | 2363 |
| 2451 scoped_ptr<SpdyFrame> settings_ack(spdy_util_.ConstructSpdySettingsAck()); | 2364 scoped_ptr<SpdyFrame> settings_ack(spdy_util_.ConstructSpdySettingsAck()); |
| 2452 scoped_ptr<SpdyFrame> req1( | 2365 scoped_ptr<SpdyFrame> req1( |
| 2453 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); | 2366 spdy_util_.ConstructSpdyGet(nullptr, 0, false, 1, LOWEST, true)); |
| 2454 scoped_ptr<SpdyFrame> req2( | 2367 scoped_ptr<SpdyFrame> req2( |
| 2455 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true)); | 2368 spdy_util_.ConstructSpdyGet(nullptr, 0, false, 3, LOWEST, true)); |
| 2456 scoped_ptr<SpdyFrame> req3( | 2369 scoped_ptr<SpdyFrame> req3( |
| 2457 spdy_util_.ConstructSpdyGet(NULL, 0, false, 5, LOWEST, true)); | 2370 spdy_util_.ConstructSpdyGet(nullptr, 0, false, 5, LOWEST, true)); |
| 2458 MockWrite writes[] = { | 2371 MockWrite writes[] = { |
| 2459 CreateMockWrite(*settings_ack, 1), | 2372 CreateMockWrite(*settings_ack, 1), |
| 2460 CreateMockWrite(*req1, 2), | 2373 CreateMockWrite(*req1, 2), |
| 2461 CreateMockWrite(*req2, 5), | 2374 CreateMockWrite(*req2, 5), |
| 2462 CreateMockWrite(*req3, 8), | 2375 CreateMockWrite(*req3, 8), |
| 2463 }; | 2376 }; |
| 2464 | 2377 |
| 2465 // Set up the socket so we read a SETTINGS frame that sets max concurrent | 2378 // Set up the socket so we read a SETTINGS frame that sets max concurrent |
| 2466 // streams to 1. | 2379 // streams to 1. |
| 2467 scoped_ptr<SpdyFrame> settings_frame( | 2380 scoped_ptr<SpdyFrame> settings_frame( |
| 2468 spdy_util_.ConstructSpdySettings(new_settings)); | 2381 spdy_util_.ConstructSpdySettings(new_settings)); |
| 2469 | 2382 |
| 2470 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); | 2383 scoped_ptr<SpdyFrame> resp1( |
| 2384 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); |
| 2471 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true)); | 2385 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true)); |
| 2472 | 2386 |
| 2473 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); | 2387 scoped_ptr<SpdyFrame> resp2( |
| 2388 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 3)); |
| 2474 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true)); | 2389 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true)); |
| 2475 | 2390 |
| 2476 scoped_ptr<SpdyFrame> resp3(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 5)); | 2391 scoped_ptr<SpdyFrame> resp3( |
| 2392 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 5)); |
| 2477 scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(5, true)); | 2393 scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(5, true)); |
| 2478 | 2394 |
| 2479 MockRead reads[] = { | 2395 MockRead reads[] = { |
| 2480 CreateMockRead(*settings_frame), | 2396 CreateMockRead(*settings_frame, 0), |
| 2481 CreateMockRead(*resp1, 3), | 2397 CreateMockRead(*resp1, 3), |
| 2482 CreateMockRead(*body1, 4), | 2398 CreateMockRead(*body1, 4), |
| 2483 CreateMockRead(*resp2, 6), | 2399 CreateMockRead(*resp2, 6), |
| 2484 CreateMockRead(*body2, 7), | 2400 CreateMockRead(*body2, 7), |
| 2485 CreateMockRead(*resp3, 9), | 2401 CreateMockRead(*resp3, 9), |
| 2486 CreateMockRead(*body3, 10), | 2402 CreateMockRead(*body3, 10), |
| 2487 MockRead(ASYNC, 0, 11) // EOF | 2403 MockRead(ASYNC, ERR_IO_PENDING, 11), |
| 2404 MockRead(ASYNC, 0, 12) // EOF |
| 2488 }; | 2405 }; |
| 2489 | 2406 |
| 2490 DeterministicSocketData data(reads, arraysize(reads), | 2407 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); |
| 2491 writes, arraysize(writes)); | 2408 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 2492 data.set_connect_data(connect_data); | |
| 2493 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 2494 | 2409 |
| 2495 CreateDeterministicNetworkSession(); | 2410 CreateNetworkSession(); |
| 2496 | 2411 |
| 2497 base::WeakPtr<SpdySession> session = | 2412 base::WeakPtr<SpdySession> session = |
| 2498 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 2413 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 2499 | 2414 |
| 2500 // Read the settings frame. | 2415 // Read the settings frame. |
| 2501 data.RunFor(1); | 2416 base::RunLoop().RunUntilIdle(); |
| 2502 | 2417 |
| 2503 GURL url1(kDefaultURL); | 2418 GURL url1(kDefaultURL); |
| 2504 base::WeakPtr<SpdyStream> spdy_stream1 = | 2419 base::WeakPtr<SpdyStream> spdy_stream1 = |
| 2505 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, | 2420 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, |
| 2506 session, url1, LOWEST, BoundNetLog()); | 2421 session, url1, LOWEST, BoundNetLog()); |
| 2507 ASSERT_TRUE(spdy_stream1.get() != NULL); | 2422 ASSERT_TRUE(spdy_stream1.get() != nullptr); |
| 2508 EXPECT_EQ(0u, spdy_stream1->stream_id()); | 2423 EXPECT_EQ(0u, spdy_stream1->stream_id()); |
| 2509 test::StreamDelegateDoNothing delegate1(spdy_stream1); | 2424 test::StreamDelegateDoNothing delegate1(spdy_stream1); |
| 2510 spdy_stream1->SetDelegate(&delegate1); | 2425 spdy_stream1->SetDelegate(&delegate1); |
| 2511 | 2426 |
| 2512 TestCompletionCallback callback2; | 2427 TestCompletionCallback callback2; |
| 2513 GURL url2(kDefaultURL); | 2428 GURL url2(kDefaultURL); |
| 2514 SpdyStreamRequest request2; | 2429 SpdyStreamRequest request2; |
| 2515 ASSERT_EQ(ERR_IO_PENDING, | 2430 ASSERT_EQ(ERR_IO_PENDING, |
| 2516 request2.StartRequest( | 2431 request2.StartRequest( |
| 2517 SPDY_REQUEST_RESPONSE_STREAM, | 2432 SPDY_REQUEST_RESPONSE_STREAM, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2529 EXPECT_EQ(1u, session->num_created_streams()); | 2444 EXPECT_EQ(1u, session->num_created_streams()); |
| 2530 EXPECT_EQ(2u, session->pending_create_stream_queue_size(LOWEST)); | 2445 EXPECT_EQ(2u, session->pending_create_stream_queue_size(LOWEST)); |
| 2531 | 2446 |
| 2532 scoped_ptr<SpdyHeaderBlock> headers( | 2447 scoped_ptr<SpdyHeaderBlock> headers( |
| 2533 spdy_util_.ConstructGetHeaderBlock(url1.spec())); | 2448 spdy_util_.ConstructGetHeaderBlock(url1.spec())); |
| 2534 spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); | 2449 spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); |
| 2535 EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); | 2450 EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); |
| 2536 | 2451 |
| 2537 // Run until 1st stream is activated and then closed. | 2452 // Run until 1st stream is activated and then closed. |
| 2538 EXPECT_EQ(0u, delegate1.stream_id()); | 2453 EXPECT_EQ(0u, delegate1.stream_id()); |
| 2539 data.RunFor(4); | 2454 base::RunLoop().RunUntilIdle(); |
| 2540 EXPECT_EQ(NULL, spdy_stream1.get()); | 2455 EXPECT_FALSE(spdy_stream1); |
| 2541 EXPECT_EQ(1u, delegate1.stream_id()); | 2456 EXPECT_EQ(1u, delegate1.stream_id()); |
| 2542 | 2457 |
| 2543 EXPECT_EQ(0u, session->num_active_streams()); | 2458 EXPECT_EQ(0u, session->num_active_streams()); |
| 2544 EXPECT_EQ(0u, session->num_created_streams()); | |
| 2545 EXPECT_EQ(1u, session->pending_create_stream_queue_size(LOWEST)); | 2459 EXPECT_EQ(1u, session->pending_create_stream_queue_size(LOWEST)); |
| 2546 | 2460 |
| 2547 // Pump loop for SpdySession::ProcessPendingStreamRequests() to | 2461 // Pump loop for SpdySession::ProcessPendingStreamRequests() to |
| 2548 // create the 2nd stream. | 2462 // create the 2nd stream. |
| 2549 base::MessageLoop::current()->RunUntilIdle(); | 2463 base::RunLoop().RunUntilIdle(); |
| 2550 | 2464 |
| 2551 EXPECT_EQ(0u, session->num_active_streams()); | 2465 EXPECT_EQ(0u, session->num_active_streams()); |
| 2552 EXPECT_EQ(1u, session->num_created_streams()); | 2466 EXPECT_EQ(1u, session->num_created_streams()); |
| 2553 EXPECT_EQ(1u, session->pending_create_stream_queue_size(LOWEST)); | 2467 EXPECT_EQ(1u, session->pending_create_stream_queue_size(LOWEST)); |
| 2554 | 2468 |
| 2555 base::WeakPtr<SpdyStream> stream2 = request2.ReleaseStream(); | 2469 base::WeakPtr<SpdyStream> stream2 = request2.ReleaseStream(); |
| 2556 test::StreamDelegateDoNothing delegate2(stream2); | 2470 test::StreamDelegateDoNothing delegate2(stream2); |
| 2557 stream2->SetDelegate(&delegate2); | 2471 stream2->SetDelegate(&delegate2); |
| 2558 scoped_ptr<SpdyHeaderBlock> headers2( | 2472 scoped_ptr<SpdyHeaderBlock> headers2( |
| 2559 spdy_util_.ConstructGetHeaderBlock(url2.spec())); | 2473 spdy_util_.ConstructGetHeaderBlock(url2.spec())); |
| 2560 stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND); | 2474 stream2->SendRequestHeaders(headers2.Pass(), NO_MORE_DATA_TO_SEND); |
| 2561 EXPECT_TRUE(stream2->HasUrlFromHeaders()); | 2475 EXPECT_TRUE(stream2->HasUrlFromHeaders()); |
| 2562 | 2476 |
| 2563 // Run until 2nd stream is activated and then closed. | 2477 // Run until 2nd stream is activated and then closed. |
| 2564 EXPECT_EQ(0u, delegate2.stream_id()); | 2478 EXPECT_EQ(0u, delegate2.stream_id()); |
| 2565 data.RunFor(3); | 2479 base::RunLoop().RunUntilIdle(); |
| 2566 EXPECT_EQ(NULL, stream2.get()); | 2480 EXPECT_FALSE(stream2); |
| 2567 EXPECT_EQ(3u, delegate2.stream_id()); | 2481 EXPECT_EQ(3u, delegate2.stream_id()); |
| 2568 | 2482 |
| 2569 EXPECT_EQ(0u, session->num_active_streams()); | 2483 EXPECT_EQ(0u, session->num_active_streams()); |
| 2570 EXPECT_EQ(0u, session->num_created_streams()); | |
| 2571 EXPECT_EQ(0u, session->pending_create_stream_queue_size(LOWEST)); | 2484 EXPECT_EQ(0u, session->pending_create_stream_queue_size(LOWEST)); |
| 2572 | 2485 |
| 2573 // Pump loop for SpdySession::ProcessPendingStreamRequests() to | 2486 // Pump loop for SpdySession::ProcessPendingStreamRequests() to |
| 2574 // create the 3rd stream. | 2487 // create the 3rd stream. |
| 2575 base::MessageLoop::current()->RunUntilIdle(); | 2488 base::RunLoop().RunUntilIdle(); |
| 2576 | 2489 |
| 2577 EXPECT_EQ(0u, session->num_active_streams()); | 2490 EXPECT_EQ(0u, session->num_active_streams()); |
| 2578 EXPECT_EQ(1u, session->num_created_streams()); | 2491 EXPECT_EQ(1u, session->num_created_streams()); |
| 2579 EXPECT_EQ(0u, session->pending_create_stream_queue_size(LOWEST)); | 2492 EXPECT_EQ(0u, session->pending_create_stream_queue_size(LOWEST)); |
| 2580 | 2493 |
| 2581 base::WeakPtr<SpdyStream> stream3 = request3.ReleaseStream(); | 2494 base::WeakPtr<SpdyStream> stream3 = request3.ReleaseStream(); |
| 2582 test::StreamDelegateDoNothing delegate3(stream3); | 2495 test::StreamDelegateDoNothing delegate3(stream3); |
| 2583 stream3->SetDelegate(&delegate3); | 2496 stream3->SetDelegate(&delegate3); |
| 2584 scoped_ptr<SpdyHeaderBlock> headers3( | 2497 scoped_ptr<SpdyHeaderBlock> headers3( |
| 2585 spdy_util_.ConstructGetHeaderBlock(url3.spec())); | 2498 spdy_util_.ConstructGetHeaderBlock(url3.spec())); |
| 2586 stream3->SendRequestHeaders(headers3.Pass(), NO_MORE_DATA_TO_SEND); | 2499 stream3->SendRequestHeaders(headers3.Pass(), NO_MORE_DATA_TO_SEND); |
| 2587 EXPECT_TRUE(stream3->HasUrlFromHeaders()); | 2500 EXPECT_TRUE(stream3->HasUrlFromHeaders()); |
| 2588 | 2501 |
| 2589 // Run until 2nd stream is activated and then closed. | 2502 // Run until 2nd stream is activated and then closed. |
| 2590 EXPECT_EQ(0u, delegate3.stream_id()); | 2503 EXPECT_EQ(0u, delegate3.stream_id()); |
| 2591 data.RunFor(3); | 2504 base::RunLoop().RunUntilIdle(); |
| 2592 EXPECT_EQ(NULL, stream3.get()); | 2505 EXPECT_FALSE(stream3); |
| 2593 EXPECT_EQ(5u, delegate3.stream_id()); | 2506 EXPECT_EQ(5u, delegate3.stream_id()); |
| 2594 | 2507 |
| 2595 EXPECT_EQ(0u, session->num_active_streams()); | 2508 EXPECT_EQ(0u, session->num_active_streams()); |
| 2596 EXPECT_EQ(0u, session->num_created_streams()); | 2509 EXPECT_EQ(0u, session->num_created_streams()); |
| 2597 EXPECT_EQ(0u, session->pending_create_stream_queue_size(LOWEST)); | 2510 EXPECT_EQ(0u, session->pending_create_stream_queue_size(LOWEST)); |
| 2598 | 2511 |
| 2599 data.RunFor(1); | 2512 data.CompleteRead(); |
| 2513 base::RunLoop().RunUntilIdle(); |
| 2600 } | 2514 } |
| 2601 | 2515 |
| 2602 TEST_P(SpdySessionTest, CancelTwoStalledCreateStream) { | 2516 TEST_P(SpdySessionTest, CancelTwoStalledCreateStream) { |
| 2603 session_deps_.host_resolver->set_synchronous_mode(true); | 2517 session_deps_.host_resolver->set_synchronous_mode(true); |
| 2604 | 2518 |
| 2605 MockRead reads[] = { | 2519 MockRead reads[] = { |
| 2606 MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. | 2520 MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. |
| 2607 }; | 2521 }; |
| 2608 | 2522 |
| 2609 StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0); | 2523 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0); |
| 2610 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 2611 | |
| 2612 data.set_connect_data(connect_data); | |
| 2613 session_deps_.socket_factory->AddSocketDataProvider(&data); | 2524 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 2614 | 2525 |
| 2615 CreateNetworkSession(); | 2526 CreateNetworkSession(); |
| 2616 | 2527 |
| 2617 base::WeakPtr<SpdySession> session = | 2528 base::WeakPtr<SpdySession> session = |
| 2618 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 2529 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 2619 | 2530 |
| 2620 // Leave room for only one more stream to be created. | 2531 // Leave room for only one more stream to be created. |
| 2621 for (size_t i = 0; i < kInitialMaxConcurrentStreams - 1; ++i) { | 2532 for (size_t i = 0; i < kInitialMaxConcurrentStreams - 1; ++i) { |
| 2622 base::WeakPtr<SpdyStream> spdy_stream = | 2533 base::WeakPtr<SpdyStream> spdy_stream = |
| 2623 CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, | 2534 CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, |
| 2624 session, test_url_, MEDIUM, BoundNetLog()); | 2535 session, test_url_, MEDIUM, BoundNetLog()); |
| 2625 ASSERT_TRUE(spdy_stream != NULL); | 2536 ASSERT_TRUE(spdy_stream != nullptr); |
| 2626 } | 2537 } |
| 2627 | 2538 |
| 2628 GURL url1(kDefaultURL); | 2539 GURL url1(kDefaultURL); |
| 2629 base::WeakPtr<SpdyStream> spdy_stream1 = | 2540 base::WeakPtr<SpdyStream> spdy_stream1 = |
| 2630 CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, | 2541 CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, |
| 2631 session, url1, LOWEST, BoundNetLog()); | 2542 session, url1, LOWEST, BoundNetLog()); |
| 2632 ASSERT_TRUE(spdy_stream1.get() != NULL); | 2543 ASSERT_TRUE(spdy_stream1.get() != nullptr); |
| 2633 EXPECT_EQ(0u, spdy_stream1->stream_id()); | 2544 EXPECT_EQ(0u, spdy_stream1->stream_id()); |
| 2634 | 2545 |
| 2635 TestCompletionCallback callback2; | 2546 TestCompletionCallback callback2; |
| 2636 GURL url2(kDefaultURL); | 2547 GURL url2(kDefaultURL); |
| 2637 SpdyStreamRequest request2; | 2548 SpdyStreamRequest request2; |
| 2638 ASSERT_EQ(ERR_IO_PENDING, | 2549 ASSERT_EQ(ERR_IO_PENDING, |
| 2639 request2.StartRequest( | 2550 request2.StartRequest( |
| 2640 SPDY_BIDIRECTIONAL_STREAM, session, url2, LOWEST, BoundNetLog(), | 2551 SPDY_BIDIRECTIONAL_STREAM, session, url2, LOWEST, BoundNetLog(), |
| 2641 callback2.callback())); | 2552 callback2.callback())); |
| 2642 | 2553 |
| 2643 TestCompletionCallback callback3; | 2554 TestCompletionCallback callback3; |
| 2644 GURL url3(kDefaultURL); | 2555 GURL url3(kDefaultURL); |
| 2645 SpdyStreamRequest request3; | 2556 SpdyStreamRequest request3; |
| 2646 ASSERT_EQ(ERR_IO_PENDING, | 2557 ASSERT_EQ(ERR_IO_PENDING, |
| 2647 request3.StartRequest( | 2558 request3.StartRequest( |
| 2648 SPDY_BIDIRECTIONAL_STREAM, session, url3, LOWEST, BoundNetLog(), | 2559 SPDY_BIDIRECTIONAL_STREAM, session, url3, LOWEST, BoundNetLog(), |
| 2649 callback3.callback())); | 2560 callback3.callback())); |
| 2650 | 2561 |
| 2651 EXPECT_EQ(0u, session->num_active_streams()); | 2562 EXPECT_EQ(0u, session->num_active_streams()); |
| 2652 EXPECT_EQ(kInitialMaxConcurrentStreams, session->num_created_streams()); | 2563 EXPECT_EQ(kInitialMaxConcurrentStreams, session->num_created_streams()); |
| 2653 EXPECT_EQ(2u, session->pending_create_stream_queue_size(LOWEST)); | 2564 EXPECT_EQ(2u, session->pending_create_stream_queue_size(LOWEST)); |
| 2654 | 2565 |
| 2655 // Cancel the first stream; this will allow the second stream to be created. | 2566 // Cancel the first stream; this will allow the second stream to be created. |
| 2656 EXPECT_TRUE(spdy_stream1.get() != NULL); | 2567 EXPECT_TRUE(spdy_stream1); |
| 2657 spdy_stream1->Cancel(); | 2568 spdy_stream1->Cancel(); |
| 2658 EXPECT_EQ(NULL, spdy_stream1.get()); | 2569 EXPECT_FALSE(spdy_stream1); |
| 2659 | 2570 |
| 2660 EXPECT_EQ(OK, callback2.WaitForResult()); | 2571 EXPECT_EQ(OK, callback2.WaitForResult()); |
| 2661 EXPECT_EQ(0u, session->num_active_streams()); | 2572 EXPECT_EQ(0u, session->num_active_streams()); |
| 2662 EXPECT_EQ(kInitialMaxConcurrentStreams, session->num_created_streams()); | 2573 EXPECT_EQ(kInitialMaxConcurrentStreams, session->num_created_streams()); |
| 2663 EXPECT_EQ(1u, session->pending_create_stream_queue_size(LOWEST)); | 2574 EXPECT_EQ(1u, session->pending_create_stream_queue_size(LOWEST)); |
| 2664 | 2575 |
| 2665 // Cancel the second stream; this will allow the third stream to be created. | 2576 // Cancel the second stream; this will allow the third stream to be created. |
| 2666 base::WeakPtr<SpdyStream> spdy_stream2 = request2.ReleaseStream(); | 2577 base::WeakPtr<SpdyStream> spdy_stream2 = request2.ReleaseStream(); |
| 2667 spdy_stream2->Cancel(); | 2578 spdy_stream2->Cancel(); |
| 2668 EXPECT_EQ(NULL, spdy_stream2.get()); | 2579 EXPECT_FALSE(spdy_stream2); |
| 2669 | 2580 |
| 2670 EXPECT_EQ(OK, callback3.WaitForResult()); | 2581 EXPECT_EQ(OK, callback3.WaitForResult()); |
| 2671 EXPECT_EQ(0u, session->num_active_streams()); | 2582 EXPECT_EQ(0u, session->num_active_streams()); |
| 2672 EXPECT_EQ(kInitialMaxConcurrentStreams, session->num_created_streams()); | 2583 EXPECT_EQ(kInitialMaxConcurrentStreams, session->num_created_streams()); |
| 2673 EXPECT_EQ(0u, session->pending_create_stream_queue_size(LOWEST)); | 2584 EXPECT_EQ(0u, session->pending_create_stream_queue_size(LOWEST)); |
| 2674 | 2585 |
| 2675 // Cancel the third stream. | 2586 // Cancel the third stream. |
| 2676 base::WeakPtr<SpdyStream> spdy_stream3 = request3.ReleaseStream(); | 2587 base::WeakPtr<SpdyStream> spdy_stream3 = request3.ReleaseStream(); |
| 2677 spdy_stream3->Cancel(); | 2588 spdy_stream3->Cancel(); |
| 2678 EXPECT_EQ(NULL, spdy_stream3.get()); | 2589 EXPECT_FALSE(spdy_stream3); |
| 2679 EXPECT_EQ(0u, session->num_active_streams()); | 2590 EXPECT_EQ(0u, session->num_active_streams()); |
| 2680 EXPECT_EQ(kInitialMaxConcurrentStreams - 1, session->num_created_streams()); | 2591 EXPECT_EQ(kInitialMaxConcurrentStreams - 1, session->num_created_streams()); |
| 2681 EXPECT_EQ(0u, session->pending_create_stream_queue_size(LOWEST)); | 2592 EXPECT_EQ(0u, session->pending_create_stream_queue_size(LOWEST)); |
| 2682 } | 2593 } |
| 2683 | 2594 |
| 2684 // Test that SpdySession::DoReadLoop reads data from the socket | 2595 // Test that SpdySession::DoReadLoop reads data from the socket |
| 2685 // without yielding. This test makes 32k - 1 bytes of data available | 2596 // without yielding. This test makes 32k - 1 bytes of data available |
| 2686 // on the socket for reading. It then verifies that it has read all | 2597 // on the socket for reading. It then verifies that it has read all |
| 2687 // the available data without yielding. | 2598 // the available data without yielding. |
| 2688 TEST_P(SpdySessionTest, ReadDataWithoutYielding) { | 2599 TEST_P(SpdySessionTest, ReadDataWithoutYielding) { |
| 2689 MockConnect connect_data(SYNCHRONOUS, OK); | 2600 session_deps_.host_resolver->set_synchronous_mode(true); |
| 2601 |
| 2690 BufferedSpdyFramer framer(spdy_util_.spdy_version(), false); | 2602 BufferedSpdyFramer framer(spdy_util_.spdy_version(), false); |
| 2691 | 2603 |
| 2692 scoped_ptr<SpdyFrame> req1( | 2604 scoped_ptr<SpdyFrame> req1( |
| 2693 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); | 2605 spdy_util_.ConstructSpdyGet(nullptr, 0, false, 1, MEDIUM, true)); |
| 2694 MockWrite writes[] = { | 2606 MockWrite writes[] = { |
| 2695 CreateMockWrite(*req1, 0), | 2607 CreateMockWrite(*req1, 0), |
| 2696 }; | 2608 }; |
| 2697 | 2609 |
| 2698 // Build buffer of size kMaxReadBytesWithoutYielding / 4 | 2610 // Build buffer of size kMaxReadBytesWithoutYielding / 4 |
| 2699 // (-spdy_data_frame_size). | 2611 // (-spdy_data_frame_size). |
| 2700 ASSERT_EQ(32 * 1024, kMaxReadBytesWithoutYielding); | 2612 ASSERT_EQ(32 * 1024, kMaxReadBytesWithoutYielding); |
| 2701 const int kPayloadSize = | 2613 const int kPayloadSize = |
| 2702 kMaxReadBytesWithoutYielding / 4 - framer.GetControlFrameHeaderSize(); | 2614 kMaxReadBytesWithoutYielding / 4 - framer.GetControlFrameHeaderSize(); |
| 2703 TestDataStream test_stream; | 2615 TestDataStream test_stream; |
| 2704 scoped_refptr<IOBuffer> payload(new IOBuffer(kPayloadSize)); | 2616 scoped_refptr<IOBuffer> payload(new IOBuffer(kPayloadSize)); |
| 2705 char* payload_data = payload->data(); | 2617 char* payload_data = payload->data(); |
| 2706 test_stream.GetBytes(payload_data, kPayloadSize); | 2618 test_stream.GetBytes(payload_data, kPayloadSize); |
| 2707 | 2619 |
| 2708 scoped_ptr<SpdyFrame> partial_data_frame( | 2620 scoped_ptr<SpdyFrame> partial_data_frame( |
| 2709 framer.CreateDataFrame(1, payload_data, kPayloadSize, DATA_FLAG_NONE)); | 2621 framer.CreateDataFrame(1, payload_data, kPayloadSize, DATA_FLAG_NONE)); |
| 2710 scoped_ptr<SpdyFrame> finish_data_frame( | 2622 scoped_ptr<SpdyFrame> finish_data_frame( |
| 2711 framer.CreateDataFrame(1, payload_data, kPayloadSize - 1, DATA_FLAG_FIN)); | 2623 framer.CreateDataFrame(1, payload_data, kPayloadSize - 1, DATA_FLAG_FIN)); |
| 2712 | 2624 |
| 2713 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); | 2625 scoped_ptr<SpdyFrame> resp1( |
| 2626 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); |
| 2714 | 2627 |
| 2715 // Write 1 byte less than kMaxReadBytes to check that DoRead reads up to 32k | 2628 // Write 1 byte less than kMaxReadBytes to check that DoRead reads up to 32k |
| 2716 // bytes. | 2629 // bytes. |
| 2717 MockRead reads[] = { | 2630 MockRead reads[] = { |
| 2718 CreateMockRead(*resp1, 1), | 2631 CreateMockRead(*resp1, 1), |
| 2719 CreateMockRead(*partial_data_frame, 2), | 2632 MockRead(ASYNC, ERR_IO_PENDING, 2), |
| 2720 CreateMockRead(*partial_data_frame, 3, SYNCHRONOUS), | 2633 CreateMockRead(*partial_data_frame, 3), |
| 2721 CreateMockRead(*partial_data_frame, 4, SYNCHRONOUS), | 2634 CreateMockRead(*partial_data_frame, 4, SYNCHRONOUS), |
| 2722 CreateMockRead(*finish_data_frame, 5, SYNCHRONOUS), | 2635 CreateMockRead(*partial_data_frame, 5, SYNCHRONOUS), |
| 2723 MockRead(ASYNC, 0, 6) // EOF | 2636 CreateMockRead(*finish_data_frame, 6, SYNCHRONOUS), |
| 2637 MockRead(ASYNC, 0, 7) // EOF |
| 2724 }; | 2638 }; |
| 2725 | 2639 |
| 2726 // Create SpdySession and SpdyStream and send the request. | 2640 // Create SpdySession and SpdyStream and send the request. |
| 2727 DeterministicSocketData data(reads, arraysize(reads), | 2641 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); |
| 2728 writes, arraysize(writes)); | 2642 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 2729 data.set_connect_data(connect_data); | |
| 2730 session_deps_.host_resolver->set_synchronous_mode(true); | |
| 2731 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 2732 | 2643 |
| 2733 CreateDeterministicNetworkSession(); | 2644 CreateNetworkSession(); |
| 2734 | 2645 |
| 2735 base::WeakPtr<SpdySession> session = | 2646 base::WeakPtr<SpdySession> session = |
| 2736 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 2647 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 2737 | 2648 |
| 2738 GURL url1(kDefaultURL); | 2649 GURL url1(kDefaultURL); |
| 2739 base::WeakPtr<SpdyStream> spdy_stream1 = | 2650 base::WeakPtr<SpdyStream> spdy_stream1 = |
| 2740 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, | 2651 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, |
| 2741 session, url1, MEDIUM, BoundNetLog()); | 2652 session, url1, MEDIUM, BoundNetLog()); |
| 2742 ASSERT_TRUE(spdy_stream1.get() != NULL); | 2653 ASSERT_TRUE(spdy_stream1.get() != nullptr); |
| 2743 EXPECT_EQ(0u, spdy_stream1->stream_id()); | 2654 EXPECT_EQ(0u, spdy_stream1->stream_id()); |
| 2744 test::StreamDelegateDoNothing delegate1(spdy_stream1); | 2655 test::StreamDelegateDoNothing delegate1(spdy_stream1); |
| 2745 spdy_stream1->SetDelegate(&delegate1); | 2656 spdy_stream1->SetDelegate(&delegate1); |
| 2746 | 2657 |
| 2747 scoped_ptr<SpdyHeaderBlock> headers1( | 2658 scoped_ptr<SpdyHeaderBlock> headers1( |
| 2748 spdy_util_.ConstructGetHeaderBlock(url1.spec())); | 2659 spdy_util_.ConstructGetHeaderBlock(url1.spec())); |
| 2749 spdy_stream1->SendRequestHeaders(headers1.Pass(), NO_MORE_DATA_TO_SEND); | 2660 spdy_stream1->SendRequestHeaders(headers1.Pass(), NO_MORE_DATA_TO_SEND); |
| 2750 EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); | 2661 EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); |
| 2751 | 2662 |
| 2752 // Set up the TaskObserver to verify SpdySession::DoReadLoop doesn't | 2663 // Set up the TaskObserver to verify SpdySession::DoReadLoop doesn't |
| 2753 // post a task. | 2664 // post a task. |
| 2754 SpdySessionTestTaskObserver observer("spdy_session.cc", "DoReadLoop"); | 2665 SpdySessionTestTaskObserver observer("spdy_session.cc", "DoReadLoop"); |
| 2755 | 2666 |
| 2756 // Run until 1st read. | 2667 // Run until 1st read. |
| 2757 EXPECT_EQ(0u, delegate1.stream_id()); | 2668 EXPECT_EQ(0u, delegate1.stream_id()); |
| 2758 data.RunFor(2); | 2669 base::RunLoop().RunUntilIdle(); |
| 2759 EXPECT_EQ(1u, delegate1.stream_id()); | 2670 EXPECT_EQ(1u, delegate1.stream_id()); |
| 2760 EXPECT_EQ(0u, observer.executed_count()); | 2671 EXPECT_EQ(0u, observer.executed_count()); |
| 2761 | 2672 |
| 2762 // Read all the data and verify SpdySession::DoReadLoop has not | 2673 // Read all the data and verify SpdySession::DoReadLoop has not |
| 2763 // posted a task. | 2674 // posted a task. |
| 2764 data.RunFor(4); | 2675 data.CompleteRead(); |
| 2765 EXPECT_EQ(NULL, spdy_stream1.get()); | 2676 base::RunLoop().RunUntilIdle(); |
| 2677 EXPECT_FALSE(spdy_stream1); |
| 2766 | 2678 |
| 2767 // Verify task observer's executed_count is zero, which indicates DoRead read | 2679 // Verify task observer's executed_count is zero, which indicates DoRead read |
| 2768 // all the available data. | 2680 // all the available data. |
| 2769 EXPECT_EQ(0u, observer.executed_count()); | 2681 EXPECT_EQ(0u, observer.executed_count()); |
| 2770 EXPECT_TRUE(data.AllWriteDataConsumed()); | 2682 EXPECT_TRUE(data.AllWriteDataConsumed()); |
| 2771 EXPECT_TRUE(data.AllReadDataConsumed()); | 2683 EXPECT_TRUE(data.AllReadDataConsumed()); |
| 2772 } | 2684 } |
| 2773 | 2685 |
| 2774 // Test that SpdySession::DoReadLoop yields while reading the | 2686 // Test that SpdySession::DoReadLoop yields while reading the |
| 2775 // data. This test makes 32k + 1 bytes of data available on the socket | 2687 // data. This test makes 32k + 1 bytes of data available on the socket |
| 2776 // for reading. It then verifies that DoRead has yielded even though | 2688 // for reading. It then verifies that DoRead has yielded even though |
| 2777 // there is data available for it to read (i.e, socket()->Read didn't | 2689 // there is data available for it to read (i.e, socket()->Read didn't |
| 2778 // return ERR_IO_PENDING during socket reads). | 2690 // return ERR_IO_PENDING during socket reads). |
| 2779 TEST_P(SpdySessionTest, TestYieldingDuringReadData) { | 2691 TEST_P(SpdySessionTest, TestYieldingDuringReadData) { |
| 2780 MockConnect connect_data(SYNCHRONOUS, OK); | 2692 session_deps_.host_resolver->set_synchronous_mode(true); |
| 2693 |
| 2781 BufferedSpdyFramer framer(spdy_util_.spdy_version(), false); | 2694 BufferedSpdyFramer framer(spdy_util_.spdy_version(), false); |
| 2782 | 2695 |
| 2783 scoped_ptr<SpdyFrame> req1( | 2696 scoped_ptr<SpdyFrame> req1( |
| 2784 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); | 2697 spdy_util_.ConstructSpdyGet(nullptr, 0, false, 1, MEDIUM, true)); |
| 2785 MockWrite writes[] = { | 2698 MockWrite writes[] = { |
| 2786 CreateMockWrite(*req1, 0), | 2699 CreateMockWrite(*req1, 0), |
| 2787 }; | 2700 }; |
| 2788 | 2701 |
| 2789 // Build buffer of size kMaxReadBytesWithoutYielding / 4 | 2702 // Build buffer of size kMaxReadBytesWithoutYielding / 4 |
| 2790 // (-spdy_data_frame_size). | 2703 // (-spdy_data_frame_size). |
| 2791 ASSERT_EQ(32 * 1024, kMaxReadBytesWithoutYielding); | 2704 ASSERT_EQ(32 * 1024, kMaxReadBytesWithoutYielding); |
| 2792 const int kPayloadSize = | 2705 const int kPayloadSize = |
| 2793 kMaxReadBytesWithoutYielding / 4 - framer.GetControlFrameHeaderSize(); | 2706 kMaxReadBytesWithoutYielding / 4 - framer.GetControlFrameHeaderSize(); |
| 2794 TestDataStream test_stream; | 2707 TestDataStream test_stream; |
| 2795 scoped_refptr<IOBuffer> payload(new IOBuffer(kPayloadSize)); | 2708 scoped_refptr<IOBuffer> payload(new IOBuffer(kPayloadSize)); |
| 2796 char* payload_data = payload->data(); | 2709 char* payload_data = payload->data(); |
| 2797 test_stream.GetBytes(payload_data, kPayloadSize); | 2710 test_stream.GetBytes(payload_data, kPayloadSize); |
| 2798 | 2711 |
| 2799 scoped_ptr<SpdyFrame> partial_data_frame( | 2712 scoped_ptr<SpdyFrame> partial_data_frame( |
| 2800 framer.CreateDataFrame(1, payload_data, kPayloadSize, DATA_FLAG_NONE)); | 2713 framer.CreateDataFrame(1, payload_data, kPayloadSize, DATA_FLAG_NONE)); |
| 2801 scoped_ptr<SpdyFrame> finish_data_frame( | 2714 scoped_ptr<SpdyFrame> finish_data_frame( |
| 2802 framer.CreateDataFrame(1, "h", 1, DATA_FLAG_FIN)); | 2715 framer.CreateDataFrame(1, "h", 1, DATA_FLAG_FIN)); |
| 2803 | 2716 |
| 2804 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); | 2717 scoped_ptr<SpdyFrame> resp1( |
| 2718 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); |
| 2805 | 2719 |
| 2806 // Write 1 byte more than kMaxReadBytes to check that DoRead yields. | 2720 // Write 1 byte more than kMaxReadBytes to check that DoRead yields. |
| 2807 MockRead reads[] = { | 2721 MockRead reads[] = { |
| 2808 CreateMockRead(*resp1, 1), | 2722 CreateMockRead(*resp1, 1), |
| 2809 CreateMockRead(*partial_data_frame, 2), | 2723 MockRead(ASYNC, ERR_IO_PENDING, 2), |
| 2810 CreateMockRead(*partial_data_frame, 3, SYNCHRONOUS), | 2724 CreateMockRead(*partial_data_frame, 3), |
| 2811 CreateMockRead(*partial_data_frame, 4, SYNCHRONOUS), | 2725 CreateMockRead(*partial_data_frame, 4, SYNCHRONOUS), |
| 2812 CreateMockRead(*partial_data_frame, 5, SYNCHRONOUS), | 2726 CreateMockRead(*partial_data_frame, 5, SYNCHRONOUS), |
| 2813 CreateMockRead(*finish_data_frame, 6, SYNCHRONOUS), | 2727 CreateMockRead(*partial_data_frame, 6, SYNCHRONOUS), |
| 2814 MockRead(ASYNC, 0, 7) // EOF | 2728 CreateMockRead(*finish_data_frame, 7, SYNCHRONOUS), |
| 2729 MockRead(ASYNC, 0, 8) // EOF |
| 2815 }; | 2730 }; |
| 2816 | 2731 |
| 2817 // Create SpdySession and SpdyStream and send the request. | 2732 // Create SpdySession and SpdyStream and send the request. |
| 2818 DeterministicSocketData data(reads, arraysize(reads), | 2733 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); |
| 2819 writes, arraysize(writes)); | 2734 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 2820 data.set_connect_data(connect_data); | |
| 2821 session_deps_.host_resolver->set_synchronous_mode(true); | |
| 2822 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 2823 | 2735 |
| 2824 CreateDeterministicNetworkSession(); | 2736 CreateNetworkSession(); |
| 2825 | 2737 |
| 2826 base::WeakPtr<SpdySession> session = | 2738 base::WeakPtr<SpdySession> session = |
| 2827 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 2739 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 2828 | 2740 |
| 2829 GURL url1(kDefaultURL); | 2741 GURL url1(kDefaultURL); |
| 2830 base::WeakPtr<SpdyStream> spdy_stream1 = | 2742 base::WeakPtr<SpdyStream> spdy_stream1 = |
| 2831 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, | 2743 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, |
| 2832 session, url1, MEDIUM, BoundNetLog()); | 2744 session, url1, MEDIUM, BoundNetLog()); |
| 2833 ASSERT_TRUE(spdy_stream1.get() != NULL); | 2745 ASSERT_TRUE(spdy_stream1.get() != nullptr); |
| 2834 EXPECT_EQ(0u, spdy_stream1->stream_id()); | 2746 EXPECT_EQ(0u, spdy_stream1->stream_id()); |
| 2835 test::StreamDelegateDoNothing delegate1(spdy_stream1); | 2747 test::StreamDelegateDoNothing delegate1(spdy_stream1); |
| 2836 spdy_stream1->SetDelegate(&delegate1); | 2748 spdy_stream1->SetDelegate(&delegate1); |
| 2837 | 2749 |
| 2838 scoped_ptr<SpdyHeaderBlock> headers1( | 2750 scoped_ptr<SpdyHeaderBlock> headers1( |
| 2839 spdy_util_.ConstructGetHeaderBlock(url1.spec())); | 2751 spdy_util_.ConstructGetHeaderBlock(url1.spec())); |
| 2840 spdy_stream1->SendRequestHeaders(headers1.Pass(), NO_MORE_DATA_TO_SEND); | 2752 spdy_stream1->SendRequestHeaders(headers1.Pass(), NO_MORE_DATA_TO_SEND); |
| 2841 EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); | 2753 EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); |
| 2842 | 2754 |
| 2843 // Set up the TaskObserver to verify SpdySession::DoReadLoop posts a | 2755 // Set up the TaskObserver to verify SpdySession::DoReadLoop posts a |
| 2844 // task. | 2756 // task. |
| 2845 SpdySessionTestTaskObserver observer("spdy_session.cc", "DoReadLoop"); | 2757 SpdySessionTestTaskObserver observer("spdy_session.cc", "DoReadLoop"); |
| 2846 | 2758 |
| 2847 // Run until 1st read. | 2759 // Run until 1st read. |
| 2848 EXPECT_EQ(0u, delegate1.stream_id()); | 2760 EXPECT_EQ(0u, delegate1.stream_id()); |
| 2849 data.RunFor(2); | 2761 base::RunLoop().RunUntilIdle(); |
| 2850 EXPECT_EQ(1u, delegate1.stream_id()); | 2762 EXPECT_EQ(1u, delegate1.stream_id()); |
| 2851 EXPECT_EQ(0u, observer.executed_count()); | 2763 EXPECT_EQ(0u, observer.executed_count()); |
| 2852 | 2764 |
| 2853 // Read all the data and verify SpdySession::DoReadLoop has posted a | 2765 // Read all the data and verify SpdySession::DoReadLoop has posted a |
| 2854 // task. | 2766 // task. |
| 2855 data.RunFor(6); | 2767 data.CompleteRead(); |
| 2856 EXPECT_EQ(NULL, spdy_stream1.get()); | 2768 base::RunLoop().RunUntilIdle(); |
| 2769 EXPECT_FALSE(spdy_stream1); |
| 2857 | 2770 |
| 2858 // Verify task observer's executed_count is 1, which indicates DoRead has | 2771 // Verify task observer's executed_count is 1, which indicates DoRead has |
| 2859 // posted only one task and thus yielded though there is data available for it | 2772 // posted only one task and thus yielded though there is data available for it |
| 2860 // to read. | 2773 // to read. |
| 2861 EXPECT_EQ(1u, observer.executed_count()); | 2774 EXPECT_EQ(1u, observer.executed_count()); |
| 2862 EXPECT_TRUE(data.AllWriteDataConsumed()); | 2775 EXPECT_TRUE(data.AllWriteDataConsumed()); |
| 2863 EXPECT_TRUE(data.AllReadDataConsumed()); | 2776 EXPECT_TRUE(data.AllReadDataConsumed()); |
| 2864 } | 2777 } |
| 2865 | 2778 |
| 2866 // Test that SpdySession::DoReadLoop() tests interactions of yielding | 2779 // Test that SpdySession::DoReadLoop() tests interactions of yielding |
| 2867 // + async, by doing the following MockReads. | 2780 // + async, by doing the following MockReads. |
| 2868 // | 2781 // |
| 2869 // MockRead of SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 2K | 2782 // MockRead of SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 2K |
| 2870 // ASYNC 8K, SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 2K. | 2783 // ASYNC 8K, SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 2K. |
| 2871 // | 2784 // |
| 2872 // The above reads 26K synchronously. Since that is less that 32K, we | 2785 // The above reads 26K synchronously. Since that is less that 32K, we |
| 2873 // will attempt to read again. However, that DoRead() will return | 2786 // will attempt to read again. However, that DoRead() will return |
| 2874 // ERR_IO_PENDING (because of async read), so DoReadLoop() will | 2787 // ERR_IO_PENDING (because of async read), so DoReadLoop() will |
| 2875 // yield. When we come back, DoRead() will read the results from the | 2788 // yield. When we come back, DoRead() will read the results from the |
| 2876 // async read, and rest of the data synchronously. | 2789 // async read, and rest of the data synchronously. |
| 2877 TEST_P(SpdySessionTest, TestYieldingDuringAsyncReadData) { | 2790 TEST_P(SpdySessionTest, TestYieldingDuringAsyncReadData) { |
| 2878 MockConnect connect_data(SYNCHRONOUS, OK); | 2791 session_deps_.host_resolver->set_synchronous_mode(true); |
| 2792 |
| 2879 BufferedSpdyFramer framer(spdy_util_.spdy_version(), false); | 2793 BufferedSpdyFramer framer(spdy_util_.spdy_version(), false); |
| 2880 | 2794 |
| 2881 scoped_ptr<SpdyFrame> req1( | 2795 scoped_ptr<SpdyFrame> req1( |
| 2882 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); | 2796 spdy_util_.ConstructSpdyGet(nullptr, 0, false, 1, MEDIUM, true)); |
| 2883 MockWrite writes[] = { | 2797 MockWrite writes[] = { |
| 2884 CreateMockWrite(*req1, 0), | 2798 CreateMockWrite(*req1, 0), |
| 2885 }; | 2799 }; |
| 2886 | 2800 |
| 2887 // Build buffer of size kMaxReadBytesWithoutYielding / 4 | 2801 // Build buffer of size kMaxReadBytesWithoutYielding / 4 |
| 2888 // (-spdy_data_frame_size). | 2802 // (-spdy_data_frame_size). |
| 2889 ASSERT_EQ(32 * 1024, kMaxReadBytesWithoutYielding); | 2803 ASSERT_EQ(32 * 1024, kMaxReadBytesWithoutYielding); |
| 2890 TestDataStream test_stream; | 2804 TestDataStream test_stream; |
| 2891 const int kEightKPayloadSize = | 2805 const int kEightKPayloadSize = |
| 2892 kMaxReadBytesWithoutYielding / 4 - framer.GetControlFrameHeaderSize(); | 2806 kMaxReadBytesWithoutYielding / 4 - framer.GetControlFrameHeaderSize(); |
| 2893 scoped_refptr<IOBuffer> eightk_payload(new IOBuffer(kEightKPayloadSize)); | 2807 scoped_refptr<IOBuffer> eightk_payload(new IOBuffer(kEightKPayloadSize)); |
| 2894 char* eightk_payload_data = eightk_payload->data(); | 2808 char* eightk_payload_data = eightk_payload->data(); |
| 2895 test_stream.GetBytes(eightk_payload_data, kEightKPayloadSize); | 2809 test_stream.GetBytes(eightk_payload_data, kEightKPayloadSize); |
| 2896 | 2810 |
| 2897 // Build buffer of 2k size. | 2811 // Build buffer of 2k size. |
| 2898 TestDataStream test_stream2; | 2812 TestDataStream test_stream2; |
| 2899 const int kTwoKPayloadSize = kEightKPayloadSize - 6 * 1024; | 2813 const int kTwoKPayloadSize = kEightKPayloadSize - 6 * 1024; |
| 2900 scoped_refptr<IOBuffer> twok_payload(new IOBuffer(kTwoKPayloadSize)); | 2814 scoped_refptr<IOBuffer> twok_payload(new IOBuffer(kTwoKPayloadSize)); |
| 2901 char* twok_payload_data = twok_payload->data(); | 2815 char* twok_payload_data = twok_payload->data(); |
| 2902 test_stream2.GetBytes(twok_payload_data, kTwoKPayloadSize); | 2816 test_stream2.GetBytes(twok_payload_data, kTwoKPayloadSize); |
| 2903 | 2817 |
| 2904 scoped_ptr<SpdyFrame> eightk_data_frame(framer.CreateDataFrame( | 2818 scoped_ptr<SpdyFrame> eightk_data_frame(framer.CreateDataFrame( |
| 2905 1, eightk_payload_data, kEightKPayloadSize, DATA_FLAG_NONE)); | 2819 1, eightk_payload_data, kEightKPayloadSize, DATA_FLAG_NONE)); |
| 2906 scoped_ptr<SpdyFrame> twok_data_frame(framer.CreateDataFrame( | 2820 scoped_ptr<SpdyFrame> twok_data_frame(framer.CreateDataFrame( |
| 2907 1, twok_payload_data, kTwoKPayloadSize, DATA_FLAG_NONE)); | 2821 1, twok_payload_data, kTwoKPayloadSize, DATA_FLAG_NONE)); |
| 2908 scoped_ptr<SpdyFrame> finish_data_frame(framer.CreateDataFrame( | 2822 scoped_ptr<SpdyFrame> finish_data_frame(framer.CreateDataFrame( |
| 2909 1, "h", 1, DATA_FLAG_FIN)); | 2823 1, "h", 1, DATA_FLAG_FIN)); |
| 2910 | 2824 |
| 2911 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); | 2825 scoped_ptr<SpdyFrame> resp1( |
| 2826 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); |
| 2912 | 2827 |
| 2913 MockRead reads[] = { | 2828 MockRead reads[] = { |
| 2914 CreateMockRead(*resp1, 1), | 2829 CreateMockRead(*resp1, 1), |
| 2915 CreateMockRead(*eightk_data_frame, 2), | 2830 MockRead(ASYNC, ERR_IO_PENDING, 2), |
| 2916 CreateMockRead(*eightk_data_frame, 3, SYNCHRONOUS), | 2831 CreateMockRead(*eightk_data_frame, 3), |
| 2917 CreateMockRead(*eightk_data_frame, 4, SYNCHRONOUS), | 2832 CreateMockRead(*eightk_data_frame, 4, SYNCHRONOUS), |
| 2918 CreateMockRead(*twok_data_frame, 5, SYNCHRONOUS), | 2833 CreateMockRead(*eightk_data_frame, 5, SYNCHRONOUS), |
| 2919 CreateMockRead(*eightk_data_frame, 6, ASYNC), | 2834 CreateMockRead(*twok_data_frame, 6, SYNCHRONOUS), |
| 2920 CreateMockRead(*eightk_data_frame, 7, SYNCHRONOUS), | 2835 CreateMockRead(*eightk_data_frame, 7, ASYNC), |
| 2921 CreateMockRead(*eightk_data_frame, 8, SYNCHRONOUS), | 2836 CreateMockRead(*eightk_data_frame, 8, SYNCHRONOUS), |
| 2922 CreateMockRead(*eightk_data_frame, 9, SYNCHRONOUS), | 2837 CreateMockRead(*eightk_data_frame, 9, SYNCHRONOUS), |
| 2923 CreateMockRead(*twok_data_frame, 10, SYNCHRONOUS), | 2838 CreateMockRead(*eightk_data_frame, 10, SYNCHRONOUS), |
| 2924 CreateMockRead(*finish_data_frame, 11, SYNCHRONOUS), | 2839 CreateMockRead(*twok_data_frame, 11, SYNCHRONOUS), |
| 2925 MockRead(ASYNC, 0, 12) // EOF | 2840 CreateMockRead(*finish_data_frame, 12, SYNCHRONOUS), |
| 2841 MockRead(ASYNC, 0, 13) // EOF |
| 2926 }; | 2842 }; |
| 2927 | 2843 |
| 2928 // Create SpdySession and SpdyStream and send the request. | 2844 // Create SpdySession and SpdyStream and send the request. |
| 2929 DeterministicSocketData data(reads, arraysize(reads), | 2845 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); |
| 2930 writes, arraysize(writes)); | 2846 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 2931 data.set_connect_data(connect_data); | |
| 2932 session_deps_.host_resolver->set_synchronous_mode(true); | |
| 2933 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 2934 | 2847 |
| 2935 CreateDeterministicNetworkSession(); | 2848 CreateNetworkSession(); |
| 2936 | 2849 |
| 2937 base::WeakPtr<SpdySession> session = | 2850 base::WeakPtr<SpdySession> session = |
| 2938 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 2851 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 2939 | 2852 |
| 2940 GURL url1(kDefaultURL); | 2853 GURL url1(kDefaultURL); |
| 2941 base::WeakPtr<SpdyStream> spdy_stream1 = | 2854 base::WeakPtr<SpdyStream> spdy_stream1 = |
| 2942 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, | 2855 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, |
| 2943 session, url1, MEDIUM, BoundNetLog()); | 2856 session, url1, MEDIUM, BoundNetLog()); |
| 2944 ASSERT_TRUE(spdy_stream1.get() != NULL); | 2857 ASSERT_TRUE(spdy_stream1.get() != nullptr); |
| 2945 EXPECT_EQ(0u, spdy_stream1->stream_id()); | 2858 EXPECT_EQ(0u, spdy_stream1->stream_id()); |
| 2946 test::StreamDelegateDoNothing delegate1(spdy_stream1); | 2859 test::StreamDelegateDoNothing delegate1(spdy_stream1); |
| 2947 spdy_stream1->SetDelegate(&delegate1); | 2860 spdy_stream1->SetDelegate(&delegate1); |
| 2948 | 2861 |
| 2949 scoped_ptr<SpdyHeaderBlock> headers1( | 2862 scoped_ptr<SpdyHeaderBlock> headers1( |
| 2950 spdy_util_.ConstructGetHeaderBlock(url1.spec())); | 2863 spdy_util_.ConstructGetHeaderBlock(url1.spec())); |
| 2951 spdy_stream1->SendRequestHeaders(headers1.Pass(), NO_MORE_DATA_TO_SEND); | 2864 spdy_stream1->SendRequestHeaders(headers1.Pass(), NO_MORE_DATA_TO_SEND); |
| 2952 EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); | 2865 EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); |
| 2953 | 2866 |
| 2954 // Set up the TaskObserver to monitor SpdySession::DoReadLoop | 2867 // Set up the TaskObserver to monitor SpdySession::DoReadLoop |
| 2955 // posting of tasks. | 2868 // posting of tasks. |
| 2956 SpdySessionTestTaskObserver observer("spdy_session.cc", "DoReadLoop"); | 2869 SpdySessionTestTaskObserver observer("spdy_session.cc", "DoReadLoop"); |
| 2957 | 2870 |
| 2958 // Run until 1st read. | 2871 // Run until 1st read. |
| 2959 EXPECT_EQ(0u, delegate1.stream_id()); | 2872 EXPECT_EQ(0u, delegate1.stream_id()); |
| 2960 data.RunFor(2); | 2873 base::RunLoop().RunUntilIdle(); |
| 2961 EXPECT_EQ(1u, delegate1.stream_id()); | 2874 EXPECT_EQ(1u, delegate1.stream_id()); |
| 2962 EXPECT_EQ(0u, observer.executed_count()); | 2875 EXPECT_EQ(0u, observer.executed_count()); |
| 2963 | 2876 |
| 2964 // Read all the data and verify SpdySession::DoReadLoop has posted a | 2877 // Read all the data and verify SpdySession::DoReadLoop has posted a |
| 2965 // task. | 2878 // task. |
| 2966 data.RunFor(12); | 2879 data.CompleteRead(); |
| 2967 EXPECT_EQ(NULL, spdy_stream1.get()); | 2880 base::RunLoop().RunUntilIdle(); |
| 2881 EXPECT_FALSE(spdy_stream1); |
| 2968 | 2882 |
| 2969 // Verify task observer's executed_count is 1, which indicates DoRead has | 2883 // Verify task observer's executed_count is 1, which indicates DoRead has |
| 2970 // posted only one task and thus yielded though there is data available for | 2884 // posted only one task and thus yielded though there is data available for |
| 2971 // it to read. | 2885 // it to read. |
| 2972 EXPECT_EQ(1u, observer.executed_count()); | 2886 EXPECT_EQ(1u, observer.executed_count()); |
| 2973 EXPECT_TRUE(data.AllWriteDataConsumed()); | 2887 EXPECT_TRUE(data.AllWriteDataConsumed()); |
| 2974 EXPECT_TRUE(data.AllReadDataConsumed()); | 2888 EXPECT_TRUE(data.AllReadDataConsumed()); |
| 2975 } | 2889 } |
| 2976 | 2890 |
| 2977 // Send a GoAway frame when SpdySession is in DoReadLoop. Make sure | 2891 // Send a GoAway frame when SpdySession is in DoReadLoop. Make sure |
| 2978 // nothing blows up. | 2892 // nothing blows up. |
| 2979 TEST_P(SpdySessionTest, GoAwayWhileInDoReadLoop) { | 2893 TEST_P(SpdySessionTest, GoAwayWhileInDoReadLoop) { |
| 2980 MockConnect connect_data(SYNCHRONOUS, OK); | 2894 session_deps_.host_resolver->set_synchronous_mode(true); |
| 2895 |
| 2981 BufferedSpdyFramer framer(spdy_util_.spdy_version(), false); | 2896 BufferedSpdyFramer framer(spdy_util_.spdy_version(), false); |
| 2982 | 2897 |
| 2983 scoped_ptr<SpdyFrame> req1( | 2898 scoped_ptr<SpdyFrame> req1( |
| 2984 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); | 2899 spdy_util_.ConstructSpdyGet(nullptr, 0, false, 1, MEDIUM, true)); |
| 2985 MockWrite writes[] = { | 2900 MockWrite writes[] = { |
| 2986 CreateMockWrite(*req1, 0), | 2901 CreateMockWrite(*req1, 0), |
| 2987 }; | 2902 }; |
| 2988 | 2903 |
| 2989 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); | 2904 scoped_ptr<SpdyFrame> resp1( |
| 2905 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); |
| 2990 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true)); | 2906 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true)); |
| 2991 scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway()); | 2907 scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway()); |
| 2992 | 2908 |
| 2993 MockRead reads[] = { | 2909 MockRead reads[] = { |
| 2994 CreateMockRead(*resp1, 1), | 2910 CreateMockRead(*resp1, 1), |
| 2995 CreateMockRead(*body1, 2), | 2911 MockRead(ASYNC, ERR_IO_PENDING, 2), |
| 2996 CreateMockRead(*goaway, 3), | 2912 CreateMockRead(*body1, 3), |
| 2913 CreateMockRead(*goaway, 4), |
| 2997 }; | 2914 }; |
| 2998 | 2915 |
| 2999 // Create SpdySession and SpdyStream and send the request. | 2916 // Create SpdySession and SpdyStream and send the request. |
| 3000 DeterministicSocketData data(reads, arraysize(reads), | 2917 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); |
| 3001 writes, arraysize(writes)); | 2918 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 3002 data.set_connect_data(connect_data); | |
| 3003 session_deps_.host_resolver->set_synchronous_mode(true); | |
| 3004 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 3005 | 2919 |
| 3006 CreateDeterministicNetworkSession(); | 2920 CreateNetworkSession(); |
| 3007 | 2921 |
| 3008 base::WeakPtr<SpdySession> session = | 2922 base::WeakPtr<SpdySession> session = |
| 3009 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 2923 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 3010 | 2924 |
| 3011 GURL url1(kDefaultURL); | 2925 GURL url1(kDefaultURL); |
| 3012 base::WeakPtr<SpdyStream> spdy_stream1 = | 2926 base::WeakPtr<SpdyStream> spdy_stream1 = |
| 3013 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, | 2927 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, |
| 3014 session, url1, MEDIUM, BoundNetLog()); | 2928 session, url1, MEDIUM, BoundNetLog()); |
| 3015 test::StreamDelegateDoNothing delegate1(spdy_stream1); | 2929 test::StreamDelegateDoNothing delegate1(spdy_stream1); |
| 3016 spdy_stream1->SetDelegate(&delegate1); | 2930 spdy_stream1->SetDelegate(&delegate1); |
| 3017 ASSERT_TRUE(spdy_stream1.get() != NULL); | 2931 ASSERT_TRUE(spdy_stream1.get() != nullptr); |
| 3018 EXPECT_EQ(0u, spdy_stream1->stream_id()); | 2932 EXPECT_EQ(0u, spdy_stream1->stream_id()); |
| 3019 | 2933 |
| 3020 scoped_ptr<SpdyHeaderBlock> headers1( | 2934 scoped_ptr<SpdyHeaderBlock> headers1( |
| 3021 spdy_util_.ConstructGetHeaderBlock(url1.spec())); | 2935 spdy_util_.ConstructGetHeaderBlock(url1.spec())); |
| 3022 spdy_stream1->SendRequestHeaders(headers1.Pass(), NO_MORE_DATA_TO_SEND); | 2936 spdy_stream1->SendRequestHeaders(headers1.Pass(), NO_MORE_DATA_TO_SEND); |
| 3023 EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); | 2937 EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); |
| 3024 | 2938 |
| 3025 // Run until 1st read. | 2939 // Run until 1st read. |
| 3026 EXPECT_EQ(0u, spdy_stream1->stream_id()); | 2940 EXPECT_EQ(0u, spdy_stream1->stream_id()); |
| 3027 data.RunFor(1); | 2941 base::RunLoop().RunUntilIdle(); |
| 3028 EXPECT_EQ(1u, spdy_stream1->stream_id()); | 2942 EXPECT_EQ(1u, spdy_stream1->stream_id()); |
| 3029 | 2943 |
| 3030 // Run until GoAway. | 2944 // Run until GoAway. |
| 3031 data.RunFor(3); | 2945 data.CompleteRead(); |
| 3032 EXPECT_EQ(NULL, spdy_stream1.get()); | 2946 base::RunLoop().RunUntilIdle(); |
| 2947 EXPECT_FALSE(spdy_stream1); |
| 3033 EXPECT_TRUE(data.AllWriteDataConsumed()); | 2948 EXPECT_TRUE(data.AllWriteDataConsumed()); |
| 3034 EXPECT_TRUE(data.AllReadDataConsumed()); | 2949 EXPECT_TRUE(data.AllReadDataConsumed()); |
| 3035 EXPECT_TRUE(session == NULL); | 2950 EXPECT_FALSE(session); |
| 3036 } | 2951 } |
| 3037 | 2952 |
| 3038 // Within this framework, a SpdySession should be initialized with | 2953 // Within this framework, a SpdySession should be initialized with |
| 3039 // flow control disabled for protocol version 2, with flow control | 2954 // flow control disabled for protocol version 2, with flow control |
| 3040 // enabled only for streams for protocol version 3, and with flow | 2955 // enabled only for streams for protocol version 3, and with flow |
| 3041 // control enabled for streams and sessions for higher versions. | 2956 // control enabled for streams and sessions for higher versions. |
| 3042 TEST_P(SpdySessionTest, ProtocolNegotiation) { | 2957 TEST_P(SpdySessionTest, ProtocolNegotiation) { |
| 3043 session_deps_.host_resolver->set_synchronous_mode(true); | 2958 session_deps_.host_resolver->set_synchronous_mode(true); |
| 3044 | 2959 |
| 3045 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 3046 MockRead reads[] = { | 2960 MockRead reads[] = { |
| 3047 MockRead(SYNCHRONOUS, 0, 0) // EOF | 2961 MockRead(SYNCHRONOUS, 0, 0) // EOF |
| 3048 }; | 2962 }; |
| 3049 StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0); | 2963 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0); |
| 3050 data.set_connect_data(connect_data); | |
| 3051 session_deps_.socket_factory->AddSocketDataProvider(&data); | 2964 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 3052 | 2965 |
| 3053 CreateNetworkSession(); | 2966 CreateNetworkSession(); |
| 3054 base::WeakPtr<SpdySession> session = | 2967 base::WeakPtr<SpdySession> session = |
| 3055 CreateFakeSpdySession(spdy_session_pool_, key_); | 2968 CreateFakeSpdySession(spdy_session_pool_, key_); |
| 3056 | 2969 |
| 3057 EXPECT_EQ(spdy_util_.spdy_version(), | 2970 EXPECT_EQ(spdy_util_.spdy_version(), |
| 3058 session->buffered_spdy_framer_->protocol_version()); | 2971 session->buffered_spdy_framer_->protocol_version()); |
| 3059 EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION, | 2972 EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION, |
| 3060 session->flow_control_state()); | 2973 session->flow_control_state()); |
| 3061 EXPECT_EQ(SpdySession::GetDefaultInitialWindowSize(GetParam()), | 2974 EXPECT_EQ(SpdySession::GetDefaultInitialWindowSize(GetParam()), |
| 3062 session->session_send_window_size_); | 2975 session->session_send_window_size_); |
| 3063 EXPECT_EQ(SpdySession::GetDefaultInitialWindowSize(GetParam()), | 2976 EXPECT_EQ(SpdySession::GetDefaultInitialWindowSize(GetParam()), |
| 3064 session->session_recv_window_size_); | 2977 session->session_recv_window_size_); |
| 3065 EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); | 2978 EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); |
| 3066 } | 2979 } |
| 3067 | 2980 |
| 3068 // Tests the case of a non-SPDY request closing an idle SPDY session when no | 2981 // Tests the case of a non-SPDY request closing an idle SPDY session when no |
| 3069 // pointers to the idle session are currently held. | 2982 // pointers to the idle session are currently held. |
| 3070 TEST_P(SpdySessionTest, CloseOneIdleConnection) { | 2983 TEST_P(SpdySessionTest, CloseOneIdleConnection) { |
| 3071 ClientSocketPoolManager::set_max_sockets_per_group( | 2984 ClientSocketPoolManager::set_max_sockets_per_group( |
| 3072 HttpNetworkSession::NORMAL_SOCKET_POOL, 1); | 2985 HttpNetworkSession::NORMAL_SOCKET_POOL, 1); |
| 3073 ClientSocketPoolManager::set_max_sockets_per_pool( | 2986 ClientSocketPoolManager::set_max_sockets_per_pool( |
| 3074 HttpNetworkSession::NORMAL_SOCKET_POOL, 1); | 2987 HttpNetworkSession::NORMAL_SOCKET_POOL, 1); |
| 3075 | 2988 |
| 3076 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 3077 MockRead reads[] = { | 2989 MockRead reads[] = { |
| 3078 MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. | 2990 MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. |
| 3079 }; | 2991 }; |
| 3080 StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0); | 2992 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0); |
| 3081 data.set_connect_data(connect_data); | |
| 3082 session_deps_.socket_factory->AddSocketDataProvider(&data); | 2993 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 3083 session_deps_.socket_factory->AddSocketDataProvider(&data); | 2994 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 3084 | 2995 |
| 3085 CreateNetworkSession(); | 2996 CreateNetworkSession(); |
| 3086 | 2997 |
| 3087 TransportClientSocketPool* pool = | 2998 TransportClientSocketPool* pool = |
| 3088 http_session_->GetTransportSocketPool( | 2999 http_session_->GetTransportSocketPool( |
| 3089 HttpNetworkSession::NORMAL_SOCKET_POOL); | 3000 HttpNetworkSession::NORMAL_SOCKET_POOL); |
| 3090 | 3001 |
| 3091 // Create an idle SPDY session. | 3002 // Create an idle SPDY session. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 3106 scoped_ptr<ClientSocketHandle> connection2(new ClientSocketHandle); | 3017 scoped_ptr<ClientSocketHandle> connection2(new ClientSocketHandle); |
| 3107 EXPECT_EQ(ERR_IO_PENDING, | 3018 EXPECT_EQ(ERR_IO_PENDING, |
| 3108 connection2->Init(host_port2.ToString(), params2, DEFAULT_PRIORITY, | 3019 connection2->Init(host_port2.ToString(), params2, DEFAULT_PRIORITY, |
| 3109 callback2.callback(), pool, BoundNetLog())); | 3020 callback2.callback(), pool, BoundNetLog())); |
| 3110 EXPECT_TRUE(pool->IsStalled()); | 3021 EXPECT_TRUE(pool->IsStalled()); |
| 3111 | 3022 |
| 3112 // The socket pool should close the connection asynchronously and establish a | 3023 // The socket pool should close the connection asynchronously and establish a |
| 3113 // new connection. | 3024 // new connection. |
| 3114 EXPECT_EQ(OK, callback2.WaitForResult()); | 3025 EXPECT_EQ(OK, callback2.WaitForResult()); |
| 3115 EXPECT_FALSE(pool->IsStalled()); | 3026 EXPECT_FALSE(pool->IsStalled()); |
| 3116 EXPECT_TRUE(session1 == NULL); | 3027 EXPECT_FALSE(session1); |
| 3117 } | 3028 } |
| 3118 | 3029 |
| 3119 // Tests the case of a non-SPDY request closing an idle SPDY session when no | 3030 // Tests the case of a non-SPDY request closing an idle SPDY session when no |
| 3120 // pointers to the idle session are currently held, in the case the SPDY session | 3031 // pointers to the idle session are currently held, in the case the SPDY session |
| 3121 // has an alias. | 3032 // has an alias. |
| 3122 TEST_P(SpdySessionTest, CloseOneIdleConnectionWithAlias) { | 3033 TEST_P(SpdySessionTest, CloseOneIdleConnectionWithAlias) { |
| 3123 ClientSocketPoolManager::set_max_sockets_per_group( | 3034 ClientSocketPoolManager::set_max_sockets_per_group( |
| 3124 HttpNetworkSession::NORMAL_SOCKET_POOL, 1); | 3035 HttpNetworkSession::NORMAL_SOCKET_POOL, 1); |
| 3125 ClientSocketPoolManager::set_max_sockets_per_pool( | 3036 ClientSocketPoolManager::set_max_sockets_per_pool( |
| 3126 HttpNetworkSession::NORMAL_SOCKET_POOL, 1); | 3037 HttpNetworkSession::NORMAL_SOCKET_POOL, 1); |
| 3127 | 3038 |
| 3128 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 3129 MockRead reads[] = { | 3039 MockRead reads[] = { |
| 3130 MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. | 3040 MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. |
| 3131 }; | 3041 }; |
| 3132 StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0); | 3042 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0); |
| 3133 data.set_connect_data(connect_data); | |
| 3134 session_deps_.socket_factory->AddSocketDataProvider(&data); | 3043 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 3135 session_deps_.socket_factory->AddSocketDataProvider(&data); | 3044 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 3136 | 3045 |
| 3137 session_deps_.host_resolver->set_synchronous_mode(true); | 3046 session_deps_.host_resolver->set_synchronous_mode(true); |
| 3138 session_deps_.host_resolver->rules()->AddIPLiteralRule( | 3047 session_deps_.host_resolver->rules()->AddIPLiteralRule( |
| 3139 "1.com", "192.168.0.2", std::string()); | 3048 "1.com", "192.168.0.2", std::string()); |
| 3140 session_deps_.host_resolver->rules()->AddIPLiteralRule( | 3049 session_deps_.host_resolver->rules()->AddIPLiteralRule( |
| 3141 "2.com", "192.168.0.2", std::string()); | 3050 "2.com", "192.168.0.2", std::string()); |
| 3142 // Not strictly needed. | 3051 // Not strictly needed. |
| 3143 session_deps_.host_resolver->rules()->AddIPLiteralRule( | 3052 session_deps_.host_resolver->rules()->AddIPLiteralRule( |
| (...skipping 12 matching lines...) Expand all Loading... |
| 3156 CreateInsecureSpdySession(http_session_, key1, BoundNetLog()); | 3065 CreateInsecureSpdySession(http_session_, key1, BoundNetLog()); |
| 3157 EXPECT_FALSE(pool->IsStalled()); | 3066 EXPECT_FALSE(pool->IsStalled()); |
| 3158 | 3067 |
| 3159 // Set up an alias for the idle SPDY session, increasing its ref count to 2. | 3068 // Set up an alias for the idle SPDY session, increasing its ref count to 2. |
| 3160 SpdySessionKey key2(HostPortPair("2.com", 80), ProxyServer::Direct(), | 3069 SpdySessionKey key2(HostPortPair("2.com", 80), ProxyServer::Direct(), |
| 3161 PRIVACY_MODE_DISABLED); | 3070 PRIVACY_MODE_DISABLED); |
| 3162 HostResolver::RequestInfo info(key2.host_port_pair()); | 3071 HostResolver::RequestInfo info(key2.host_port_pair()); |
| 3163 AddressList addresses; | 3072 AddressList addresses; |
| 3164 // Pre-populate the DNS cache, since a synchronous resolution is required in | 3073 // Pre-populate the DNS cache, since a synchronous resolution is required in |
| 3165 // order to create the alias. | 3074 // order to create the alias. |
| 3166 session_deps_.host_resolver->Resolve(info, | 3075 session_deps_.host_resolver->Resolve(info, DEFAULT_PRIORITY, &addresses, |
| 3167 DEFAULT_PRIORITY, | 3076 CompletionCallback(), nullptr, |
| 3168 &addresses, | |
| 3169 CompletionCallback(), | |
| 3170 NULL, | |
| 3171 BoundNetLog()); | 3077 BoundNetLog()); |
| 3172 // Get a session for |key2|, which should return the session created earlier. | 3078 // Get a session for |key2|, which should return the session created earlier. |
| 3173 base::WeakPtr<SpdySession> session2 = | 3079 base::WeakPtr<SpdySession> session2 = |
| 3174 spdy_session_pool_->FindAvailableSession(key2, BoundNetLog()); | 3080 spdy_session_pool_->FindAvailableSession(key2, BoundNetLog()); |
| 3175 ASSERT_EQ(session1.get(), session2.get()); | 3081 ASSERT_EQ(session1.get(), session2.get()); |
| 3176 EXPECT_FALSE(pool->IsStalled()); | 3082 EXPECT_FALSE(pool->IsStalled()); |
| 3177 | 3083 |
| 3178 // Trying to create a new connection should cause the pool to be stalled, and | 3084 // Trying to create a new connection should cause the pool to be stalled, and |
| 3179 // post a task asynchronously to try and close the session. | 3085 // post a task asynchronously to try and close the session. |
| 3180 TestCompletionCallback callback3; | 3086 TestCompletionCallback callback3; |
| 3181 HostPortPair host_port3("3.com", 80); | 3087 HostPortPair host_port3("3.com", 80); |
| 3182 scoped_refptr<TransportSocketParams> params3( | 3088 scoped_refptr<TransportSocketParams> params3( |
| 3183 new TransportSocketParams( | 3089 new TransportSocketParams( |
| 3184 host_port3, false, false, OnHostResolutionCallback(), | 3090 host_port3, false, false, OnHostResolutionCallback(), |
| 3185 TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT)); | 3091 TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT)); |
| 3186 scoped_ptr<ClientSocketHandle> connection3(new ClientSocketHandle); | 3092 scoped_ptr<ClientSocketHandle> connection3(new ClientSocketHandle); |
| 3187 EXPECT_EQ(ERR_IO_PENDING, | 3093 EXPECT_EQ(ERR_IO_PENDING, |
| 3188 connection3->Init(host_port3.ToString(), params3, DEFAULT_PRIORITY, | 3094 connection3->Init(host_port3.ToString(), params3, DEFAULT_PRIORITY, |
| 3189 callback3.callback(), pool, BoundNetLog())); | 3095 callback3.callback(), pool, BoundNetLog())); |
| 3190 EXPECT_TRUE(pool->IsStalled()); | 3096 EXPECT_TRUE(pool->IsStalled()); |
| 3191 | 3097 |
| 3192 // The socket pool should close the connection asynchronously and establish a | 3098 // The socket pool should close the connection asynchronously and establish a |
| 3193 // new connection. | 3099 // new connection. |
| 3194 EXPECT_EQ(OK, callback3.WaitForResult()); | 3100 EXPECT_EQ(OK, callback3.WaitForResult()); |
| 3195 EXPECT_FALSE(pool->IsStalled()); | 3101 EXPECT_FALSE(pool->IsStalled()); |
| 3196 EXPECT_TRUE(session1 == NULL); | 3102 EXPECT_FALSE(session1); |
| 3197 EXPECT_TRUE(session2 == NULL); | 3103 EXPECT_FALSE(session2); |
| 3198 } | 3104 } |
| 3199 | 3105 |
| 3200 // Tests that when a SPDY session becomes idle, it closes itself if there is | 3106 // Tests that when a SPDY session becomes idle, it closes itself if there is |
| 3201 // a lower layer pool stalled on the per-pool socket limit. | 3107 // a lower layer pool stalled on the per-pool socket limit. |
| 3202 TEST_P(SpdySessionTest, CloseSessionOnIdleWhenPoolStalled) { | 3108 TEST_P(SpdySessionTest, CloseSessionOnIdleWhenPoolStalled) { |
| 3203 ClientSocketPoolManager::set_max_sockets_per_group( | 3109 ClientSocketPoolManager::set_max_sockets_per_group( |
| 3204 HttpNetworkSession::NORMAL_SOCKET_POOL, 1); | 3110 HttpNetworkSession::NORMAL_SOCKET_POOL, 1); |
| 3205 ClientSocketPoolManager::set_max_sockets_per_pool( | 3111 ClientSocketPoolManager::set_max_sockets_per_pool( |
| 3206 HttpNetworkSession::NORMAL_SOCKET_POOL, 1); | 3112 HttpNetworkSession::NORMAL_SOCKET_POOL, 1); |
| 3207 | 3113 |
| 3208 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 3209 MockRead reads[] = { | 3114 MockRead reads[] = { |
| 3210 MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. | 3115 MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. |
| 3211 }; | 3116 }; |
| 3212 scoped_ptr<SpdyFrame> req1( | 3117 scoped_ptr<SpdyFrame> req1( |
| 3213 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); | 3118 spdy_util_.ConstructSpdyGet(nullptr, 0, false, 1, LOWEST, true)); |
| 3214 scoped_ptr<SpdyFrame> cancel1( | 3119 scoped_ptr<SpdyFrame> cancel1( |
| 3215 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL)); | 3120 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL)); |
| 3216 MockWrite writes[] = { | 3121 MockWrite writes[] = { |
| 3217 CreateMockWrite(*req1, 1), | 3122 CreateMockWrite(*req1, 1), |
| 3218 CreateMockWrite(*cancel1, 1), | 3123 CreateMockWrite(*cancel1, 1), |
| 3219 }; | 3124 }; |
| 3220 StaticSocketDataProvider data(reads, arraysize(reads), | 3125 StaticSocketDataProvider data(reads, arraysize(reads), |
| 3221 writes, arraysize(writes)); | 3126 writes, arraysize(writes)); |
| 3222 data.set_connect_data(connect_data); | |
| 3223 session_deps_.socket_factory->AddSocketDataProvider(&data); | 3127 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 3224 | 3128 |
| 3225 MockRead http_reads[] = { | 3129 MockRead http_reads[] = { |
| 3226 MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. | 3130 MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. |
| 3227 }; | 3131 }; |
| 3228 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), | 3132 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), nullptr, |
| 3229 NULL, 0); | 3133 0); |
| 3230 http_data.set_connect_data(connect_data); | |
| 3231 session_deps_.socket_factory->AddSocketDataProvider(&http_data); | 3134 session_deps_.socket_factory->AddSocketDataProvider(&http_data); |
| 3232 | 3135 |
| 3233 | 3136 |
| 3234 CreateNetworkSession(); | 3137 CreateNetworkSession(); |
| 3235 | 3138 |
| 3236 TransportClientSocketPool* pool = | 3139 TransportClientSocketPool* pool = |
| 3237 http_session_->GetTransportSocketPool( | 3140 http_session_->GetTransportSocketPool( |
| 3238 HttpNetworkSession::NORMAL_SOCKET_POOL); | 3141 HttpNetworkSession::NORMAL_SOCKET_POOL); |
| 3239 | 3142 |
| 3240 // Create a SPDY session. | 3143 // Create a SPDY session. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 3256 test::StreamDelegateDoNothing delegate1(spdy_stream1); | 3159 test::StreamDelegateDoNothing delegate1(spdy_stream1); |
| 3257 spdy_stream1->SetDelegate(&delegate1); | 3160 spdy_stream1->SetDelegate(&delegate1); |
| 3258 | 3161 |
| 3259 scoped_ptr<SpdyHeaderBlock> headers1( | 3162 scoped_ptr<SpdyHeaderBlock> headers1( |
| 3260 spdy_util_.ConstructGetHeaderBlock(url1.spec())); | 3163 spdy_util_.ConstructGetHeaderBlock(url1.spec())); |
| 3261 EXPECT_EQ(ERR_IO_PENDING, | 3164 EXPECT_EQ(ERR_IO_PENDING, |
| 3262 spdy_stream1->SendRequestHeaders( | 3165 spdy_stream1->SendRequestHeaders( |
| 3263 headers1.Pass(), NO_MORE_DATA_TO_SEND)); | 3166 headers1.Pass(), NO_MORE_DATA_TO_SEND)); |
| 3264 EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); | 3167 EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); |
| 3265 | 3168 |
| 3266 base::MessageLoop::current()->RunUntilIdle(); | 3169 base::RunLoop().RunUntilIdle(); |
| 3267 | 3170 |
| 3268 // Trying to create a new connection should cause the pool to be stalled, and | 3171 // Trying to create a new connection should cause the pool to be stalled, and |
| 3269 // post a task asynchronously to try and close the session. | 3172 // post a task asynchronously to try and close the session. |
| 3270 TestCompletionCallback callback2; | 3173 TestCompletionCallback callback2; |
| 3271 HostPortPair host_port2("2.com", 80); | 3174 HostPortPair host_port2("2.com", 80); |
| 3272 scoped_refptr<TransportSocketParams> params2( | 3175 scoped_refptr<TransportSocketParams> params2( |
| 3273 new TransportSocketParams( | 3176 new TransportSocketParams( |
| 3274 host_port2, false, false, OnHostResolutionCallback(), | 3177 host_port2, false, false, OnHostResolutionCallback(), |
| 3275 TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT)); | 3178 TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT)); |
| 3276 scoped_ptr<ClientSocketHandle> connection2(new ClientSocketHandle); | 3179 scoped_ptr<ClientSocketHandle> connection2(new ClientSocketHandle); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 3291 ASSERT_TRUE(spdy_stream1.get()); | 3194 ASSERT_TRUE(spdy_stream1.get()); |
| 3292 spdy_stream1->Cancel(); | 3195 spdy_stream1->Cancel(); |
| 3293 base::RunLoop().RunUntilIdle(); | 3196 base::RunLoop().RunUntilIdle(); |
| 3294 ASSERT_FALSE(pool->IsStalled()); | 3197 ASSERT_FALSE(pool->IsStalled()); |
| 3295 EXPECT_EQ(OK, callback2.WaitForResult()); | 3198 EXPECT_EQ(OK, callback2.WaitForResult()); |
| 3296 } | 3199 } |
| 3297 | 3200 |
| 3298 // Verify that SpdySessionKey and therefore SpdySession is different when | 3201 // Verify that SpdySessionKey and therefore SpdySession is different when |
| 3299 // privacy mode is enabled or disabled. | 3202 // privacy mode is enabled or disabled. |
| 3300 TEST_P(SpdySessionTest, SpdySessionKeyPrivacyMode) { | 3203 TEST_P(SpdySessionTest, SpdySessionKeyPrivacyMode) { |
| 3301 CreateDeterministicNetworkSession(); | 3204 CreateNetworkSession(); |
| 3302 | 3205 |
| 3303 HostPortPair host_port_pair("www.example.org", 443); | 3206 HostPortPair host_port_pair("www.example.org", 443); |
| 3304 SpdySessionKey key_privacy_enabled(host_port_pair, ProxyServer::Direct(), | 3207 SpdySessionKey key_privacy_enabled(host_port_pair, ProxyServer::Direct(), |
| 3305 PRIVACY_MODE_ENABLED); | 3208 PRIVACY_MODE_ENABLED); |
| 3306 SpdySessionKey key_privacy_disabled(host_port_pair, ProxyServer::Direct(), | 3209 SpdySessionKey key_privacy_disabled(host_port_pair, ProxyServer::Direct(), |
| 3307 PRIVACY_MODE_DISABLED); | 3210 PRIVACY_MODE_DISABLED); |
| 3308 | 3211 |
| 3309 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_enabled)); | 3212 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_enabled)); |
| 3310 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_disabled)); | 3213 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_disabled)); |
| 3311 | 3214 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3352 private: | 3255 private: |
| 3353 const base::WeakPtr<SpdySession> session_; | 3256 const base::WeakPtr<SpdySession> session_; |
| 3354 }; | 3257 }; |
| 3355 | 3258 |
| 3356 // Create another stream in response to a stream being reset. Nothing | 3259 // Create another stream in response to a stream being reset. Nothing |
| 3357 // should blow up. This is a regression test for | 3260 // should blow up. This is a regression test for |
| 3358 // http://crbug.com/263690 . | 3261 // http://crbug.com/263690 . |
| 3359 TEST_P(SpdySessionTest, CreateStreamOnStreamReset) { | 3262 TEST_P(SpdySessionTest, CreateStreamOnStreamReset) { |
| 3360 session_deps_.host_resolver->set_synchronous_mode(true); | 3263 session_deps_.host_resolver->set_synchronous_mode(true); |
| 3361 | 3264 |
| 3362 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 3363 | |
| 3364 scoped_ptr<SpdyFrame> req( | 3265 scoped_ptr<SpdyFrame> req( |
| 3365 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); | 3266 spdy_util_.ConstructSpdyGet(nullptr, 0, false, 1, MEDIUM, true)); |
| 3366 MockWrite writes[] = { | 3267 MockWrite writes[] = { |
| 3367 CreateMockWrite(*req, 0), | 3268 CreateMockWrite(*req, 0), |
| 3368 }; | 3269 }; |
| 3369 | 3270 |
| 3370 scoped_ptr<SpdyFrame> rst( | 3271 scoped_ptr<SpdyFrame> rst( |
| 3371 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_REFUSED_STREAM)); | 3272 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_REFUSED_STREAM)); |
| 3372 MockRead reads[] = { | 3273 MockRead reads[] = { |
| 3373 CreateMockRead(*rst, 1), | 3274 MockRead(ASYNC, ERR_IO_PENDING, 1), |
| 3374 MockRead(ASYNC, 0, 2) // EOF | 3275 CreateMockRead(*rst, 2), |
| 3276 MockRead(ASYNC, ERR_IO_PENDING, 3), |
| 3277 MockRead(ASYNC, 0, 4) // EOF |
| 3375 }; | 3278 }; |
| 3376 DeterministicSocketData data(reads, arraysize(reads), | 3279 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); |
| 3377 writes, arraysize(writes)); | 3280 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 3378 data.set_connect_data(connect_data); | |
| 3379 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 3380 | 3281 |
| 3381 CreateDeterministicNetworkSession(); | 3282 CreateNetworkSession(); |
| 3382 | 3283 |
| 3383 base::WeakPtr<SpdySession> session = | 3284 base::WeakPtr<SpdySession> session = |
| 3384 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 3285 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 3385 | 3286 |
| 3386 GURL url(kDefaultURL); | 3287 GURL url(kDefaultURL); |
| 3387 base::WeakPtr<SpdyStream> spdy_stream = | 3288 base::WeakPtr<SpdyStream> spdy_stream = |
| 3388 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, | 3289 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, |
| 3389 session, url, MEDIUM, BoundNetLog()); | 3290 session, url, MEDIUM, BoundNetLog()); |
| 3390 ASSERT_TRUE(spdy_stream.get() != NULL); | 3291 ASSERT_TRUE(spdy_stream.get() != nullptr); |
| 3391 EXPECT_EQ(0u, spdy_stream->stream_id()); | 3292 EXPECT_EQ(0u, spdy_stream->stream_id()); |
| 3392 | 3293 |
| 3393 StreamCreatingDelegate delegate(spdy_stream, session); | 3294 StreamCreatingDelegate delegate(spdy_stream, session); |
| 3394 spdy_stream->SetDelegate(&delegate); | 3295 spdy_stream->SetDelegate(&delegate); |
| 3395 | 3296 |
| 3396 scoped_ptr<SpdyHeaderBlock> headers( | 3297 scoped_ptr<SpdyHeaderBlock> headers( |
| 3397 spdy_util_.ConstructGetHeaderBlock(url.spec())); | 3298 spdy_util_.ConstructGetHeaderBlock(url.spec())); |
| 3398 spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); | 3299 spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); |
| 3399 EXPECT_TRUE(spdy_stream->HasUrlFromHeaders()); | 3300 EXPECT_TRUE(spdy_stream->HasUrlFromHeaders()); |
| 3400 | 3301 |
| 3401 EXPECT_EQ(0u, spdy_stream->stream_id()); | 3302 EXPECT_EQ(0u, spdy_stream->stream_id()); |
| 3402 | 3303 |
| 3403 data.RunFor(1); | 3304 base::RunLoop().RunUntilIdle(); |
| 3404 | 3305 |
| 3405 EXPECT_EQ(1u, spdy_stream->stream_id()); | 3306 EXPECT_EQ(1u, spdy_stream->stream_id()); |
| 3406 | 3307 |
| 3407 // Cause the stream to be reset, which should cause another stream | 3308 // Cause the stream to be reset, which should cause another stream |
| 3408 // to be created. | 3309 // to be created. |
| 3409 data.RunFor(1); | 3310 data.CompleteRead(); |
| 3311 base::RunLoop().RunUntilIdle(); |
| 3410 | 3312 |
| 3411 EXPECT_EQ(NULL, spdy_stream.get()); | 3313 EXPECT_FALSE(spdy_stream); |
| 3412 EXPECT_TRUE(delegate.StreamIsClosed()); | 3314 EXPECT_TRUE(delegate.StreamIsClosed()); |
| 3413 EXPECT_EQ(0u, session->num_active_streams()); | 3315 EXPECT_EQ(0u, session->num_active_streams()); |
| 3414 EXPECT_EQ(1u, session->num_created_streams()); | 3316 EXPECT_EQ(1u, session->num_created_streams()); |
| 3317 |
| 3318 data.CompleteRead(); |
| 3319 base::RunLoop().RunUntilIdle(); |
| 3320 EXPECT_FALSE(session); |
| 3415 } | 3321 } |
| 3416 | 3322 |
| 3417 // The tests below are only for SPDY/3 and above. | 3323 // The tests below are only for SPDY/3 and above. |
| 3418 | 3324 |
| 3419 TEST_P(SpdySessionTest, UpdateStreamsSendWindowSize) { | 3325 TEST_P(SpdySessionTest, UpdateStreamsSendWindowSize) { |
| 3420 // Set SETTINGS_INITIAL_WINDOW_SIZE to a small number so that WINDOW_UPDATE | 3326 // Set SETTINGS_INITIAL_WINDOW_SIZE to a small number so that WINDOW_UPDATE |
| 3421 // gets sent. | 3327 // gets sent. |
| 3422 SettingsMap new_settings; | 3328 SettingsMap new_settings; |
| 3423 int32 window_size = 1; | 3329 int32 window_size = 1; |
| 3424 new_settings[SETTINGS_INITIAL_WINDOW_SIZE] = | 3330 new_settings[SETTINGS_INITIAL_WINDOW_SIZE] = |
| 3425 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, window_size); | 3331 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, window_size); |
| 3426 | 3332 |
| 3427 // Set up the socket so we read a SETTINGS frame that sets | 3333 // Set up the socket so we read a SETTINGS frame that sets |
| 3428 // INITIAL_WINDOW_SIZE. | 3334 // INITIAL_WINDOW_SIZE. |
| 3429 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 3430 scoped_ptr<SpdyFrame> settings_frame( | 3335 scoped_ptr<SpdyFrame> settings_frame( |
| 3431 spdy_util_.ConstructSpdySettings(new_settings)); | 3336 spdy_util_.ConstructSpdySettings(new_settings)); |
| 3432 MockRead reads[] = { | 3337 MockRead reads[] = { |
| 3433 CreateMockRead(*settings_frame, 0), | 3338 CreateMockRead(*settings_frame, 0), |
| 3434 MockRead(ASYNC, 0, 1) // EOF | 3339 MockRead(ASYNC, ERR_IO_PENDING, 1), |
| 3340 MockRead(ASYNC, 0, 2) // EOF |
| 3435 }; | 3341 }; |
| 3436 | 3342 |
| 3437 scoped_ptr<SpdyFrame> settings_ack(spdy_util_.ConstructSpdySettingsAck()); | 3343 scoped_ptr<SpdyFrame> settings_ack(spdy_util_.ConstructSpdySettingsAck()); |
| 3438 MockWrite writes[] = { | 3344 MockWrite writes[] = { |
| 3439 CreateMockWrite(*settings_ack, 2), | 3345 CreateMockWrite(*settings_ack, 3), |
| 3440 }; | 3346 }; |
| 3441 | 3347 |
| 3442 session_deps_.host_resolver->set_synchronous_mode(true); | 3348 session_deps_.host_resolver->set_synchronous_mode(true); |
| 3443 | 3349 |
| 3444 DeterministicSocketData data(reads, arraysize(reads), | 3350 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); |
| 3445 writes, arraysize(writes)); | 3351 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 3446 data.set_connect_data(connect_data); | |
| 3447 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 3448 | 3352 |
| 3449 CreateDeterministicNetworkSession(); | 3353 CreateNetworkSession(); |
| 3450 | 3354 |
| 3451 base::WeakPtr<SpdySession> session = | 3355 base::WeakPtr<SpdySession> session = |
| 3452 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 3356 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 3453 base::WeakPtr<SpdyStream> spdy_stream1 = | 3357 base::WeakPtr<SpdyStream> spdy_stream1 = |
| 3454 CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, | 3358 CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, |
| 3455 session, test_url_, MEDIUM, BoundNetLog()); | 3359 session, test_url_, MEDIUM, BoundNetLog()); |
| 3456 ASSERT_TRUE(spdy_stream1.get() != NULL); | 3360 ASSERT_TRUE(spdy_stream1.get() != nullptr); |
| 3457 TestCompletionCallback callback1; | 3361 TestCompletionCallback callback1; |
| 3458 EXPECT_NE(spdy_stream1->send_window_size(), window_size); | 3362 EXPECT_NE(spdy_stream1->send_window_size(), window_size); |
| 3459 | 3363 |
| 3460 data.RunFor(1); // Process the SETTINGS frame, but not the EOF | 3364 // Process the SETTINGS frame. |
| 3461 base::MessageLoop::current()->RunUntilIdle(); | 3365 base::RunLoop().RunUntilIdle(); |
| 3462 EXPECT_EQ(session->stream_initial_send_window_size(), window_size); | 3366 EXPECT_EQ(session->stream_initial_send_window_size(), window_size); |
| 3463 EXPECT_EQ(spdy_stream1->send_window_size(), window_size); | 3367 EXPECT_EQ(spdy_stream1->send_window_size(), window_size); |
| 3464 | 3368 |
| 3465 // Release the first one, this will allow the second to be created. | 3369 // Release the first one, this will allow the second to be created. |
| 3466 spdy_stream1->Cancel(); | 3370 spdy_stream1->Cancel(); |
| 3467 EXPECT_EQ(NULL, spdy_stream1.get()); | 3371 EXPECT_FALSE(spdy_stream1); |
| 3468 | 3372 |
| 3469 base::WeakPtr<SpdyStream> spdy_stream2 = | 3373 base::WeakPtr<SpdyStream> spdy_stream2 = |
| 3470 CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, | 3374 CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, |
| 3471 session, test_url_, MEDIUM, BoundNetLog()); | 3375 session, test_url_, MEDIUM, BoundNetLog()); |
| 3472 ASSERT_TRUE(spdy_stream2.get() != NULL); | 3376 ASSERT_TRUE(spdy_stream2.get() != nullptr); |
| 3473 EXPECT_EQ(spdy_stream2->send_window_size(), window_size); | 3377 EXPECT_EQ(spdy_stream2->send_window_size(), window_size); |
| 3474 spdy_stream2->Cancel(); | 3378 spdy_stream2->Cancel(); |
| 3475 EXPECT_EQ(NULL, spdy_stream2.get()); | 3379 EXPECT_FALSE(spdy_stream2); |
| 3380 |
| 3381 EXPECT_TRUE(session); |
| 3382 data.CompleteRead(); |
| 3383 base::RunLoop().RunUntilIdle(); |
| 3384 EXPECT_FALSE(session); |
| 3476 } | 3385 } |
| 3477 | 3386 |
| 3478 // The tests below are only for SPDY/3.1 and above. | 3387 // The tests below are only for SPDY/3.1 and above. |
| 3479 | 3388 |
| 3480 // SpdySession::{Increase,Decrease}RecvWindowSize should properly | 3389 // SpdySession::{Increase,Decrease}RecvWindowSize should properly |
| 3481 // adjust the session receive window size for SPDY 3.1 and higher. In | 3390 // adjust the session receive window size. In addition, |
| 3482 // addition, SpdySession::IncreaseRecvWindowSize should trigger | 3391 // SpdySession::IncreaseRecvWindowSize should trigger |
| 3483 // sending a WINDOW_UPDATE frame for a large enough delta. | 3392 // sending a WINDOW_UPDATE frame for a large enough delta. |
| 3484 TEST_P(SpdySessionTest, AdjustRecvWindowSize) { | 3393 TEST_P(SpdySessionTest, AdjustRecvWindowSize) { |
| 3485 if (GetParam() < kProtoSPDY31) | 3394 if (GetParam() < kProtoSPDY31) |
| 3486 return; | 3395 return; |
| 3487 | 3396 |
| 3488 session_deps_.host_resolver->set_synchronous_mode(true); | 3397 session_deps_.host_resolver->set_synchronous_mode(true); |
| 3489 | 3398 |
| 3490 const int32 initial_window_size = | 3399 const int32 initial_window_size = |
| 3491 SpdySession::GetDefaultInitialWindowSize(GetParam()); | 3400 SpdySession::GetDefaultInitialWindowSize(GetParam()); |
| 3492 const int32 delta_window_size = 100; | 3401 const int32 delta_window_size = 100; |
| 3493 | 3402 |
| 3494 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 3495 MockRead reads[] = { | 3403 MockRead reads[] = { |
| 3496 MockRead(ASYNC, 0, 1) // EOF | 3404 MockRead(ASYNC, ERR_IO_PENDING, 1), MockRead(ASYNC, 0, 2) // EOF |
| 3497 }; | 3405 }; |
| 3498 scoped_ptr<SpdyFrame> window_update(spdy_util_.ConstructSpdyWindowUpdate( | 3406 scoped_ptr<SpdyFrame> window_update(spdy_util_.ConstructSpdyWindowUpdate( |
| 3499 kSessionFlowControlStreamId, initial_window_size + delta_window_size)); | 3407 kSessionFlowControlStreamId, initial_window_size + delta_window_size)); |
| 3500 MockWrite writes[] = { | 3408 MockWrite writes[] = { |
| 3501 CreateMockWrite(*window_update, 0), | 3409 CreateMockWrite(*window_update, 0), |
| 3502 }; | 3410 }; |
| 3503 DeterministicSocketData data(reads, arraysize(reads), | 3411 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); |
| 3504 writes, arraysize(writes)); | 3412 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 3505 data.set_connect_data(connect_data); | |
| 3506 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 3507 | 3413 |
| 3508 CreateDeterministicNetworkSession(); | 3414 CreateNetworkSession(); |
| 3509 base::WeakPtr<SpdySession> session = | 3415 base::WeakPtr<SpdySession> session = |
| 3510 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 3416 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 3511 EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION, | 3417 EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION, |
| 3512 session->flow_control_state()); | 3418 session->flow_control_state()); |
| 3513 | 3419 |
| 3514 EXPECT_EQ(initial_window_size, session->session_recv_window_size_); | 3420 EXPECT_EQ(initial_window_size, session->session_recv_window_size_); |
| 3515 EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); | 3421 EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); |
| 3516 | 3422 |
| 3517 session->IncreaseRecvWindowSize(delta_window_size); | 3423 session->IncreaseRecvWindowSize(delta_window_size); |
| 3518 EXPECT_EQ(initial_window_size + delta_window_size, | 3424 EXPECT_EQ(initial_window_size + delta_window_size, |
| 3519 session->session_recv_window_size_); | 3425 session->session_recv_window_size_); |
| 3520 EXPECT_EQ(delta_window_size, session->session_unacked_recv_window_bytes_); | 3426 EXPECT_EQ(delta_window_size, session->session_unacked_recv_window_bytes_); |
| 3521 | 3427 |
| 3522 // Should trigger sending a WINDOW_UPDATE frame. | 3428 // Should trigger sending a WINDOW_UPDATE frame. |
| 3523 session->IncreaseRecvWindowSize(initial_window_size); | 3429 session->IncreaseRecvWindowSize(initial_window_size); |
| 3524 EXPECT_EQ(initial_window_size + delta_window_size + initial_window_size, | 3430 EXPECT_EQ(initial_window_size + delta_window_size + initial_window_size, |
| 3525 session->session_recv_window_size_); | 3431 session->session_recv_window_size_); |
| 3526 EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); | 3432 EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); |
| 3527 | 3433 |
| 3528 data.RunFor(1); | 3434 base::RunLoop().RunUntilIdle(); |
| 3529 | 3435 |
| 3530 // DecreaseRecvWindowSize() expects |in_io_loop_| to be true. | 3436 // DecreaseRecvWindowSize() expects |in_io_loop_| to be true. |
| 3531 session->in_io_loop_ = true; | 3437 session->in_io_loop_ = true; |
| 3532 session->DecreaseRecvWindowSize(initial_window_size + delta_window_size + | 3438 session->DecreaseRecvWindowSize(initial_window_size + delta_window_size + |
| 3533 initial_window_size); | 3439 initial_window_size); |
| 3534 session->in_io_loop_ = false; | 3440 session->in_io_loop_ = false; |
| 3535 EXPECT_EQ(0, session->session_recv_window_size_); | 3441 EXPECT_EQ(0, session->session_recv_window_size_); |
| 3536 EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); | 3442 EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); |
| 3443 |
| 3444 EXPECT_TRUE(session); |
| 3445 data.CompleteRead(); |
| 3446 base::RunLoop().RunUntilIdle(); |
| 3447 EXPECT_FALSE(session); |
| 3537 } | 3448 } |
| 3538 | 3449 |
| 3539 // SpdySession::{Increase,Decrease}SendWindowSize should properly | 3450 // SpdySession::{Increase,Decrease}SendWindowSize should properly |
| 3540 // adjust the session send window size when the "enable_spdy_31" flag | 3451 // adjust the session send window size when the "enable_spdy_31" flag |
| 3541 // is set. | 3452 // is set. |
| 3542 TEST_P(SpdySessionTest, AdjustSendWindowSize) { | 3453 TEST_P(SpdySessionTest, AdjustSendWindowSize) { |
| 3543 if (GetParam() < kProtoSPDY31) | 3454 if (GetParam() < kProtoSPDY31) |
| 3544 return; | 3455 return; |
| 3545 | 3456 |
| 3546 session_deps_.host_resolver->set_synchronous_mode(true); | 3457 session_deps_.host_resolver->set_synchronous_mode(true); |
| 3547 | 3458 |
| 3548 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 3549 MockRead reads[] = { | 3459 MockRead reads[] = { |
| 3550 MockRead(SYNCHRONOUS, 0, 0) // EOF | 3460 MockRead(SYNCHRONOUS, 0, 0) // EOF |
| 3551 }; | 3461 }; |
| 3552 StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0); | 3462 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0); |
| 3553 data.set_connect_data(connect_data); | |
| 3554 session_deps_.socket_factory->AddSocketDataProvider(&data); | 3463 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 3555 | 3464 |
| 3556 CreateNetworkSession(); | 3465 CreateNetworkSession(); |
| 3557 base::WeakPtr<SpdySession> session = | 3466 base::WeakPtr<SpdySession> session = |
| 3558 CreateFakeSpdySession(spdy_session_pool_, key_); | 3467 CreateFakeSpdySession(spdy_session_pool_, key_); |
| 3559 EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION, | 3468 EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION, |
| 3560 session->flow_control_state()); | 3469 session->flow_control_state()); |
| 3561 | 3470 |
| 3562 const int32 initial_window_size = | 3471 const int32 initial_window_size = |
| 3563 SpdySession::GetDefaultInitialWindowSize(GetParam()); | 3472 SpdySession::GetDefaultInitialWindowSize(GetParam()); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 3575 | 3484 |
| 3576 // Incoming data for an inactive stream should not cause the session | 3485 // Incoming data for an inactive stream should not cause the session |
| 3577 // receive window size to decrease, but it should cause the unacked | 3486 // receive window size to decrease, but it should cause the unacked |
| 3578 // bytes to increase. | 3487 // bytes to increase. |
| 3579 TEST_P(SpdySessionTest, SessionFlowControlInactiveStream) { | 3488 TEST_P(SpdySessionTest, SessionFlowControlInactiveStream) { |
| 3580 if (GetParam() < kProtoSPDY31) | 3489 if (GetParam() < kProtoSPDY31) |
| 3581 return; | 3490 return; |
| 3582 | 3491 |
| 3583 session_deps_.host_resolver->set_synchronous_mode(true); | 3492 session_deps_.host_resolver->set_synchronous_mode(true); |
| 3584 | 3493 |
| 3585 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 3586 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyBodyFrame(1, false)); | 3494 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyBodyFrame(1, false)); |
| 3587 MockRead reads[] = { | 3495 MockRead reads[] = { |
| 3588 CreateMockRead(*resp, 0), | 3496 CreateMockRead(*resp, 0), |
| 3589 MockRead(ASYNC, 0, 1) // EOF | 3497 MockRead(ASYNC, ERR_IO_PENDING, 1), |
| 3498 MockRead(ASYNC, 0, 2) // EOF |
| 3590 }; | 3499 }; |
| 3591 DeterministicSocketData data(reads, arraysize(reads), NULL, 0); | 3500 SequencedSocketData data(reads, arraysize(reads), nullptr, 0); |
| 3592 data.set_connect_data(connect_data); | 3501 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 3593 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 3594 | 3502 |
| 3595 CreateDeterministicNetworkSession(); | 3503 CreateNetworkSession(); |
| 3596 base::WeakPtr<SpdySession> session = | 3504 base::WeakPtr<SpdySession> session = |
| 3597 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 3505 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 3598 EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION, | 3506 EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION, |
| 3599 session->flow_control_state()); | 3507 session->flow_control_state()); |
| 3600 | 3508 |
| 3601 EXPECT_EQ(SpdySession::GetDefaultInitialWindowSize(GetParam()), | 3509 EXPECT_EQ(SpdySession::GetDefaultInitialWindowSize(GetParam()), |
| 3602 session->session_recv_window_size_); | 3510 session->session_recv_window_size_); |
| 3603 EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); | 3511 EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); |
| 3604 | 3512 |
| 3605 data.RunFor(1); | 3513 base::RunLoop().RunUntilIdle(); |
| 3606 | 3514 |
| 3607 EXPECT_EQ(SpdySession::GetDefaultInitialWindowSize(GetParam()), | 3515 EXPECT_EQ(SpdySession::GetDefaultInitialWindowSize(GetParam()), |
| 3608 session->session_recv_window_size_); | 3516 session->session_recv_window_size_); |
| 3609 EXPECT_EQ(kUploadDataSize, session->session_unacked_recv_window_bytes_); | 3517 EXPECT_EQ(kUploadDataSize, session->session_unacked_recv_window_bytes_); |
| 3610 | 3518 |
| 3611 data.RunFor(1); | 3519 EXPECT_TRUE(session); |
| 3520 data.CompleteRead(); |
| 3521 base::RunLoop().RunUntilIdle(); |
| 3522 EXPECT_FALSE(session); |
| 3612 } | 3523 } |
| 3613 | 3524 |
| 3614 // The frame header is not included in flow control, but frame payload | 3525 // The frame header is not included in flow control, but frame payload |
| 3615 // (including optional pad length and padding) is. | 3526 // (including optional pad length and padding) is. |
| 3616 TEST_P(SpdySessionTest, SessionFlowControlPadding) { | 3527 TEST_P(SpdySessionTest, SessionFlowControlPadding) { |
| 3617 // Padding only exists in HTTP/2. | 3528 // Padding only exists in HTTP/2. |
| 3618 if (GetParam() < kProtoSPDY4MinimumVersion) | 3529 if (GetParam() < kProtoSPDY4MinimumVersion) |
| 3619 return; | 3530 return; |
| 3620 | 3531 |
| 3621 session_deps_.host_resolver->set_synchronous_mode(true); | 3532 session_deps_.host_resolver->set_synchronous_mode(true); |
| 3622 | 3533 |
| 3623 const int padding_length = 42; | 3534 const int padding_length = 42; |
| 3624 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 3625 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyBodyFrame( | 3535 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyBodyFrame( |
| 3626 1, kUploadData, kUploadDataSize, false, padding_length)); | 3536 1, kUploadData, kUploadDataSize, false, padding_length)); |
| 3627 MockRead reads[] = { | 3537 MockRead reads[] = { |
| 3628 CreateMockRead(*resp, 0), MockRead(ASYNC, 0, 1) // EOF | 3538 CreateMockRead(*resp, 0), |
| 3539 MockRead(ASYNC, ERR_IO_PENDING, 1), |
| 3540 MockRead(ASYNC, 0, 2) // EOF |
| 3629 }; | 3541 }; |
| 3630 DeterministicSocketData data(reads, arraysize(reads), NULL, 0); | 3542 SequencedSocketData data(reads, arraysize(reads), nullptr, 0); |
| 3631 data.set_connect_data(connect_data); | 3543 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 3632 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 3633 | 3544 |
| 3634 CreateDeterministicNetworkSession(); | 3545 CreateNetworkSession(); |
| 3635 base::WeakPtr<SpdySession> session = | 3546 base::WeakPtr<SpdySession> session = |
| 3636 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 3547 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 3637 EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION, | 3548 EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION, |
| 3638 session->flow_control_state()); | 3549 session->flow_control_state()); |
| 3639 | 3550 |
| 3640 EXPECT_EQ(SpdySession::GetDefaultInitialWindowSize(GetParam()), | 3551 EXPECT_EQ(SpdySession::GetDefaultInitialWindowSize(GetParam()), |
| 3641 session->session_recv_window_size_); | 3552 session->session_recv_window_size_); |
| 3642 EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); | 3553 EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); |
| 3643 | 3554 |
| 3644 data.RunFor(1); | 3555 base::RunLoop().RunUntilIdle(); |
| 3645 | 3556 |
| 3646 EXPECT_EQ(SpdySession::GetDefaultInitialWindowSize(GetParam()), | 3557 EXPECT_EQ(SpdySession::GetDefaultInitialWindowSize(GetParam()), |
| 3647 session->session_recv_window_size_); | 3558 session->session_recv_window_size_); |
| 3648 EXPECT_EQ(kUploadDataSize + padding_length, | 3559 EXPECT_EQ(kUploadDataSize + padding_length, |
| 3649 session->session_unacked_recv_window_bytes_); | 3560 session->session_unacked_recv_window_bytes_); |
| 3650 | 3561 |
| 3651 data.RunFor(1); | 3562 data.CompleteRead(); |
| 3563 base::RunLoop().RunUntilIdle(); |
| 3564 EXPECT_FALSE(session); |
| 3652 } | 3565 } |
| 3653 | 3566 |
| 3654 // Peer sends more data than stream level receiving flow control window. | 3567 // Peer sends more data than stream level receiving flow control window. |
| 3655 TEST_P(SpdySessionTest, StreamFlowControlTooMuchData) { | 3568 TEST_P(SpdySessionTest, StreamFlowControlTooMuchData) { |
| 3656 const int32 stream_max_recv_window_size = 1024; | 3569 const int32 stream_max_recv_window_size = 1024; |
| 3657 const int32 data_frame_size = 2 * stream_max_recv_window_size; | 3570 const int32 data_frame_size = 2 * stream_max_recv_window_size; |
| 3658 | 3571 |
| 3659 scoped_ptr<SpdyFrame> req( | 3572 scoped_ptr<SpdyFrame> req( |
| 3660 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); | 3573 spdy_util_.ConstructSpdyGet(nullptr, 0, false, 1, LOWEST, true)); |
| 3574 scoped_ptr<SpdyFrame> rst( |
| 3575 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_FLOW_CONTROL_ERROR)); |
| 3661 MockWrite writes[] = { | 3576 MockWrite writes[] = { |
| 3662 CreateMockWrite(*req, 0), | 3577 CreateMockWrite(*req, 0), CreateMockWrite(*rst, 4), |
| 3663 }; | 3578 }; |
| 3664 | 3579 |
| 3665 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); | 3580 scoped_ptr<SpdyFrame> resp( |
| 3581 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); |
| 3666 const std::string payload(data_frame_size, 'a'); | 3582 const std::string payload(data_frame_size, 'a'); |
| 3667 scoped_ptr<SpdyFrame> data_frame(spdy_util_.ConstructSpdyBodyFrame( | 3583 scoped_ptr<SpdyFrame> data_frame(spdy_util_.ConstructSpdyBodyFrame( |
| 3668 1, payload.data(), data_frame_size, false)); | 3584 1, payload.data(), data_frame_size, false)); |
| 3669 MockRead reads[] = { | 3585 MockRead reads[] = { |
| 3670 CreateMockRead(*resp, 1), | 3586 CreateMockRead(*resp, 1), |
| 3671 CreateMockRead(*data_frame, 2), | 3587 MockRead(ASYNC, ERR_IO_PENDING, 2), |
| 3672 MockRead(ASYNC, 0, 3), | 3588 CreateMockRead(*data_frame, 3), |
| 3589 MockRead(ASYNC, ERR_IO_PENDING, 5), |
| 3590 MockRead(ASYNC, 0, 6), |
| 3673 }; | 3591 }; |
| 3674 | 3592 |
| 3675 DeterministicSocketData data(reads, arraysize(reads), writes, | 3593 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); |
| 3676 arraysize(writes)); | 3594 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 3677 data.set_connect_data(MockConnect(SYNCHRONOUS, OK)); | 3595 CreateNetworkSession(); |
| 3678 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 3679 CreateDeterministicNetworkSession(); | |
| 3680 | 3596 |
| 3681 SpdySessionPoolPeer pool_peer(spdy_session_pool_); | 3597 SpdySessionPoolPeer pool_peer(spdy_session_pool_); |
| 3682 pool_peer.SetStreamInitialRecvWindowSize(stream_max_recv_window_size); | 3598 pool_peer.SetStreamInitialRecvWindowSize(stream_max_recv_window_size); |
| 3683 base::WeakPtr<SpdySession> session = | 3599 base::WeakPtr<SpdySession> session = |
| 3684 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 3600 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 3685 EXPECT_LE(SpdySession::FLOW_CONTROL_STREAM, session->flow_control_state()); | 3601 EXPECT_LE(SpdySession::FLOW_CONTROL_STREAM, session->flow_control_state()); |
| 3686 | 3602 |
| 3687 GURL url(kDefaultURL); | 3603 GURL url(kDefaultURL); |
| 3688 base::WeakPtr<SpdyStream> spdy_stream = CreateStreamSynchronously( | 3604 base::WeakPtr<SpdyStream> spdy_stream = CreateStreamSynchronously( |
| 3689 SPDY_REQUEST_RESPONSE_STREAM, session, url, LOWEST, BoundNetLog()); | 3605 SPDY_REQUEST_RESPONSE_STREAM, session, url, LOWEST, BoundNetLog()); |
| 3690 EXPECT_EQ(stream_max_recv_window_size, spdy_stream->recv_window_size()); | 3606 EXPECT_EQ(stream_max_recv_window_size, spdy_stream->recv_window_size()); |
| 3691 | 3607 |
| 3692 test::StreamDelegateDoNothing delegate(spdy_stream); | 3608 test::StreamDelegateDoNothing delegate(spdy_stream); |
| 3693 spdy_stream->SetDelegate(&delegate); | 3609 spdy_stream->SetDelegate(&delegate); |
| 3694 | 3610 |
| 3695 scoped_ptr<SpdyHeaderBlock> headers( | 3611 scoped_ptr<SpdyHeaderBlock> headers( |
| 3696 spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); | 3612 spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); |
| 3697 EXPECT_EQ(ERR_IO_PENDING, spdy_stream->SendRequestHeaders( | 3613 EXPECT_EQ(ERR_IO_PENDING, spdy_stream->SendRequestHeaders( |
| 3698 headers.Pass(), NO_MORE_DATA_TO_SEND)); | 3614 headers.Pass(), NO_MORE_DATA_TO_SEND)); |
| 3699 | 3615 |
| 3700 // Request and response. | 3616 // Request and response. |
| 3701 data.RunFor(2); | 3617 base::RunLoop().RunUntilIdle(); |
| 3702 EXPECT_EQ(1u, spdy_stream->stream_id()); | 3618 EXPECT_EQ(1u, spdy_stream->stream_id()); |
| 3703 | 3619 |
| 3704 // Too large data frame causes flow control error, should close stream. | 3620 // Too large data frame causes flow control error, should close stream. |
| 3705 data.RunFor(1); | 3621 data.CompleteRead(); |
| 3706 EXPECT_EQ(nullptr, spdy_stream.get()); | 3622 base::RunLoop().RunUntilIdle(); |
| 3623 EXPECT_FALSE(spdy_stream); |
| 3624 |
| 3625 EXPECT_TRUE(session); |
| 3626 data.CompleteRead(); |
| 3627 base::RunLoop().RunUntilIdle(); |
| 3628 EXPECT_FALSE(session); |
| 3707 } | 3629 } |
| 3708 | 3630 |
| 3709 // Regression test for a bug that was caused by including unsent WINDOW_UPDATE | 3631 // Regression test for a bug that was caused by including unsent WINDOW_UPDATE |
| 3710 // deltas in the receiving window size when checking incoming frames for flow | 3632 // deltas in the receiving window size when checking incoming frames for flow |
| 3711 // control errors at session level. | 3633 // control errors at session level. |
| 3712 TEST_P(SpdySessionTest, SessionFlowControlTooMuchDataTwoDataFrames) { | 3634 TEST_P(SpdySessionTest, SessionFlowControlTooMuchDataTwoDataFrames) { |
| 3713 if (GetParam() < kProtoSPDY31) | 3635 if (GetParam() < kProtoSPDY31) |
| 3714 return; | 3636 return; |
| 3715 | 3637 |
| 3716 const int32 session_max_recv_window_size = 500; | 3638 const int32 session_max_recv_window_size = 500; |
| 3717 const int32 first_data_frame_size = 200; | 3639 const int32 first_data_frame_size = 200; |
| 3718 const int32 second_data_frame_size = 400; | 3640 const int32 second_data_frame_size = 400; |
| 3719 | 3641 |
| 3720 // First data frame should not trigger a WINDOW_UPDATE. | 3642 // First data frame should not trigger a WINDOW_UPDATE. |
| 3721 ASSERT_GT(session_max_recv_window_size / 2, first_data_frame_size); | 3643 ASSERT_GT(session_max_recv_window_size / 2, first_data_frame_size); |
| 3722 // Second data frame would be fine had there been a WINDOW_UPDATE. | 3644 // Second data frame would be fine had there been a WINDOW_UPDATE. |
| 3723 ASSERT_GT(session_max_recv_window_size, second_data_frame_size); | 3645 ASSERT_GT(session_max_recv_window_size, second_data_frame_size); |
| 3724 // But in fact, the two data frames together overflow the receiving window at | 3646 // But in fact, the two data frames together overflow the receiving window at |
| 3725 // session level. | 3647 // session level. |
| 3726 ASSERT_LT(session_max_recv_window_size, | 3648 ASSERT_LT(session_max_recv_window_size, |
| 3727 first_data_frame_size + second_data_frame_size); | 3649 first_data_frame_size + second_data_frame_size); |
| 3728 | 3650 |
| 3729 session_deps_.host_resolver->set_synchronous_mode(true); | 3651 session_deps_.host_resolver->set_synchronous_mode(true); |
| 3730 | 3652 |
| 3653 scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway( |
| 3654 0, GOAWAY_FLOW_CONTROL_ERROR, |
| 3655 "delta_window_size is 400 in DecreaseRecvWindowSize, which is larger " |
| 3656 "than the receive window size of 500")); |
| 3657 MockWrite writes[] = { |
| 3658 CreateMockWrite(*goaway, 4), |
| 3659 }; |
| 3660 |
| 3731 const std::string first_data_frame(first_data_frame_size, 'a'); | 3661 const std::string first_data_frame(first_data_frame_size, 'a'); |
| 3732 scoped_ptr<SpdyFrame> first(spdy_util_.ConstructSpdyBodyFrame( | 3662 scoped_ptr<SpdyFrame> first(spdy_util_.ConstructSpdyBodyFrame( |
| 3733 1, first_data_frame.data(), first_data_frame_size, false)); | 3663 1, first_data_frame.data(), first_data_frame_size, false)); |
| 3734 const std::string second_data_frame(second_data_frame_size, 'b'); | 3664 const std::string second_data_frame(second_data_frame_size, 'b'); |
| 3735 scoped_ptr<SpdyFrame> second(spdy_util_.ConstructSpdyBodyFrame( | 3665 scoped_ptr<SpdyFrame> second(spdy_util_.ConstructSpdyBodyFrame( |
| 3736 1, second_data_frame.data(), second_data_frame_size, false)); | 3666 1, second_data_frame.data(), second_data_frame_size, false)); |
| 3737 MockRead reads[] = { | 3667 MockRead reads[] = { |
| 3738 CreateMockRead(*first, 0), | 3668 CreateMockRead(*first, 0), |
| 3739 CreateMockRead(*second, 1), | 3669 MockRead(ASYNC, ERR_IO_PENDING, 1), |
| 3740 MockRead(ASYNC, 0, 2), | 3670 CreateMockRead(*second, 2), |
| 3671 MockRead(ASYNC, 0, 3), |
| 3741 }; | 3672 }; |
| 3742 DeterministicSocketData data(reads, arraysize(reads), NULL, 0); | 3673 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); |
| 3743 data.set_connect_data(MockConnect(SYNCHRONOUS, OK)); | 3674 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 3744 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 3745 | 3675 |
| 3746 CreateDeterministicNetworkSession(); | 3676 CreateNetworkSession(); |
| 3747 base::WeakPtr<SpdySession> session = | 3677 base::WeakPtr<SpdySession> session = |
| 3748 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 3678 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 3749 EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION, | 3679 EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION, |
| 3750 session->flow_control_state()); | 3680 session->flow_control_state()); |
| 3751 // Setting session level receiving window size to smaller than initial is not | 3681 // Setting session level receiving window size to smaller than initial is not |
| 3752 // possible via SpdySessionPoolPeer. | 3682 // possible via SpdySessionPoolPeer. |
| 3753 session->session_recv_window_size_ = session_max_recv_window_size; | 3683 session->session_recv_window_size_ = session_max_recv_window_size; |
| 3754 | 3684 |
| 3755 // First data frame is immediately consumed and does not trigger | 3685 // First data frame is immediately consumed and does not trigger |
| 3756 // WINDOW_UPDATE. | 3686 // WINDOW_UPDATE. |
| 3757 data.RunFor(1); | 3687 base::RunLoop().RunUntilIdle(); |
| 3758 EXPECT_EQ(first_data_frame_size, session->session_unacked_recv_window_bytes_); | 3688 EXPECT_EQ(first_data_frame_size, session->session_unacked_recv_window_bytes_); |
| 3759 EXPECT_EQ(session_max_recv_window_size, session->session_recv_window_size_); | 3689 EXPECT_EQ(session_max_recv_window_size, session->session_recv_window_size_); |
| 3760 EXPECT_EQ(SpdySession::STATE_AVAILABLE, session->availability_state_); | 3690 EXPECT_EQ(SpdySession::STATE_AVAILABLE, session->availability_state_); |
| 3761 | 3691 |
| 3762 // Second data frame overflows receiving window, causes session to close. | 3692 // Second data frame overflows receiving window, causes session to close. |
| 3763 data.RunFor(1); | 3693 data.CompleteRead(); |
| 3694 base::RunLoop().RunUntilIdle(); |
| 3764 EXPECT_EQ(SpdySession::STATE_DRAINING, session->availability_state_); | 3695 EXPECT_EQ(SpdySession::STATE_DRAINING, session->availability_state_); |
| 3765 } | 3696 } |
| 3766 | 3697 |
| 3767 // Regression test for a bug that was caused by including unsent WINDOW_UPDATE | 3698 // Regression test for a bug that was caused by including unsent WINDOW_UPDATE |
| 3768 // deltas in the receiving window size when checking incoming data frames for | 3699 // deltas in the receiving window size when checking incoming data frames for |
| 3769 // flow control errors at stream level. | 3700 // flow control errors at stream level. |
| 3770 TEST_P(SpdySessionTest, StreamFlowControlTooMuchDataTwoDataFrames) { | 3701 TEST_P(SpdySessionTest, StreamFlowControlTooMuchDataTwoDataFrames) { |
| 3771 if (GetParam() < kProtoSPDY3) | 3702 if (GetParam() < kProtoSPDY3) |
| 3772 return; | 3703 return; |
| 3773 | 3704 |
| 3774 const int32 stream_max_recv_window_size = 500; | 3705 const int32 stream_max_recv_window_size = 500; |
| 3775 const int32 first_data_frame_size = 200; | 3706 const int32 first_data_frame_size = 200; |
| 3776 const int32 second_data_frame_size = 400; | 3707 const int32 second_data_frame_size = 400; |
| 3777 | 3708 |
| 3778 // First data frame should not trigger a WINDOW_UPDATE. | 3709 // First data frame should not trigger a WINDOW_UPDATE. |
| 3779 ASSERT_GT(stream_max_recv_window_size / 2, first_data_frame_size); | 3710 ASSERT_GT(stream_max_recv_window_size / 2, first_data_frame_size); |
| 3780 // Second data frame would be fine had there been a WINDOW_UPDATE. | 3711 // Second data frame would be fine had there been a WINDOW_UPDATE. |
| 3781 ASSERT_GT(stream_max_recv_window_size, second_data_frame_size); | 3712 ASSERT_GT(stream_max_recv_window_size, second_data_frame_size); |
| 3782 // But in fact, they should overflow the receiving window at stream level. | 3713 // But in fact, they should overflow the receiving window at stream level. |
| 3783 ASSERT_LT(stream_max_recv_window_size, | 3714 ASSERT_LT(stream_max_recv_window_size, |
| 3784 first_data_frame_size + second_data_frame_size); | 3715 first_data_frame_size + second_data_frame_size); |
| 3785 | 3716 |
| 3786 scoped_ptr<SpdyFrame> req( | 3717 scoped_ptr<SpdyFrame> req( |
| 3787 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); | 3718 spdy_util_.ConstructSpdyGet(nullptr, 0, false, 1, LOWEST, true)); |
| 3788 scoped_ptr<SpdyFrame> rst( | 3719 scoped_ptr<SpdyFrame> rst( |
| 3789 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_FLOW_CONTROL_ERROR)); | 3720 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_FLOW_CONTROL_ERROR)); |
| 3790 MockWrite writes[] = { | 3721 MockWrite writes[] = { |
| 3791 CreateMockWrite(*req, 0), CreateMockWrite(*rst, 4), | 3722 CreateMockWrite(*req, 0), CreateMockWrite(*rst, 6), |
| 3792 }; | 3723 }; |
| 3793 | 3724 |
| 3794 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); | 3725 scoped_ptr<SpdyFrame> resp( |
| 3726 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); |
| 3795 const std::string first_data_frame(first_data_frame_size, 'a'); | 3727 const std::string first_data_frame(first_data_frame_size, 'a'); |
| 3796 scoped_ptr<SpdyFrame> first(spdy_util_.ConstructSpdyBodyFrame( | 3728 scoped_ptr<SpdyFrame> first(spdy_util_.ConstructSpdyBodyFrame( |
| 3797 1, first_data_frame.data(), first_data_frame_size, false)); | 3729 1, first_data_frame.data(), first_data_frame_size, false)); |
| 3798 const std::string second_data_frame(second_data_frame_size, 'b'); | 3730 const std::string second_data_frame(second_data_frame_size, 'b'); |
| 3799 scoped_ptr<SpdyFrame> second(spdy_util_.ConstructSpdyBodyFrame( | 3731 scoped_ptr<SpdyFrame> second(spdy_util_.ConstructSpdyBodyFrame( |
| 3800 1, second_data_frame.data(), second_data_frame_size, false)); | 3732 1, second_data_frame.data(), second_data_frame_size, false)); |
| 3801 MockRead reads[] = { | 3733 MockRead reads[] = { |
| 3802 CreateMockRead(*resp, 1), | 3734 CreateMockRead(*resp, 1), |
| 3803 CreateMockRead(*first, 2), | 3735 MockRead(ASYNC, ERR_IO_PENDING, 2), |
| 3804 CreateMockRead(*second, 3), | 3736 CreateMockRead(*first, 3), |
| 3805 MockRead(ASYNC, 0, 5), | 3737 MockRead(ASYNC, ERR_IO_PENDING, 4), |
| 3738 CreateMockRead(*second, 5), |
| 3739 MockRead(ASYNC, ERR_IO_PENDING, 7), |
| 3740 MockRead(ASYNC, 0, 8), |
| 3806 }; | 3741 }; |
| 3807 | 3742 |
| 3808 DeterministicSocketData data(reads, arraysize(reads), writes, | 3743 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); |
| 3809 arraysize(writes)); | 3744 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 3810 data.set_connect_data(MockConnect(SYNCHRONOUS, OK)); | |
| 3811 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 3812 | 3745 |
| 3813 CreateDeterministicNetworkSession(); | 3746 CreateNetworkSession(); |
| 3814 SpdySessionPoolPeer pool_peer(spdy_session_pool_); | 3747 SpdySessionPoolPeer pool_peer(spdy_session_pool_); |
| 3815 pool_peer.SetStreamInitialRecvWindowSize(stream_max_recv_window_size); | 3748 pool_peer.SetStreamInitialRecvWindowSize(stream_max_recv_window_size); |
| 3816 | 3749 |
| 3817 base::WeakPtr<SpdySession> session = | 3750 base::WeakPtr<SpdySession> session = |
| 3818 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 3751 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 3819 EXPECT_LE(SpdySession::FLOW_CONTROL_STREAM, session->flow_control_state()); | 3752 EXPECT_LE(SpdySession::FLOW_CONTROL_STREAM, session->flow_control_state()); |
| 3820 | 3753 |
| 3821 base::WeakPtr<SpdyStream> spdy_stream = CreateStreamSynchronously( | 3754 base::WeakPtr<SpdyStream> spdy_stream = CreateStreamSynchronously( |
| 3822 SPDY_REQUEST_RESPONSE_STREAM, session, test_url_, LOWEST, BoundNetLog()); | 3755 SPDY_REQUEST_RESPONSE_STREAM, session, test_url_, LOWEST, BoundNetLog()); |
| 3823 test::StreamDelegateDoNothing delegate(spdy_stream); | 3756 test::StreamDelegateDoNothing delegate(spdy_stream); |
| 3824 spdy_stream->SetDelegate(&delegate); | 3757 spdy_stream->SetDelegate(&delegate); |
| 3825 | 3758 |
| 3826 scoped_ptr<SpdyHeaderBlock> headers( | 3759 scoped_ptr<SpdyHeaderBlock> headers( |
| 3827 spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); | 3760 spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); |
| 3828 EXPECT_EQ(ERR_IO_PENDING, spdy_stream->SendRequestHeaders( | 3761 EXPECT_EQ(ERR_IO_PENDING, spdy_stream->SendRequestHeaders( |
| 3829 headers.Pass(), NO_MORE_DATA_TO_SEND)); | 3762 headers.Pass(), NO_MORE_DATA_TO_SEND)); |
| 3830 | 3763 |
| 3831 // Request and response. | 3764 // Request and response. |
| 3832 data.RunFor(2); | 3765 base::RunLoop().RunUntilIdle(); |
| 3833 EXPECT_TRUE(spdy_stream->IsLocallyClosed()); | 3766 EXPECT_TRUE(spdy_stream->IsLocallyClosed()); |
| 3834 EXPECT_EQ(stream_max_recv_window_size, spdy_stream->recv_window_size()); | 3767 EXPECT_EQ(stream_max_recv_window_size, spdy_stream->recv_window_size()); |
| 3835 | 3768 |
| 3836 // First data frame. | 3769 // First data frame. |
| 3837 data.RunFor(1); | 3770 data.CompleteRead(); |
| 3771 base::RunLoop().RunUntilIdle(); |
| 3838 EXPECT_TRUE(spdy_stream->IsLocallyClosed()); | 3772 EXPECT_TRUE(spdy_stream->IsLocallyClosed()); |
| 3839 EXPECT_EQ(stream_max_recv_window_size - first_data_frame_size, | 3773 EXPECT_EQ(stream_max_recv_window_size - first_data_frame_size, |
| 3840 spdy_stream->recv_window_size()); | 3774 spdy_stream->recv_window_size()); |
| 3841 | 3775 |
| 3842 // Consume first data frame. This does not trigger a WINDOW_UPDATE. | 3776 // Consume first data frame. This does not trigger a WINDOW_UPDATE. |
| 3843 std::string received_data = delegate.TakeReceivedData(); | 3777 std::string received_data = delegate.TakeReceivedData(); |
| 3844 EXPECT_EQ(static_cast<size_t>(first_data_frame_size), received_data.size()); | 3778 EXPECT_EQ(static_cast<size_t>(first_data_frame_size), received_data.size()); |
| 3845 EXPECT_EQ(stream_max_recv_window_size, spdy_stream->recv_window_size()); | 3779 EXPECT_EQ(stream_max_recv_window_size, spdy_stream->recv_window_size()); |
| 3846 | 3780 |
| 3847 // Second data frame overflows receiving window, causes the stream to close. | 3781 // Second data frame overflows receiving window, causes the stream to close. |
| 3848 data.RunFor(1); | 3782 data.CompleteRead(); |
| 3783 base::RunLoop().RunUntilIdle(); |
| 3849 EXPECT_FALSE(spdy_stream.get()); | 3784 EXPECT_FALSE(spdy_stream.get()); |
| 3850 | 3785 |
| 3851 // RST_STREAM | 3786 // RST_STREAM |
| 3852 data.RunFor(1); | 3787 EXPECT_TRUE(session); |
| 3788 data.CompleteRead(); |
| 3789 base::RunLoop().RunUntilIdle(); |
| 3790 EXPECT_FALSE(session); |
| 3853 } | 3791 } |
| 3854 | 3792 |
| 3855 // A delegate that drops any received data. | 3793 // A delegate that drops any received data. |
| 3856 class DropReceivedDataDelegate : public test::StreamDelegateSendImmediate { | 3794 class DropReceivedDataDelegate : public test::StreamDelegateSendImmediate { |
| 3857 public: | 3795 public: |
| 3858 DropReceivedDataDelegate(const base::WeakPtr<SpdyStream>& stream, | 3796 DropReceivedDataDelegate(const base::WeakPtr<SpdyStream>& stream, |
| 3859 base::StringPiece data) | 3797 base::StringPiece data) |
| 3860 : StreamDelegateSendImmediate(stream, data) {} | 3798 : StreamDelegateSendImmediate(stream, data) {} |
| 3861 | 3799 |
| 3862 ~DropReceivedDataDelegate() override {} | 3800 ~DropReceivedDataDelegate() override {} |
| 3863 | 3801 |
| 3864 // Drop any received data. | 3802 // Drop any received data. |
| 3865 void OnDataReceived(scoped_ptr<SpdyBuffer> buffer) override {} | 3803 void OnDataReceived(scoped_ptr<SpdyBuffer> buffer) override {} |
| 3866 }; | 3804 }; |
| 3867 | 3805 |
| 3868 // Send data back and forth but use a delegate that drops its received | 3806 // Send data back and forth but use a delegate that drops its received |
| 3869 // data. The receive window should still increase to its original | 3807 // data. The receive window should still increase to its original |
| 3870 // value, i.e. we shouldn't "leak" receive window bytes. | 3808 // value, i.e. we shouldn't "leak" receive window bytes. |
| 3871 TEST_P(SpdySessionTest, SessionFlowControlNoReceiveLeaks) { | 3809 TEST_P(SpdySessionTest, SessionFlowControlNoReceiveLeaks) { |
| 3872 if (GetParam() < kProtoSPDY31) | 3810 if (GetParam() < kProtoSPDY31) |
| 3873 return; | 3811 return; |
| 3874 | 3812 |
| 3875 const char kStreamUrl[] = "http://www.example.org/"; | 3813 const char kStreamUrl[] = "http://www.example.org/"; |
| 3876 | 3814 |
| 3877 const int32 msg_data_size = 100; | 3815 const int32 msg_data_size = 100; |
| 3878 const std::string msg_data(msg_data_size, 'a'); | 3816 const std::string msg_data(msg_data_size, 'a'); |
| 3879 | 3817 |
| 3880 MockConnect connect_data(SYNCHRONOUS, OK); | 3818 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost( |
| 3881 | 3819 kStreamUrl, 1, msg_data_size, MEDIUM, nullptr, 0)); |
| 3882 scoped_ptr<SpdyFrame> req( | |
| 3883 spdy_util_.ConstructSpdyPost( | |
| 3884 kStreamUrl, 1, msg_data_size, MEDIUM, NULL, 0)); | |
| 3885 scoped_ptr<SpdyFrame> msg( | 3820 scoped_ptr<SpdyFrame> msg( |
| 3886 spdy_util_.ConstructSpdyBodyFrame( | 3821 spdy_util_.ConstructSpdyBodyFrame( |
| 3887 1, msg_data.data(), msg_data_size, false)); | 3822 1, msg_data.data(), msg_data_size, false)); |
| 3888 MockWrite writes[] = { | 3823 MockWrite writes[] = { |
| 3889 CreateMockWrite(*req, 0), | 3824 CreateMockWrite(*req, 0), |
| 3890 CreateMockWrite(*msg, 2), | 3825 CreateMockWrite(*msg, 2), |
| 3891 }; | 3826 }; |
| 3892 | 3827 |
| 3893 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); | 3828 scoped_ptr<SpdyFrame> resp( |
| 3829 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); |
| 3894 scoped_ptr<SpdyFrame> echo( | 3830 scoped_ptr<SpdyFrame> echo( |
| 3895 spdy_util_.ConstructSpdyBodyFrame( | 3831 spdy_util_.ConstructSpdyBodyFrame( |
| 3896 1, msg_data.data(), msg_data_size, false)); | 3832 1, msg_data.data(), msg_data_size, false)); |
| 3897 scoped_ptr<SpdyFrame> window_update( | 3833 scoped_ptr<SpdyFrame> window_update( |
| 3898 spdy_util_.ConstructSpdyWindowUpdate( | 3834 spdy_util_.ConstructSpdyWindowUpdate( |
| 3899 kSessionFlowControlStreamId, msg_data_size)); | 3835 kSessionFlowControlStreamId, msg_data_size)); |
| 3900 MockRead reads[] = { | 3836 MockRead reads[] = { |
| 3901 CreateMockRead(*resp, 1), | 3837 CreateMockRead(*resp, 1), |
| 3902 CreateMockRead(*echo, 3), | 3838 CreateMockRead(*echo, 3), |
| 3903 MockRead(ASYNC, 0, 4) // EOF | 3839 MockRead(ASYNC, ERR_IO_PENDING, 4), |
| 3840 MockRead(ASYNC, 0, 5) // EOF |
| 3904 }; | 3841 }; |
| 3905 | 3842 |
| 3906 // Create SpdySession and SpdyStream and send the request. | 3843 // Create SpdySession and SpdyStream and send the request. |
| 3907 DeterministicSocketData data(reads, arraysize(reads), | 3844 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); |
| 3908 writes, arraysize(writes)); | |
| 3909 data.set_connect_data(connect_data); | |
| 3910 session_deps_.host_resolver->set_synchronous_mode(true); | 3845 session_deps_.host_resolver->set_synchronous_mode(true); |
| 3911 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | 3846 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 3912 | 3847 |
| 3913 CreateDeterministicNetworkSession(); | 3848 CreateNetworkSession(); |
| 3914 | 3849 |
| 3915 base::WeakPtr<SpdySession> session = | 3850 base::WeakPtr<SpdySession> session = |
| 3916 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 3851 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 3917 | 3852 |
| 3918 GURL url(kStreamUrl); | 3853 GURL url(kStreamUrl); |
| 3919 base::WeakPtr<SpdyStream> stream = | 3854 base::WeakPtr<SpdyStream> stream = |
| 3920 CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, | 3855 CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, |
| 3921 session, url, MEDIUM, BoundNetLog()); | 3856 session, url, MEDIUM, BoundNetLog()); |
| 3922 ASSERT_TRUE(stream.get() != NULL); | 3857 ASSERT_TRUE(stream.get() != nullptr); |
| 3923 EXPECT_EQ(0u, stream->stream_id()); | 3858 EXPECT_EQ(0u, stream->stream_id()); |
| 3924 | 3859 |
| 3925 DropReceivedDataDelegate delegate(stream, msg_data); | 3860 DropReceivedDataDelegate delegate(stream, msg_data); |
| 3926 stream->SetDelegate(&delegate); | 3861 stream->SetDelegate(&delegate); |
| 3927 | 3862 |
| 3928 scoped_ptr<SpdyHeaderBlock> headers( | 3863 scoped_ptr<SpdyHeaderBlock> headers( |
| 3929 spdy_util_.ConstructPostHeaderBlock(url.spec(), msg_data_size)); | 3864 spdy_util_.ConstructPostHeaderBlock(url.spec(), msg_data_size)); |
| 3930 EXPECT_EQ(ERR_IO_PENDING, | 3865 EXPECT_EQ(ERR_IO_PENDING, |
| 3931 stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND)); | 3866 stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND)); |
| 3932 EXPECT_TRUE(stream->HasUrlFromHeaders()); | 3867 EXPECT_TRUE(stream->HasUrlFromHeaders()); |
| 3933 | 3868 |
| 3934 const int32 initial_window_size = | 3869 const int32 initial_window_size = |
| 3935 SpdySession::GetDefaultInitialWindowSize(GetParam()); | 3870 SpdySession::GetDefaultInitialWindowSize(GetParam()); |
| 3936 EXPECT_EQ(initial_window_size, session->session_recv_window_size_); | 3871 EXPECT_EQ(initial_window_size, session->session_recv_window_size_); |
| 3937 EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); | 3872 EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); |
| 3938 | 3873 |
| 3939 data.RunFor(4); | 3874 base::RunLoop().RunUntilIdle(); |
| 3940 | |
| 3941 EXPECT_TRUE(data.AllWriteDataConsumed()); | |
| 3942 EXPECT_TRUE(data.AllReadDataConsumed()); | |
| 3943 | 3875 |
| 3944 EXPECT_EQ(initial_window_size, session->session_recv_window_size_); | 3876 EXPECT_EQ(initial_window_size, session->session_recv_window_size_); |
| 3945 EXPECT_EQ(msg_data_size, session->session_unacked_recv_window_bytes_); | 3877 EXPECT_EQ(msg_data_size, session->session_unacked_recv_window_bytes_); |
| 3946 | 3878 |
| 3947 stream->Close(); | 3879 stream->Close(); |
| 3948 EXPECT_EQ(NULL, stream.get()); | 3880 EXPECT_FALSE(stream); |
| 3949 | 3881 |
| 3950 EXPECT_EQ(OK, delegate.WaitForClose()); | 3882 EXPECT_EQ(OK, delegate.WaitForClose()); |
| 3951 | 3883 |
| 3952 EXPECT_EQ(initial_window_size, session->session_recv_window_size_); | 3884 EXPECT_EQ(initial_window_size, session->session_recv_window_size_); |
| 3953 EXPECT_EQ(msg_data_size, session->session_unacked_recv_window_bytes_); | 3885 EXPECT_EQ(msg_data_size, session->session_unacked_recv_window_bytes_); |
| 3886 |
| 3887 data.CompleteRead(); |
| 3888 base::RunLoop().RunUntilIdle(); |
| 3889 EXPECT_FALSE(session); |
| 3954 } | 3890 } |
| 3955 | 3891 |
| 3956 // Send data back and forth but close the stream before its data frame | 3892 // Send data back and forth but close the stream before its data frame |
| 3957 // can be written to the socket. The send window should then increase | 3893 // can be written to the socket. The send window should then increase |
| 3958 // to its original value, i.e. we shouldn't "leak" send window bytes. | 3894 // to its original value, i.e. we shouldn't "leak" send window bytes. |
| 3959 TEST_P(SpdySessionTest, SessionFlowControlNoSendLeaks) { | 3895 TEST_P(SpdySessionTest, SessionFlowControlNoSendLeaks) { |
| 3960 if (GetParam() < kProtoSPDY31) | 3896 if (GetParam() < kProtoSPDY31) |
| 3961 return; | 3897 return; |
| 3962 | 3898 |
| 3963 const char kStreamUrl[] = "http://www.example.org/"; | 3899 const char kStreamUrl[] = "http://www.example.org/"; |
| 3964 | 3900 |
| 3965 const int32 msg_data_size = 100; | 3901 const int32 msg_data_size = 100; |
| 3966 const std::string msg_data(msg_data_size, 'a'); | 3902 const std::string msg_data(msg_data_size, 'a'); |
| 3967 | 3903 |
| 3968 MockConnect connect_data(SYNCHRONOUS, OK); | 3904 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost( |
| 3969 | 3905 kStreamUrl, 1, msg_data_size, MEDIUM, nullptr, 0)); |
| 3970 scoped_ptr<SpdyFrame> req( | |
| 3971 spdy_util_.ConstructSpdyPost( | |
| 3972 kStreamUrl, 1, msg_data_size, MEDIUM, NULL, 0)); | |
| 3973 MockWrite writes[] = { | 3906 MockWrite writes[] = { |
| 3974 CreateMockWrite(*req, 0), | 3907 CreateMockWrite(*req, 0), |
| 3975 }; | 3908 }; |
| 3976 | 3909 |
| 3977 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); | 3910 scoped_ptr<SpdyFrame> resp( |
| 3911 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); |
| 3978 MockRead reads[] = { | 3912 MockRead reads[] = { |
| 3979 CreateMockRead(*resp, 1), | 3913 MockRead(ASYNC, ERR_IO_PENDING, 1), |
| 3980 MockRead(ASYNC, 0, 2) // EOF | 3914 CreateMockRead(*resp, 2), |
| 3915 MockRead(ASYNC, 0, 3) // EOF |
| 3981 }; | 3916 }; |
| 3982 | 3917 |
| 3983 // Create SpdySession and SpdyStream and send the request. | 3918 // Create SpdySession and SpdyStream and send the request. |
| 3984 DeterministicSocketData data(reads, arraysize(reads), | 3919 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); |
| 3985 writes, arraysize(writes)); | |
| 3986 data.set_connect_data(connect_data); | |
| 3987 session_deps_.host_resolver->set_synchronous_mode(true); | 3920 session_deps_.host_resolver->set_synchronous_mode(true); |
| 3988 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | 3921 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 3989 | 3922 |
| 3990 CreateDeterministicNetworkSession(); | 3923 CreateNetworkSession(); |
| 3991 | 3924 |
| 3992 base::WeakPtr<SpdySession> session = | 3925 base::WeakPtr<SpdySession> session = |
| 3993 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 3926 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 3994 | 3927 |
| 3995 GURL url(kStreamUrl); | 3928 GURL url(kStreamUrl); |
| 3996 base::WeakPtr<SpdyStream> stream = | 3929 base::WeakPtr<SpdyStream> stream = |
| 3997 CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, | 3930 CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, |
| 3998 session, url, MEDIUM, BoundNetLog()); | 3931 session, url, MEDIUM, BoundNetLog()); |
| 3999 ASSERT_TRUE(stream.get() != NULL); | 3932 ASSERT_TRUE(stream.get() != nullptr); |
| 4000 EXPECT_EQ(0u, stream->stream_id()); | 3933 EXPECT_EQ(0u, stream->stream_id()); |
| 4001 | 3934 |
| 4002 test::StreamDelegateSendImmediate delegate(stream, msg_data); | 3935 test::StreamDelegateSendImmediate delegate(stream, msg_data); |
| 4003 stream->SetDelegate(&delegate); | 3936 stream->SetDelegate(&delegate); |
| 4004 | 3937 |
| 4005 scoped_ptr<SpdyHeaderBlock> headers( | 3938 scoped_ptr<SpdyHeaderBlock> headers( |
| 4006 spdy_util_.ConstructPostHeaderBlock(url.spec(), msg_data_size)); | 3939 spdy_util_.ConstructPostHeaderBlock(url.spec(), msg_data_size)); |
| 4007 EXPECT_EQ(ERR_IO_PENDING, | 3940 EXPECT_EQ(ERR_IO_PENDING, |
| 4008 stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND)); | 3941 stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND)); |
| 4009 EXPECT_TRUE(stream->HasUrlFromHeaders()); | 3942 EXPECT_TRUE(stream->HasUrlFromHeaders()); |
| 4010 | 3943 |
| 4011 const int32 initial_window_size = | 3944 const int32 initial_window_size = |
| 4012 SpdySession::GetDefaultInitialWindowSize(GetParam()); | 3945 SpdySession::GetDefaultInitialWindowSize(GetParam()); |
| 4013 EXPECT_EQ(initial_window_size, session->session_send_window_size_); | 3946 EXPECT_EQ(initial_window_size, session->session_send_window_size_); |
| 4014 | 3947 |
| 4015 data.RunFor(1); | 3948 // Write request. |
| 3949 base::RunLoop().RunUntilIdle(); |
| 4016 | 3950 |
| 4017 EXPECT_EQ(initial_window_size, session->session_send_window_size_); | 3951 EXPECT_EQ(initial_window_size, session->session_send_window_size_); |
| 4018 | 3952 |
| 4019 data.RunFor(1); | 3953 // Read response, but do not run the message loop, so that the body is not |
| 4020 | 3954 // written to the socket. |
| 4021 EXPECT_TRUE(data.AllWriteDataConsumed()); | 3955 data.CompleteRead(); |
| 4022 EXPECT_TRUE(data.AllReadDataConsumed()); | |
| 4023 | 3956 |
| 4024 EXPECT_EQ(initial_window_size - msg_data_size, | 3957 EXPECT_EQ(initial_window_size - msg_data_size, |
| 4025 session->session_send_window_size_); | 3958 session->session_send_window_size_); |
| 4026 | 3959 |
| 4027 // Closing the stream should increase the session's send window. | 3960 // Closing the stream should increase the session's send window. |
| 4028 stream->Close(); | 3961 stream->Close(); |
| 4029 EXPECT_EQ(NULL, stream.get()); | 3962 EXPECT_FALSE(stream); |
| 4030 | 3963 |
| 4031 EXPECT_EQ(initial_window_size, session->session_send_window_size_); | 3964 EXPECT_EQ(initial_window_size, session->session_send_window_size_); |
| 4032 | 3965 |
| 4033 EXPECT_EQ(OK, delegate.WaitForClose()); | 3966 EXPECT_EQ(OK, delegate.WaitForClose()); |
| 3967 |
| 3968 base::RunLoop().RunUntilIdle(); |
| 3969 EXPECT_FALSE(session); |
| 3970 |
| 3971 EXPECT_TRUE(data.AllWriteDataConsumed()); |
| 3972 EXPECT_TRUE(data.AllReadDataConsumed()); |
| 4034 } | 3973 } |
| 4035 | 3974 |
| 4036 // Send data back and forth; the send and receive windows should | 3975 // Send data back and forth; the send and receive windows should |
| 4037 // change appropriately. | 3976 // change appropriately. |
| 4038 TEST_P(SpdySessionTest, SessionFlowControlEndToEnd) { | 3977 TEST_P(SpdySessionTest, SessionFlowControlEndToEnd) { |
| 4039 if (GetParam() < kProtoSPDY31) | 3978 if (GetParam() < kProtoSPDY31) |
| 4040 return; | 3979 return; |
| 4041 | 3980 |
| 4042 const char kStreamUrl[] = "http://www.example.org/"; | 3981 const char kStreamUrl[] = "http://www.example.org/"; |
| 4043 | 3982 |
| 4044 const int32 msg_data_size = 100; | 3983 const int32 msg_data_size = 100; |
| 4045 const std::string msg_data(msg_data_size, 'a'); | 3984 const std::string msg_data(msg_data_size, 'a'); |
| 4046 | 3985 |
| 4047 MockConnect connect_data(SYNCHRONOUS, OK); | 3986 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost( |
| 4048 | 3987 kStreamUrl, 1, msg_data_size, MEDIUM, nullptr, 0)); |
| 4049 scoped_ptr<SpdyFrame> req( | |
| 4050 spdy_util_.ConstructSpdyPost( | |
| 4051 kStreamUrl, 1, msg_data_size, MEDIUM, NULL, 0)); | |
| 4052 scoped_ptr<SpdyFrame> msg( | 3988 scoped_ptr<SpdyFrame> msg( |
| 4053 spdy_util_.ConstructSpdyBodyFrame( | 3989 spdy_util_.ConstructSpdyBodyFrame( |
| 4054 1, msg_data.data(), msg_data_size, false)); | 3990 1, msg_data.data(), msg_data_size, false)); |
| 4055 MockWrite writes[] = { | 3991 MockWrite writes[] = { |
| 4056 CreateMockWrite(*req, 0), | 3992 CreateMockWrite(*req, 0), |
| 4057 CreateMockWrite(*msg, 2), | 3993 CreateMockWrite(*msg, 2), |
| 4058 }; | 3994 }; |
| 4059 | 3995 |
| 4060 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); | 3996 scoped_ptr<SpdyFrame> resp( |
| 3997 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); |
| 4061 scoped_ptr<SpdyFrame> echo( | 3998 scoped_ptr<SpdyFrame> echo( |
| 4062 spdy_util_.ConstructSpdyBodyFrame( | 3999 spdy_util_.ConstructSpdyBodyFrame( |
| 4063 1, msg_data.data(), msg_data_size, false)); | 4000 1, msg_data.data(), msg_data_size, false)); |
| 4064 scoped_ptr<SpdyFrame> window_update( | 4001 scoped_ptr<SpdyFrame> window_update( |
| 4065 spdy_util_.ConstructSpdyWindowUpdate( | 4002 spdy_util_.ConstructSpdyWindowUpdate( |
| 4066 kSessionFlowControlStreamId, msg_data_size)); | 4003 kSessionFlowControlStreamId, msg_data_size)); |
| 4067 MockRead reads[] = { | 4004 MockRead reads[] = { |
| 4068 CreateMockRead(*resp, 1), | 4005 CreateMockRead(*resp, 1), |
| 4069 CreateMockRead(*echo, 3), | 4006 MockRead(ASYNC, ERR_IO_PENDING, 3), |
| 4070 CreateMockRead(*window_update, 4), | 4007 CreateMockRead(*echo, 4), |
| 4071 MockRead(ASYNC, 0, 5) // EOF | 4008 MockRead(ASYNC, ERR_IO_PENDING, 5), |
| 4009 CreateMockRead(*window_update, 6), |
| 4010 MockRead(ASYNC, ERR_IO_PENDING, 7), |
| 4011 MockRead(ASYNC, 0, 8) // EOF |
| 4072 }; | 4012 }; |
| 4073 | 4013 |
| 4074 // Create SpdySession and SpdyStream and send the request. | 4014 // Create SpdySession and SpdyStream and send the request. |
| 4075 DeterministicSocketData data(reads, arraysize(reads), | 4015 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); |
| 4076 writes, arraysize(writes)); | |
| 4077 data.set_connect_data(connect_data); | |
| 4078 session_deps_.host_resolver->set_synchronous_mode(true); | 4016 session_deps_.host_resolver->set_synchronous_mode(true); |
| 4079 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | 4017 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 4080 | 4018 |
| 4081 CreateDeterministicNetworkSession(); | 4019 CreateNetworkSession(); |
| 4082 | 4020 |
| 4083 base::WeakPtr<SpdySession> session = | 4021 base::WeakPtr<SpdySession> session = |
| 4084 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 4022 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 4085 | 4023 |
| 4086 GURL url(kStreamUrl); | 4024 GURL url(kStreamUrl); |
| 4087 base::WeakPtr<SpdyStream> stream = | 4025 base::WeakPtr<SpdyStream> stream = |
| 4088 CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, | 4026 CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, |
| 4089 session, url, MEDIUM, BoundNetLog()); | 4027 session, url, MEDIUM, BoundNetLog()); |
| 4090 ASSERT_TRUE(stream.get() != NULL); | 4028 ASSERT_TRUE(stream.get() != nullptr); |
| 4091 EXPECT_EQ(0u, stream->stream_id()); | 4029 EXPECT_EQ(0u, stream->stream_id()); |
| 4092 | 4030 |
| 4093 test::StreamDelegateSendImmediate delegate(stream, msg_data); | 4031 test::StreamDelegateSendImmediate delegate(stream, msg_data); |
| 4094 stream->SetDelegate(&delegate); | 4032 stream->SetDelegate(&delegate); |
| 4095 | 4033 |
| 4096 scoped_ptr<SpdyHeaderBlock> headers( | 4034 scoped_ptr<SpdyHeaderBlock> headers( |
| 4097 spdy_util_.ConstructPostHeaderBlock(url.spec(), msg_data_size)); | 4035 spdy_util_.ConstructPostHeaderBlock(url.spec(), msg_data_size)); |
| 4098 EXPECT_EQ(ERR_IO_PENDING, | 4036 EXPECT_EQ(ERR_IO_PENDING, |
| 4099 stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND)); | 4037 stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND)); |
| 4100 EXPECT_TRUE(stream->HasUrlFromHeaders()); | 4038 EXPECT_TRUE(stream->HasUrlFromHeaders()); |
| 4101 | 4039 |
| 4102 const int32 initial_window_size = | 4040 const int32 initial_window_size = |
| 4103 SpdySession::GetDefaultInitialWindowSize(GetParam()); | 4041 SpdySession::GetDefaultInitialWindowSize(GetParam()); |
| 4104 EXPECT_EQ(initial_window_size, session->session_send_window_size_); | 4042 EXPECT_EQ(initial_window_size, session->session_send_window_size_); |
| 4105 EXPECT_EQ(initial_window_size, session->session_recv_window_size_); | 4043 EXPECT_EQ(initial_window_size, session->session_recv_window_size_); |
| 4106 EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); | 4044 EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); |
| 4107 | 4045 |
| 4108 data.RunFor(1); | 4046 // Send request and message. |
| 4109 | 4047 base::RunLoop().RunUntilIdle(); |
| 4110 EXPECT_EQ(initial_window_size, session->session_send_window_size_); | |
| 4111 EXPECT_EQ(initial_window_size, session->session_recv_window_size_); | |
| 4112 EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); | |
| 4113 | |
| 4114 data.RunFor(1); | |
| 4115 | 4048 |
| 4116 EXPECT_EQ(initial_window_size - msg_data_size, | 4049 EXPECT_EQ(initial_window_size - msg_data_size, |
| 4117 session->session_send_window_size_); | 4050 session->session_send_window_size_); |
| 4118 EXPECT_EQ(initial_window_size, session->session_recv_window_size_); | 4051 EXPECT_EQ(initial_window_size, session->session_recv_window_size_); |
| 4119 EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); | 4052 EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); |
| 4120 | 4053 |
| 4121 data.RunFor(1); | 4054 // Read echo. |
| 4055 data.CompleteRead(); |
| 4056 base::RunLoop().RunUntilIdle(); |
| 4122 | 4057 |
| 4123 EXPECT_EQ(initial_window_size - msg_data_size, | 4058 EXPECT_EQ(initial_window_size - msg_data_size, |
| 4124 session->session_send_window_size_); | 4059 session->session_send_window_size_); |
| 4125 EXPECT_EQ(initial_window_size, session->session_recv_window_size_); | |
| 4126 EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); | |
| 4127 | |
| 4128 data.RunFor(1); | |
| 4129 | |
| 4130 EXPECT_EQ(initial_window_size - msg_data_size, | |
| 4131 session->session_send_window_size_); | |
| 4132 EXPECT_EQ(initial_window_size - msg_data_size, | 4060 EXPECT_EQ(initial_window_size - msg_data_size, |
| 4133 session->session_recv_window_size_); | 4061 session->session_recv_window_size_); |
| 4134 EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); | 4062 EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); |
| 4135 | 4063 |
| 4136 data.RunFor(1); | 4064 // Read window update. |
| 4065 data.CompleteRead(); |
| 4066 base::RunLoop().RunUntilIdle(); |
| 4137 | 4067 |
| 4138 EXPECT_EQ(initial_window_size, session->session_send_window_size_); | 4068 EXPECT_EQ(initial_window_size, session->session_send_window_size_); |
| 4139 EXPECT_EQ(initial_window_size - msg_data_size, | 4069 EXPECT_EQ(initial_window_size - msg_data_size, |
| 4140 session->session_recv_window_size_); | 4070 session->session_recv_window_size_); |
| 4141 EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); | 4071 EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); |
| 4142 | 4072 |
| 4143 EXPECT_TRUE(data.AllWriteDataConsumed()); | |
| 4144 EXPECT_TRUE(data.AllReadDataConsumed()); | |
| 4145 | |
| 4146 EXPECT_EQ(msg_data, delegate.TakeReceivedData()); | 4073 EXPECT_EQ(msg_data, delegate.TakeReceivedData()); |
| 4147 | 4074 |
| 4148 // Draining the delegate's read queue should increase the session's | 4075 // Draining the delegate's read queue should increase the session's |
| 4149 // receive window. | 4076 // receive window. |
| 4150 EXPECT_EQ(initial_window_size, session->session_send_window_size_); | 4077 EXPECT_EQ(initial_window_size, session->session_send_window_size_); |
| 4151 EXPECT_EQ(initial_window_size, session->session_recv_window_size_); | 4078 EXPECT_EQ(initial_window_size, session->session_recv_window_size_); |
| 4152 EXPECT_EQ(msg_data_size, session->session_unacked_recv_window_bytes_); | 4079 EXPECT_EQ(msg_data_size, session->session_unacked_recv_window_bytes_); |
| 4153 | 4080 |
| 4154 stream->Close(); | 4081 stream->Close(); |
| 4155 EXPECT_EQ(NULL, stream.get()); | 4082 EXPECT_FALSE(stream); |
| 4156 | 4083 |
| 4157 EXPECT_EQ(OK, delegate.WaitForClose()); | 4084 EXPECT_EQ(OK, delegate.WaitForClose()); |
| 4158 | 4085 |
| 4159 EXPECT_EQ(initial_window_size, session->session_send_window_size_); | 4086 EXPECT_EQ(initial_window_size, session->session_send_window_size_); |
| 4160 EXPECT_EQ(initial_window_size, session->session_recv_window_size_); | 4087 EXPECT_EQ(initial_window_size, session->session_recv_window_size_); |
| 4161 EXPECT_EQ(msg_data_size, session->session_unacked_recv_window_bytes_); | 4088 EXPECT_EQ(msg_data_size, session->session_unacked_recv_window_bytes_); |
| 4089 |
| 4090 data.CompleteRead(); |
| 4091 base::RunLoop().RunUntilIdle(); |
| 4092 EXPECT_FALSE(session); |
| 4162 } | 4093 } |
| 4163 | 4094 |
| 4164 // Given a stall function and an unstall function, runs a test to make | 4095 // Given a stall function and an unstall function, runs a test to make |
| 4165 // sure that a stream resumes after unstall. | 4096 // sure that a stream resumes after unstall. |
| 4166 void SpdySessionTest::RunResumeAfterUnstallTest( | 4097 void SpdySessionTest::RunResumeAfterUnstallTest( |
| 4167 const base::Callback<void(SpdySession*, SpdyStream*)>& stall_function, | 4098 const base::Callback<void(SpdySession*, SpdyStream*)>& stall_function, |
| 4168 const base::Callback<void(SpdySession*, SpdyStream*, int32)>& | 4099 const base::Callback<void(SpdySession*, SpdyStream*, int32)>& |
| 4169 unstall_function) { | 4100 unstall_function) { |
| 4170 const char kStreamUrl[] = "http://www.example.org/"; | 4101 const char kStreamUrl[] = "http://www.example.org/"; |
| 4171 GURL url(kStreamUrl); | 4102 GURL url(kStreamUrl); |
| 4172 | 4103 |
| 4173 session_deps_.host_resolver->set_synchronous_mode(true); | 4104 session_deps_.host_resolver->set_synchronous_mode(true); |
| 4174 | 4105 |
| 4175 scoped_ptr<SpdyFrame> req( | 4106 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost( |
| 4176 spdy_util_.ConstructSpdyPost( | 4107 kStreamUrl, 1, kBodyDataSize, LOWEST, nullptr, 0)); |
| 4177 kStreamUrl, 1, kBodyDataSize, LOWEST, NULL, 0)); | |
| 4178 scoped_ptr<SpdyFrame> body( | 4108 scoped_ptr<SpdyFrame> body( |
| 4179 spdy_util_.ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, true)); | 4109 spdy_util_.ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, true)); |
| 4180 MockWrite writes[] = { | 4110 MockWrite writes[] = { |
| 4181 CreateMockWrite(*req, 0), | 4111 CreateMockWrite(*req, 0), |
| 4182 CreateMockWrite(*body, 1), | 4112 CreateMockWrite(*body, 1), |
| 4183 }; | 4113 }; |
| 4184 | 4114 |
| 4185 scoped_ptr<SpdyFrame> resp( | 4115 scoped_ptr<SpdyFrame> resp( |
| 4186 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); | 4116 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); |
| 4187 scoped_ptr<SpdyFrame> echo( | 4117 scoped_ptr<SpdyFrame> echo( |
| 4188 spdy_util_.ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, false)); | 4118 spdy_util_.ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, false)); |
| 4189 MockRead reads[] = { | 4119 MockRead reads[] = { |
| 4190 CreateMockRead(*resp, 2), | 4120 CreateMockRead(*resp, 2), MockRead(ASYNC, 0, 3) // EOF |
| 4191 MockRead(ASYNC, 0, 0, 3), // EOF | |
| 4192 }; | 4121 }; |
| 4193 | 4122 |
| 4194 DeterministicSocketData data(reads, arraysize(reads), | 4123 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); |
| 4195 writes, arraysize(writes)); | 4124 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 4196 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 4197 data.set_connect_data(connect_data); | |
| 4198 | 4125 |
| 4199 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | 4126 CreateNetworkSession(); |
| 4200 | |
| 4201 CreateDeterministicNetworkSession(); | |
| 4202 base::WeakPtr<SpdySession> session = | 4127 base::WeakPtr<SpdySession> session = |
| 4203 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 4128 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 4204 EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION, | 4129 EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION, |
| 4205 session->flow_control_state()); | 4130 session->flow_control_state()); |
| 4206 | 4131 |
| 4207 base::WeakPtr<SpdyStream> stream = | 4132 base::WeakPtr<SpdyStream> stream = |
| 4208 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, | 4133 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, |
| 4209 session, url, LOWEST, BoundNetLog()); | 4134 session, url, LOWEST, BoundNetLog()); |
| 4210 ASSERT_TRUE(stream.get() != NULL); | 4135 ASSERT_TRUE(stream.get() != nullptr); |
| 4211 | 4136 |
| 4212 test::StreamDelegateWithBody delegate(stream, kBodyDataStringPiece); | 4137 test::StreamDelegateWithBody delegate(stream, kBodyDataStringPiece); |
| 4213 stream->SetDelegate(&delegate); | 4138 stream->SetDelegate(&delegate); |
| 4214 | 4139 |
| 4215 EXPECT_FALSE(stream->HasUrlFromHeaders()); | 4140 EXPECT_FALSE(stream->HasUrlFromHeaders()); |
| 4216 EXPECT_FALSE(stream->send_stalled_by_flow_control()); | 4141 EXPECT_FALSE(stream->send_stalled_by_flow_control()); |
| 4217 | 4142 |
| 4218 scoped_ptr<SpdyHeaderBlock> headers( | 4143 scoped_ptr<SpdyHeaderBlock> headers( |
| 4219 spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize)); | 4144 spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize)); |
| 4220 EXPECT_EQ(ERR_IO_PENDING, | 4145 EXPECT_EQ(ERR_IO_PENDING, |
| 4221 stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND)); | 4146 stream->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND)); |
| 4222 EXPECT_TRUE(stream->HasUrlFromHeaders()); | 4147 EXPECT_TRUE(stream->HasUrlFromHeaders()); |
| 4223 EXPECT_EQ(kStreamUrl, stream->GetUrlFromHeaders().spec()); | 4148 EXPECT_EQ(kStreamUrl, stream->GetUrlFromHeaders().spec()); |
| 4224 | 4149 |
| 4225 stall_function.Run(session.get(), stream.get()); | 4150 stall_function.Run(session.get(), stream.get()); |
| 4226 | 4151 |
| 4227 data.RunFor(1); | 4152 base::RunLoop().RunUntilIdle(); |
| 4228 | 4153 |
| 4229 EXPECT_TRUE(stream->send_stalled_by_flow_control()); | 4154 EXPECT_TRUE(stream->send_stalled_by_flow_control()); |
| 4230 | 4155 |
| 4231 unstall_function.Run(session.get(), stream.get(), kBodyDataSize); | 4156 unstall_function.Run(session.get(), stream.get(), kBodyDataSize); |
| 4232 | 4157 |
| 4233 EXPECT_FALSE(stream->send_stalled_by_flow_control()); | 4158 EXPECT_FALSE(stream->send_stalled_by_flow_control()); |
| 4234 | 4159 |
| 4235 data.RunFor(3); | |
| 4236 | |
| 4237 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate.WaitForClose()); | 4160 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate.WaitForClose()); |
| 4238 | 4161 |
| 4239 EXPECT_TRUE(delegate.send_headers_completed()); | 4162 EXPECT_TRUE(delegate.send_headers_completed()); |
| 4240 EXPECT_EQ("200", delegate.GetResponseHeaderValue(":status")); | 4163 EXPECT_EQ("200", delegate.GetResponseHeaderValue(":status")); |
| 4241 EXPECT_EQ(std::string(), delegate.TakeReceivedData()); | 4164 EXPECT_EQ(std::string(), delegate.TakeReceivedData()); |
| 4165 EXPECT_FALSE(session); |
| 4242 EXPECT_TRUE(data.AllWriteDataConsumed()); | 4166 EXPECT_TRUE(data.AllWriteDataConsumed()); |
| 4243 } | 4167 } |
| 4244 | 4168 |
| 4245 // Run the resume-after-unstall test with all possible stall and | 4169 // Run the resume-after-unstall test with all possible stall and |
| 4246 // unstall sequences. | 4170 // unstall sequences. |
| 4247 | 4171 |
| 4248 TEST_P(SpdySessionTest, ResumeAfterUnstallSession) { | 4172 TEST_P(SpdySessionTest, ResumeAfterUnstallSession) { |
| 4249 if (GetParam() < kProtoSPDY31) | 4173 if (GetParam() < kProtoSPDY31) |
| 4250 return; | 4174 return; |
| 4251 | 4175 |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4318 // increased. | 4242 // increased. |
| 4319 TEST_P(SpdySessionTest, ResumeByPriorityAfterSendWindowSizeIncrease) { | 4243 TEST_P(SpdySessionTest, ResumeByPriorityAfterSendWindowSizeIncrease) { |
| 4320 if (GetParam() < kProtoSPDY31) | 4244 if (GetParam() < kProtoSPDY31) |
| 4321 return; | 4245 return; |
| 4322 | 4246 |
| 4323 const char kStreamUrl[] = "http://www.example.org/"; | 4247 const char kStreamUrl[] = "http://www.example.org/"; |
| 4324 GURL url(kStreamUrl); | 4248 GURL url(kStreamUrl); |
| 4325 | 4249 |
| 4326 session_deps_.host_resolver->set_synchronous_mode(true); | 4250 session_deps_.host_resolver->set_synchronous_mode(true); |
| 4327 | 4251 |
| 4328 scoped_ptr<SpdyFrame> req1( | 4252 scoped_ptr<SpdyFrame> req1(spdy_util_.ConstructSpdyPost( |
| 4329 spdy_util_.ConstructSpdyPost( | 4253 kStreamUrl, 1, kBodyDataSize, LOWEST, nullptr, 0)); |
| 4330 kStreamUrl, 1, kBodyDataSize, LOWEST, NULL, 0)); | 4254 scoped_ptr<SpdyFrame> req2(spdy_util_.ConstructSpdyPost( |
| 4331 scoped_ptr<SpdyFrame> req2( | 4255 kStreamUrl, 3, kBodyDataSize, MEDIUM, nullptr, 0)); |
| 4332 spdy_util_.ConstructSpdyPost( | |
| 4333 kStreamUrl, 3, kBodyDataSize, MEDIUM, NULL, 0)); | |
| 4334 scoped_ptr<SpdyFrame> body1( | 4256 scoped_ptr<SpdyFrame> body1( |
| 4335 spdy_util_.ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, true)); | 4257 spdy_util_.ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, true)); |
| 4336 scoped_ptr<SpdyFrame> body2( | 4258 scoped_ptr<SpdyFrame> body2( |
| 4337 spdy_util_.ConstructSpdyBodyFrame(3, kBodyData, kBodyDataSize, true)); | 4259 spdy_util_.ConstructSpdyBodyFrame(3, kBodyData, kBodyDataSize, true)); |
| 4338 MockWrite writes[] = { | 4260 MockWrite writes[] = { |
| 4339 CreateMockWrite(*req1, 0), | 4261 CreateMockWrite(*req1, 0), |
| 4340 CreateMockWrite(*req2, 1), | 4262 CreateMockWrite(*req2, 1), |
| 4341 CreateMockWrite(*body2, 2), | 4263 CreateMockWrite(*body2, 2), |
| 4342 CreateMockWrite(*body1, 3), | 4264 CreateMockWrite(*body1, 3), |
| 4343 }; | 4265 }; |
| 4344 | 4266 |
| 4345 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); | 4267 scoped_ptr<SpdyFrame> resp1( |
| 4346 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); | 4268 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); |
| 4269 scoped_ptr<SpdyFrame> resp2( |
| 4270 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 3)); |
| 4347 MockRead reads[] = { | 4271 MockRead reads[] = { |
| 4348 CreateMockRead(*resp1, 4), | 4272 CreateMockRead(*resp1, 4), |
| 4349 CreateMockRead(*resp2, 5), | 4273 CreateMockRead(*resp2, 5), |
| 4350 MockRead(ASYNC, 0, 0, 6), // EOF | 4274 MockRead(ASYNC, 0, 6) // EOF |
| 4351 }; | 4275 }; |
| 4352 | 4276 |
| 4353 DeterministicSocketData data(reads, arraysize(reads), | 4277 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); |
| 4354 writes, arraysize(writes)); | 4278 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 4355 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 4356 data.set_connect_data(connect_data); | |
| 4357 | 4279 |
| 4358 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | 4280 CreateNetworkSession(); |
| 4359 | |
| 4360 CreateDeterministicNetworkSession(); | |
| 4361 base::WeakPtr<SpdySession> session = | 4281 base::WeakPtr<SpdySession> session = |
| 4362 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 4282 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 4363 EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION, | 4283 EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION, |
| 4364 session->flow_control_state()); | 4284 session->flow_control_state()); |
| 4365 | 4285 |
| 4366 base::WeakPtr<SpdyStream> stream1 = | 4286 base::WeakPtr<SpdyStream> stream1 = |
| 4367 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, | 4287 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, |
| 4368 session, url, LOWEST, BoundNetLog()); | 4288 session, url, LOWEST, BoundNetLog()); |
| 4369 ASSERT_TRUE(stream1.get() != NULL); | 4289 ASSERT_TRUE(stream1.get() != nullptr); |
| 4370 | 4290 |
| 4371 test::StreamDelegateWithBody delegate1(stream1, kBodyDataStringPiece); | 4291 test::StreamDelegateWithBody delegate1(stream1, kBodyDataStringPiece); |
| 4372 stream1->SetDelegate(&delegate1); | 4292 stream1->SetDelegate(&delegate1); |
| 4373 | 4293 |
| 4374 EXPECT_FALSE(stream1->HasUrlFromHeaders()); | 4294 EXPECT_FALSE(stream1->HasUrlFromHeaders()); |
| 4375 | 4295 |
| 4376 base::WeakPtr<SpdyStream> stream2 = | 4296 base::WeakPtr<SpdyStream> stream2 = |
| 4377 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, | 4297 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, |
| 4378 session, url, MEDIUM, BoundNetLog()); | 4298 session, url, MEDIUM, BoundNetLog()); |
| 4379 ASSERT_TRUE(stream2.get() != NULL); | 4299 ASSERT_TRUE(stream2.get() != nullptr); |
| 4380 | 4300 |
| 4381 test::StreamDelegateWithBody delegate2(stream2, kBodyDataStringPiece); | 4301 test::StreamDelegateWithBody delegate2(stream2, kBodyDataStringPiece); |
| 4382 stream2->SetDelegate(&delegate2); | 4302 stream2->SetDelegate(&delegate2); |
| 4383 | 4303 |
| 4384 EXPECT_FALSE(stream2->HasUrlFromHeaders()); | 4304 EXPECT_FALSE(stream2->HasUrlFromHeaders()); |
| 4385 | 4305 |
| 4386 EXPECT_FALSE(stream1->send_stalled_by_flow_control()); | 4306 EXPECT_FALSE(stream1->send_stalled_by_flow_control()); |
| 4387 EXPECT_FALSE(stream2->send_stalled_by_flow_control()); | 4307 EXPECT_FALSE(stream2->send_stalled_by_flow_control()); |
| 4388 | 4308 |
| 4389 StallSessionSend(session.get()); | 4309 StallSessionSend(session.get()); |
| 4390 | 4310 |
| 4391 scoped_ptr<SpdyHeaderBlock> headers1( | 4311 scoped_ptr<SpdyHeaderBlock> headers1( |
| 4392 spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize)); | 4312 spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize)); |
| 4393 EXPECT_EQ(ERR_IO_PENDING, | 4313 EXPECT_EQ(ERR_IO_PENDING, |
| 4394 stream1->SendRequestHeaders(headers1.Pass(), MORE_DATA_TO_SEND)); | 4314 stream1->SendRequestHeaders(headers1.Pass(), MORE_DATA_TO_SEND)); |
| 4395 EXPECT_TRUE(stream1->HasUrlFromHeaders()); | 4315 EXPECT_TRUE(stream1->HasUrlFromHeaders()); |
| 4396 EXPECT_EQ(kStreamUrl, stream1->GetUrlFromHeaders().spec()); | 4316 EXPECT_EQ(kStreamUrl, stream1->GetUrlFromHeaders().spec()); |
| 4397 | 4317 |
| 4398 data.RunFor(1); | 4318 base::RunLoop().RunUntilIdle(); |
| 4399 EXPECT_EQ(1u, stream1->stream_id()); | 4319 EXPECT_EQ(1u, stream1->stream_id()); |
| 4400 EXPECT_TRUE(stream1->send_stalled_by_flow_control()); | 4320 EXPECT_TRUE(stream1->send_stalled_by_flow_control()); |
| 4401 | 4321 |
| 4402 scoped_ptr<SpdyHeaderBlock> headers2( | 4322 scoped_ptr<SpdyHeaderBlock> headers2( |
| 4403 spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize)); | 4323 spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize)); |
| 4404 EXPECT_EQ(ERR_IO_PENDING, | 4324 EXPECT_EQ(ERR_IO_PENDING, |
| 4405 stream2->SendRequestHeaders(headers2.Pass(), MORE_DATA_TO_SEND)); | 4325 stream2->SendRequestHeaders(headers2.Pass(), MORE_DATA_TO_SEND)); |
| 4406 EXPECT_TRUE(stream2->HasUrlFromHeaders()); | 4326 EXPECT_TRUE(stream2->HasUrlFromHeaders()); |
| 4407 EXPECT_EQ(kStreamUrl, stream2->GetUrlFromHeaders().spec()); | 4327 EXPECT_EQ(kStreamUrl, stream2->GetUrlFromHeaders().spec()); |
| 4408 | 4328 |
| 4409 data.RunFor(1); | 4329 base::RunLoop().RunUntilIdle(); |
| 4410 EXPECT_EQ(3u, stream2->stream_id()); | 4330 EXPECT_EQ(3u, stream2->stream_id()); |
| 4411 EXPECT_TRUE(stream2->send_stalled_by_flow_control()); | 4331 EXPECT_TRUE(stream2->send_stalled_by_flow_control()); |
| 4412 | 4332 |
| 4413 // This should unstall only stream2. | 4333 // This should unstall only stream2. |
| 4414 UnstallSessionSend(session.get(), kBodyDataSize); | 4334 UnstallSessionSend(session.get(), kBodyDataSize); |
| 4415 | 4335 |
| 4416 EXPECT_TRUE(stream1->send_stalled_by_flow_control()); | 4336 EXPECT_TRUE(stream1->send_stalled_by_flow_control()); |
| 4417 EXPECT_FALSE(stream2->send_stalled_by_flow_control()); | 4337 EXPECT_FALSE(stream2->send_stalled_by_flow_control()); |
| 4418 | 4338 |
| 4419 data.RunFor(1); | 4339 base::RunLoop().RunUntilIdle(); |
| 4420 | 4340 |
| 4421 EXPECT_TRUE(stream1->send_stalled_by_flow_control()); | 4341 EXPECT_TRUE(stream1->send_stalled_by_flow_control()); |
| 4422 EXPECT_FALSE(stream2->send_stalled_by_flow_control()); | 4342 EXPECT_FALSE(stream2->send_stalled_by_flow_control()); |
| 4423 | 4343 |
| 4424 // This should then unstall stream1. | 4344 // This should then unstall stream1. |
| 4425 UnstallSessionSend(session.get(), kBodyDataSize); | 4345 UnstallSessionSend(session.get(), kBodyDataSize); |
| 4426 | 4346 |
| 4427 EXPECT_FALSE(stream1->send_stalled_by_flow_control()); | 4347 EXPECT_FALSE(stream1->send_stalled_by_flow_control()); |
| 4428 EXPECT_FALSE(stream2->send_stalled_by_flow_control()); | 4348 EXPECT_FALSE(stream2->send_stalled_by_flow_control()); |
| 4429 | 4349 |
| 4430 data.RunFor(4); | 4350 base::RunLoop().RunUntilIdle(); |
| 4431 | 4351 |
| 4432 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate1.WaitForClose()); | 4352 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate1.WaitForClose()); |
| 4433 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate2.WaitForClose()); | 4353 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate2.WaitForClose()); |
| 4434 | 4354 |
| 4435 EXPECT_TRUE(delegate1.send_headers_completed()); | 4355 EXPECT_TRUE(delegate1.send_headers_completed()); |
| 4436 EXPECT_EQ("200", delegate1.GetResponseHeaderValue(":status")); | 4356 EXPECT_EQ("200", delegate1.GetResponseHeaderValue(":status")); |
| 4437 EXPECT_EQ(std::string(), delegate1.TakeReceivedData()); | 4357 EXPECT_EQ(std::string(), delegate1.TakeReceivedData()); |
| 4438 | 4358 |
| 4439 EXPECT_TRUE(delegate2.send_headers_completed()); | 4359 EXPECT_TRUE(delegate2.send_headers_completed()); |
| 4440 EXPECT_EQ("200", delegate2.GetResponseHeaderValue(":status")); | 4360 EXPECT_EQ("200", delegate2.GetResponseHeaderValue(":status")); |
| 4441 EXPECT_EQ(std::string(), delegate2.TakeReceivedData()); | 4361 EXPECT_EQ(std::string(), delegate2.TakeReceivedData()); |
| 4442 | 4362 |
| 4363 EXPECT_FALSE(session); |
| 4443 EXPECT_TRUE(data.AllWriteDataConsumed()); | 4364 EXPECT_TRUE(data.AllWriteDataConsumed()); |
| 4365 EXPECT_TRUE(data.AllReadDataConsumed()); |
| 4444 } | 4366 } |
| 4445 | 4367 |
| 4446 // Delegate that closes a given stream after sending its body. | 4368 // Delegate that closes a given stream after sending its body. |
| 4447 class StreamClosingDelegate : public test::StreamDelegateWithBody { | 4369 class StreamClosingDelegate : public test::StreamDelegateWithBody { |
| 4448 public: | 4370 public: |
| 4449 StreamClosingDelegate(const base::WeakPtr<SpdyStream>& stream, | 4371 StreamClosingDelegate(const base::WeakPtr<SpdyStream>& stream, |
| 4450 base::StringPiece data) | 4372 base::StringPiece data) |
| 4451 : StreamDelegateWithBody(stream, data) {} | 4373 : StreamDelegateWithBody(stream, data) {} |
| 4452 | 4374 |
| 4453 ~StreamClosingDelegate() override {} | 4375 ~StreamClosingDelegate() override {} |
| 4454 | 4376 |
| 4455 void set_stream_to_close(const base::WeakPtr<SpdyStream>& stream_to_close) { | 4377 void set_stream_to_close(const base::WeakPtr<SpdyStream>& stream_to_close) { |
| 4456 stream_to_close_ = stream_to_close; | 4378 stream_to_close_ = stream_to_close; |
| 4457 } | 4379 } |
| 4458 | 4380 |
| 4459 void OnDataSent() override { | 4381 void OnDataSent() override { |
| 4460 test::StreamDelegateWithBody::OnDataSent(); | 4382 test::StreamDelegateWithBody::OnDataSent(); |
| 4461 if (stream_to_close_.get()) { | 4383 if (stream_to_close_.get()) { |
| 4462 stream_to_close_->Close(); | 4384 stream_to_close_->Close(); |
| 4463 EXPECT_EQ(NULL, stream_to_close_.get()); | 4385 EXPECT_FALSE(stream_to_close_); |
| 4464 } | 4386 } |
| 4465 } | 4387 } |
| 4466 | 4388 |
| 4467 private: | 4389 private: |
| 4468 base::WeakPtr<SpdyStream> stream_to_close_; | 4390 base::WeakPtr<SpdyStream> stream_to_close_; |
| 4469 }; | 4391 }; |
| 4470 | 4392 |
| 4471 // Cause a stall by reducing the flow control send window to | 4393 // Cause a stall by reducing the flow control send window to |
| 4472 // 0. Unstalling the session should properly handle deleted streams. | 4394 // 0. Unstalling the session should properly handle deleted streams. |
| 4473 TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedStreams) { | 4395 TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedStreams) { |
| 4474 if (GetParam() < kProtoSPDY31) | 4396 if (GetParam() < kProtoSPDY31) |
| 4475 return; | 4397 return; |
| 4476 | 4398 |
| 4477 const char kStreamUrl[] = "http://www.example.org/"; | 4399 const char kStreamUrl[] = "http://www.example.org/"; |
| 4478 GURL url(kStreamUrl); | 4400 GURL url(kStreamUrl); |
| 4479 | 4401 |
| 4480 session_deps_.host_resolver->set_synchronous_mode(true); | 4402 session_deps_.host_resolver->set_synchronous_mode(true); |
| 4481 | 4403 |
| 4482 scoped_ptr<SpdyFrame> req1( | 4404 scoped_ptr<SpdyFrame> req1(spdy_util_.ConstructSpdyPost( |
| 4483 spdy_util_.ConstructSpdyPost( | 4405 kStreamUrl, 1, kBodyDataSize, LOWEST, nullptr, 0)); |
| 4484 kStreamUrl, 1, kBodyDataSize, LOWEST, NULL, 0)); | 4406 scoped_ptr<SpdyFrame> req2(spdy_util_.ConstructSpdyPost( |
| 4485 scoped_ptr<SpdyFrame> req2( | 4407 kStreamUrl, 3, kBodyDataSize, LOWEST, nullptr, 0)); |
| 4486 spdy_util_.ConstructSpdyPost( | 4408 scoped_ptr<SpdyFrame> req3(spdy_util_.ConstructSpdyPost( |
| 4487 kStreamUrl, 3, kBodyDataSize, LOWEST, NULL, 0)); | 4409 kStreamUrl, 5, kBodyDataSize, LOWEST, nullptr, 0)); |
| 4488 scoped_ptr<SpdyFrame> req3( | |
| 4489 spdy_util_.ConstructSpdyPost( | |
| 4490 kStreamUrl, 5, kBodyDataSize, LOWEST, NULL, 0)); | |
| 4491 scoped_ptr<SpdyFrame> body2( | 4410 scoped_ptr<SpdyFrame> body2( |
| 4492 spdy_util_.ConstructSpdyBodyFrame(3, kBodyData, kBodyDataSize, true)); | 4411 spdy_util_.ConstructSpdyBodyFrame(3, kBodyData, kBodyDataSize, true)); |
| 4493 MockWrite writes[] = { | 4412 MockWrite writes[] = { |
| 4494 CreateMockWrite(*req1, 0), | 4413 CreateMockWrite(*req1, 0), |
| 4495 CreateMockWrite(*req2, 1), | 4414 CreateMockWrite(*req2, 1), |
| 4496 CreateMockWrite(*req3, 2), | 4415 CreateMockWrite(*req3, 2), |
| 4497 CreateMockWrite(*body2, 3), | 4416 CreateMockWrite(*body2, 3), |
| 4498 }; | 4417 }; |
| 4499 | 4418 |
| 4500 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); | 4419 scoped_ptr<SpdyFrame> resp2( |
| 4420 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 3)); |
| 4501 MockRead reads[] = { | 4421 MockRead reads[] = { |
| 4502 CreateMockRead(*resp2, 4), | 4422 CreateMockRead(*resp2, 4), |
| 4503 MockRead(ASYNC, 0, 0, 5), // EOF | 4423 MockRead(ASYNC, ERR_IO_PENDING, 5), |
| 4424 MockRead(ASYNC, 0, 6) // EOF |
| 4504 }; | 4425 }; |
| 4505 | 4426 |
| 4506 DeterministicSocketData data(reads, arraysize(reads), | 4427 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); |
| 4507 writes, arraysize(writes)); | 4428 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 4508 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 4509 data.set_connect_data(connect_data); | |
| 4510 | 4429 |
| 4511 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | 4430 CreateNetworkSession(); |
| 4512 | |
| 4513 CreateDeterministicNetworkSession(); | |
| 4514 base::WeakPtr<SpdySession> session = | 4431 base::WeakPtr<SpdySession> session = |
| 4515 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 4432 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 4516 EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION, | 4433 EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION, |
| 4517 session->flow_control_state()); | 4434 session->flow_control_state()); |
| 4518 | 4435 |
| 4519 base::WeakPtr<SpdyStream> stream1 = | 4436 base::WeakPtr<SpdyStream> stream1 = |
| 4520 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, | 4437 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, |
| 4521 session, url, LOWEST, BoundNetLog()); | 4438 session, url, LOWEST, BoundNetLog()); |
| 4522 ASSERT_TRUE(stream1.get() != NULL); | 4439 ASSERT_TRUE(stream1.get() != nullptr); |
| 4523 | 4440 |
| 4524 test::StreamDelegateWithBody delegate1(stream1, kBodyDataStringPiece); | 4441 test::StreamDelegateWithBody delegate1(stream1, kBodyDataStringPiece); |
| 4525 stream1->SetDelegate(&delegate1); | 4442 stream1->SetDelegate(&delegate1); |
| 4526 | 4443 |
| 4527 EXPECT_FALSE(stream1->HasUrlFromHeaders()); | 4444 EXPECT_FALSE(stream1->HasUrlFromHeaders()); |
| 4528 | 4445 |
| 4529 base::WeakPtr<SpdyStream> stream2 = | 4446 base::WeakPtr<SpdyStream> stream2 = |
| 4530 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, | 4447 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, |
| 4531 session, url, LOWEST, BoundNetLog()); | 4448 session, url, LOWEST, BoundNetLog()); |
| 4532 ASSERT_TRUE(stream2.get() != NULL); | 4449 ASSERT_TRUE(stream2.get() != nullptr); |
| 4533 | 4450 |
| 4534 StreamClosingDelegate delegate2(stream2, kBodyDataStringPiece); | 4451 StreamClosingDelegate delegate2(stream2, kBodyDataStringPiece); |
| 4535 stream2->SetDelegate(&delegate2); | 4452 stream2->SetDelegate(&delegate2); |
| 4536 | 4453 |
| 4537 EXPECT_FALSE(stream2->HasUrlFromHeaders()); | 4454 EXPECT_FALSE(stream2->HasUrlFromHeaders()); |
| 4538 | 4455 |
| 4539 base::WeakPtr<SpdyStream> stream3 = | 4456 base::WeakPtr<SpdyStream> stream3 = |
| 4540 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, | 4457 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, |
| 4541 session, url, LOWEST, BoundNetLog()); | 4458 session, url, LOWEST, BoundNetLog()); |
| 4542 ASSERT_TRUE(stream3.get() != NULL); | 4459 ASSERT_TRUE(stream3.get() != nullptr); |
| 4543 | 4460 |
| 4544 test::StreamDelegateWithBody delegate3(stream3, kBodyDataStringPiece); | 4461 test::StreamDelegateWithBody delegate3(stream3, kBodyDataStringPiece); |
| 4545 stream3->SetDelegate(&delegate3); | 4462 stream3->SetDelegate(&delegate3); |
| 4546 | 4463 |
| 4547 EXPECT_FALSE(stream3->HasUrlFromHeaders()); | 4464 EXPECT_FALSE(stream3->HasUrlFromHeaders()); |
| 4548 | 4465 |
| 4549 EXPECT_FALSE(stream1->send_stalled_by_flow_control()); | 4466 EXPECT_FALSE(stream1->send_stalled_by_flow_control()); |
| 4550 EXPECT_FALSE(stream2->send_stalled_by_flow_control()); | 4467 EXPECT_FALSE(stream2->send_stalled_by_flow_control()); |
| 4551 EXPECT_FALSE(stream3->send_stalled_by_flow_control()); | 4468 EXPECT_FALSE(stream3->send_stalled_by_flow_control()); |
| 4552 | 4469 |
| 4553 StallSessionSend(session.get()); | 4470 StallSessionSend(session.get()); |
| 4554 | 4471 |
| 4555 scoped_ptr<SpdyHeaderBlock> headers1( | 4472 scoped_ptr<SpdyHeaderBlock> headers1( |
| 4556 spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize)); | 4473 spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize)); |
| 4557 EXPECT_EQ(ERR_IO_PENDING, | 4474 EXPECT_EQ(ERR_IO_PENDING, |
| 4558 stream1->SendRequestHeaders(headers1.Pass(), MORE_DATA_TO_SEND)); | 4475 stream1->SendRequestHeaders(headers1.Pass(), MORE_DATA_TO_SEND)); |
| 4559 EXPECT_TRUE(stream1->HasUrlFromHeaders()); | 4476 EXPECT_TRUE(stream1->HasUrlFromHeaders()); |
| 4560 EXPECT_EQ(kStreamUrl, stream1->GetUrlFromHeaders().spec()); | 4477 EXPECT_EQ(kStreamUrl, stream1->GetUrlFromHeaders().spec()); |
| 4561 | 4478 |
| 4562 data.RunFor(1); | 4479 base::RunLoop().RunUntilIdle(); |
| 4563 EXPECT_EQ(1u, stream1->stream_id()); | 4480 EXPECT_EQ(1u, stream1->stream_id()); |
| 4564 EXPECT_TRUE(stream1->send_stalled_by_flow_control()); | 4481 EXPECT_TRUE(stream1->send_stalled_by_flow_control()); |
| 4565 | 4482 |
| 4566 scoped_ptr<SpdyHeaderBlock> headers2( | 4483 scoped_ptr<SpdyHeaderBlock> headers2( |
| 4567 spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize)); | 4484 spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize)); |
| 4568 EXPECT_EQ(ERR_IO_PENDING, | 4485 EXPECT_EQ(ERR_IO_PENDING, |
| 4569 stream2->SendRequestHeaders(headers2.Pass(), MORE_DATA_TO_SEND)); | 4486 stream2->SendRequestHeaders(headers2.Pass(), MORE_DATA_TO_SEND)); |
| 4570 EXPECT_TRUE(stream2->HasUrlFromHeaders()); | 4487 EXPECT_TRUE(stream2->HasUrlFromHeaders()); |
| 4571 EXPECT_EQ(kStreamUrl, stream2->GetUrlFromHeaders().spec()); | 4488 EXPECT_EQ(kStreamUrl, stream2->GetUrlFromHeaders().spec()); |
| 4572 | 4489 |
| 4573 data.RunFor(1); | 4490 base::RunLoop().RunUntilIdle(); |
| 4574 EXPECT_EQ(3u, stream2->stream_id()); | 4491 EXPECT_EQ(3u, stream2->stream_id()); |
| 4575 EXPECT_TRUE(stream2->send_stalled_by_flow_control()); | 4492 EXPECT_TRUE(stream2->send_stalled_by_flow_control()); |
| 4576 | 4493 |
| 4577 scoped_ptr<SpdyHeaderBlock> headers3( | 4494 scoped_ptr<SpdyHeaderBlock> headers3( |
| 4578 spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize)); | 4495 spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize)); |
| 4579 EXPECT_EQ(ERR_IO_PENDING, | 4496 EXPECT_EQ(ERR_IO_PENDING, |
| 4580 stream3->SendRequestHeaders(headers3.Pass(), MORE_DATA_TO_SEND)); | 4497 stream3->SendRequestHeaders(headers3.Pass(), MORE_DATA_TO_SEND)); |
| 4581 EXPECT_TRUE(stream3->HasUrlFromHeaders()); | 4498 EXPECT_TRUE(stream3->HasUrlFromHeaders()); |
| 4582 EXPECT_EQ(kStreamUrl, stream3->GetUrlFromHeaders().spec()); | 4499 EXPECT_EQ(kStreamUrl, stream3->GetUrlFromHeaders().spec()); |
| 4583 | 4500 |
| 4584 data.RunFor(1); | 4501 base::RunLoop().RunUntilIdle(); |
| 4585 EXPECT_EQ(5u, stream3->stream_id()); | 4502 EXPECT_EQ(5u, stream3->stream_id()); |
| 4586 EXPECT_TRUE(stream3->send_stalled_by_flow_control()); | 4503 EXPECT_TRUE(stream3->send_stalled_by_flow_control()); |
| 4587 | 4504 |
| 4588 SpdyStreamId stream_id1 = stream1->stream_id(); | 4505 SpdyStreamId stream_id1 = stream1->stream_id(); |
| 4589 SpdyStreamId stream_id2 = stream2->stream_id(); | 4506 SpdyStreamId stream_id2 = stream2->stream_id(); |
| 4590 SpdyStreamId stream_id3 = stream3->stream_id(); | 4507 SpdyStreamId stream_id3 = stream3->stream_id(); |
| 4591 | 4508 |
| 4592 // Close stream1 preemptively. | 4509 // Close stream1 preemptively. |
| 4593 session->CloseActiveStream(stream_id1, ERR_CONNECTION_CLOSED); | 4510 session->CloseActiveStream(stream_id1, ERR_CONNECTION_CLOSED); |
| 4594 EXPECT_EQ(NULL, stream1.get()); | 4511 EXPECT_FALSE(stream1); |
| 4595 | 4512 |
| 4596 EXPECT_FALSE(session->IsStreamActive(stream_id1)); | 4513 EXPECT_FALSE(session->IsStreamActive(stream_id1)); |
| 4597 EXPECT_TRUE(session->IsStreamActive(stream_id2)); | 4514 EXPECT_TRUE(session->IsStreamActive(stream_id2)); |
| 4598 EXPECT_TRUE(session->IsStreamActive(stream_id3)); | 4515 EXPECT_TRUE(session->IsStreamActive(stream_id3)); |
| 4599 | 4516 |
| 4600 // Unstall stream2, which should then close stream3. | 4517 // Unstall stream2, which should then close stream3. |
| 4601 delegate2.set_stream_to_close(stream3); | 4518 delegate2.set_stream_to_close(stream3); |
| 4602 UnstallSessionSend(session.get(), kBodyDataSize); | 4519 UnstallSessionSend(session.get(), kBodyDataSize); |
| 4603 | 4520 |
| 4604 data.RunFor(1); | 4521 base::RunLoop().RunUntilIdle(); |
| 4605 EXPECT_EQ(NULL, stream3.get()); | 4522 EXPECT_FALSE(stream3); |
| 4606 | 4523 |
| 4607 EXPECT_FALSE(stream2->send_stalled_by_flow_control()); | 4524 EXPECT_FALSE(stream2->send_stalled_by_flow_control()); |
| 4608 EXPECT_FALSE(session->IsStreamActive(stream_id1)); | 4525 EXPECT_FALSE(session->IsStreamActive(stream_id1)); |
| 4609 EXPECT_TRUE(session->IsStreamActive(stream_id2)); | 4526 EXPECT_TRUE(session->IsStreamActive(stream_id2)); |
| 4610 EXPECT_FALSE(session->IsStreamActive(stream_id3)); | 4527 EXPECT_FALSE(session->IsStreamActive(stream_id3)); |
| 4611 | 4528 |
| 4612 data.RunFor(2); | 4529 data.CompleteRead(); |
| 4613 EXPECT_EQ(NULL, stream2.get()); | 4530 base::RunLoop().RunUntilIdle(); |
| 4531 EXPECT_FALSE(stream2); |
| 4532 EXPECT_FALSE(session); |
| 4614 | 4533 |
| 4615 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate1.WaitForClose()); | 4534 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate1.WaitForClose()); |
| 4616 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate2.WaitForClose()); | 4535 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate2.WaitForClose()); |
| 4617 EXPECT_EQ(OK, delegate3.WaitForClose()); | 4536 EXPECT_EQ(OK, delegate3.WaitForClose()); |
| 4618 | 4537 |
| 4619 EXPECT_TRUE(delegate1.send_headers_completed()); | 4538 EXPECT_TRUE(delegate1.send_headers_completed()); |
| 4620 EXPECT_EQ(std::string(), delegate1.TakeReceivedData()); | 4539 EXPECT_EQ(std::string(), delegate1.TakeReceivedData()); |
| 4621 | 4540 |
| 4622 EXPECT_TRUE(delegate2.send_headers_completed()); | 4541 EXPECT_TRUE(delegate2.send_headers_completed()); |
| 4623 EXPECT_EQ("200", delegate2.GetResponseHeaderValue(":status")); | 4542 EXPECT_EQ("200", delegate2.GetResponseHeaderValue(":status")); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 4634 // being closed. | 4553 // being closed. |
| 4635 TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedSession) { | 4554 TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedSession) { |
| 4636 if (GetParam() < kProtoSPDY31) | 4555 if (GetParam() < kProtoSPDY31) |
| 4637 return; | 4556 return; |
| 4638 | 4557 |
| 4639 const char kStreamUrl[] = "http://www.example.org/"; | 4558 const char kStreamUrl[] = "http://www.example.org/"; |
| 4640 GURL url(kStreamUrl); | 4559 GURL url(kStreamUrl); |
| 4641 | 4560 |
| 4642 session_deps_.host_resolver->set_synchronous_mode(true); | 4561 session_deps_.host_resolver->set_synchronous_mode(true); |
| 4643 | 4562 |
| 4644 scoped_ptr<SpdyFrame> req1( | 4563 scoped_ptr<SpdyFrame> req1(spdy_util_.ConstructSpdyPost( |
| 4645 spdy_util_.ConstructSpdyPost( | 4564 kStreamUrl, 1, kBodyDataSize, LOWEST, nullptr, 0)); |
| 4646 kStreamUrl, 1, kBodyDataSize, LOWEST, NULL, 0)); | 4565 scoped_ptr<SpdyFrame> req2(spdy_util_.ConstructSpdyPost( |
| 4647 scoped_ptr<SpdyFrame> req2( | 4566 kStreamUrl, 3, kBodyDataSize, LOWEST, nullptr, 0)); |
| 4648 spdy_util_.ConstructSpdyPost( | |
| 4649 kStreamUrl, 3, kBodyDataSize, LOWEST, NULL, 0)); | |
| 4650 scoped_ptr<SpdyFrame> body1( | 4567 scoped_ptr<SpdyFrame> body1( |
| 4651 spdy_util_.ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, false)); | 4568 spdy_util_.ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, false)); |
| 4652 MockWrite writes[] = { | 4569 MockWrite writes[] = { |
| 4653 CreateMockWrite(*req1, 0), | 4570 CreateMockWrite(*req1, 0), |
| 4654 CreateMockWrite(*req2, 1), | 4571 CreateMockWrite(*req2, 1), |
| 4655 }; | 4572 }; |
| 4656 | 4573 |
| 4657 MockRead reads[] = { | 4574 MockRead reads[] = { |
| 4658 MockRead(ASYNC, 0, 0, 2), // EOF | 4575 MockRead(ASYNC, ERR_IO_PENDING, 2), MockRead(ASYNC, 0, 3) // EOF |
| 4659 }; | 4576 }; |
| 4660 | 4577 |
| 4661 DeterministicSocketData data(reads, arraysize(reads), | 4578 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); |
| 4662 writes, arraysize(writes)); | 4579 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 4663 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 4664 data.set_connect_data(connect_data); | |
| 4665 | 4580 |
| 4666 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | 4581 CreateNetworkSession(); |
| 4667 | |
| 4668 CreateDeterministicNetworkSession(); | |
| 4669 base::WeakPtr<SpdySession> session = | 4582 base::WeakPtr<SpdySession> session = |
| 4670 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 4583 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 4671 EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION, | 4584 EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION, |
| 4672 session->flow_control_state()); | 4585 session->flow_control_state()); |
| 4673 | 4586 |
| 4674 base::WeakPtr<SpdyStream> stream1 = | 4587 base::WeakPtr<SpdyStream> stream1 = |
| 4675 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, | 4588 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, |
| 4676 session, url, LOWEST, BoundNetLog()); | 4589 session, url, LOWEST, BoundNetLog()); |
| 4677 ASSERT_TRUE(stream1.get() != NULL); | 4590 ASSERT_TRUE(stream1.get() != nullptr); |
| 4678 | 4591 |
| 4679 test::StreamDelegateWithBody delegate1(stream1, kBodyDataStringPiece); | 4592 test::StreamDelegateWithBody delegate1(stream1, kBodyDataStringPiece); |
| 4680 stream1->SetDelegate(&delegate1); | 4593 stream1->SetDelegate(&delegate1); |
| 4681 | 4594 |
| 4682 EXPECT_FALSE(stream1->HasUrlFromHeaders()); | 4595 EXPECT_FALSE(stream1->HasUrlFromHeaders()); |
| 4683 | 4596 |
| 4684 base::WeakPtr<SpdyStream> stream2 = | 4597 base::WeakPtr<SpdyStream> stream2 = |
| 4685 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, | 4598 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, |
| 4686 session, url, LOWEST, BoundNetLog()); | 4599 session, url, LOWEST, BoundNetLog()); |
| 4687 ASSERT_TRUE(stream2.get() != NULL); | 4600 ASSERT_TRUE(stream2.get() != nullptr); |
| 4688 | 4601 |
| 4689 test::StreamDelegateWithBody delegate2(stream2, kBodyDataStringPiece); | 4602 test::StreamDelegateWithBody delegate2(stream2, kBodyDataStringPiece); |
| 4690 stream2->SetDelegate(&delegate2); | 4603 stream2->SetDelegate(&delegate2); |
| 4691 | 4604 |
| 4692 EXPECT_FALSE(stream2->HasUrlFromHeaders()); | 4605 EXPECT_FALSE(stream2->HasUrlFromHeaders()); |
| 4693 | 4606 |
| 4694 EXPECT_FALSE(stream1->send_stalled_by_flow_control()); | 4607 EXPECT_FALSE(stream1->send_stalled_by_flow_control()); |
| 4695 EXPECT_FALSE(stream2->send_stalled_by_flow_control()); | 4608 EXPECT_FALSE(stream2->send_stalled_by_flow_control()); |
| 4696 | 4609 |
| 4697 StallSessionSend(session.get()); | 4610 StallSessionSend(session.get()); |
| 4698 | 4611 |
| 4699 scoped_ptr<SpdyHeaderBlock> headers1( | 4612 scoped_ptr<SpdyHeaderBlock> headers1( |
| 4700 spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize)); | 4613 spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize)); |
| 4701 EXPECT_EQ(ERR_IO_PENDING, | 4614 EXPECT_EQ(ERR_IO_PENDING, |
| 4702 stream1->SendRequestHeaders(headers1.Pass(), MORE_DATA_TO_SEND)); | 4615 stream1->SendRequestHeaders(headers1.Pass(), MORE_DATA_TO_SEND)); |
| 4703 EXPECT_TRUE(stream1->HasUrlFromHeaders()); | 4616 EXPECT_TRUE(stream1->HasUrlFromHeaders()); |
| 4704 EXPECT_EQ(kStreamUrl, stream1->GetUrlFromHeaders().spec()); | 4617 EXPECT_EQ(kStreamUrl, stream1->GetUrlFromHeaders().spec()); |
| 4705 | 4618 |
| 4706 data.RunFor(1); | 4619 base::RunLoop().RunUntilIdle(); |
| 4707 EXPECT_EQ(1u, stream1->stream_id()); | 4620 EXPECT_EQ(1u, stream1->stream_id()); |
| 4708 EXPECT_TRUE(stream1->send_stalled_by_flow_control()); | 4621 EXPECT_TRUE(stream1->send_stalled_by_flow_control()); |
| 4709 | 4622 |
| 4710 scoped_ptr<SpdyHeaderBlock> headers2( | 4623 scoped_ptr<SpdyHeaderBlock> headers2( |
| 4711 spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize)); | 4624 spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize)); |
| 4712 EXPECT_EQ(ERR_IO_PENDING, | 4625 EXPECT_EQ(ERR_IO_PENDING, |
| 4713 stream2->SendRequestHeaders(headers2.Pass(), MORE_DATA_TO_SEND)); | 4626 stream2->SendRequestHeaders(headers2.Pass(), MORE_DATA_TO_SEND)); |
| 4714 EXPECT_TRUE(stream2->HasUrlFromHeaders()); | 4627 EXPECT_TRUE(stream2->HasUrlFromHeaders()); |
| 4715 EXPECT_EQ(kStreamUrl, stream2->GetUrlFromHeaders().spec()); | 4628 EXPECT_EQ(kStreamUrl, stream2->GetUrlFromHeaders().spec()); |
| 4716 | 4629 |
| 4717 data.RunFor(1); | 4630 base::RunLoop().RunUntilIdle(); |
| 4718 EXPECT_EQ(3u, stream2->stream_id()); | 4631 EXPECT_EQ(3u, stream2->stream_id()); |
| 4719 EXPECT_TRUE(stream2->send_stalled_by_flow_control()); | 4632 EXPECT_TRUE(stream2->send_stalled_by_flow_control()); |
| 4720 | 4633 |
| 4721 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); | 4634 EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_)); |
| 4722 | 4635 |
| 4723 // Unstall stream1. | 4636 // Unstall stream1. |
| 4724 UnstallSessionSend(session.get(), kBodyDataSize); | 4637 UnstallSessionSend(session.get(), kBodyDataSize); |
| 4725 | 4638 |
| 4726 // Close the session (since we can't do it from within the delegate | 4639 // Close the session (since we can't do it from within the delegate |
| 4727 // method, since it's in the stream's loop). | 4640 // method, since it's in the stream's loop). |
| 4728 session->CloseSessionOnError(ERR_CONNECTION_CLOSED, "Closing session"); | 4641 session->CloseSessionOnError(ERR_CONNECTION_CLOSED, "Closing session"); |
| 4642 data.CompleteRead(); |
| 4729 base::RunLoop().RunUntilIdle(); | 4643 base::RunLoop().RunUntilIdle(); |
| 4730 EXPECT_TRUE(session == NULL); | 4644 EXPECT_FALSE(session); |
| 4731 | 4645 |
| 4732 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); | 4646 EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_)); |
| 4733 | 4647 |
| 4734 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate1.WaitForClose()); | 4648 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate1.WaitForClose()); |
| 4735 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate2.WaitForClose()); | 4649 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate2.WaitForClose()); |
| 4736 | 4650 |
| 4737 EXPECT_TRUE(delegate1.send_headers_completed()); | 4651 EXPECT_TRUE(delegate1.send_headers_completed()); |
| 4738 EXPECT_EQ(std::string(), delegate1.TakeReceivedData()); | 4652 EXPECT_EQ(std::string(), delegate1.TakeReceivedData()); |
| 4739 | 4653 |
| 4740 EXPECT_TRUE(delegate2.send_headers_completed()); | 4654 EXPECT_TRUE(delegate2.send_headers_completed()); |
| 4741 EXPECT_EQ(std::string(), delegate2.TakeReceivedData()); | 4655 EXPECT_EQ(std::string(), delegate2.TakeReceivedData()); |
| 4742 | 4656 |
| 4743 EXPECT_TRUE(data.AllWriteDataConsumed()); | 4657 EXPECT_TRUE(data.AllWriteDataConsumed()); |
| 4744 } | 4658 } |
| 4745 | 4659 |
| 4746 TEST_P(SpdySessionTest, GoAwayOnSessionFlowControlError) { | 4660 TEST_P(SpdySessionTest, GoAwayOnSessionFlowControlError) { |
| 4747 if (GetParam() < kProtoSPDY31) | 4661 if (GetParam() < kProtoSPDY31) |
| 4748 return; | 4662 return; |
| 4749 | 4663 |
| 4750 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 4751 | |
| 4752 scoped_ptr<SpdyFrame> req( | 4664 scoped_ptr<SpdyFrame> req( |
| 4753 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); | 4665 spdy_util_.ConstructSpdyGet(nullptr, 0, false, 1, LOWEST, true)); |
| 4754 scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway( | 4666 scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway( |
| 4755 0, | 4667 0, GOAWAY_FLOW_CONTROL_ERROR, |
| 4756 GOAWAY_FLOW_CONTROL_ERROR, | |
| 4757 "delta_window_size is 6 in DecreaseRecvWindowSize, which is larger than " | 4668 "delta_window_size is 6 in DecreaseRecvWindowSize, which is larger than " |
| 4758 "the receive window size of 1")); | 4669 "the receive window size of 1")); |
| 4759 MockWrite writes[] = { | 4670 MockWrite writes[] = { |
| 4760 CreateMockWrite(*req, 0), CreateMockWrite(*goaway, 3), | 4671 CreateMockWrite(*req, 0), CreateMockWrite(*goaway, 4), |
| 4761 }; | 4672 }; |
| 4762 | 4673 |
| 4763 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); | 4674 scoped_ptr<SpdyFrame> resp( |
| 4675 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); |
| 4764 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); | 4676 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); |
| 4765 MockRead reads[] = { | 4677 MockRead reads[] = { |
| 4766 CreateMockRead(*resp, 1), CreateMockRead(*body, 2), | 4678 MockRead(ASYNC, ERR_IO_PENDING, 1), |
| 4679 CreateMockRead(*resp, 2), |
| 4680 CreateMockRead(*body, 3), |
| 4767 }; | 4681 }; |
| 4768 | 4682 |
| 4769 DeterministicSocketData data( | 4683 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); |
| 4770 reads, arraysize(reads), writes, arraysize(writes)); | 4684 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 4771 data.set_connect_data(connect_data); | |
| 4772 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 4773 | 4685 |
| 4774 CreateDeterministicNetworkSession(); | 4686 CreateNetworkSession(); |
| 4775 | 4687 |
| 4776 base::WeakPtr<SpdySession> session = | 4688 base::WeakPtr<SpdySession> session = |
| 4777 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 4689 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 4778 | 4690 |
| 4779 GURL url(kDefaultURL); | 4691 GURL url(kDefaultURL); |
| 4780 base::WeakPtr<SpdyStream> spdy_stream = CreateStreamSynchronously( | 4692 base::WeakPtr<SpdyStream> spdy_stream = CreateStreamSynchronously( |
| 4781 SPDY_REQUEST_RESPONSE_STREAM, session, url, LOWEST, BoundNetLog()); | 4693 SPDY_REQUEST_RESPONSE_STREAM, session, url, LOWEST, BoundNetLog()); |
| 4782 ASSERT_TRUE(spdy_stream.get() != NULL); | 4694 ASSERT_TRUE(spdy_stream.get() != nullptr); |
| 4783 test::StreamDelegateDoNothing delegate(spdy_stream); | 4695 test::StreamDelegateDoNothing delegate(spdy_stream); |
| 4784 spdy_stream->SetDelegate(&delegate); | 4696 spdy_stream->SetDelegate(&delegate); |
| 4785 | 4697 |
| 4786 scoped_ptr<SpdyHeaderBlock> headers( | 4698 scoped_ptr<SpdyHeaderBlock> headers( |
| 4787 spdy_util_.ConstructGetHeaderBlock(url.spec())); | 4699 spdy_util_.ConstructGetHeaderBlock(url.spec())); |
| 4788 spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); | 4700 spdy_stream->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); |
| 4789 | 4701 |
| 4790 data.RunFor(1); // Write request. | 4702 // Write request. |
| 4703 base::RunLoop().RunUntilIdle(); |
| 4791 | 4704 |
| 4792 // Put session on the edge of overflowing it's recv window. | 4705 // Put session on the edge of overflowing it's recv window. |
| 4793 session->session_recv_window_size_ = 1; | 4706 session->session_recv_window_size_ = 1; |
| 4794 | 4707 |
| 4795 // Read response headers & body. Body overflows the session window, and a | 4708 // Read response headers & body. Body overflows the session window, and a |
| 4796 // goaway is written. | 4709 // goaway is written. |
| 4797 data.RunFor(3); | 4710 data.CompleteRead(); |
| 4798 base::MessageLoop::current()->RunUntilIdle(); | 4711 base::RunLoop().RunUntilIdle(); |
| 4799 | 4712 |
| 4800 EXPECT_EQ(ERR_SPDY_FLOW_CONTROL_ERROR, delegate.WaitForClose()); | 4713 EXPECT_EQ(ERR_SPDY_FLOW_CONTROL_ERROR, delegate.WaitForClose()); |
| 4801 EXPECT_TRUE(session == NULL); | 4714 EXPECT_FALSE(session); |
| 4802 } | 4715 } |
| 4803 | 4716 |
| 4804 TEST_P(SpdySessionTest, SplitHeaders) { | 4717 TEST_P(SpdySessionTest, SplitHeaders) { |
| 4805 GURL kStreamUrl("http://www.example.org/foo.dat"); | 4718 GURL kStreamUrl("http://www.example.org/foo.dat"); |
| 4806 SpdyHeaderBlock headers; | 4719 SpdyHeaderBlock headers; |
| 4807 spdy_util_.AddUrlToHeaderBlock(kStreamUrl.spec(), &headers); | 4720 spdy_util_.AddUrlToHeaderBlock(kStreamUrl.spec(), &headers); |
| 4808 headers["alpha"] = "beta"; | 4721 headers["alpha"] = "beta"; |
| 4809 | 4722 |
| 4810 SpdyHeaderBlock request_headers; | 4723 SpdyHeaderBlock request_headers; |
| 4811 SpdyHeaderBlock response_headers; | 4724 SpdyHeaderBlock response_headers; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 4825 | 4738 |
| 4826 // Regression. Sorta. Push streams and client streams were sharing a single | 4739 // Regression. Sorta. Push streams and client streams were sharing a single |
| 4827 // limit for a long time. | 4740 // limit for a long time. |
| 4828 TEST_P(SpdySessionTest, PushedStreamShouldNotCountToClientConcurrencyLimit) { | 4741 TEST_P(SpdySessionTest, PushedStreamShouldNotCountToClientConcurrencyLimit) { |
| 4829 SettingsMap new_settings; | 4742 SettingsMap new_settings; |
| 4830 new_settings[SETTINGS_MAX_CONCURRENT_STREAMS] = | 4743 new_settings[SETTINGS_MAX_CONCURRENT_STREAMS] = |
| 4831 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, 2); | 4744 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, 2); |
| 4832 scoped_ptr<SpdyFrame> settings_frame( | 4745 scoped_ptr<SpdyFrame> settings_frame( |
| 4833 spdy_util_.ConstructSpdySettings(new_settings)); | 4746 spdy_util_.ConstructSpdySettings(new_settings)); |
| 4834 scoped_ptr<SpdyFrame> pushed(spdy_util_.ConstructSpdyPush( | 4747 scoped_ptr<SpdyFrame> pushed(spdy_util_.ConstructSpdyPush( |
| 4835 NULL, 0, 2, 1, "http://www.example.org/a.dat")); | 4748 nullptr, 0, 2, 1, "http://www.example.org/a.dat")); |
| 4836 MockRead reads[] = { | 4749 MockRead reads[] = { |
| 4837 CreateMockRead(*settings_frame), CreateMockRead(*pushed, 3), | 4750 CreateMockRead(*settings_frame, 0), |
| 4838 MockRead(ASYNC, 0, 4), | 4751 MockRead(ASYNC, ERR_IO_PENDING, 3), |
| 4752 CreateMockRead(*pushed, 4), |
| 4753 MockRead(ASYNC, ERR_IO_PENDING, 5), |
| 4754 MockRead(ASYNC, 0, 6), |
| 4839 }; | 4755 }; |
| 4840 | 4756 |
| 4841 scoped_ptr<SpdyFrame> settings_ack(spdy_util_.ConstructSpdySettingsAck()); | 4757 scoped_ptr<SpdyFrame> settings_ack(spdy_util_.ConstructSpdySettingsAck()); |
| 4842 scoped_ptr<SpdyFrame> req( | 4758 scoped_ptr<SpdyFrame> req( |
| 4843 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); | 4759 spdy_util_.ConstructSpdyGet(nullptr, 0, false, 1, LOWEST, true)); |
| 4844 MockWrite writes[] = { | 4760 MockWrite writes[] = { |
| 4845 CreateMockWrite(*settings_ack, 1), CreateMockWrite(*req, 2), | 4761 CreateMockWrite(*settings_ack, 1), CreateMockWrite(*req, 2), |
| 4846 }; | 4762 }; |
| 4847 | 4763 |
| 4848 DeterministicSocketData data( | 4764 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); |
| 4849 reads, arraysize(reads), writes, arraysize(writes)); | 4765 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 4850 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 4851 data.set_connect_data(connect_data); | |
| 4852 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 4853 | 4766 |
| 4854 CreateDeterministicNetworkSession(); | 4767 CreateNetworkSession(); |
| 4855 | 4768 |
| 4856 base::WeakPtr<SpdySession> session = | 4769 base::WeakPtr<SpdySession> session = |
| 4857 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 4770 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 4858 | 4771 |
| 4859 // Read the settings frame. | 4772 // Read the settings frame. |
| 4860 data.RunFor(1); | 4773 base::RunLoop().RunUntilIdle(); |
| 4861 | 4774 |
| 4862 GURL url1(kDefaultURL); | 4775 GURL url1(kDefaultURL); |
| 4863 base::WeakPtr<SpdyStream> spdy_stream1 = CreateStreamSynchronously( | 4776 base::WeakPtr<SpdyStream> spdy_stream1 = CreateStreamSynchronously( |
| 4864 SPDY_REQUEST_RESPONSE_STREAM, session, url1, LOWEST, BoundNetLog()); | 4777 SPDY_REQUEST_RESPONSE_STREAM, session, url1, LOWEST, BoundNetLog()); |
| 4865 ASSERT_TRUE(spdy_stream1.get() != NULL); | 4778 ASSERT_TRUE(spdy_stream1.get() != nullptr); |
| 4866 EXPECT_EQ(0u, spdy_stream1->stream_id()); | 4779 EXPECT_EQ(0u, spdy_stream1->stream_id()); |
| 4867 test::StreamDelegateDoNothing delegate1(spdy_stream1); | 4780 test::StreamDelegateDoNothing delegate1(spdy_stream1); |
| 4868 spdy_stream1->SetDelegate(&delegate1); | 4781 spdy_stream1->SetDelegate(&delegate1); |
| 4869 | 4782 |
| 4870 EXPECT_EQ(0u, session->num_active_streams()); | 4783 EXPECT_EQ(0u, session->num_active_streams()); |
| 4871 EXPECT_EQ(1u, session->num_created_streams()); | 4784 EXPECT_EQ(1u, session->num_created_streams()); |
| 4872 EXPECT_EQ(0u, session->num_pushed_streams()); | 4785 EXPECT_EQ(0u, session->num_pushed_streams()); |
| 4873 EXPECT_EQ(0u, session->num_active_pushed_streams()); | 4786 EXPECT_EQ(0u, session->num_active_pushed_streams()); |
| 4874 | 4787 |
| 4875 scoped_ptr<SpdyHeaderBlock> headers( | 4788 scoped_ptr<SpdyHeaderBlock> headers( |
| 4876 spdy_util_.ConstructGetHeaderBlock(url1.spec())); | 4789 spdy_util_.ConstructGetHeaderBlock(url1.spec())); |
| 4877 spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); | 4790 spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); |
| 4878 EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); | 4791 EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); |
| 4879 | 4792 |
| 4880 // Run until 1st stream is activated. | 4793 // Run until 1st stream is activated. |
| 4881 EXPECT_EQ(0u, delegate1.stream_id()); | 4794 EXPECT_EQ(0u, delegate1.stream_id()); |
| 4882 data.RunFor(2); | 4795 base::RunLoop().RunUntilIdle(); |
| 4883 EXPECT_EQ(1u, delegate1.stream_id()); | 4796 EXPECT_EQ(1u, delegate1.stream_id()); |
| 4884 EXPECT_EQ(1u, session->num_active_streams()); | 4797 EXPECT_EQ(1u, session->num_active_streams()); |
| 4885 EXPECT_EQ(0u, session->num_created_streams()); | 4798 EXPECT_EQ(0u, session->num_created_streams()); |
| 4886 EXPECT_EQ(0u, session->num_pushed_streams()); | 4799 EXPECT_EQ(0u, session->num_pushed_streams()); |
| 4887 EXPECT_EQ(0u, session->num_active_pushed_streams()); | 4800 EXPECT_EQ(0u, session->num_active_pushed_streams()); |
| 4888 | 4801 |
| 4889 // Run until pushed stream is created. | 4802 // Run until pushed stream is created. |
| 4890 data.RunFor(1); | 4803 data.CompleteRead(); |
| 4804 base::RunLoop().RunUntilIdle(); |
| 4891 EXPECT_EQ(2u, session->num_active_streams()); | 4805 EXPECT_EQ(2u, session->num_active_streams()); |
| 4892 EXPECT_EQ(0u, session->num_created_streams()); | 4806 EXPECT_EQ(0u, session->num_created_streams()); |
| 4893 EXPECT_EQ(1u, session->num_pushed_streams()); | 4807 EXPECT_EQ(1u, session->num_pushed_streams()); |
| 4894 EXPECT_EQ(1u, session->num_active_pushed_streams()); | 4808 EXPECT_EQ(1u, session->num_active_pushed_streams()); |
| 4895 | 4809 |
| 4896 // Second stream should not be stalled, although we have 2 active streams, but | 4810 // Second stream should not be stalled, although we have 2 active streams, but |
| 4897 // one of them is push stream and should not be taken into account when we | 4811 // one of them is push stream and should not be taken into account when we |
| 4898 // create streams on the client. | 4812 // create streams on the client. |
| 4899 base::WeakPtr<SpdyStream> spdy_stream2 = CreateStreamSynchronously( | 4813 base::WeakPtr<SpdyStream> spdy_stream2 = CreateStreamSynchronously( |
| 4900 SPDY_REQUEST_RESPONSE_STREAM, session, url1, LOWEST, BoundNetLog()); | 4814 SPDY_REQUEST_RESPONSE_STREAM, session, url1, LOWEST, BoundNetLog()); |
| 4901 EXPECT_TRUE(spdy_stream2.get() != NULL); | 4815 EXPECT_TRUE(spdy_stream2); |
| 4902 EXPECT_EQ(2u, session->num_active_streams()); | 4816 EXPECT_EQ(2u, session->num_active_streams()); |
| 4903 EXPECT_EQ(1u, session->num_created_streams()); | 4817 EXPECT_EQ(1u, session->num_created_streams()); |
| 4904 EXPECT_EQ(1u, session->num_pushed_streams()); | 4818 EXPECT_EQ(1u, session->num_pushed_streams()); |
| 4905 EXPECT_EQ(1u, session->num_active_pushed_streams()); | 4819 EXPECT_EQ(1u, session->num_active_pushed_streams()); |
| 4906 | 4820 |
| 4907 // Read EOF. | 4821 // Read EOF. |
| 4908 data.RunFor(1); | 4822 data.CompleteRead(); |
| 4823 base::RunLoop().RunUntilIdle(); |
| 4824 EXPECT_FALSE(session); |
| 4909 } | 4825 } |
| 4910 | 4826 |
| 4911 TEST_P(SpdySessionTest, RejectPushedStreamExceedingConcurrencyLimit) { | 4827 TEST_P(SpdySessionTest, RejectPushedStreamExceedingConcurrencyLimit) { |
| 4912 scoped_ptr<SpdyFrame> push_a(spdy_util_.ConstructSpdyPush( | 4828 scoped_ptr<SpdyFrame> push_a(spdy_util_.ConstructSpdyPush( |
| 4913 NULL, 0, 2, 1, "http://www.example.org/a.dat")); | 4829 nullptr, 0, 2, 1, "http://www.example.org/a.dat")); |
| 4914 scoped_ptr<SpdyFrame> push_b(spdy_util_.ConstructSpdyPush( | 4830 scoped_ptr<SpdyFrame> push_b(spdy_util_.ConstructSpdyPush( |
| 4915 NULL, 0, 4, 1, "http://www.example.org/b.dat")); | 4831 nullptr, 0, 4, 1, "http://www.example.org/b.dat")); |
| 4916 MockRead reads[] = { | 4832 MockRead reads[] = { |
| 4917 CreateMockRead(*push_a, 1), CreateMockRead(*push_b, 2), | 4833 MockRead(ASYNC, ERR_IO_PENDING, 1), |
| 4918 MockRead(ASYNC, 0, 4), | 4834 CreateMockRead(*push_a, 2), |
| 4835 MockRead(ASYNC, ERR_IO_PENDING, 3), |
| 4836 CreateMockRead(*push_b, 4), |
| 4837 MockRead(ASYNC, ERR_IO_PENDING, 6), |
| 4838 MockRead(ASYNC, 0, 7), |
| 4919 }; | 4839 }; |
| 4920 | 4840 |
| 4921 scoped_ptr<SpdyFrame> req( | 4841 scoped_ptr<SpdyFrame> req( |
| 4922 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); | 4842 spdy_util_.ConstructSpdyGet(nullptr, 0, false, 1, LOWEST, true)); |
| 4923 scoped_ptr<SpdyFrame> rst( | 4843 scoped_ptr<SpdyFrame> rst( |
| 4924 spdy_util_.ConstructSpdyRstStream(4, RST_STREAM_REFUSED_STREAM)); | 4844 spdy_util_.ConstructSpdyRstStream(4, RST_STREAM_REFUSED_STREAM)); |
| 4925 MockWrite writes[] = { | 4845 MockWrite writes[] = { |
| 4926 CreateMockWrite(*req, 0), CreateMockWrite(*rst, 3), | 4846 CreateMockWrite(*req, 0), CreateMockWrite(*rst, 5), |
| 4927 }; | 4847 }; |
| 4928 | 4848 |
| 4929 DeterministicSocketData data( | 4849 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); |
| 4930 reads, arraysize(reads), writes, arraysize(writes)); | 4850 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 4931 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 4932 data.set_connect_data(connect_data); | |
| 4933 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 4934 | 4851 |
| 4935 CreateDeterministicNetworkSession(); | 4852 CreateNetworkSession(); |
| 4936 | 4853 |
| 4937 base::WeakPtr<SpdySession> session = | 4854 base::WeakPtr<SpdySession> session = |
| 4938 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 4855 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 4939 session->set_max_concurrent_pushed_streams(1); | 4856 session->set_max_concurrent_pushed_streams(1); |
| 4940 | 4857 |
| 4941 GURL url1(kDefaultURL); | 4858 GURL url1(kDefaultURL); |
| 4942 base::WeakPtr<SpdyStream> spdy_stream1 = CreateStreamSynchronously( | 4859 base::WeakPtr<SpdyStream> spdy_stream1 = CreateStreamSynchronously( |
| 4943 SPDY_REQUEST_RESPONSE_STREAM, session, url1, LOWEST, BoundNetLog()); | 4860 SPDY_REQUEST_RESPONSE_STREAM, session, url1, LOWEST, BoundNetLog()); |
| 4944 ASSERT_TRUE(spdy_stream1.get() != NULL); | 4861 ASSERT_TRUE(spdy_stream1.get() != nullptr); |
| 4945 EXPECT_EQ(0u, spdy_stream1->stream_id()); | 4862 EXPECT_EQ(0u, spdy_stream1->stream_id()); |
| 4946 test::StreamDelegateDoNothing delegate1(spdy_stream1); | 4863 test::StreamDelegateDoNothing delegate1(spdy_stream1); |
| 4947 spdy_stream1->SetDelegate(&delegate1); | 4864 spdy_stream1->SetDelegate(&delegate1); |
| 4948 | 4865 |
| 4949 EXPECT_EQ(0u, session->num_active_streams()); | 4866 EXPECT_EQ(0u, session->num_active_streams()); |
| 4950 EXPECT_EQ(1u, session->num_created_streams()); | 4867 EXPECT_EQ(1u, session->num_created_streams()); |
| 4951 EXPECT_EQ(0u, session->num_pushed_streams()); | 4868 EXPECT_EQ(0u, session->num_pushed_streams()); |
| 4952 EXPECT_EQ(0u, session->num_active_pushed_streams()); | 4869 EXPECT_EQ(0u, session->num_active_pushed_streams()); |
| 4953 | 4870 |
| 4954 scoped_ptr<SpdyHeaderBlock> headers( | 4871 scoped_ptr<SpdyHeaderBlock> headers( |
| 4955 spdy_util_.ConstructGetHeaderBlock(url1.spec())); | 4872 spdy_util_.ConstructGetHeaderBlock(url1.spec())); |
| 4956 spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); | 4873 spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); |
| 4957 EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); | 4874 EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); |
| 4958 | 4875 |
| 4959 // Run until 1st stream is activated. | 4876 // Run until 1st stream is activated. |
| 4960 EXPECT_EQ(0u, delegate1.stream_id()); | 4877 EXPECT_EQ(0u, delegate1.stream_id()); |
| 4961 data.RunFor(1); | 4878 base::RunLoop().RunUntilIdle(); |
| 4962 EXPECT_EQ(1u, delegate1.stream_id()); | 4879 EXPECT_EQ(1u, delegate1.stream_id()); |
| 4963 EXPECT_EQ(1u, session->num_active_streams()); | 4880 EXPECT_EQ(1u, session->num_active_streams()); |
| 4964 EXPECT_EQ(0u, session->num_created_streams()); | 4881 EXPECT_EQ(0u, session->num_created_streams()); |
| 4965 EXPECT_EQ(0u, session->num_pushed_streams()); | 4882 EXPECT_EQ(0u, session->num_pushed_streams()); |
| 4966 EXPECT_EQ(0u, session->num_active_pushed_streams()); | 4883 EXPECT_EQ(0u, session->num_active_pushed_streams()); |
| 4967 | 4884 |
| 4968 // Run until pushed stream is created. | 4885 // Run until pushed stream is created. |
| 4969 data.RunFor(1); | 4886 data.CompleteRead(); |
| 4887 base::RunLoop().RunUntilIdle(); |
| 4970 EXPECT_EQ(2u, session->num_active_streams()); | 4888 EXPECT_EQ(2u, session->num_active_streams()); |
| 4971 EXPECT_EQ(0u, session->num_created_streams()); | 4889 EXPECT_EQ(0u, session->num_created_streams()); |
| 4972 EXPECT_EQ(1u, session->num_pushed_streams()); | 4890 EXPECT_EQ(1u, session->num_pushed_streams()); |
| 4973 EXPECT_EQ(1u, session->num_active_pushed_streams()); | 4891 EXPECT_EQ(1u, session->num_active_pushed_streams()); |
| 4974 | 4892 |
| 4975 // Reset incoming pushed stream. | 4893 // Reset incoming pushed stream. |
| 4976 data.RunFor(2); | 4894 data.CompleteRead(); |
| 4895 base::RunLoop().RunUntilIdle(); |
| 4977 EXPECT_EQ(2u, session->num_active_streams()); | 4896 EXPECT_EQ(2u, session->num_active_streams()); |
| 4978 EXPECT_EQ(0u, session->num_created_streams()); | 4897 EXPECT_EQ(0u, session->num_created_streams()); |
| 4979 EXPECT_EQ(1u, session->num_pushed_streams()); | 4898 EXPECT_EQ(1u, session->num_pushed_streams()); |
| 4980 EXPECT_EQ(1u, session->num_active_pushed_streams()); | 4899 EXPECT_EQ(1u, session->num_active_pushed_streams()); |
| 4981 | 4900 |
| 4982 // Read EOF. | 4901 // Read EOF. |
| 4983 data.RunFor(1); | 4902 data.CompleteRead(); |
| 4903 base::RunLoop().RunUntilIdle(); |
| 4904 EXPECT_FALSE(session); |
| 4984 } | 4905 } |
| 4985 | 4906 |
| 4986 TEST_P(SpdySessionTest, IgnoreReservedRemoteStreamsCount) { | 4907 TEST_P(SpdySessionTest, IgnoreReservedRemoteStreamsCount) { |
| 4987 // Streams in reserved remote state exist only in SPDY4. | 4908 // Streams in reserved remote state exist only in SPDY4. |
| 4988 if (spdy_util_.spdy_version() < SPDY4) | 4909 if (spdy_util_.spdy_version() < SPDY4) |
| 4989 return; | 4910 return; |
| 4990 | 4911 |
| 4991 scoped_ptr<SpdyFrame> push_a(spdy_util_.ConstructSpdyPush( | 4912 scoped_ptr<SpdyFrame> push_a(spdy_util_.ConstructSpdyPush( |
| 4992 NULL, 0, 2, 1, "http://www.example.org/a.dat")); | 4913 nullptr, 0, 2, 1, "http://www.example.org/a.dat")); |
| 4993 scoped_ptr<SpdyHeaderBlock> push_headers(new SpdyHeaderBlock); | 4914 scoped_ptr<SpdyHeaderBlock> push_headers(new SpdyHeaderBlock); |
| 4994 spdy_util_.AddUrlToHeaderBlock("http://www.example.org/b.dat", | 4915 spdy_util_.AddUrlToHeaderBlock("http://www.example.org/b.dat", |
| 4995 push_headers.get()); | 4916 push_headers.get()); |
| 4996 scoped_ptr<SpdyFrame> push_b( | 4917 scoped_ptr<SpdyFrame> push_b( |
| 4997 spdy_util_.ConstructInitialSpdyPushFrame(push_headers.Pass(), 4, 1)); | 4918 spdy_util_.ConstructInitialSpdyPushFrame(push_headers.Pass(), 4, 1)); |
| 4998 scoped_ptr<SpdyFrame> headers_b( | 4919 scoped_ptr<SpdyFrame> headers_b( |
| 4999 spdy_util_.ConstructSpdyPushHeaders(4, NULL, 0)); | 4920 spdy_util_.ConstructSpdyPushHeaders(4, nullptr, 0)); |
| 5000 MockRead reads[] = { | 4921 MockRead reads[] = { |
| 5001 CreateMockRead(*push_a, 1), CreateMockRead(*push_b, 2), | 4922 MockRead(ASYNC, ERR_IO_PENDING, 1), |
| 5002 CreateMockRead(*headers_b, 3), MockRead(ASYNC, 0, 5), | 4923 CreateMockRead(*push_a, 2), |
| 4924 MockRead(ASYNC, ERR_IO_PENDING, 3), |
| 4925 CreateMockRead(*push_b, 4), |
| 4926 MockRead(ASYNC, ERR_IO_PENDING, 5), |
| 4927 CreateMockRead(*headers_b, 6), |
| 4928 MockRead(ASYNC, ERR_IO_PENDING, 8), |
| 4929 MockRead(ASYNC, 0, 9), |
| 5003 }; | 4930 }; |
| 5004 | 4931 |
| 5005 scoped_ptr<SpdyFrame> req( | 4932 scoped_ptr<SpdyFrame> req( |
| 5006 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); | 4933 spdy_util_.ConstructSpdyGet(nullptr, 0, false, 1, LOWEST, true)); |
| 5007 scoped_ptr<SpdyFrame> rst( | 4934 scoped_ptr<SpdyFrame> rst( |
| 5008 spdy_util_.ConstructSpdyRstStream(4, RST_STREAM_REFUSED_STREAM)); | 4935 spdy_util_.ConstructSpdyRstStream(4, RST_STREAM_REFUSED_STREAM)); |
| 5009 MockWrite writes[] = { | 4936 MockWrite writes[] = { |
| 5010 CreateMockWrite(*req, 0), CreateMockWrite(*rst, 4), | 4937 CreateMockWrite(*req, 0), CreateMockWrite(*rst, 7), |
| 5011 }; | 4938 }; |
| 5012 | 4939 |
| 5013 DeterministicSocketData data( | 4940 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); |
| 5014 reads, arraysize(reads), writes, arraysize(writes)); | 4941 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 5015 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 5016 data.set_connect_data(connect_data); | |
| 5017 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 5018 | 4942 |
| 5019 CreateDeterministicNetworkSession(); | 4943 CreateNetworkSession(); |
| 5020 | 4944 |
| 5021 base::WeakPtr<SpdySession> session = | 4945 base::WeakPtr<SpdySession> session = |
| 5022 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 4946 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 5023 session->set_max_concurrent_pushed_streams(1); | 4947 session->set_max_concurrent_pushed_streams(1); |
| 5024 | 4948 |
| 5025 GURL url1(kDefaultURL); | 4949 GURL url1(kDefaultURL); |
| 5026 base::WeakPtr<SpdyStream> spdy_stream1 = CreateStreamSynchronously( | 4950 base::WeakPtr<SpdyStream> spdy_stream1 = CreateStreamSynchronously( |
| 5027 SPDY_REQUEST_RESPONSE_STREAM, session, url1, LOWEST, BoundNetLog()); | 4951 SPDY_REQUEST_RESPONSE_STREAM, session, url1, LOWEST, BoundNetLog()); |
| 5028 ASSERT_TRUE(spdy_stream1.get() != NULL); | 4952 ASSERT_TRUE(spdy_stream1.get() != nullptr); |
| 5029 EXPECT_EQ(0u, spdy_stream1->stream_id()); | 4953 EXPECT_EQ(0u, spdy_stream1->stream_id()); |
| 5030 test::StreamDelegateDoNothing delegate1(spdy_stream1); | 4954 test::StreamDelegateDoNothing delegate1(spdy_stream1); |
| 5031 spdy_stream1->SetDelegate(&delegate1); | 4955 spdy_stream1->SetDelegate(&delegate1); |
| 5032 | 4956 |
| 5033 EXPECT_EQ(0u, session->num_active_streams()); | 4957 EXPECT_EQ(0u, session->num_active_streams()); |
| 5034 EXPECT_EQ(1u, session->num_created_streams()); | 4958 EXPECT_EQ(1u, session->num_created_streams()); |
| 5035 EXPECT_EQ(0u, session->num_pushed_streams()); | 4959 EXPECT_EQ(0u, session->num_pushed_streams()); |
| 5036 EXPECT_EQ(0u, session->num_active_pushed_streams()); | 4960 EXPECT_EQ(0u, session->num_active_pushed_streams()); |
| 5037 | 4961 |
| 5038 scoped_ptr<SpdyHeaderBlock> headers( | 4962 scoped_ptr<SpdyHeaderBlock> headers( |
| 5039 spdy_util_.ConstructGetHeaderBlock(url1.spec())); | 4963 spdy_util_.ConstructGetHeaderBlock(url1.spec())); |
| 5040 spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); | 4964 spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); |
| 5041 EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); | 4965 EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); |
| 5042 | 4966 |
| 5043 // Run until 1st stream is activated. | 4967 // Run until 1st stream is activated. |
| 5044 EXPECT_EQ(0u, delegate1.stream_id()); | 4968 EXPECT_EQ(0u, delegate1.stream_id()); |
| 5045 data.RunFor(1); | 4969 base::RunLoop().RunUntilIdle(); |
| 5046 EXPECT_EQ(1u, delegate1.stream_id()); | 4970 EXPECT_EQ(1u, delegate1.stream_id()); |
| 5047 EXPECT_EQ(1u, session->num_active_streams()); | 4971 EXPECT_EQ(1u, session->num_active_streams()); |
| 5048 EXPECT_EQ(0u, session->num_created_streams()); | 4972 EXPECT_EQ(0u, session->num_created_streams()); |
| 5049 EXPECT_EQ(0u, session->num_pushed_streams()); | 4973 EXPECT_EQ(0u, session->num_pushed_streams()); |
| 5050 EXPECT_EQ(0u, session->num_active_pushed_streams()); | 4974 EXPECT_EQ(0u, session->num_active_pushed_streams()); |
| 5051 | 4975 |
| 5052 // Run until pushed stream is created. | 4976 // Run until pushed stream is created. |
| 5053 data.RunFor(1); | 4977 data.CompleteRead(); |
| 4978 base::RunLoop().RunUntilIdle(); |
| 5054 EXPECT_EQ(2u, session->num_active_streams()); | 4979 EXPECT_EQ(2u, session->num_active_streams()); |
| 5055 EXPECT_EQ(0u, session->num_created_streams()); | 4980 EXPECT_EQ(0u, session->num_created_streams()); |
| 5056 EXPECT_EQ(1u, session->num_pushed_streams()); | 4981 EXPECT_EQ(1u, session->num_pushed_streams()); |
| 5057 EXPECT_EQ(1u, session->num_active_pushed_streams()); | 4982 EXPECT_EQ(1u, session->num_active_pushed_streams()); |
| 5058 | 4983 |
| 5059 // Accept promised stream. It should not count towards pushed stream limit. | 4984 // Accept promised stream. It should not count towards pushed stream limit. |
| 5060 data.RunFor(1); | 4985 data.CompleteRead(); |
| 4986 base::RunLoop().RunUntilIdle(); |
| 5061 EXPECT_EQ(3u, session->num_active_streams()); | 4987 EXPECT_EQ(3u, session->num_active_streams()); |
| 5062 EXPECT_EQ(0u, session->num_created_streams()); | 4988 EXPECT_EQ(0u, session->num_created_streams()); |
| 5063 EXPECT_EQ(2u, session->num_pushed_streams()); | 4989 EXPECT_EQ(2u, session->num_pushed_streams()); |
| 5064 EXPECT_EQ(1u, session->num_active_pushed_streams()); | 4990 EXPECT_EQ(1u, session->num_active_pushed_streams()); |
| 5065 | 4991 |
| 5066 // Reset last pushed stream upon headers reception as it is going to be 2nd, | 4992 // Reset last pushed stream upon headers reception as it is going to be 2nd, |
| 5067 // while we accept only one. | 4993 // while we accept only one. |
| 5068 data.RunFor(2); | 4994 data.CompleteRead(); |
| 4995 base::RunLoop().RunUntilIdle(); |
| 5069 EXPECT_EQ(2u, session->num_active_streams()); | 4996 EXPECT_EQ(2u, session->num_active_streams()); |
| 5070 EXPECT_EQ(0u, session->num_created_streams()); | 4997 EXPECT_EQ(0u, session->num_created_streams()); |
| 5071 EXPECT_EQ(1u, session->num_pushed_streams()); | 4998 EXPECT_EQ(1u, session->num_pushed_streams()); |
| 5072 EXPECT_EQ(1u, session->num_active_pushed_streams()); | 4999 EXPECT_EQ(1u, session->num_active_pushed_streams()); |
| 5073 | 5000 |
| 5074 // Read EOF. | 5001 // Read EOF. |
| 5075 data.RunFor(1); | 5002 data.CompleteRead(); |
| 5003 base::RunLoop().RunUntilIdle(); |
| 5004 EXPECT_FALSE(session); |
| 5076 } | 5005 } |
| 5077 | 5006 |
| 5078 TEST_P(SpdySessionTest, CancelReservedStreamOnHeadersReceived) { | 5007 TEST_P(SpdySessionTest, CancelReservedStreamOnHeadersReceived) { |
| 5079 // Streams in reserved remote state exist only in SPDY4. | 5008 // Streams in reserved remote state exist only in SPDY4. |
| 5080 if (spdy_util_.spdy_version() < SPDY4) | 5009 if (spdy_util_.spdy_version() < SPDY4) |
| 5081 return; | 5010 return; |
| 5082 | 5011 |
| 5083 const char kPushedUrl[] = "http://www.example.org/a.dat"; | 5012 const char kPushedUrl[] = "http://www.example.org/a.dat"; |
| 5084 scoped_ptr<SpdyHeaderBlock> push_headers(new SpdyHeaderBlock); | 5013 scoped_ptr<SpdyHeaderBlock> push_headers(new SpdyHeaderBlock); |
| 5085 spdy_util_.AddUrlToHeaderBlock(kPushedUrl, push_headers.get()); | 5014 spdy_util_.AddUrlToHeaderBlock(kPushedUrl, push_headers.get()); |
| 5086 scoped_ptr<SpdyFrame> push_promise( | 5015 scoped_ptr<SpdyFrame> push_promise( |
| 5087 spdy_util_.ConstructInitialSpdyPushFrame(push_headers.Pass(), 2, 1)); | 5016 spdy_util_.ConstructInitialSpdyPushFrame(push_headers.Pass(), 2, 1)); |
| 5088 scoped_ptr<SpdyFrame> headers_frame( | 5017 scoped_ptr<SpdyFrame> headers_frame( |
| 5089 spdy_util_.ConstructSpdyPushHeaders(2, NULL, 0)); | 5018 spdy_util_.ConstructSpdyPushHeaders(2, nullptr, 0)); |
| 5090 MockRead reads[] = { | 5019 MockRead reads[] = { |
| 5091 CreateMockRead(*push_promise, 1), CreateMockRead(*headers_frame, 2), | 5020 MockRead(ASYNC, ERR_IO_PENDING, 1), |
| 5092 MockRead(ASYNC, 0, 4), | 5021 CreateMockRead(*push_promise, 2), |
| 5022 MockRead(ASYNC, ERR_IO_PENDING, 3), |
| 5023 CreateMockRead(*headers_frame, 4), |
| 5024 MockRead(ASYNC, ERR_IO_PENDING, 6), |
| 5025 MockRead(ASYNC, 0, 7), |
| 5093 }; | 5026 }; |
| 5094 | 5027 |
| 5095 scoped_ptr<SpdyFrame> req( | 5028 scoped_ptr<SpdyFrame> req( |
| 5096 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); | 5029 spdy_util_.ConstructSpdyGet(nullptr, 0, false, 1, LOWEST, true)); |
| 5097 scoped_ptr<SpdyFrame> rst( | 5030 scoped_ptr<SpdyFrame> rst( |
| 5098 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_CANCEL)); | 5031 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_CANCEL)); |
| 5099 MockWrite writes[] = { | 5032 MockWrite writes[] = { |
| 5100 CreateMockWrite(*req, 0), CreateMockWrite(*rst, 3), | 5033 CreateMockWrite(*req, 0), CreateMockWrite(*rst, 5), |
| 5101 }; | 5034 }; |
| 5102 | 5035 |
| 5103 DeterministicSocketData data( | 5036 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); |
| 5104 reads, arraysize(reads), writes, arraysize(writes)); | 5037 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 5105 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 5106 data.set_connect_data(connect_data); | |
| 5107 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); | |
| 5108 | 5038 |
| 5109 CreateDeterministicNetworkSession(); | 5039 CreateNetworkSession(); |
| 5110 | 5040 |
| 5111 base::WeakPtr<SpdySession> session = | 5041 base::WeakPtr<SpdySession> session = |
| 5112 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 5042 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 5113 | 5043 |
| 5114 GURL url1(kDefaultURL); | 5044 GURL url1(kDefaultURL); |
| 5115 base::WeakPtr<SpdyStream> spdy_stream1 = CreateStreamSynchronously( | 5045 base::WeakPtr<SpdyStream> spdy_stream1 = CreateStreamSynchronously( |
| 5116 SPDY_REQUEST_RESPONSE_STREAM, session, url1, LOWEST, BoundNetLog()); | 5046 SPDY_REQUEST_RESPONSE_STREAM, session, url1, LOWEST, BoundNetLog()); |
| 5117 ASSERT_TRUE(spdy_stream1.get() != NULL); | 5047 ASSERT_TRUE(spdy_stream1.get() != nullptr); |
| 5118 EXPECT_EQ(0u, spdy_stream1->stream_id()); | 5048 EXPECT_EQ(0u, spdy_stream1->stream_id()); |
| 5119 test::StreamDelegateDoNothing delegate1(spdy_stream1); | 5049 test::StreamDelegateDoNothing delegate1(spdy_stream1); |
| 5120 spdy_stream1->SetDelegate(&delegate1); | 5050 spdy_stream1->SetDelegate(&delegate1); |
| 5121 | 5051 |
| 5122 EXPECT_EQ(0u, session->num_active_streams()); | 5052 EXPECT_EQ(0u, session->num_active_streams()); |
| 5123 EXPECT_EQ(1u, session->num_created_streams()); | 5053 EXPECT_EQ(1u, session->num_created_streams()); |
| 5124 EXPECT_EQ(0u, session->num_pushed_streams()); | 5054 EXPECT_EQ(0u, session->num_pushed_streams()); |
| 5125 EXPECT_EQ(0u, session->num_active_pushed_streams()); | 5055 EXPECT_EQ(0u, session->num_active_pushed_streams()); |
| 5126 | 5056 |
| 5127 scoped_ptr<SpdyHeaderBlock> headers( | 5057 scoped_ptr<SpdyHeaderBlock> headers( |
| 5128 spdy_util_.ConstructGetHeaderBlock(url1.spec())); | 5058 spdy_util_.ConstructGetHeaderBlock(url1.spec())); |
| 5129 spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); | 5059 spdy_stream1->SendRequestHeaders(headers.Pass(), NO_MORE_DATA_TO_SEND); |
| 5130 EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); | 5060 EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); |
| 5131 | 5061 |
| 5132 // Run until 1st stream is activated. | 5062 // Run until 1st stream is activated. |
| 5133 EXPECT_EQ(0u, delegate1.stream_id()); | 5063 EXPECT_EQ(0u, delegate1.stream_id()); |
| 5134 data.RunFor(1); | 5064 base::RunLoop().RunUntilIdle(); |
| 5135 EXPECT_EQ(1u, delegate1.stream_id()); | 5065 EXPECT_EQ(1u, delegate1.stream_id()); |
| 5136 EXPECT_EQ(1u, session->num_active_streams()); | 5066 EXPECT_EQ(1u, session->num_active_streams()); |
| 5137 EXPECT_EQ(0u, session->num_created_streams()); | 5067 EXPECT_EQ(0u, session->num_created_streams()); |
| 5138 EXPECT_EQ(0u, session->num_pushed_streams()); | 5068 EXPECT_EQ(0u, session->num_pushed_streams()); |
| 5139 EXPECT_EQ(0u, session->num_active_pushed_streams()); | 5069 EXPECT_EQ(0u, session->num_active_pushed_streams()); |
| 5140 | 5070 |
| 5141 // Run until pushed stream is created. | 5071 // Run until pushed stream is created. |
| 5142 data.RunFor(1); | 5072 data.CompleteRead(); |
| 5073 base::RunLoop().RunUntilIdle(); |
| 5143 EXPECT_EQ(2u, session->num_active_streams()); | 5074 EXPECT_EQ(2u, session->num_active_streams()); |
| 5144 EXPECT_EQ(0u, session->num_created_streams()); | 5075 EXPECT_EQ(0u, session->num_created_streams()); |
| 5145 EXPECT_EQ(1u, session->num_pushed_streams()); | 5076 EXPECT_EQ(1u, session->num_pushed_streams()); |
| 5146 EXPECT_EQ(0u, session->num_active_pushed_streams()); | 5077 EXPECT_EQ(0u, session->num_active_pushed_streams()); |
| 5147 | 5078 |
| 5148 base::WeakPtr<SpdyStream> pushed_stream; | 5079 base::WeakPtr<SpdyStream> pushed_stream; |
| 5149 int rv = | 5080 int rv = |
| 5150 session->GetPushStream(GURL(kPushedUrl), &pushed_stream, BoundNetLog()); | 5081 session->GetPushStream(GURL(kPushedUrl), &pushed_stream, BoundNetLog()); |
| 5151 ASSERT_EQ(OK, rv); | 5082 ASSERT_EQ(OK, rv); |
| 5152 ASSERT_TRUE(pushed_stream.get() != NULL); | 5083 ASSERT_TRUE(pushed_stream.get() != nullptr); |
| 5153 test::StreamDelegateCloseOnHeaders delegate2(pushed_stream); | 5084 test::StreamDelegateCloseOnHeaders delegate2(pushed_stream); |
| 5154 pushed_stream->SetDelegate(&delegate2); | 5085 pushed_stream->SetDelegate(&delegate2); |
| 5155 | 5086 |
| 5156 // Receive headers for pushed stream. Delegate will cancel the stream, ensure | 5087 // Receive headers for pushed stream. Delegate will cancel the stream, ensure |
| 5157 // that all our counters are in consistent state. | 5088 // that all our counters are in consistent state. |
| 5158 data.RunFor(1); | 5089 data.CompleteRead(); |
| 5090 base::RunLoop().RunUntilIdle(); |
| 5159 EXPECT_EQ(1u, session->num_active_streams()); | 5091 EXPECT_EQ(1u, session->num_active_streams()); |
| 5160 EXPECT_EQ(0u, session->num_created_streams()); | 5092 EXPECT_EQ(0u, session->num_created_streams()); |
| 5161 EXPECT_EQ(0u, session->num_pushed_streams()); | 5093 EXPECT_EQ(0u, session->num_pushed_streams()); |
| 5162 EXPECT_EQ(0u, session->num_active_pushed_streams()); | 5094 EXPECT_EQ(0u, session->num_active_pushed_streams()); |
| 5163 | 5095 |
| 5164 // Read EOF. | 5096 // Read EOF. |
| 5165 data.RunFor(2); | 5097 data.CompleteRead(); |
| 5098 base::RunLoop().RunUntilIdle(); |
| 5099 EXPECT_TRUE(data.AllWriteDataConsumed()); |
| 5100 EXPECT_TRUE(data.AllReadDataConsumed()); |
| 5166 } | 5101 } |
| 5167 | 5102 |
| 5168 TEST_P(SpdySessionTest, RejectInvalidUnknownFrames) { | 5103 TEST_P(SpdySessionTest, RejectInvalidUnknownFrames) { |
| 5169 session_deps_.host_resolver->set_synchronous_mode(true); | 5104 session_deps_.host_resolver->set_synchronous_mode(true); |
| 5170 | 5105 |
| 5171 MockRead reads[] = { | 5106 MockRead reads[] = { |
| 5172 MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. | 5107 MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. |
| 5173 }; | 5108 }; |
| 5174 | 5109 |
| 5175 StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0); | 5110 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0); |
| 5176 | |
| 5177 MockConnect connect_data(SYNCHRONOUS, OK); | |
| 5178 data.set_connect_data(connect_data); | |
| 5179 session_deps_.socket_factory->AddSocketDataProvider(&data); | 5111 session_deps_.socket_factory->AddSocketDataProvider(&data); |
| 5180 | 5112 |
| 5181 CreateNetworkSession(); | 5113 CreateNetworkSession(); |
| 5182 base::WeakPtr<SpdySession> session = | 5114 base::WeakPtr<SpdySession> session = |
| 5183 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); | 5115 CreateInsecureSpdySession(http_session_, key_, BoundNetLog()); |
| 5184 | 5116 |
| 5185 session->stream_hi_water_mark_ = 5; | 5117 session->stream_hi_water_mark_ = 5; |
| 5186 // Low client (odd) ids are fine. | 5118 // Low client (odd) ids are fine. |
| 5187 EXPECT_TRUE(session->OnUnknownFrame(3, 0)); | 5119 EXPECT_TRUE(session->OnUnknownFrame(3, 0)); |
| 5188 // Client id exceeding watermark. | 5120 // Client id exceeding watermark. |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5346 ssl_info.cert = ImportCertFromFile(GetTestCertsDirectory(), | 5278 ssl_info.cert = ImportCertFromFile(GetTestCertsDirectory(), |
| 5347 "spdy_pooling.pem"); | 5279 "spdy_pooling.pem"); |
| 5348 ssl_info.is_issued_by_known_root = true; | 5280 ssl_info.is_issued_by_known_root = true; |
| 5349 ssl_info.public_key_hashes.push_back(test::GetTestHashValue(primary_pin)); | 5281 ssl_info.public_key_hashes.push_back(test::GetTestHashValue(primary_pin)); |
| 5350 | 5282 |
| 5351 EXPECT_TRUE(SpdySession::CanPool( | 5283 EXPECT_TRUE(SpdySession::CanPool( |
| 5352 &tss, ssl_info, "www.example.org", "mail.example.org")); | 5284 &tss, ssl_info, "www.example.org", "mail.example.org")); |
| 5353 } | 5285 } |
| 5354 | 5286 |
| 5355 } // namespace net | 5287 } // namespace net |
| OLD | NEW |