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

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

Issue 9582034: Fork SPDY/2 and SPDY/3 versions of our SPDY tests, in preparation for landing (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Fix merge bug Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/spdy/spdy_session_spdy3_unittest.cc ('k') | net/spdy/spdy_stream_spdy2_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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.
4
5 #include "net/spdy/spdy_session.h"
6
7 #include "net/base/ip_endpoint.h"
8 #include "net/base/net_log_unittest.h"
9 #include "net/spdy/spdy_io_buffer.h"
10 #include "net/spdy/spdy_session_pool.h"
11 #include "net/spdy/spdy_stream.h"
12 #include "net/spdy/spdy_test_util.h"
13 #include "testing/platform_test.h"
14
15 namespace net {
16
17 // TODO(cbentzel): Expose compression setter/getter in public SpdySession
18 // interface rather than going through all these contortions.
19 class SpdySessionTest : public PlatformTest {
20 public:
21 static void TurnOffCompression() {
22 spdy::SpdyFramer::set_enable_compression_default(false);
23 }
24 protected:
25 virtual void TearDown() {
26 // Wanted to be 100% sure PING is disabled.
27 SpdySession::set_enable_ping_based_connection_checking(false);
28 }
29 };
30
31 class TestSpdyStreamDelegate : public net::SpdyStream::Delegate {
32 public:
33 explicit TestSpdyStreamDelegate(const CompletionCallback& callback)
34 : callback_(callback) {}
35 virtual ~TestSpdyStreamDelegate() {}
36
37 virtual bool OnSendHeadersComplete(int status) { return true; }
38
39 virtual int OnSendBody() {
40 return ERR_UNEXPECTED;
41 }
42
43 virtual int OnSendBodyComplete(int /*status*/, bool* /*eof*/) {
44 return ERR_UNEXPECTED;
45 }
46
47 virtual int OnResponseReceived(const spdy::SpdyHeaderBlock& response,
48 base::Time response_time,
49 int status) {
50 return status;
51 }
52
53 virtual void OnDataReceived(const char* buffer, int bytes) {
54 }
55
56 virtual void OnDataSent(int length) {
57 }
58
59 virtual void OnClose(int status) {
60 CompletionCallback callback = callback_;
61 callback_.Reset();
62 callback.Run(OK);
63 }
64
65 virtual void set_chunk_callback(net::ChunkCallback *) {}
66
67 private:
68 CompletionCallback callback_;
69 };
70
71 // Test the SpdyIOBuffer class.
72 TEST_F(SpdySessionTest, SpdyIOBuffer) {
73 std::priority_queue<SpdyIOBuffer> queue_;
74 const size_t kQueueSize = 100;
75
76 // Insert 100 items; pri 100 to 1.
77 for (size_t index = 0; index < kQueueSize; ++index) {
78 SpdyIOBuffer buffer(new IOBuffer(), 0, kQueueSize - index, NULL);
79 queue_.push(buffer);
80 }
81
82 // Insert several priority 0 items last.
83 const size_t kNumDuplicates = 12;
84 IOBufferWithSize* buffers[kNumDuplicates];
85 for (size_t index = 0; index < kNumDuplicates; ++index) {
86 buffers[index] = new IOBufferWithSize(index+1);
87 queue_.push(SpdyIOBuffer(buffers[index], buffers[index]->size(), 0, NULL));
88 }
89
90 EXPECT_EQ(kQueueSize + kNumDuplicates, queue_.size());
91
92 // Verify the P0 items come out in FIFO order.
93 for (size_t index = 0; index < kNumDuplicates; ++index) {
94 SpdyIOBuffer buffer = queue_.top();
95 EXPECT_EQ(0, buffer.priority());
96 EXPECT_EQ(index + 1, buffer.size());
97 queue_.pop();
98 }
99
100 int priority = 1;
101 while (queue_.size()) {
102 SpdyIOBuffer buffer = queue_.top();
103 EXPECT_EQ(priority++, buffer.priority());
104 queue_.pop();
105 }
106 }
107
108 TEST_F(SpdySessionTest, GoAway) {
109 SpdySessionDependencies session_deps;
110 session_deps.host_resolver->set_synchronous_mode(true);
111
112 MockConnect connect_data(SYNCHRONOUS, OK);
113 scoped_ptr<spdy::SpdyFrame> goaway(ConstructSpdyGoAway());
114 MockRead reads[] = {
115 CreateMockRead(*goaway),
116 MockRead(SYNCHRONOUS, 0, 0) // EOF
117 };
118 StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
119 data.set_connect_data(connect_data);
120 session_deps.socket_factory->AddSocketDataProvider(&data);
121
122 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
123 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
124
125 scoped_refptr<HttpNetworkSession> http_session(
126 SpdySessionDependencies::SpdyCreateSession(&session_deps));
127
128 const std::string kTestHost("www.foo.com");
129 const int kTestPort = 80;
130 HostPortPair test_host_port_pair(kTestHost, kTestPort);
131 HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
132
133 SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
134 EXPECT_FALSE(spdy_session_pool->HasSession(pair));
135 scoped_refptr<SpdySession> session =
136 spdy_session_pool->Get(pair, BoundNetLog());
137 EXPECT_TRUE(spdy_session_pool->HasSession(pair));
138
139 scoped_refptr<TransportSocketParams> transport_params(
140 new TransportSocketParams(test_host_port_pair,
141 MEDIUM,
142 false,
143 false));
144 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
145 EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
146 transport_params, MEDIUM, CompletionCallback(),
147 http_session->GetTransportSocketPool(),
148 BoundNetLog()));
149 EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
150
151 // Flush the SpdySession::OnReadComplete() task.
152 MessageLoop::current()->RunAllPending();
153
154 EXPECT_FALSE(spdy_session_pool->HasSession(pair));
155
156 scoped_refptr<SpdySession> session2 =
157 spdy_session_pool->Get(pair, BoundNetLog());
158
159 // Delete the first session.
160 session = NULL;
161
162 // Delete the second session.
163 spdy_session_pool->Remove(session2);
164 session2 = NULL;
165 }
166
167 TEST_F(SpdySessionTest, Ping) {
168 SpdySessionDependencies session_deps;
169 session_deps.host_resolver->set_synchronous_mode(true);
170
171 MockConnect connect_data(SYNCHRONOUS, OK);
172 scoped_ptr<spdy::SpdyFrame> read_ping(ConstructSpdyPing());
173 MockRead reads[] = {
174 CreateMockRead(*read_ping),
175 CreateMockRead(*read_ping),
176 MockRead(SYNCHRONOUS, 0, 0) // EOF
177 };
178 scoped_ptr<spdy::SpdyFrame> write_ping(ConstructSpdyPing());
179 MockRead writes[] = {
180 CreateMockRead(*write_ping),
181 CreateMockRead(*write_ping),
182 };
183 StaticSocketDataProvider data(
184 reads, arraysize(reads), writes, arraysize(writes));
185 data.set_connect_data(connect_data);
186 session_deps.socket_factory->AddSocketDataProvider(&data);
187
188 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
189 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
190
191 scoped_refptr<HttpNetworkSession> http_session(
192 SpdySessionDependencies::SpdyCreateSession(&session_deps));
193
194 static const char kStreamUrl[] = "http://www.google.com/";
195 GURL url(kStreamUrl);
196
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());
201
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));
207
208
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 BoundNetLog()));
219 EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
220
221 scoped_refptr<SpdyStream> spdy_stream1;
222 TestCompletionCallback callback1;
223 EXPECT_EQ(OK, session->CreateStream(url,
224 MEDIUM,
225 &spdy_stream1,
226 BoundNetLog(),
227 callback1.callback()));
228 scoped_ptr<TestSpdyStreamDelegate> delegate(
229 new TestSpdyStreamDelegate(callback1.callback()));
230 spdy_stream1->SetDelegate(delegate.get());
231
232 base::TimeTicks before_ping_time = base::TimeTicks::Now();
233
234 // Enable sending of PING.
235 SpdySession::set_enable_ping_based_connection_checking(true);
236 SpdySession::set_connection_at_risk_of_loss_seconds(0);
237 SpdySession::set_trailing_ping_delay_time_ms(0);
238 SpdySession::set_hung_interval_ms(50);
239
240 session->SendPrefacePingIfNoneInFlight();
241
242 EXPECT_EQ(OK, callback1.WaitForResult());
243
244 session->CheckPingStatus(before_ping_time);
245
246 EXPECT_EQ(0, session->pings_in_flight());
247 EXPECT_GT(session->next_ping_id(), static_cast<uint32>(1));
248 EXPECT_FALSE(session->trailing_ping_pending());
249 EXPECT_FALSE(session->check_ping_status_pending());
250 EXPECT_GE(session->received_data_time(), before_ping_time);
251
252 EXPECT_FALSE(spdy_session_pool->HasSession(pair));
253
254 // Delete the first session.
255 session = NULL;
256 }
257
258 TEST_F(SpdySessionTest, FailedPing) {
259 SpdySessionDependencies session_deps;
260 session_deps.host_resolver->set_synchronous_mode(true);
261
262 MockConnect connect_data(SYNCHRONOUS, OK);
263 scoped_ptr<spdy::SpdyFrame> read_ping(ConstructSpdyPing());
264 MockRead reads[] = {
265 CreateMockRead(*read_ping),
266 MockRead(SYNCHRONOUS, 0, 0) // EOF
267 };
268 scoped_ptr<spdy::SpdyFrame> write_ping(ConstructSpdyPing());
269 MockRead writes[] = {
270 CreateMockRead(*write_ping),
271 };
272 StaticSocketDataProvider data(
273 reads, arraysize(reads), writes, arraysize(writes));
274 data.set_connect_data(connect_data);
275 session_deps.socket_factory->AddSocketDataProvider(&data);
276
277 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
278 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
279
280 scoped_refptr<HttpNetworkSession> http_session(
281 SpdySessionDependencies::SpdyCreateSession(&session_deps));
282
283 static const char kStreamUrl[] = "http://www.gmail.com/";
284 GURL url(kStreamUrl);
285
286 const std::string kTestHost("www.gmail.com");
287 const int kTestPort = 80;
288 HostPortPair test_host_port_pair(kTestHost, kTestPort);
289 HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
290
291 SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
292 EXPECT_FALSE(spdy_session_pool->HasSession(pair));
293 scoped_refptr<SpdySession> session =
294 spdy_session_pool->Get(pair, BoundNetLog());
295 EXPECT_TRUE(spdy_session_pool->HasSession(pair));
296
297 scoped_refptr<TransportSocketParams> transport_params(
298 new TransportSocketParams(test_host_port_pair,
299 MEDIUM,
300 false,
301 false));
302 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
303 EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
304 transport_params, MEDIUM, CompletionCallback(),
305 http_session->GetTransportSocketPool(),
306 BoundNetLog()));
307 EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
308
309 scoped_refptr<SpdyStream> spdy_stream1;
310 TestCompletionCallback callback1;
311 EXPECT_EQ(OK, session->CreateStream(url,
312 MEDIUM,
313 &spdy_stream1,
314 BoundNetLog(),
315 callback1.callback()));
316 scoped_ptr<TestSpdyStreamDelegate> delegate(
317 new TestSpdyStreamDelegate(callback1.callback()));
318 spdy_stream1->SetDelegate(delegate.get());
319
320 // Enable sending of PING.
321 SpdySession::set_enable_ping_based_connection_checking(true);
322 SpdySession::set_connection_at_risk_of_loss_seconds(0);
323 SpdySession::set_trailing_ping_delay_time_ms(0);
324 SpdySession::set_hung_interval_ms(0);
325
326 // Send a PING frame.
327 session->WritePingFrame(1);
328 EXPECT_LT(0, session->pings_in_flight());
329 EXPECT_GT(session->next_ping_id(), static_cast<uint32>(1));
330 EXPECT_TRUE(session->check_ping_status_pending());
331
332 // Assert session is not closed.
333 EXPECT_FALSE(session->IsClosed());
334 EXPECT_LT(0u, session->num_active_streams());
335 EXPECT_TRUE(spdy_session_pool->HasSession(pair));
336
337 // We set last time we have received any data in 1 sec less than now.
338 // CheckPingStatus will trigger timeout because hung interval is zero.
339 base::TimeTicks now = base::TimeTicks::Now();
340 session->received_data_time_ = now - base::TimeDelta::FromSeconds(1);
341 session->CheckPingStatus(now);
342
343 EXPECT_TRUE(session->IsClosed());
344 EXPECT_EQ(0u, session->num_active_streams());
345 EXPECT_EQ(0u, session->num_unclaimed_pushed_streams());
346 EXPECT_FALSE(spdy_session_pool->HasSession(pair));
347
348 // Delete the first session.
349 session = NULL;
350 }
351
352 class StreamReleaserCallback : public TestCompletionCallbackBase {
353 public:
354 StreamReleaserCallback(SpdySession* session,
355 SpdyStream* first_stream)
356 : session_(session),
357 first_stream_(first_stream),
358 ALLOW_THIS_IN_INITIALIZER_LIST(callback_(
359 base::Bind(&StreamReleaserCallback::OnComplete,
360 base::Unretained(this)))) {
361 }
362
363 virtual ~StreamReleaserCallback() {}
364
365 scoped_refptr<SpdyStream>* stream() { return &stream_; }
366
367 const CompletionCallback& callback() const { return callback_; }
368
369 private:
370 void OnComplete(int result) {
371 session_->CloseSessionOnError(ERR_FAILED, false, "On complete.");
372 session_ = NULL;
373 first_stream_->Cancel();
374 first_stream_ = NULL;
375 stream_->Cancel();
376 stream_ = NULL;
377 SetResult(result);
378 }
379
380 scoped_refptr<SpdySession> session_;
381 scoped_refptr<SpdyStream> first_stream_;
382 scoped_refptr<SpdyStream> stream_;
383 CompletionCallback callback_;
384 };
385
386 // TODO(kristianm): Could also test with more sessions where some are idle,
387 // and more than one session to a HostPortPair.
388 TEST_F(SpdySessionTest, CloseIdleSessions) {
389 SpdySessionDependencies session_deps;
390 scoped_refptr<HttpNetworkSession> http_session(
391 SpdySessionDependencies::SpdyCreateSession(&session_deps));
392 SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
393
394 // Set up session 1
395 const std::string kTestHost1("http://www.a.com");
396 HostPortPair test_host_port_pair1(kTestHost1, 80);
397 HostPortProxyPair pair1(test_host_port_pair1, ProxyServer::Direct());
398 scoped_refptr<SpdySession> session1 =
399 spdy_session_pool->Get(pair1, BoundNetLog());
400 scoped_refptr<SpdyStream> spdy_stream1;
401 TestCompletionCallback callback1;
402 GURL url1(kTestHost1);
403 EXPECT_EQ(OK, session1->CreateStream(url1,
404 MEDIUM, /* priority, not important */
405 &spdy_stream1,
406 BoundNetLog(),
407 callback1.callback()));
408
409 // Set up session 2
410 const std::string kTestHost2("http://www.b.com");
411 HostPortPair test_host_port_pair2(kTestHost2, 80);
412 HostPortProxyPair pair2(test_host_port_pair2, ProxyServer::Direct());
413 scoped_refptr<SpdySession> session2 =
414 spdy_session_pool->Get(pair2, BoundNetLog());
415 scoped_refptr<SpdyStream> spdy_stream2;
416 TestCompletionCallback callback2;
417 GURL url2(kTestHost2);
418 EXPECT_EQ(OK, session2->CreateStream(
419 url2, MEDIUM, /* priority, not important */
420 &spdy_stream2, BoundNetLog(), callback2.callback()));
421
422 // Set up session 3
423 const std::string kTestHost3("http://www.c.com");
424 HostPortPair test_host_port_pair3(kTestHost3, 80);
425 HostPortProxyPair pair3(test_host_port_pair3, ProxyServer::Direct());
426 scoped_refptr<SpdySession> session3 =
427 spdy_session_pool->Get(pair3, BoundNetLog());
428 scoped_refptr<SpdyStream> spdy_stream3;
429 TestCompletionCallback callback3;
430 GURL url3(kTestHost3);
431 EXPECT_EQ(OK, session3->CreateStream(
432 url3, MEDIUM, /* priority, not important */
433 &spdy_stream3, BoundNetLog(), callback3.callback()));
434
435 // All sessions are active and not closed
436 EXPECT_TRUE(session1->is_active());
437 EXPECT_FALSE(session1->IsClosed());
438 EXPECT_TRUE(session2->is_active());
439 EXPECT_FALSE(session2->IsClosed());
440 EXPECT_TRUE(session3->is_active());
441 EXPECT_FALSE(session3->IsClosed());
442
443 // Should not do anything, all are active
444 spdy_session_pool->CloseIdleSessions();
445 EXPECT_TRUE(session1->is_active());
446 EXPECT_FALSE(session1->IsClosed());
447 EXPECT_TRUE(session2->is_active());
448 EXPECT_FALSE(session2->IsClosed());
449 EXPECT_TRUE(session3->is_active());
450 EXPECT_FALSE(session3->IsClosed());
451
452 // Make sessions 1 and 3 inactive, but keep them open.
453 // Session 2 still open and active
454 session1->CloseStream(spdy_stream1->stream_id(), OK);
455 session3->CloseStream(spdy_stream3->stream_id(), OK);
456 EXPECT_FALSE(session1->is_active());
457 EXPECT_FALSE(session1->IsClosed());
458 EXPECT_TRUE(session2->is_active());
459 EXPECT_FALSE(session2->IsClosed());
460 EXPECT_FALSE(session3->is_active());
461 EXPECT_FALSE(session3->IsClosed());
462
463 // Should close session 1 and 3, 2 should be left open
464 spdy_session_pool->CloseIdleSessions();
465 EXPECT_FALSE(session1->is_active());
466 EXPECT_TRUE(session1->IsClosed());
467 EXPECT_TRUE(session2->is_active());
468 EXPECT_FALSE(session2->IsClosed());
469 EXPECT_FALSE(session3->is_active());
470 EXPECT_TRUE(session3->IsClosed());
471
472 // Should not do anything
473 spdy_session_pool->CloseIdleSessions();
474 EXPECT_TRUE(session2->is_active());
475 EXPECT_FALSE(session2->IsClosed());
476
477 // Make 2 not active
478 session2->CloseStream(spdy_stream2->stream_id(), OK);
479 EXPECT_FALSE(session2->is_active());
480 EXPECT_FALSE(session2->IsClosed());
481
482 // This should close session 2
483 spdy_session_pool->CloseIdleSessions();
484 EXPECT_FALSE(session2->is_active());
485 EXPECT_TRUE(session2->IsClosed());
486 }
487
488 // Start with max concurrent streams set to 1. Request two streams. Receive a
489 // settings frame setting max concurrent streams to 2. Have the callback
490 // release the stream, which releases its reference (the last) to the session.
491 // Make sure nothing blows up.
492 // http://crbug.com/57331
493 TEST_F(SpdySessionTest, OnSettings) {
494 SpdySessionDependencies session_deps;
495 session_deps.host_resolver->set_synchronous_mode(true);
496
497 spdy::SpdySettings new_settings;
498 spdy::SettingsFlagsAndId id(0);
499 id.set_id(spdy::SETTINGS_MAX_CONCURRENT_STREAMS);
500 const size_t max_concurrent_streams = 2;
501 new_settings.push_back(spdy::SpdySetting(id, max_concurrent_streams));
502
503 // Set up the socket so we read a SETTINGS frame that raises max concurrent
504 // streams to 2.
505 MockConnect connect_data(SYNCHRONOUS, OK);
506 scoped_ptr<spdy::SpdyFrame> settings_frame(
507 ConstructSpdySettings(new_settings));
508 MockRead reads[] = {
509 CreateMockRead(*settings_frame),
510 MockRead(SYNCHRONOUS, 0, 0) // EOF
511 };
512
513 StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
514 data.set_connect_data(connect_data);
515 session_deps.socket_factory->AddSocketDataProvider(&data);
516
517 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
518 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
519
520 scoped_refptr<HttpNetworkSession> http_session(
521 SpdySessionDependencies::SpdyCreateSession(&session_deps));
522
523 const std::string kTestHost("www.foo.com");
524 const int kTestPort = 80;
525 HostPortPair test_host_port_pair(kTestHost, kTestPort);
526 HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
527
528 // Initialize the SpdySettingsStorage with 1 max concurrent streams.
529 SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
530 spdy::SpdySettings old_settings;
531 id.set_flags(spdy::SETTINGS_FLAG_PLEASE_PERSIST);
532 old_settings.push_back(spdy::SpdySetting(id, 1));
533 spdy_session_pool->http_server_properties()->SetSpdySettings(
534 test_host_port_pair, old_settings);
535
536 // Create a session.
537 EXPECT_FALSE(spdy_session_pool->HasSession(pair));
538 scoped_refptr<SpdySession> session =
539 spdy_session_pool->Get(pair, BoundNetLog());
540 ASSERT_TRUE(spdy_session_pool->HasSession(pair));
541
542 scoped_refptr<TransportSocketParams> transport_params(
543 new TransportSocketParams(test_host_port_pair,
544 MEDIUM,
545 false,
546 false));
547 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
548 EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
549 transport_params, MEDIUM, CompletionCallback(),
550 http_session->GetTransportSocketPool(),
551 BoundNetLog()));
552 EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
553
554 // Create 2 streams. First will succeed. Second will be pending.
555 scoped_refptr<SpdyStream> spdy_stream1;
556 TestCompletionCallback callback1;
557 GURL url("http://www.google.com");
558 EXPECT_EQ(OK,
559 session->CreateStream(url,
560 MEDIUM, /* priority, not important */
561 &spdy_stream1,
562 BoundNetLog(),
563 callback1.callback()));
564
565 StreamReleaserCallback stream_releaser(session, spdy_stream1);
566
567 ASSERT_EQ(ERR_IO_PENDING,
568 session->CreateStream(url,
569 MEDIUM, /* priority, not important */
570 stream_releaser.stream(),
571 BoundNetLog(),
572 stream_releaser.callback()));
573
574 // Make sure |stream_releaser| holds the last refs.
575 session = NULL;
576 spdy_stream1 = NULL;
577
578 EXPECT_EQ(OK, stream_releaser.WaitForResult());
579 }
580
581 // Start with max concurrent streams set to 1. Request two streams. When the
582 // first completes, have the callback close itself, which should trigger the
583 // second stream creation. Then cancel that one immediately. Don't crash.
584 // http://crbug.com/63532
585 TEST_F(SpdySessionTest, CancelPendingCreateStream) {
586 SpdySessionDependencies session_deps;
587 session_deps.host_resolver->set_synchronous_mode(true);
588
589 MockRead reads[] = {
590 MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
591 };
592
593 StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
594 MockConnect connect_data(SYNCHRONOUS, OK);
595
596 data.set_connect_data(connect_data);
597 session_deps.socket_factory->AddSocketDataProvider(&data);
598
599 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
600 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
601
602 scoped_refptr<HttpNetworkSession> http_session(
603 SpdySessionDependencies::SpdyCreateSession(&session_deps));
604
605 const std::string kTestHost("www.foo.com");
606 const int kTestPort = 80;
607 HostPortPair test_host_port_pair(kTestHost, kTestPort);
608 HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
609
610 // Initialize the SpdySettingsStorage with 1 max concurrent streams.
611 SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
612 spdy::SpdySettings settings;
613 spdy::SettingsFlagsAndId id(0);
614 id.set_id(spdy::SETTINGS_MAX_CONCURRENT_STREAMS);
615 id.set_flags(spdy::SETTINGS_FLAG_PLEASE_PERSIST);
616 settings.push_back(spdy::SpdySetting(id, 1));
617 spdy_session_pool->http_server_properties()->SetSpdySettings(
618 test_host_port_pair, settings);
619
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));
625
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 BoundNetLog()));
636 EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
637
638 // Use scoped_ptr to let us invalidate the memory when we want to, to trigger
639 // a valgrind error if the callback is invoked when it's not supposed to be.
640 scoped_ptr<TestCompletionCallback> callback(new TestCompletionCallback);
641
642 // Create 2 streams. First will succeed. Second will be pending.
643 scoped_refptr<SpdyStream> spdy_stream1;
644 GURL url("http://www.google.com");
645 ASSERT_EQ(OK,
646 session->CreateStream(url,
647 MEDIUM, /* priority, not important */
648 &spdy_stream1,
649 BoundNetLog(),
650 callback->callback()));
651
652 scoped_refptr<SpdyStream> spdy_stream2;
653 ASSERT_EQ(ERR_IO_PENDING,
654 session->CreateStream(url,
655 MEDIUM, /* priority, not important */
656 &spdy_stream2,
657 BoundNetLog(),
658 callback->callback()));
659
660 // Release the first one, this will allow the second to be created.
661 spdy_stream1->Cancel();
662 spdy_stream1 = NULL;
663
664 session->CancelPendingCreateStreams(&spdy_stream2);
665 callback.reset();
666
667 // Should not crash when running the pending callback.
668 MessageLoop::current()->RunAllPending();
669 }
670
671 TEST_F(SpdySessionTest, SendSettingsOnNewSession) {
672 SpdySessionDependencies session_deps;
673 session_deps.host_resolver->set_synchronous_mode(true);
674
675 MockRead reads[] = {
676 MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
677 };
678
679 // Create the bogus setting that we want to verify is sent out.
680 // Note that it will be marked as SETTINGS_FLAG_PERSISTED when sent out. But
681 // to set it into the SpdySettingsStorage, we need to mark as
682 // SETTINGS_FLAG_PLEASE_PERSIST.
683 spdy::SpdySettings settings;
684 const uint32 kBogusSettingId = 0xABAB;
685 const uint32 kBogusSettingValue = 0xCDCD;
686 spdy::SettingsFlagsAndId id(0);
687 id.set_id(kBogusSettingId);
688 id.set_flags(spdy::SETTINGS_FLAG_PERSISTED);
689 settings.push_back(spdy::SpdySetting(id, kBogusSettingValue));
690 MockConnect connect_data(SYNCHRONOUS, OK);
691 scoped_ptr<spdy::SpdyFrame> settings_frame(
692 ConstructSpdySettings(settings));
693 MockWrite writes[] = {
694 CreateMockWrite(*settings_frame),
695 };
696
697 StaticSocketDataProvider data(
698 reads, arraysize(reads), writes, arraysize(writes));
699 data.set_connect_data(connect_data);
700 session_deps.socket_factory->AddSocketDataProvider(&data);
701
702 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
703 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
704
705 scoped_refptr<HttpNetworkSession> http_session(
706 SpdySessionDependencies::SpdyCreateSession(&session_deps));
707
708 const std::string kTestHost("www.foo.com");
709 const int kTestPort = 80;
710 HostPortPair test_host_port_pair(kTestHost, kTestPort);
711 HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
712
713 id.set_flags(spdy::SETTINGS_FLAG_PLEASE_PERSIST);
714 settings.clear();
715 settings.push_back(spdy::SpdySetting(id, kBogusSettingValue));
716 SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
717 spdy_session_pool->http_server_properties()->SetSpdySettings(
718 test_host_port_pair, settings);
719 EXPECT_FALSE(spdy_session_pool->HasSession(pair));
720 scoped_refptr<SpdySession> session =
721 spdy_session_pool->Get(pair, BoundNetLog());
722 EXPECT_TRUE(spdy_session_pool->HasSession(pair));
723
724 scoped_refptr<TransportSocketParams> transport_params(
725 new TransportSocketParams(test_host_port_pair,
726 MEDIUM,
727 false,
728 false));
729 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
730 EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
731 transport_params, MEDIUM, CompletionCallback(),
732 http_session->GetTransportSocketPool(),
733 BoundNetLog()));
734 EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
735 MessageLoop::current()->RunAllPending();
736 EXPECT_TRUE(data.at_write_eof());
737 }
738
739 // This test has two variants, one for each style of closing the connection.
740 // If |clean_via_close_current_sessions| is false, the sessions are closed
741 // manually, calling SpdySessionPool::Remove() directly. If it is true,
742 // sessions are closed with SpdySessionPool::CloseCurrentSessions().
743 void IPPoolingTest(bool clean_via_close_current_sessions) {
744 const int kTestPort = 80;
745 struct TestHosts {
746 std::string name;
747 std::string iplist;
748 HostPortProxyPair pair;
749 AddressList addresses;
750 } test_hosts[] = {
751 { "www.foo.com", "192.0.2.33,192.168.0.1,192.168.0.5" },
752 { "images.foo.com", "192.168.0.2,192.168.0.3,192.168.0.5,192.0.2.33" },
753 { "js.foo.com", "192.168.0.4,192.168.0.3" },
754 };
755
756 SpdySessionDependencies session_deps;
757 session_deps.host_resolver->set_synchronous_mode(true);
758 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_hosts); i++) {
759 session_deps.host_resolver->rules()->AddIPLiteralRule(test_hosts[i].name,
760 test_hosts[i].iplist, "");
761
762 // This test requires that the HostResolver cache be populated. Normal
763 // code would have done this already, but we do it manually.
764 HostResolver::RequestInfo info(HostPortPair(test_hosts[i].name, kTestPort));
765 session_deps.host_resolver->Resolve(
766 info, &test_hosts[i].addresses, CompletionCallback(), NULL,
767 BoundNetLog());
768
769 // Setup a HostPortProxyPair
770 test_hosts[i].pair = HostPortProxyPair(
771 HostPortPair(test_hosts[i].name, kTestPort), ProxyServer::Direct());
772 }
773
774 MockConnect connect_data(SYNCHRONOUS, OK);
775 MockRead reads[] = {
776 MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
777 };
778
779 StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
780 data.set_connect_data(connect_data);
781 session_deps.socket_factory->AddSocketDataProvider(&data);
782
783 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
784 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
785
786 scoped_refptr<HttpNetworkSession> http_session(
787 SpdySessionDependencies::SpdyCreateSession(&session_deps));
788
789 // Setup the first session to the first host.
790 SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
791 EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[0].pair));
792 scoped_refptr<SpdySession> session =
793 spdy_session_pool->Get(test_hosts[0].pair, BoundNetLog());
794 EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[0].pair));
795
796 HostPortPair test_host_port_pair(test_hosts[0].name, kTestPort);
797 scoped_refptr<TransportSocketParams> transport_params(
798 new TransportSocketParams(test_host_port_pair,
799 MEDIUM,
800 false,
801 false));
802 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
803 EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
804 transport_params, MEDIUM, CompletionCallback(),
805 http_session->GetTransportSocketPool(),
806 BoundNetLog()));
807 EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
808
809 // TODO(rtenneti): MockClientSocket::GetPeerAddress return's 0 as the port
810 // number. Fix it to return port 80 and then use GetPeerAddress to AddAlias.
811 const addrinfo* address = test_hosts[0].addresses.head();
812 SpdySessionPoolPeer pool_peer(spdy_session_pool);
813 pool_peer.AddAlias(address, test_hosts[0].pair);
814
815 // Flush the SpdySession::OnReadComplete() task.
816 MessageLoop::current()->RunAllPending();
817
818 // The third host has no overlap with the first, so it can't pool IPs.
819 EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[2].pair));
820
821 // The second host overlaps with the first, and should IP pool.
822 EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[1].pair));
823
824 // Verify that the second host, through a proxy, won't share the IP.
825 HostPortProxyPair proxy_pair(test_hosts[1].pair.first,
826 ProxyServer::FromPacString("HTTP http://proxy.foo.com/"));
827 EXPECT_FALSE(spdy_session_pool->HasSession(proxy_pair));
828
829 // Overlap between 2 and 3 does is not transitive to 1.
830 EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[2].pair));
831
832 // Create a new session to host 2.
833 scoped_refptr<SpdySession> session2 =
834 spdy_session_pool->Get(test_hosts[2].pair, BoundNetLog());
835
836 // Verify that we have sessions for everything.
837 EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[0].pair));
838 EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[1].pair));
839 EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[2].pair));
840
841 // Cleanup the sessions.
842 if (!clean_via_close_current_sessions) {
843 spdy_session_pool->Remove(session);
844 session = NULL;
845 spdy_session_pool->Remove(session2);
846 session2 = NULL;
847 } else {
848 spdy_session_pool->CloseCurrentSessions();
849 }
850
851 // Verify that the map is all cleaned up.
852 EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[0].pair));
853 EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[1].pair));
854 EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[2].pair));
855 }
856
857 TEST_F(SpdySessionTest, IPPooling) {
858 IPPoolingTest(false);
859 }
860
861 TEST_F(SpdySessionTest, IPPoolingCloseCurrentSessions) {
862 IPPoolingTest(true);
863 }
864
865 TEST_F(SpdySessionTest, ClearSettingsStorage) {
866 SpdySettingsStorage settings_storage;
867 const std::string kTestHost("www.foo.com");
868 const int kTestPort = 80;
869 HostPortPair test_host_port_pair(kTestHost, kTestPort);
870 spdy::SpdySettings test_settings;
871 spdy::SettingsFlagsAndId id(0);
872 id.set_id(spdy::SETTINGS_MAX_CONCURRENT_STREAMS);
873 id.set_flags(spdy::SETTINGS_FLAG_PLEASE_PERSIST);
874 const size_t max_concurrent_streams = 2;
875 test_settings.push_back(spdy::SpdySetting(id, max_concurrent_streams));
876
877 settings_storage.Set(test_host_port_pair, test_settings);
878 EXPECT_NE(0u, settings_storage.Get(test_host_port_pair).size());
879 settings_storage.Clear();
880 EXPECT_EQ(0u, settings_storage.Get(test_host_port_pair).size());
881 }
882
883 TEST_F(SpdySessionTest, ClearSettingsStorageOnIPAddressChanged) {
884 const std::string kTestHost("www.foo.com");
885 const int kTestPort = 80;
886 HostPortPair test_host_port_pair(kTestHost, kTestPort);
887
888 SpdySessionDependencies session_deps;
889 scoped_refptr<HttpNetworkSession> http_session(
890 SpdySessionDependencies::SpdyCreateSession(&session_deps));
891 SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
892
893 HttpServerProperties* test_http_server_properties =
894 spdy_session_pool->http_server_properties();
895 spdy::SettingsFlagsAndId id(0);
896 id.set_id(spdy::SETTINGS_MAX_CONCURRENT_STREAMS);
897 id.set_flags(spdy::SETTINGS_FLAG_PLEASE_PERSIST);
898 const size_t max_concurrent_streams = 2;
899 spdy::SpdySettings test_settings;
900 test_settings.push_back(spdy::SpdySetting(id, max_concurrent_streams));
901
902 test_http_server_properties->SetSpdySettings(test_host_port_pair,
903 test_settings);
904 EXPECT_NE(0u, test_http_server_properties->GetSpdySettings(
905 test_host_port_pair).size());
906 spdy_session_pool->OnIPAddressChanged();
907 EXPECT_EQ(0u, test_http_server_properties->GetSpdySettings(
908 test_host_port_pair).size());
909 }
910
911 TEST_F(SpdySessionTest, NeedsCredentials) {
912 SpdySessionDependencies session_deps;
913
914 MockConnect connect_data(SYNCHRONOUS, OK);
915 MockRead reads[] = {
916 MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
917 };
918 StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
919 data.set_connect_data(connect_data);
920 session_deps.socket_factory->AddSocketDataProvider(&data);
921
922 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
923 ssl.origin_bound_cert_type = CLIENT_CERT_ECDSA_SIGN;
924 ssl.protocol_negotiated = SSLClientSocket::kProtoSPDY3;
925 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
926
927 scoped_refptr<HttpNetworkSession> http_session(
928 SpdySessionDependencies::SpdyCreateSession(&session_deps));
929
930 const std::string kTestHost("www.foo.com");
931 const int kTestPort = 80;
932 HostPortPair test_host_port_pair(kTestHost, kTestPort);
933 HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
934
935 SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
936 EXPECT_FALSE(spdy_session_pool->HasSession(pair));
937 scoped_refptr<SpdySession> session =
938 spdy_session_pool->Get(pair, BoundNetLog());
939 EXPECT_TRUE(spdy_session_pool->HasSession(pair));
940
941 SSLConfig ssl_config;
942 scoped_refptr<TransportSocketParams> transport_params(
943 new TransportSocketParams(test_host_port_pair,
944 MEDIUM,
945 false,
946 false));
947 scoped_refptr<SOCKSSocketParams> socks_params;
948 scoped_refptr<HttpProxySocketParams> http_proxy_params;
949 scoped_refptr<SSLSocketParams> ssl_params(
950 new SSLSocketParams(transport_params,
951 socks_params,
952 http_proxy_params,
953 ProxyServer::SCHEME_DIRECT,
954 test_host_port_pair,
955 ssl_config,
956 0,
957 false,
958 false));
959 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
960 EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
961 ssl_params, MEDIUM, CompletionCallback(),
962 http_session->GetSSLSocketPool(),
963 BoundNetLog()));
964
965 EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), true, OK));
966
967 EXPECT_FALSE(session->NeedsCredentials(test_host_port_pair));
968 const std::string kTestHost2("www.bar.com");
969 HostPortPair test_host_port_pair2(kTestHost2, kTestPort);
970 EXPECT_TRUE(session->NeedsCredentials(test_host_port_pair2));
971
972 // Flush the SpdySession::OnReadComplete() task.
973 MessageLoop::current()->RunAllPending();
974
975 spdy_session_pool->Remove(session);
976 EXPECT_FALSE(spdy_session_pool->HasSession(pair));
977 }
978
979 TEST_F(SpdySessionTest, SendCredentials) {
980 SpdySessionDependencies session_deps;
981
982 MockConnect connect_data(SYNCHRONOUS, OK);
983 MockRead reads[] = {
984 MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
985 };
986 spdy::SpdySettings settings;
987 scoped_ptr<spdy::SpdyFrame> settings_frame(
988 ConstructSpdySettings(settings));
989 MockWrite writes[] = {
990 CreateMockWrite(*settings_frame),
991 };
992 StaticSocketDataProvider data(reads, arraysize(reads),
993 writes, arraysize(writes));
994 data.set_connect_data(connect_data);
995 session_deps.socket_factory->AddSocketDataProvider(&data);
996
997 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
998 ssl.origin_bound_cert_type = CLIENT_CERT_ECDSA_SIGN;
999 ssl.protocol_negotiated = SSLClientSocket::kProtoSPDY3;
1000 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
1001
1002 scoped_refptr<HttpNetworkSession> http_session(
1003 SpdySessionDependencies::SpdyCreateSession(&session_deps));
1004
1005 const std::string kTestHost("www.foo.com");
1006 const int kTestPort = 80;
1007 HostPortPair test_host_port_pair(kTestHost, kTestPort);
1008 HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
1009
1010 SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
1011 EXPECT_FALSE(spdy_session_pool->HasSession(pair));
1012 scoped_refptr<SpdySession> session =
1013 spdy_session_pool->Get(pair, BoundNetLog());
1014 EXPECT_TRUE(spdy_session_pool->HasSession(pair));
1015
1016 SSLConfig ssl_config;
1017 scoped_refptr<TransportSocketParams> transport_params(
1018 new TransportSocketParams(test_host_port_pair,
1019 MEDIUM,
1020 false,
1021 false));
1022 scoped_refptr<SOCKSSocketParams> socks_params;
1023 scoped_refptr<HttpProxySocketParams> http_proxy_params;
1024 scoped_refptr<SSLSocketParams> ssl_params(
1025 new SSLSocketParams(transport_params,
1026 socks_params,
1027 http_proxy_params,
1028 ProxyServer::SCHEME_DIRECT,
1029 test_host_port_pair,
1030 ssl_config,
1031 0,
1032 false,
1033 false));
1034 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
1035 EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
1036 ssl_params, MEDIUM, CompletionCallback(),
1037 http_session->GetSSLSocketPool(),
1038 BoundNetLog()));
1039
1040 EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), true, OK));
1041
1042 EXPECT_FALSE(session->NeedsCredentials(test_host_port_pair));
1043 const std::string kTestHost2("www.bar.com");
1044 HostPortPair test_host_port_pair2(kTestHost2, kTestPort);
1045 EXPECT_TRUE(session->NeedsCredentials(test_host_port_pair2));
1046
1047 // Flush the SpdySession::OnReadComplete() task.
1048 MessageLoop::current()->RunAllPending();
1049
1050 spdy_session_pool->Remove(session);
1051 EXPECT_FALSE(spdy_session_pool->HasSession(pair));
1052 }
1053
1054 TEST_F(SpdySessionTest, CloseSessionOnError) {
1055 SpdySessionDependencies session_deps;
1056 session_deps.host_resolver->set_synchronous_mode(true);
1057
1058 MockConnect connect_data(SYNCHRONOUS, OK);
1059 scoped_ptr<spdy::SpdyFrame> goaway(ConstructSpdyGoAway());
1060 MockRead reads[] = {
1061 CreateMockRead(*goaway),
1062 MockRead(SYNCHRONOUS, 0, 0) // EOF
1063 };
1064
1065 net::CapturingBoundNetLog log(net::CapturingNetLog::kUnbounded);
1066
1067 StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
1068 data.set_connect_data(connect_data);
1069 session_deps.socket_factory->AddSocketDataProvider(&data);
1070
1071 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
1072 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
1073
1074 scoped_refptr<HttpNetworkSession> http_session(
1075 SpdySessionDependencies::SpdyCreateSession(&session_deps));
1076
1077 const std::string kTestHost("www.foo.com");
1078 const int kTestPort = 80;
1079 HostPortPair test_host_port_pair(kTestHost, kTestPort);
1080 HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
1081
1082 SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
1083 EXPECT_FALSE(spdy_session_pool->HasSession(pair));
1084 scoped_refptr<SpdySession> session =
1085 spdy_session_pool->Get(pair, log.bound());
1086 EXPECT_TRUE(spdy_session_pool->HasSession(pair));
1087
1088 scoped_refptr<TransportSocketParams> transport_params(
1089 new TransportSocketParams(test_host_port_pair,
1090 MEDIUM,
1091 false,
1092 false));
1093 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
1094 EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
1095 transport_params, MEDIUM, CompletionCallback(),
1096 http_session->GetTransportSocketPool(),
1097 log.bound()));
1098 EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
1099
1100 // Flush the SpdySession::OnReadComplete() task.
1101 MessageLoop::current()->RunAllPending();
1102
1103 EXPECT_FALSE(spdy_session_pool->HasSession(pair));
1104
1105 // Check that the NetLog was filled reasonably.
1106 net::CapturingNetLog::EntryList entries;
1107 log.GetEntries(&entries);
1108 EXPECT_LT(0u, entries.size());
1109
1110 // Check that we logged SPDY_SESSION_CLOSE correctly.
1111 int pos = net::ExpectLogContainsSomewhere(
1112 entries, 0,
1113 net::NetLog::TYPE_SPDY_SESSION_CLOSE,
1114 net::NetLog::PHASE_NONE);
1115
1116 CapturingNetLog::Entry entry = entries[pos];
1117 NetLogSpdySessionCloseParameter* request_params =
1118 static_cast<NetLogSpdySessionCloseParameter*>(
1119 entry.extra_parameters.get());
1120 EXPECT_EQ(ERR_CONNECTION_CLOSED, request_params->status());
1121 }
1122
1123 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/spdy_session_spdy3_unittest.cc ('k') | net/spdy/spdy_stream_spdy2_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698