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 |