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

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

Issue 7349023: Changed SPDY's ip connection pooling logic to only add the used IP, (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 5 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
« net/spdy/spdy_session_pool.cc ('K') | « net/spdy/spdy_session_pool.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "net/spdy/spdy_io_buffer.h" 7 #include "net/spdy/spdy_io_buffer.h"
8 #include "net/spdy/spdy_session_pool.h" 8 #include "net/spdy/spdy_session_pool.h"
9 #include "net/spdy/spdy_stream.h" 9 #include "net/spdy/spdy_stream.h"
10 #include "net/spdy/spdy_test_util.h" 10 #include "net/spdy/spdy_test_util.h"
11 #include "testing/platform_test.h" 11 #include "testing/platform_test.h"
12 12
13 namespace net { 13 namespace net {
14 14
15 // TODO(cbentzel): Expose compression setter/getter in public SpdySession 15 // TODO(cbentzel): Expose compression setter/getter in public SpdySession
16 // interface rather than going through all these contortions. 16 // interface rather than going through all these contortions.
17 class SpdySessionTest : public PlatformTest { 17 class SpdySessionTest : public PlatformTest {
18 public: 18 public:
19 static void TurnOffCompression() { 19 static void TurnOffCompression() {
20 spdy::SpdyFramer::set_enable_compression_default(false); 20 spdy::SpdyFramer::set_enable_compression_default(false);
21 } 21 }
22
23 // This test has two variants, one for each style of closing the connection.
willchan no longer on Chromium 2011/07/17 01:23:45 Did you just move this to gain the friend access?
ramant (doing other things) 2011/07/17 08:12:30 Done.
24 // If |clean_via_close_current_sessions| is false, the sessions are closed
25 // manually, calling SpdySessionPool::Remove() directly. If it is true,
26 // sessions are closed with SpdySessionPool::CloseCurrentSessions().
27 static void IPPoolingTest(bool clean_via_close_current_sessions) {
28 const int kTestPort = 80;
29 struct TestHosts {
30 std::string name;
31 std::string iplist;
32 HostPortProxyPair pair;
33 } test_hosts[] = {
34 { "www.foo.com", "192.168.0.1,192.168.0.5" },
35 { "images.foo.com", "192.168.0.1,192.168.0.2,192.168.0.3" },
36 { "js.foo.com", "192.168.0.4,192.168.0.3" },
37 };
38
39 SpdySessionDependencies session_deps;
40 session_deps.host_resolver->set_synchronous_mode(true);
41 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_hosts); i++) {
42 session_deps.host_resolver->rules()->AddIPLiteralRule(test_hosts[i].name,
43 test_hosts[i].iplist, "");
44
45 // This test requires that the HostResolver cache be populated. Normal
46 // code would have done this already, but we do it manually.
47 HostResolver::RequestInfo info(
48 HostPortPair(test_hosts[i].name, kTestPort));
49 AddressList result;
50 session_deps.host_resolver->Resolve(
51 info, &result, NULL, NULL, BoundNetLog());
52
53 // Setup a HostPortProxyPair
54 test_hosts[i].pair = HostPortProxyPair(
55 HostPortPair(test_hosts[i].name, kTestPort), ProxyServer::Direct());
56 }
57
58 MockConnect connect_data(false, OK);
59 MockRead reads[] = {
60 MockRead(false, ERR_IO_PENDING) // Stall forever.
61 };
62
63 StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
64 data.set_connect_data(connect_data);
65 session_deps.socket_factory->AddSocketDataProvider(&data);
66
67 SSLSocketDataProvider ssl(false, OK);
68 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
69
70 scoped_refptr<HttpNetworkSession> http_session(
71 SpdySessionDependencies::SpdyCreateSession(&session_deps));
72
73 // Setup the first session to the first host.
74 SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
75 EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[0].pair));
76 scoped_refptr<SpdySession> session =
77 spdy_session_pool->Get(test_hosts[0].pair, BoundNetLog());
78 EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[0].pair));
79
80 HostPortPair test_host_port_pair(test_hosts[0].name, kTestPort);
81 scoped_refptr<TransportSocketParams> transport_params(
82 new TransportSocketParams(test_host_port_pair,
83 MEDIUM,
84 GURL(),
85 false,
86 false));
87 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
88 EXPECT_EQ(OK,
89 connection->Init(test_host_port_pair.ToString(),
90 transport_params, MEDIUM,
91 NULL, http_session->transport_socket_pool(),
92 BoundNetLog()));
93 spdy_session_pool->AddAliases(test_hosts[0].pair);
94 EXPECT_EQ(OK,
95 session->InitializeWithSocket(connection.release(), false, OK));
96
97 // Flush the SpdySession::OnReadComplete() task.
98 MessageLoop::current()->RunAllPending();
99
100 // The third host has no overlap with the first, so it can't pool IPs.
101 EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[2].pair));
102
103 // The second host overlaps with the first, and should IP pool.
104 EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[1].pair));
105
106 // Verify that the second host, through a proxy, won't share the IP.
107 HostPortProxyPair proxy_pair(test_hosts[1].pair.first,
108 ProxyServer::FromPacString("HTTP http://proxy.foo.com/"));
109 EXPECT_FALSE(spdy_session_pool->HasSession(proxy_pair));
110
111 // Overlap between 2 and 3 does is not transitive to 1.
112 EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[2].pair));
113
114 // Create a new session to host 2.
115 scoped_refptr<SpdySession> session2 =
116 spdy_session_pool->Get(test_hosts[2].pair, BoundNetLog());
117
118 // Verify that we have sessions for everything.
119 EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[0].pair));
120 EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[1].pair));
121 EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[2].pair));
122
123 // Cleanup the sessions.
124 if (!clean_via_close_current_sessions) {
125 spdy_session_pool->Remove(session);
126 session = NULL;
127 spdy_session_pool->Remove(session2);
128 session2 = NULL;
129 } else {
130 spdy_session_pool->CloseCurrentSessions();
131 }
132
133 // Verify that the map is all cleaned up.
134 EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[0].pair));
135 EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[1].pair));
136 EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[2].pair));
137 }
138
22 }; 139 };
23 140
24 namespace {
25
26 // Test the SpdyIOBuffer class. 141 // Test the SpdyIOBuffer class.
27 TEST_F(SpdySessionTest, SpdyIOBuffer) { 142 TEST_F(SpdySessionTest, SpdyIOBuffer) {
28 std::priority_queue<SpdyIOBuffer> queue_; 143 std::priority_queue<SpdyIOBuffer> queue_;
29 const size_t kQueueSize = 100; 144 const size_t kQueueSize = 100;
30 145
31 // Insert 100 items; pri 100 to 1. 146 // Insert 100 items; pri 100 to 1.
32 for (size_t index = 0; index < kQueueSize; ++index) { 147 for (size_t index = 0; index < kQueueSize; ++index) {
33 SpdyIOBuffer buffer(new IOBuffer(), 0, kQueueSize - index, NULL); 148 SpdyIOBuffer buffer(new IOBuffer(), 0, kQueueSize - index, NULL);
34 queue_.push(buffer); 149 queue_.push(buffer);
35 } 150 }
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 MEDIUM, 211 MEDIUM,
97 GURL(), 212 GURL(),
98 false, 213 false,
99 false)); 214 false));
100 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle); 215 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
101 EXPECT_EQ(OK, 216 EXPECT_EQ(OK,
102 connection->Init(test_host_port_pair.ToString(), 217 connection->Init(test_host_port_pair.ToString(),
103 transport_params, MEDIUM, 218 transport_params, MEDIUM,
104 NULL, http_session->transport_socket_pool(), 219 NULL, http_session->transport_socket_pool(),
105 BoundNetLog())); 220 BoundNetLog()));
221 spdy_session_pool->AddAliases(pair);
willchan no longer on Chromium 2011/07/17 01:23:45 Why is this necessary?
ramant (doing other things) 2011/07/17 08:12:30 Done.
106 EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK)); 222 EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
107 223
108 // Flush the SpdySession::OnReadComplete() task. 224 // Flush the SpdySession::OnReadComplete() task.
109 MessageLoop::current()->RunAllPending(); 225 MessageLoop::current()->RunAllPending();
110 226
111 EXPECT_FALSE(spdy_session_pool->HasSession(pair)); 227 EXPECT_FALSE(spdy_session_pool->HasSession(pair));
112 228
113 scoped_refptr<SpdySession> session2 = 229 scoped_refptr<SpdySession> session2 =
114 spdy_session_pool->Get(pair, BoundNetLog()); 230 spdy_session_pool->Get(pair, BoundNetLog());
115 231
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 MEDIUM, 324 MEDIUM,
209 GURL(), 325 GURL(),
210 false, 326 false,
211 false)); 327 false));
212 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle); 328 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
213 EXPECT_EQ(OK, 329 EXPECT_EQ(OK,
214 connection->Init(test_host_port_pair.ToString(), 330 connection->Init(test_host_port_pair.ToString(),
215 transport_params, MEDIUM, 331 transport_params, MEDIUM,
216 NULL, http_session->transport_socket_pool(), 332 NULL, http_session->transport_socket_pool(),
217 BoundNetLog())); 333 BoundNetLog()));
334 spdy_session_pool->AddAliases(pair);
willchan no longer on Chromium 2011/07/17 01:23:45 Why is this necessary?
ramant (doing other things) 2011/07/17 08:12:30 Done.
218 EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK)); 335 EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
219 336
220 // Create 2 streams. First will succeed. Second will be pending. 337 // Create 2 streams. First will succeed. Second will be pending.
221 scoped_refptr<SpdyStream> spdy_stream1; 338 scoped_refptr<SpdyStream> spdy_stream1;
222 TestCompletionCallback callback1; 339 TestCompletionCallback callback1;
223 GURL url("http://www.google.com"); 340 GURL url("http://www.google.com");
224 EXPECT_EQ(OK, 341 EXPECT_EQ(OK,
225 session->CreateStream(url, 342 session->CreateStream(url,
226 MEDIUM, /* priority, not important */ 343 MEDIUM, /* priority, not important */
227 &spdy_stream1, 344 &spdy_stream1,
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 MEDIUM, 411 MEDIUM,
295 GURL(), 412 GURL(),
296 false, 413 false,
297 false)); 414 false));
298 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle); 415 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
299 EXPECT_EQ(OK, 416 EXPECT_EQ(OK,
300 connection->Init(test_host_port_pair.ToString(), 417 connection->Init(test_host_port_pair.ToString(),
301 transport_params, MEDIUM, 418 transport_params, MEDIUM,
302 NULL, http_session->transport_socket_pool(), 419 NULL, http_session->transport_socket_pool(),
303 BoundNetLog())); 420 BoundNetLog()));
421 spdy_session_pool->AddAliases(pair);
willchan no longer on Chromium 2011/07/17 01:23:45 Why is this necessary?
ramant (doing other things) 2011/07/17 08:12:30 Done.
304 EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK)); 422 EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
305 423
306 // Use scoped_ptr to let us invalidate the memory when we want to, to trigger 424 // Use scoped_ptr to let us invalidate the memory when we want to, to trigger
307 // a valgrind error if the callback is invoked when it's not supposed to be. 425 // a valgrind error if the callback is invoked when it's not supposed to be.
308 scoped_ptr<TestCompletionCallback> callback(new TestCompletionCallback); 426 scoped_ptr<TestCompletionCallback> callback(new TestCompletionCallback);
309 427
310 // Create 2 streams. First will succeed. Second will be pending. 428 // Create 2 streams. First will succeed. Second will be pending.
311 scoped_refptr<SpdyStream> spdy_stream1; 429 scoped_refptr<SpdyStream> spdy_stream1;
312 GURL url("http://www.google.com"); 430 GURL url("http://www.google.com");
313 ASSERT_EQ(OK, 431 ASSERT_EQ(OK,
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 MEDIUM, 512 MEDIUM,
395 GURL(), 513 GURL(),
396 false, 514 false,
397 false)); 515 false));
398 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle); 516 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
399 EXPECT_EQ(OK, 517 EXPECT_EQ(OK,
400 connection->Init(test_host_port_pair.ToString(), 518 connection->Init(test_host_port_pair.ToString(),
401 transport_params, MEDIUM, 519 transport_params, MEDIUM,
402 NULL, http_session->transport_socket_pool(), 520 NULL, http_session->transport_socket_pool(),
403 BoundNetLog())); 521 BoundNetLog()));
522 spdy_session_pool->AddAliases(pair);
willchan no longer on Chromium 2011/07/17 01:23:45 Ditto
ramant (doing other things) 2011/07/17 08:12:30 Done.
404 EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK)); 523 EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
405 MessageLoop::current()->RunAllPending(); 524 MessageLoop::current()->RunAllPending();
406 EXPECT_TRUE(data.at_write_eof()); 525 EXPECT_TRUE(data.at_write_eof());
407 } 526 }
408 527
409 // This test has two variants, one for each style of closing the connection.
410 // If |clean_via_close_current_sessions| is false, the sessions are closed
411 // manually, calling SpdySessionPool::Remove() directly. If it is true,
412 // sessions are closed with SpdySessionPool::CloseCurrentSessions().
413 void IPPoolingTest(bool clean_via_close_current_sessions) {
414 const int kTestPort = 80;
415 struct TestHosts {
416 std::string name;
417 std::string iplist;
418 HostPortProxyPair pair;
419 } test_hosts[] = {
420 { "www.foo.com", "192.168.0.1,192.168.0.5" },
421 { "images.foo.com", "192.168.0.2,192.168.0.3,192.168.0.5" },
422 { "js.foo.com", "192.168.0.4,192.168.0.3" },
423 };
424
425 SpdySessionDependencies session_deps;
426 session_deps.host_resolver->set_synchronous_mode(true);
427 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_hosts); i++) {
428 session_deps.host_resolver->rules()->AddIPLiteralRule(test_hosts[i].name,
429 test_hosts[i].iplist, "");
430
431 // This test requires that the HostResolver cache be populated. Normal
432 // code would have done this already, but we do it manually.
433 HostResolver::RequestInfo info(HostPortPair(test_hosts[i].name, kTestPort));
434 AddressList result;
435 session_deps.host_resolver->Resolve(
436 info, &result, NULL, NULL, BoundNetLog());
437
438 // Setup a HostPortProxyPair
439 test_hosts[i].pair = HostPortProxyPair(
440 HostPortPair(test_hosts[i].name, kTestPort), ProxyServer::Direct());
441 }
442
443 MockConnect connect_data(false, OK);
444 MockRead reads[] = {
445 MockRead(false, ERR_IO_PENDING) // Stall forever.
446 };
447
448 StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
449 data.set_connect_data(connect_data);
450 session_deps.socket_factory->AddSocketDataProvider(&data);
451
452 SSLSocketDataProvider ssl(false, OK);
453 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
454
455 scoped_refptr<HttpNetworkSession> http_session(
456 SpdySessionDependencies::SpdyCreateSession(&session_deps));
457
458 // Setup the first session to the first host.
459 SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
460 EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[0].pair));
461 scoped_refptr<SpdySession> session =
462 spdy_session_pool->Get(test_hosts[0].pair, BoundNetLog());
463 EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[0].pair));
464
465 HostPortPair test_host_port_pair(test_hosts[0].name, kTestPort);
466 scoped_refptr<TransportSocketParams> transport_params(
467 new TransportSocketParams(test_host_port_pair,
468 MEDIUM,
469 GURL(),
470 false,
471 false));
472 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
473 EXPECT_EQ(OK,
474 connection->Init(test_host_port_pair.ToString(),
475 transport_params, MEDIUM,
476 NULL, http_session->transport_socket_pool(),
477 BoundNetLog()));
478 EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
479
480 // Flush the SpdySession::OnReadComplete() task.
481 MessageLoop::current()->RunAllPending();
482
483 // The third host has no overlap with the first, so it can't pool IPs.
484 EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[2].pair));
485
486 // The second host overlaps with the first, and should IP pool.
487 EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[1].pair));
488
489 // Verify that the second host, through a proxy, won't share the IP.
490 HostPortProxyPair proxy_pair(test_hosts[1].pair.first,
491 ProxyServer::FromPacString("HTTP http://proxy.foo.com/"));
492 EXPECT_FALSE(spdy_session_pool->HasSession(proxy_pair));
493
494 // Overlap between 2 and 3 does is not transitive to 1.
495 EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[2].pair));
496
497 // Create a new session to host 2.
498 scoped_refptr<SpdySession> session2 =
499 spdy_session_pool->Get(test_hosts[2].pair, BoundNetLog());
500
501 // Verify that we have sessions for everything.
502 EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[0].pair));
503 EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[1].pair));
504 EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[2].pair));
505
506 // Cleanup the sessions.
507 if (!clean_via_close_current_sessions) {
508 spdy_session_pool->Remove(session);
509 session = NULL;
510 spdy_session_pool->Remove(session2);
511 session2 = NULL;
512 } else {
513 spdy_session_pool->CloseCurrentSessions();
514 }
515
516 // Verify that the map is all cleaned up.
517 EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[0].pair));
518 EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[1].pair));
519 EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[2].pair));
520 }
521
522 TEST_F(SpdySessionTest, IPPooling) { 528 TEST_F(SpdySessionTest, IPPooling) {
523 IPPoolingTest(false); 529 SpdySessionTest::IPPoolingTest(false);
524 } 530 }
525 531
526 TEST_F(SpdySessionTest, IPPoolingCloseCurrentSessions) { 532 TEST_F(SpdySessionTest, IPPoolingCloseCurrentSessions) {
527 IPPoolingTest(true); 533 SpdySessionTest::IPPoolingTest(true);
528 } 534 }
529 535
530 TEST_F(SpdySessionTest, ClearSettingsStorage) { 536 TEST_F(SpdySessionTest, ClearSettingsStorage) {
531 SpdySettingsStorage settings_storage; 537 SpdySettingsStorage settings_storage;
532 const std::string kTestHost("www.foo.com"); 538 const std::string kTestHost("www.foo.com");
533 const int kTestPort = 80; 539 const int kTestPort = 80;
534 HostPortPair test_host_port_pair(kTestHost, kTestPort); 540 HostPortPair test_host_port_pair(kTestHost, kTestPort);
535 spdy::SpdySettings test_settings; 541 spdy::SpdySettings test_settings;
536 spdy::SettingsFlagsAndId id(0); 542 spdy::SettingsFlagsAndId id(0);
537 id.set_id(spdy::SETTINGS_MAX_CONCURRENT_STREAMS); 543 id.set_id(spdy::SETTINGS_MAX_CONCURRENT_STREAMS);
(...skipping 25 matching lines...) Expand all
563 const size_t max_concurrent_streams = 2; 569 const size_t max_concurrent_streams = 2;
564 spdy::SpdySettings test_settings; 570 spdy::SpdySettings test_settings;
565 test_settings.push_back(spdy::SpdySetting(id, max_concurrent_streams)); 571 test_settings.push_back(spdy::SpdySetting(id, max_concurrent_streams));
566 572
567 test_settings_storage->Set(test_host_port_pair, test_settings); 573 test_settings_storage->Set(test_host_port_pair, test_settings);
568 EXPECT_NE(0u, test_settings_storage->Get(test_host_port_pair).size()); 574 EXPECT_NE(0u, test_settings_storage->Get(test_host_port_pair).size());
569 spdy_session_pool->OnIPAddressChanged(); 575 spdy_session_pool->OnIPAddressChanged();
570 EXPECT_EQ(0u, test_settings_storage->Get(test_host_port_pair).size()); 576 EXPECT_EQ(0u, test_settings_storage->Get(test_host_port_pair).size());
571 } 577 }
572 578
573 } // namespace
574
575 } // namespace net 579 } // namespace net
OLDNEW
« net/spdy/spdy_session_pool.cc ('K') | « net/spdy/spdy_session_pool.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698