Speech refactoring: Reimplemented SpeechRecognitionManagerImpl as a FSM. (CL1.7)
[chromium-blink-merge.git] / net / spdy / spdy_session_spdy3_unittest.cc
blob7ac41c308048b07a8722c84e52a2bd86a30fbe3e
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
3 // found in the LICENSE file.
5 #include "net/spdy/spdy_session.h"
7 #include "net/base/host_cache.h"
8 #include "net/base/ip_endpoint.h"
9 #include "net/base/net_log_unittest.h"
10 #include "net/spdy/spdy_io_buffer.h"
11 #include "net/spdy/spdy_session_pool.h"
12 #include "net/spdy/spdy_stream.h"
13 #include "net/spdy/spdy_test_util_spdy3.h"
14 #include "testing/platform_test.h"
16 using namespace net::test_spdy3;
18 namespace net {
20 // TODO(cbentzel): Expose compression setter/getter in public SpdySession
21 // interface rather than going through all these contortions.
22 class SpdySessionSpdy3Test : public PlatformTest {
23 protected:
24 virtual void SetUp() {
25 SpdySession::set_default_protocol(kProtoSPDY3);
28 private:
29 SpdyTestStateHelper spdy_state_;
32 class TestSpdyStreamDelegate : public net::SpdyStream::Delegate {
33 public:
34 explicit TestSpdyStreamDelegate(const CompletionCallback& callback)
35 : callback_(callback) {}
36 virtual ~TestSpdyStreamDelegate() {}
38 virtual bool OnSendHeadersComplete(int status) { return true; }
40 virtual int OnSendBody() {
41 return ERR_UNEXPECTED;
44 virtual int OnSendBodyComplete(int /*status*/, bool* /*eof*/) {
45 return ERR_UNEXPECTED;
48 virtual int OnResponseReceived(const SpdyHeaderBlock& response,
49 base::Time response_time,
50 int status) {
51 return status;
54 virtual void OnDataReceived(const char* buffer, int bytes) {
57 virtual void OnDataSent(int length) {
60 virtual void OnClose(int status) {
61 CompletionCallback callback = callback_;
62 callback_.Reset();
63 callback.Run(OK);
66 virtual void set_chunk_callback(net::ChunkCallback *) {}
68 private:
69 CompletionCallback callback_;
72 // Test the SpdyIOBuffer class.
73 TEST_F(SpdySessionSpdy3Test, SpdyIOBuffer) {
74 std::priority_queue<SpdyIOBuffer> queue_;
75 const size_t kQueueSize = 100;
77 // Insert items with random priority and increasing buffer size
78 for (size_t index = 0; index < kQueueSize; ++index) {
79 queue_.push(SpdyIOBuffer(
80 new IOBufferWithSize(index + 1),
81 index + 1,
82 static_cast<RequestPriority>(rand() % NUM_PRIORITIES),
83 NULL));
86 EXPECT_EQ(kQueueSize, queue_.size());
88 // Verify items come out with decreasing priority or FIFO order.
89 RequestPriority last_priority = NUM_PRIORITIES;
90 size_t last_size = 0;
91 for (size_t index = 0; index < kQueueSize; ++index) {
92 SpdyIOBuffer buffer = queue_.top();
93 EXPECT_LE(buffer.priority(), last_priority);
94 if (buffer.priority() < last_priority)
95 last_size = 0;
96 EXPECT_LT(last_size, buffer.size());
97 last_priority = buffer.priority();
98 last_size = buffer.size();
99 queue_.pop();
102 EXPECT_EQ(0u, queue_.size());
105 TEST_F(SpdySessionSpdy3Test, GoAway) {
106 SpdySessionDependencies session_deps;
107 session_deps.host_resolver->set_synchronous_mode(true);
109 MockConnect connect_data(SYNCHRONOUS, OK);
110 scoped_ptr<SpdyFrame> goaway(ConstructSpdyGoAway());
111 MockRead reads[] = {
112 CreateMockRead(*goaway),
113 MockRead(SYNCHRONOUS, 0, 0) // EOF
115 StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
116 data.set_connect_data(connect_data);
117 session_deps.socket_factory->AddSocketDataProvider(&data);
119 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
120 ssl.SetNextProto(kProtoSPDY3);
121 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
123 scoped_refptr<HttpNetworkSession> http_session(
124 SpdySessionDependencies::SpdyCreateSession(&session_deps));
126 const std::string kTestHost("www.foo.com");
127 const int kTestPort = 80;
128 HostPortPair test_host_port_pair(kTestHost, kTestPort);
129 HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
131 SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
132 EXPECT_FALSE(spdy_session_pool->HasSession(pair));
133 scoped_refptr<SpdySession> session =
134 spdy_session_pool->Get(pair, BoundNetLog());
135 EXPECT_TRUE(spdy_session_pool->HasSession(pair));
137 scoped_refptr<TransportSocketParams> transport_params(
138 new TransportSocketParams(test_host_port_pair,
139 MEDIUM,
140 false,
141 false));
142 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
143 EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
144 transport_params, MEDIUM, CompletionCallback(),
145 http_session->GetTransportSocketPool(
146 HttpNetworkSession::NORMAL_SOCKET_POOL),
147 BoundNetLog()));
148 EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
149 EXPECT_EQ(3, session->GetProtocolVersion());
151 // Flush the SpdySession::OnReadComplete() task.
152 MessageLoop::current()->RunAllPending();
154 EXPECT_FALSE(spdy_session_pool->HasSession(pair));
156 scoped_refptr<SpdySession> session2 =
157 spdy_session_pool->Get(pair, BoundNetLog());
159 // Delete the first session.
160 session = NULL;
162 // Delete the second session.
163 spdy_session_pool->Remove(session2);
164 session2 = NULL;
167 TEST_F(SpdySessionSpdy3Test, Ping) {
168 SpdySessionDependencies session_deps;
169 session_deps.host_resolver->set_synchronous_mode(true);
171 MockConnect connect_data(SYNCHRONOUS, OK);
172 scoped_ptr<SpdyFrame> read_ping(ConstructSpdyPing());
173 MockRead reads[] = {
174 CreateMockRead(*read_ping),
175 CreateMockRead(*read_ping),
176 MockRead(SYNCHRONOUS, 0, 0) // EOF
178 scoped_ptr<SpdyFrame> write_ping(ConstructSpdyPing());
179 MockRead writes[] = {
180 CreateMockRead(*write_ping),
181 CreateMockRead(*write_ping),
183 StaticSocketDataProvider data(
184 reads, arraysize(reads), writes, arraysize(writes));
185 data.set_connect_data(connect_data);
186 session_deps.socket_factory->AddSocketDataProvider(&data);
188 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
189 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
191 scoped_refptr<HttpNetworkSession> http_session(
192 SpdySessionDependencies::SpdyCreateSession(&session_deps));
194 static const char kStreamUrl[] = "http://www.google.com/";
195 GURL url(kStreamUrl);
197 const std::string kTestHost("www.google.com");
198 const int kTestPort = 80;
199 HostPortPair test_host_port_pair(kTestHost, kTestPort);
200 HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
202 SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
203 EXPECT_FALSE(spdy_session_pool->HasSession(pair));
204 scoped_refptr<SpdySession> session =
205 spdy_session_pool->Get(pair, BoundNetLog());
206 EXPECT_TRUE(spdy_session_pool->HasSession(pair));
209 scoped_refptr<TransportSocketParams> transport_params(
210 new TransportSocketParams(test_host_port_pair,
211 MEDIUM,
212 false,
213 false));
214 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
215 EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
216 transport_params, MEDIUM, CompletionCallback(),
217 http_session->GetTransportSocketPool(
218 HttpNetworkSession::NORMAL_SOCKET_POOL),
219 BoundNetLog()));
220 EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
222 scoped_refptr<SpdyStream> spdy_stream1;
223 TestCompletionCallback callback1;
224 EXPECT_EQ(OK, session->CreateStream(url,
225 MEDIUM,
226 &spdy_stream1,
227 BoundNetLog(),
228 callback1.callback()));
229 scoped_ptr<TestSpdyStreamDelegate> delegate(
230 new TestSpdyStreamDelegate(callback1.callback()));
231 spdy_stream1->SetDelegate(delegate.get());
233 base::TimeTicks before_ping_time = base::TimeTicks::Now();
235 // Enable sending of PING.
236 SpdySession::set_enable_ping_based_connection_checking(true);
237 session->set_connection_at_risk_of_loss_time(base::TimeDelta::FromSeconds(0));
238 session->set_trailing_ping_delay_time(base::TimeDelta::FromSeconds(0));
239 session->set_hung_interval(base::TimeDelta::FromMilliseconds(50));
241 session->SendPrefacePingIfNoneInFlight();
243 EXPECT_EQ(OK, callback1.WaitForResult());
245 session->CheckPingStatus(before_ping_time);
247 EXPECT_EQ(0, session->pings_in_flight());
248 EXPECT_GT(session->next_ping_id(), static_cast<uint32>(1));
249 EXPECT_FALSE(session->trailing_ping_pending());
250 EXPECT_FALSE(session->check_ping_status_pending());
251 EXPECT_GE(session->received_data_time(), before_ping_time);
253 EXPECT_FALSE(spdy_session_pool->HasSession(pair));
255 // Delete the first session.
256 session = NULL;
259 TEST_F(SpdySessionSpdy3Test, FailedPing) {
260 SpdySessionDependencies session_deps;
261 session_deps.host_resolver->set_synchronous_mode(true);
263 MockConnect connect_data(SYNCHRONOUS, OK);
264 scoped_ptr<SpdyFrame> read_ping(ConstructSpdyPing());
265 MockRead reads[] = {
266 CreateMockRead(*read_ping),
267 MockRead(SYNCHRONOUS, 0, 0) // EOF
269 scoped_ptr<SpdyFrame> write_ping(ConstructSpdyPing());
270 MockRead writes[] = {
271 CreateMockRead(*write_ping),
273 StaticSocketDataProvider data(
274 reads, arraysize(reads), writes, arraysize(writes));
275 data.set_connect_data(connect_data);
276 session_deps.socket_factory->AddSocketDataProvider(&data);
278 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
279 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
281 scoped_refptr<HttpNetworkSession> http_session(
282 SpdySessionDependencies::SpdyCreateSession(&session_deps));
284 static const char kStreamUrl[] = "http://www.gmail.com/";
285 GURL url(kStreamUrl);
287 const std::string kTestHost("www.gmail.com");
288 const int kTestPort = 80;
289 HostPortPair test_host_port_pair(kTestHost, kTestPort);
290 HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
292 SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
293 EXPECT_FALSE(spdy_session_pool->HasSession(pair));
294 scoped_refptr<SpdySession> session =
295 spdy_session_pool->Get(pair, BoundNetLog());
296 EXPECT_TRUE(spdy_session_pool->HasSession(pair));
298 scoped_refptr<TransportSocketParams> transport_params(
299 new TransportSocketParams(test_host_port_pair,
300 MEDIUM,
301 false,
302 false));
303 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
304 EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
305 transport_params, MEDIUM, CompletionCallback(),
306 http_session->GetTransportSocketPool(
307 HttpNetworkSession::NORMAL_SOCKET_POOL),
308 BoundNetLog()));
309 EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
311 scoped_refptr<SpdyStream> spdy_stream1;
312 TestCompletionCallback callback1;
313 EXPECT_EQ(OK, session->CreateStream(url,
314 MEDIUM,
315 &spdy_stream1,
316 BoundNetLog(),
317 callback1.callback()));
318 scoped_ptr<TestSpdyStreamDelegate> delegate(
319 new TestSpdyStreamDelegate(callback1.callback()));
320 spdy_stream1->SetDelegate(delegate.get());
322 // Enable sending of PING.
323 SpdySession::set_enable_ping_based_connection_checking(true);
324 session->set_connection_at_risk_of_loss_time(base::TimeDelta::FromSeconds(0));
325 session->set_trailing_ping_delay_time(base::TimeDelta::FromSeconds(0));
326 session->set_hung_interval(base::TimeDelta::FromSeconds(0));
328 // Send a PING frame.
329 session->WritePingFrame(1);
330 EXPECT_LT(0, session->pings_in_flight());
331 EXPECT_GT(session->next_ping_id(), static_cast<uint32>(1));
332 EXPECT_TRUE(session->check_ping_status_pending());
334 // Assert session is not closed.
335 EXPECT_FALSE(session->IsClosed());
336 EXPECT_LT(0u, session->num_active_streams());
337 EXPECT_TRUE(spdy_session_pool->HasSession(pair));
339 // We set last time we have received any data in 1 sec less than now.
340 // CheckPingStatus will trigger timeout because hung interval is zero.
341 base::TimeTicks now = base::TimeTicks::Now();
342 session->received_data_time_ = now - base::TimeDelta::FromSeconds(1);
343 session->CheckPingStatus(now);
345 EXPECT_TRUE(session->IsClosed());
346 EXPECT_EQ(0u, session->num_active_streams());
347 EXPECT_EQ(0u, session->num_unclaimed_pushed_streams());
348 EXPECT_FALSE(spdy_session_pool->HasSession(pair));
350 // Delete the first session.
351 session = NULL;
354 class StreamReleaserCallback : public TestCompletionCallbackBase {
355 public:
356 StreamReleaserCallback(SpdySession* session,
357 SpdyStream* first_stream)
358 : session_(session),
359 first_stream_(first_stream),
360 ALLOW_THIS_IN_INITIALIZER_LIST(callback_(
361 base::Bind(&StreamReleaserCallback::OnComplete,
362 base::Unretained(this)))) {
365 virtual ~StreamReleaserCallback() {}
367 scoped_refptr<SpdyStream>* stream() { return &stream_; }
369 const CompletionCallback& callback() const { return callback_; }
371 private:
372 void OnComplete(int result) {
373 session_->CloseSessionOnError(ERR_FAILED, false, "On complete.");
374 session_ = NULL;
375 first_stream_->Cancel();
376 first_stream_ = NULL;
377 stream_->Cancel();
378 stream_ = NULL;
379 SetResult(result);
382 scoped_refptr<SpdySession> session_;
383 scoped_refptr<SpdyStream> first_stream_;
384 scoped_refptr<SpdyStream> stream_;
385 CompletionCallback callback_;
388 // TODO(kristianm): Could also test with more sessions where some are idle,
389 // and more than one session to a HostPortPair.
390 TEST_F(SpdySessionSpdy3Test, CloseIdleSessions) {
391 SpdySessionDependencies session_deps;
392 scoped_refptr<HttpNetworkSession> http_session(
393 SpdySessionDependencies::SpdyCreateSession(&session_deps));
394 SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
396 // Set up session 1
397 const std::string kTestHost1("http://www.a.com");
398 HostPortPair test_host_port_pair1(kTestHost1, 80);
399 HostPortProxyPair pair1(test_host_port_pair1, ProxyServer::Direct());
400 scoped_refptr<SpdySession> session1 =
401 spdy_session_pool->Get(pair1, BoundNetLog());
402 scoped_refptr<SpdyStream> spdy_stream1;
403 TestCompletionCallback callback1;
404 GURL url1(kTestHost1);
405 EXPECT_EQ(OK, session1->CreateStream(url1,
406 MEDIUM, /* priority, not important */
407 &spdy_stream1,
408 BoundNetLog(),
409 callback1.callback()));
411 // Set up session 2
412 const std::string kTestHost2("http://www.b.com");
413 HostPortPair test_host_port_pair2(kTestHost2, 80);
414 HostPortProxyPair pair2(test_host_port_pair2, ProxyServer::Direct());
415 scoped_refptr<SpdySession> session2 =
416 spdy_session_pool->Get(pair2, BoundNetLog());
417 scoped_refptr<SpdyStream> spdy_stream2;
418 TestCompletionCallback callback2;
419 GURL url2(kTestHost2);
420 EXPECT_EQ(OK, session2->CreateStream(
421 url2, MEDIUM, /* priority, not important */
422 &spdy_stream2, BoundNetLog(), callback2.callback()));
424 // Set up session 3
425 const std::string kTestHost3("http://www.c.com");
426 HostPortPair test_host_port_pair3(kTestHost3, 80);
427 HostPortProxyPair pair3(test_host_port_pair3, ProxyServer::Direct());
428 scoped_refptr<SpdySession> session3 =
429 spdy_session_pool->Get(pair3, BoundNetLog());
430 scoped_refptr<SpdyStream> spdy_stream3;
431 TestCompletionCallback callback3;
432 GURL url3(kTestHost3);
433 EXPECT_EQ(OK, session3->CreateStream(
434 url3, MEDIUM, /* priority, not important */
435 &spdy_stream3, BoundNetLog(), callback3.callback()));
437 // All sessions are active and not closed
438 EXPECT_TRUE(session1->is_active());
439 EXPECT_FALSE(session1->IsClosed());
440 EXPECT_TRUE(session2->is_active());
441 EXPECT_FALSE(session2->IsClosed());
442 EXPECT_TRUE(session3->is_active());
443 EXPECT_FALSE(session3->IsClosed());
445 // Should not do anything, all are active
446 spdy_session_pool->CloseIdleSessions();
447 EXPECT_TRUE(session1->is_active());
448 EXPECT_FALSE(session1->IsClosed());
449 EXPECT_TRUE(session2->is_active());
450 EXPECT_FALSE(session2->IsClosed());
451 EXPECT_TRUE(session3->is_active());
452 EXPECT_FALSE(session3->IsClosed());
454 // Make sessions 1 and 3 inactive, but keep them open.
455 // Session 2 still open and active
456 session1->CloseStream(spdy_stream1->stream_id(), OK);
457 session3->CloseStream(spdy_stream3->stream_id(), OK);
458 EXPECT_FALSE(session1->is_active());
459 EXPECT_FALSE(session1->IsClosed());
460 EXPECT_TRUE(session2->is_active());
461 EXPECT_FALSE(session2->IsClosed());
462 EXPECT_FALSE(session3->is_active());
463 EXPECT_FALSE(session3->IsClosed());
465 // Should close session 1 and 3, 2 should be left open
466 spdy_session_pool->CloseIdleSessions();
467 EXPECT_FALSE(session1->is_active());
468 EXPECT_TRUE(session1->IsClosed());
469 EXPECT_TRUE(session2->is_active());
470 EXPECT_FALSE(session2->IsClosed());
471 EXPECT_FALSE(session3->is_active());
472 EXPECT_TRUE(session3->IsClosed());
474 // Should not do anything
475 spdy_session_pool->CloseIdleSessions();
476 EXPECT_TRUE(session2->is_active());
477 EXPECT_FALSE(session2->IsClosed());
479 // Make 2 not active
480 session2->CloseStream(spdy_stream2->stream_id(), OK);
481 EXPECT_FALSE(session2->is_active());
482 EXPECT_FALSE(session2->IsClosed());
484 // This should close session 2
485 spdy_session_pool->CloseIdleSessions();
486 EXPECT_FALSE(session2->is_active());
487 EXPECT_TRUE(session2->IsClosed());
490 // Start with max concurrent streams set to 1. Request two streams. Receive a
491 // settings frame setting max concurrent streams to 2. Have the callback
492 // release the stream, which releases its reference (the last) to the session.
493 // Make sure nothing blows up.
494 // http://crbug.com/57331
495 TEST_F(SpdySessionSpdy3Test, OnSettings) {
496 SpdySessionDependencies session_deps;
497 session_deps.host_resolver->set_synchronous_mode(true);
499 SettingsMap new_settings;
500 const SpdySettingsIds kSpdySettingsIds1 = SETTINGS_MAX_CONCURRENT_STREAMS;
501 const size_t max_concurrent_streams = 2;
502 new_settings[kSpdySettingsIds1] =
503 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
505 // Set up the socket so we read a SETTINGS frame that raises max concurrent
506 // streams to 2.
507 MockConnect connect_data(SYNCHRONOUS, OK);
508 scoped_ptr<SpdyFrame> settings_frame(ConstructSpdySettings(new_settings));
509 MockRead reads[] = {
510 CreateMockRead(*settings_frame),
511 MockRead(SYNCHRONOUS, 0, 0) // EOF
514 StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
515 data.set_connect_data(connect_data);
516 session_deps.socket_factory->AddSocketDataProvider(&data);
518 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
519 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
521 scoped_refptr<HttpNetworkSession> http_session(
522 SpdySessionDependencies::SpdyCreateSession(&session_deps));
524 const std::string kTestHost("www.foo.com");
525 const int kTestPort = 80;
526 HostPortPair test_host_port_pair(kTestHost, kTestPort);
527 HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
529 // Initialize the SpdySetting with 1 max concurrent streams.
530 SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
531 spdy_session_pool->http_server_properties()->SetSpdySetting(
532 test_host_port_pair,
533 kSpdySettingsIds1,
534 SETTINGS_FLAG_PLEASE_PERSIST,
537 // Create a session.
538 EXPECT_FALSE(spdy_session_pool->HasSession(pair));
539 scoped_refptr<SpdySession> session =
540 spdy_session_pool->Get(pair, BoundNetLog());
541 ASSERT_TRUE(spdy_session_pool->HasSession(pair));
543 scoped_refptr<TransportSocketParams> transport_params(
544 new TransportSocketParams(test_host_port_pair,
545 MEDIUM,
546 false,
547 false));
548 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
549 EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
550 transport_params, MEDIUM, CompletionCallback(),
551 http_session->GetTransportSocketPool(
552 HttpNetworkSession::NORMAL_SOCKET_POOL),
553 BoundNetLog()));
554 EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
556 // Create 2 streams. First will succeed. Second will be pending.
557 scoped_refptr<SpdyStream> spdy_stream1;
558 TestCompletionCallback callback1;
559 GURL url("http://www.google.com");
560 EXPECT_EQ(OK,
561 session->CreateStream(url,
562 MEDIUM, /* priority, not important */
563 &spdy_stream1,
564 BoundNetLog(),
565 callback1.callback()));
567 StreamReleaserCallback stream_releaser(session, spdy_stream1);
569 ASSERT_EQ(ERR_IO_PENDING,
570 session->CreateStream(url,
571 MEDIUM, /* priority, not important */
572 stream_releaser.stream(),
573 BoundNetLog(),
574 stream_releaser.callback()));
576 // Make sure |stream_releaser| holds the last refs.
577 session = NULL;
578 spdy_stream1 = NULL;
580 EXPECT_EQ(OK, stream_releaser.WaitForResult());
583 // Start with max concurrent streams set to 1. Request two streams. When the
584 // first completes, have the callback close itself, which should trigger the
585 // second stream creation. Then cancel that one immediately. Don't crash.
586 // http://crbug.com/63532
587 TEST_F(SpdySessionSpdy3Test, CancelPendingCreateStream) {
588 SpdySessionDependencies session_deps;
589 session_deps.host_resolver->set_synchronous_mode(true);
591 MockRead reads[] = {
592 MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
595 StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
596 MockConnect connect_data(SYNCHRONOUS, OK);
598 data.set_connect_data(connect_data);
599 session_deps.socket_factory->AddSocketDataProvider(&data);
601 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
602 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
604 scoped_refptr<HttpNetworkSession> http_session(
605 SpdySessionDependencies::SpdyCreateSession(&session_deps));
607 const std::string kTestHost("www.foo.com");
608 const int kTestPort = 80;
609 HostPortPair test_host_port_pair(kTestHost, kTestPort);
610 HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
612 // Initialize the SpdySetting with 1 max concurrent streams.
613 SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
614 spdy_session_pool->http_server_properties()->SetSpdySetting(
615 test_host_port_pair,
616 SETTINGS_MAX_CONCURRENT_STREAMS,
617 SETTINGS_FLAG_PLEASE_PERSIST,
620 // Create a session.
621 EXPECT_FALSE(spdy_session_pool->HasSession(pair));
622 scoped_refptr<SpdySession> session =
623 spdy_session_pool->Get(pair, BoundNetLog());
624 ASSERT_TRUE(spdy_session_pool->HasSession(pair));
626 scoped_refptr<TransportSocketParams> transport_params(
627 new TransportSocketParams(test_host_port_pair,
628 MEDIUM,
629 false,
630 false));
631 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
632 EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
633 transport_params, MEDIUM, CompletionCallback(),
634 http_session->GetTransportSocketPool(
635 HttpNetworkSession::NORMAL_SOCKET_POOL),
636 BoundNetLog()));
637 EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
639 // Use scoped_ptr to let us invalidate the memory when we want to, to trigger
640 // a valgrind error if the callback is invoked when it's not supposed to be.
641 scoped_ptr<TestCompletionCallback> callback(new TestCompletionCallback);
643 // Create 2 streams. First will succeed. Second will be pending.
644 scoped_refptr<SpdyStream> spdy_stream1;
645 GURL url("http://www.google.com");
646 ASSERT_EQ(OK,
647 session->CreateStream(url,
648 MEDIUM, /* priority, not important */
649 &spdy_stream1,
650 BoundNetLog(),
651 callback->callback()));
653 scoped_refptr<SpdyStream> spdy_stream2;
654 ASSERT_EQ(ERR_IO_PENDING,
655 session->CreateStream(url,
656 MEDIUM, /* priority, not important */
657 &spdy_stream2,
658 BoundNetLog(),
659 callback->callback()));
661 // Release the first one, this will allow the second to be created.
662 spdy_stream1->Cancel();
663 spdy_stream1 = NULL;
665 session->CancelPendingCreateStreams(&spdy_stream2);
666 callback.reset();
668 // Should not crash when running the pending callback.
669 MessageLoop::current()->RunAllPending();
672 TEST_F(SpdySessionSpdy3Test, SendSettingsOnNewSession) {
673 SpdySessionDependencies session_deps;
674 session_deps.host_resolver->set_synchronous_mode(true);
676 MockRead reads[] = {
677 MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
680 // Create the bogus setting that we want to verify is sent out.
681 // Note that it will be marked as SETTINGS_FLAG_PERSISTED when sent out. But
682 // to persist it into the HttpServerProperties, we need to mark as
683 // SETTINGS_FLAG_PLEASE_PERSIST.
684 SettingsMap settings;
685 const SpdySettingsIds kSpdySettingsIds1 = SETTINGS_UPLOAD_BANDWIDTH;
686 const uint32 kBogusSettingValue = 0xCDCD;
687 settings[kSpdySettingsIds1] =
688 SettingsFlagsAndValue(SETTINGS_FLAG_PERSISTED, kBogusSettingValue);
689 MockConnect connect_data(SYNCHRONOUS, OK);
690 scoped_ptr<SpdyFrame> settings_frame(ConstructSpdySettings(settings));
691 MockWrite writes[] = {
692 CreateMockWrite(*settings_frame),
695 StaticSocketDataProvider data(
696 reads, arraysize(reads), writes, arraysize(writes));
697 data.set_connect_data(connect_data);
698 session_deps.socket_factory->AddSocketDataProvider(&data);
700 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
701 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
703 scoped_refptr<HttpNetworkSession> http_session(
704 SpdySessionDependencies::SpdyCreateSession(&session_deps));
706 const std::string kTestHost("www.foo.com");
707 const int kTestPort = 80;
708 HostPortPair test_host_port_pair(kTestHost, kTestPort);
709 HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
711 SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
712 spdy_session_pool->http_server_properties()->SetSpdySetting(
713 test_host_port_pair,
714 kSpdySettingsIds1,
715 SETTINGS_FLAG_PLEASE_PERSIST,
716 kBogusSettingValue);
718 EXPECT_FALSE(spdy_session_pool->HasSession(pair));
719 scoped_refptr<SpdySession> session =
720 spdy_session_pool->Get(pair, BoundNetLog());
721 EXPECT_TRUE(spdy_session_pool->HasSession(pair));
723 scoped_refptr<TransportSocketParams> transport_params(
724 new TransportSocketParams(test_host_port_pair,
725 MEDIUM,
726 false,
727 false));
728 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
729 EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
730 transport_params, MEDIUM, CompletionCallback(),
731 http_session->GetTransportSocketPool(
732 HttpNetworkSession::NORMAL_SOCKET_POOL),
733 BoundNetLog()));
734 EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
735 MessageLoop::current()->RunAllPending();
736 EXPECT_TRUE(data.at_write_eof());
739 namespace {
740 // This test has two variants, one for each style of closing the connection.
741 // If |clean_via_close_current_sessions| is false, the sessions are closed
742 // manually, calling SpdySessionPool::Remove() directly. If it is true,
743 // sessions are closed with SpdySessionPool::CloseCurrentSessions().
744 void IPPoolingTest(bool clean_via_close_current_sessions) {
745 const int kTestPort = 80;
746 struct TestHosts {
747 std::string name;
748 std::string iplist;
749 HostPortProxyPair pair;
750 AddressList addresses;
751 } test_hosts[] = {
752 { "www.foo.com", "192.0.2.33,192.168.0.1,192.168.0.5" },
753 { "images.foo.com", "192.168.0.2,192.168.0.3,192.168.0.5,192.0.2.33" },
754 { "js.foo.com", "192.168.0.4,192.168.0.3" },
757 SpdySessionDependencies session_deps;
758 session_deps.host_resolver->set_synchronous_mode(true);
759 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_hosts); i++) {
760 session_deps.host_resolver->rules()->AddIPLiteralRule(test_hosts[i].name,
761 test_hosts[i].iplist, "");
763 // This test requires that the HostResolver cache be populated. Normal
764 // code would have done this already, but we do it manually.
765 HostResolver::RequestInfo info(HostPortPair(test_hosts[i].name, kTestPort));
766 session_deps.host_resolver->Resolve(
767 info, &test_hosts[i].addresses, CompletionCallback(), NULL,
768 BoundNetLog());
770 // Setup a HostPortProxyPair
771 test_hosts[i].pair = HostPortProxyPair(
772 HostPortPair(test_hosts[i].name, kTestPort), ProxyServer::Direct());
775 MockConnect connect_data(SYNCHRONOUS, OK);
776 MockRead reads[] = {
777 MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
780 StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
781 data.set_connect_data(connect_data);
782 session_deps.socket_factory->AddSocketDataProvider(&data);
784 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
785 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
787 scoped_refptr<HttpNetworkSession> http_session(
788 SpdySessionDependencies::SpdyCreateSession(&session_deps));
790 // Setup the first session to the first host.
791 SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
792 EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[0].pair));
793 scoped_refptr<SpdySession> session =
794 spdy_session_pool->Get(test_hosts[0].pair, BoundNetLog());
795 EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[0].pair));
797 HostPortPair test_host_port_pair(test_hosts[0].name, kTestPort);
798 scoped_refptr<TransportSocketParams> transport_params(
799 new TransportSocketParams(test_host_port_pair,
800 MEDIUM,
801 false,
802 false));
803 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
804 EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
805 transport_params, MEDIUM, CompletionCallback(),
806 http_session->GetTransportSocketPool(
807 HttpNetworkSession::NORMAL_SOCKET_POOL),
808 BoundNetLog()));
809 EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
811 // TODO(rtenneti): MockClientSocket::GetPeerAddress return's 0 as the port
812 // number. Fix it to return port 80 and then use GetPeerAddress to AddAlias.
813 const addrinfo* address = test_hosts[0].addresses.head();
814 SpdySessionPoolPeer pool_peer(spdy_session_pool);
815 pool_peer.AddAlias(address, test_hosts[0].pair);
817 // Flush the SpdySession::OnReadComplete() task.
818 MessageLoop::current()->RunAllPending();
820 // The third host has no overlap with the first, so it can't pool IPs.
821 EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[2].pair));
823 // The second host overlaps with the first, and should IP pool.
824 EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[1].pair));
826 // Verify that the second host, through a proxy, won't share the IP.
827 HostPortProxyPair proxy_pair(test_hosts[1].pair.first,
828 ProxyServer::FromPacString("HTTP http://proxy.foo.com/"));
829 EXPECT_FALSE(spdy_session_pool->HasSession(proxy_pair));
831 // Overlap between 2 and 3 does is not transitive to 1.
832 EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[2].pair));
834 // Create a new session to host 2.
835 scoped_refptr<SpdySession> session2 =
836 spdy_session_pool->Get(test_hosts[2].pair, BoundNetLog());
838 // Verify that we have sessions for everything.
839 EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[0].pair));
840 EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[1].pair));
841 EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[2].pair));
843 // Grab the session to host 1 and verify that it is the same session
844 // we got with host 0, and that is a different than host 2's session.
845 scoped_refptr<SpdySession> session1 =
846 spdy_session_pool->Get(test_hosts[1].pair, BoundNetLog());
847 EXPECT_EQ(session.get(), session1.get());
848 EXPECT_NE(session2.get(), session1.get());
850 // Remove the aliases and observe that we still have a session for host1.
851 pool_peer.RemoveAliases(test_hosts[0].pair);
852 pool_peer.RemoveAliases(test_hosts[1].pair);
853 EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[1].pair));
855 // Expire the host cache
856 session_deps.host_resolver->GetHostCache()->clear();
857 EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[1].pair));
859 // Cleanup the sessions.
860 if (!clean_via_close_current_sessions) {
861 spdy_session_pool->Remove(session);
862 session = NULL;
863 spdy_session_pool->Remove(session2);
864 session2 = NULL;
865 } else {
866 spdy_session_pool->CloseCurrentSessions();
869 // Verify that the map is all cleaned up.
870 EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[0].pair));
871 EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[1].pair));
872 EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[2].pair));
875 } // namespace
877 TEST_F(SpdySessionSpdy3Test, IPPooling) {
878 IPPoolingTest(false);
881 TEST_F(SpdySessionSpdy3Test, IPPoolingCloseCurrentSessions) {
882 IPPoolingTest(true);
885 TEST_F(SpdySessionSpdy3Test, ClearSettingsStorageOnIPAddressChanged) {
886 const std::string kTestHost("www.foo.com");
887 const int kTestPort = 80;
888 HostPortPair test_host_port_pair(kTestHost, kTestPort);
890 SpdySessionDependencies session_deps;
891 scoped_refptr<HttpNetworkSession> http_session(
892 SpdySessionDependencies::SpdyCreateSession(&session_deps));
893 SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
895 HttpServerProperties* test_http_server_properties =
896 spdy_session_pool->http_server_properties();
897 SettingsFlagsAndValue flags_and_value1(SETTINGS_FLAG_PLEASE_PERSIST, 2);
898 test_http_server_properties->SetSpdySetting(
899 test_host_port_pair,
900 SETTINGS_MAX_CONCURRENT_STREAMS,
901 SETTINGS_FLAG_PLEASE_PERSIST,
903 EXPECT_NE(0u, test_http_server_properties->GetSpdySettings(
904 test_host_port_pair).size());
905 spdy_session_pool->OnIPAddressChanged();
906 EXPECT_EQ(0u, test_http_server_properties->GetSpdySettings(
907 test_host_port_pair).size());
910 TEST_F(SpdySessionSpdy3Test, NeedsCredentials) {
911 SpdySessionDependencies session_deps;
913 MockConnect connect_data(SYNCHRONOUS, OK);
914 MockRead reads[] = {
915 MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
917 StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
918 data.set_connect_data(connect_data);
919 session_deps.socket_factory->AddSocketDataProvider(&data);
921 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
922 ssl.domain_bound_cert_type = CLIENT_CERT_ECDSA_SIGN;
923 ssl.protocol_negotiated = kProtoSPDY3;
924 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
926 scoped_refptr<HttpNetworkSession> http_session(
927 SpdySessionDependencies::SpdyCreateSession(&session_deps));
929 const GURL url("https:/www.foo.com");
930 HostPortPair test_host_port_pair(url.host(), 443);
931 HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
933 SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
934 EXPECT_FALSE(spdy_session_pool->HasSession(pair));
935 scoped_refptr<SpdySession> session =
936 spdy_session_pool->Get(pair, BoundNetLog());
937 EXPECT_TRUE(spdy_session_pool->HasSession(pair));
939 SSLConfig ssl_config;
940 scoped_refptr<TransportSocketParams> transport_params(
941 new TransportSocketParams(test_host_port_pair,
942 MEDIUM,
943 false,
944 false));
945 scoped_refptr<SOCKSSocketParams> socks_params;
946 scoped_refptr<HttpProxySocketParams> http_proxy_params;
947 scoped_refptr<SSLSocketParams> ssl_params(
948 new SSLSocketParams(transport_params,
949 socks_params,
950 http_proxy_params,
951 ProxyServer::SCHEME_DIRECT,
952 test_host_port_pair,
953 ssl_config,
955 false,
956 false));
957 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
958 EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
959 ssl_params, MEDIUM, CompletionCallback(),
960 http_session->GetSSLSocketPool(
961 HttpNetworkSession::NORMAL_SOCKET_POOL),
962 BoundNetLog()));
964 EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), true, OK));
966 EXPECT_TRUE(session->NeedsCredentials());
968 // Flush the SpdySession::OnReadComplete() task.
969 MessageLoop::current()->RunAllPending();
971 spdy_session_pool->Remove(session);
974 TEST_F(SpdySessionSpdy3Test, SendCredentials) {
975 SpdySessionDependencies session_deps;
977 MockConnect connect_data(SYNCHRONOUS, OK);
978 MockRead reads[] = {
979 MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
981 SettingsMap settings;
982 scoped_ptr<SpdyFrame> settings_frame(ConstructSpdySettings(settings));
983 MockWrite writes[] = {
984 CreateMockWrite(*settings_frame),
986 StaticSocketDataProvider data(reads, arraysize(reads),
987 writes, arraysize(writes));
988 data.set_connect_data(connect_data);
989 session_deps.socket_factory->AddSocketDataProvider(&data);
991 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
992 ssl.domain_bound_cert_type = CLIENT_CERT_ECDSA_SIGN;
993 ssl.protocol_negotiated = kProtoSPDY3;
994 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
996 scoped_refptr<HttpNetworkSession> http_session(
997 SpdySessionDependencies::SpdyCreateSession(&session_deps));
999 const GURL kTestUrl("https://www.foo.com");
1000 HostPortPair test_host_port_pair(kTestUrl.host(), 443);
1001 HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
1003 SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
1004 EXPECT_FALSE(spdy_session_pool->HasSession(pair));
1005 scoped_refptr<SpdySession> session =
1006 spdy_session_pool->Get(pair, BoundNetLog());
1007 EXPECT_TRUE(spdy_session_pool->HasSession(pair));
1009 SSLConfig ssl_config;
1010 scoped_refptr<TransportSocketParams> transport_params(
1011 new TransportSocketParams(test_host_port_pair,
1012 MEDIUM,
1013 false,
1014 false));
1015 scoped_refptr<SOCKSSocketParams> socks_params;
1016 scoped_refptr<HttpProxySocketParams> http_proxy_params;
1017 scoped_refptr<SSLSocketParams> ssl_params(
1018 new SSLSocketParams(transport_params,
1019 socks_params,
1020 http_proxy_params,
1021 ProxyServer::SCHEME_DIRECT,
1022 test_host_port_pair,
1023 ssl_config,
1025 false,
1026 false));
1027 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
1028 EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
1029 ssl_params, MEDIUM, CompletionCallback(),
1030 http_session->GetSSLSocketPool(
1031 HttpNetworkSession::NORMAL_SOCKET_POOL),
1032 BoundNetLog()));
1034 EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), true, OK));
1035 EXPECT_TRUE(session->NeedsCredentials());
1037 // Flush the SpdySession::OnReadComplete() task.
1038 MessageLoop::current()->RunAllPending();
1040 spdy_session_pool->Remove(session);
1041 EXPECT_FALSE(spdy_session_pool->HasSession(pair));
1044 TEST_F(SpdySessionSpdy3Test, CloseSessionOnError) {
1045 SpdySessionDependencies session_deps;
1046 session_deps.host_resolver->set_synchronous_mode(true);
1048 MockConnect connect_data(SYNCHRONOUS, OK);
1049 scoped_ptr<SpdyFrame> goaway(ConstructSpdyGoAway());
1050 MockRead reads[] = {
1051 CreateMockRead(*goaway),
1052 MockRead(SYNCHRONOUS, 0, 0) // EOF
1055 net::CapturingBoundNetLog log(net::CapturingNetLog::kUnbounded);
1057 StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
1058 data.set_connect_data(connect_data);
1059 session_deps.socket_factory->AddSocketDataProvider(&data);
1061 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
1062 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
1064 scoped_refptr<HttpNetworkSession> http_session(
1065 SpdySessionDependencies::SpdyCreateSession(&session_deps));
1067 const std::string kTestHost("www.foo.com");
1068 const int kTestPort = 80;
1069 HostPortPair test_host_port_pair(kTestHost, kTestPort);
1070 HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
1072 SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
1073 EXPECT_FALSE(spdy_session_pool->HasSession(pair));
1074 scoped_refptr<SpdySession> session =
1075 spdy_session_pool->Get(pair, log.bound());
1076 EXPECT_TRUE(spdy_session_pool->HasSession(pair));
1078 scoped_refptr<TransportSocketParams> transport_params(
1079 new TransportSocketParams(test_host_port_pair,
1080 MEDIUM,
1081 false,
1082 false));
1083 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
1084 EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
1085 transport_params, MEDIUM, CompletionCallback(),
1086 http_session->GetTransportSocketPool(
1087 HttpNetworkSession::NORMAL_SOCKET_POOL),
1088 log.bound()));
1089 EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
1091 // Flush the SpdySession::OnReadComplete() task.
1092 MessageLoop::current()->RunAllPending();
1094 EXPECT_FALSE(spdy_session_pool->HasSession(pair));
1096 // Check that the NetLog was filled reasonably.
1097 net::CapturingNetLog::EntryList entries;
1098 log.GetEntries(&entries);
1099 EXPECT_LT(0u, entries.size());
1101 // Check that we logged SPDY_SESSION_CLOSE correctly.
1102 int pos = net::ExpectLogContainsSomewhere(
1103 entries, 0,
1104 net::NetLog::TYPE_SPDY_SESSION_CLOSE,
1105 net::NetLog::PHASE_NONE);
1107 CapturingNetLog::Entry entry = entries[pos];
1108 NetLogSpdySessionCloseParameter* request_params =
1109 static_cast<NetLogSpdySessionCloseParameter*>(
1110 entry.extra_parameters.get());
1111 EXPECT_EQ(ERR_CONNECTION_CLOSED, request_params->status());
1114 TEST_F(SpdySessionSpdy3Test, UpdateStreamsSendWindowSize) {
1115 // Set SETTINGS_INITIAL_WINDOW_SIZE to a small number so that WINDOW_UPDATE
1116 // gets sent.
1117 SettingsMap new_settings;
1118 int32 window_size = 1;
1119 new_settings[SETTINGS_INITIAL_WINDOW_SIZE] =
1120 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, window_size);
1122 // Set up the socket so we read a SETTINGS frame that sets
1123 // INITIAL_WINDOW_SIZE.
1124 MockConnect connect_data(SYNCHRONOUS, OK);
1125 scoped_ptr<SpdyFrame> settings_frame(ConstructSpdySettings(new_settings));
1126 MockRead reads[] = {
1127 CreateMockRead(*settings_frame),
1128 MockRead(SYNCHRONOUS, 0, 0) // EOF
1131 SpdySessionDependencies session_deps;
1132 session_deps.host_resolver->set_synchronous_mode(true);
1134 StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
1135 data.set_connect_data(connect_data);
1136 session_deps.socket_factory->AddSocketDataProvider(&data);
1138 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
1139 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
1141 scoped_refptr<HttpNetworkSession> http_session(
1142 SpdySessionDependencies::SpdyCreateSession(&session_deps));
1144 const std::string kTestHost("www.foo.com");
1145 const int kTestPort = 80;
1146 HostPortPair test_host_port_pair(kTestHost, kTestPort);
1147 HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
1149 SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
1151 // Create a session.
1152 EXPECT_FALSE(spdy_session_pool->HasSession(pair));
1153 scoped_refptr<SpdySession> session =
1154 spdy_session_pool->Get(pair, BoundNetLog());
1155 ASSERT_TRUE(spdy_session_pool->HasSession(pair));
1157 scoped_refptr<TransportSocketParams> transport_params(
1158 new TransportSocketParams(test_host_port_pair,
1159 MEDIUM,
1160 false,
1161 false));
1162 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
1163 EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
1164 transport_params, MEDIUM, CompletionCallback(),
1165 http_session->GetTransportSocketPool(
1166 HttpNetworkSession::NORMAL_SOCKET_POOL),
1167 BoundNetLog()));
1168 EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
1170 scoped_refptr<SpdyStream> spdy_stream1;
1171 TestCompletionCallback callback1;
1172 GURL url("http://www.google.com");
1173 EXPECT_EQ(OK,
1174 session->CreateStream(url,
1175 MEDIUM, /* priority, not important */
1176 &spdy_stream1,
1177 BoundNetLog(),
1178 callback1.callback()));
1179 EXPECT_NE(spdy_stream1->send_window_size(), window_size);
1181 MessageLoop::current()->RunAllPending();
1182 EXPECT_EQ(session->initial_send_window_size(), window_size);
1183 EXPECT_EQ(spdy_stream1->send_window_size(), window_size);
1185 // Release the first one, this will allow the second to be created.
1186 spdy_stream1->Cancel();
1187 spdy_stream1 = NULL;
1189 scoped_refptr<SpdyStream> spdy_stream2;
1190 EXPECT_EQ(OK,
1191 session->CreateStream(url,
1192 MEDIUM, /* priority, not important */
1193 &spdy_stream2,
1194 BoundNetLog(),
1195 callback1.callback()));
1197 EXPECT_EQ(spdy_stream2->send_window_size(), window_size);
1198 spdy_stream2->Cancel();
1199 spdy_stream2 = NULL;
1202 } // namespace net