1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/spdy/spdy_session.h"
6731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
7731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "net/spdy/spdy_io_buffer.h"
872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "net/spdy/spdy_session_pool.h"
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/spdy/spdy_stream.h"
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/spdy/spdy_test_util.h"
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "testing/platform_test.h"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace net {
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// TODO(cbentzel): Expose compression setter/getter in public SpdySession
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//                 interface rather than going through all these contortions.
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass SpdySessionTest : public PlatformTest {
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static void TurnOffCompression() {
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    spdy::SpdyFramer::set_enable_compression_default(false);
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
222c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun protected:
232c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  virtual void TearDown() {
242c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun    // Wanted to be 100% sure PING is disabled.
252c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun    SpdySession::set_enable_ping_based_connection_checking(false);
262c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  }
272c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun};
282c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun
292c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurunclass TestSpdyStreamDelegate : public net::SpdyStream::Delegate {
302c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun public:
312c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  explicit TestSpdyStreamDelegate(OldCompletionCallback* callback)
322c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun      : callback_(callback) {}
332c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  virtual ~TestSpdyStreamDelegate() {}
342c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun
352c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  virtual bool OnSendHeadersComplete(int status) { return true; }
362c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun
372c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  virtual int OnSendBody() {
382c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun    return ERR_UNEXPECTED;
392c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  }
402c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun
412c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  virtual int OnSendBodyComplete(int /*status*/, bool* /*eof*/) {
422c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun    return ERR_UNEXPECTED;
432c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  }
442c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun
452c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  virtual int OnResponseReceived(const spdy::SpdyHeaderBlock& response,
462c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun                                 base::Time response_time,
472c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun                                 int status) {
482c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun    return status;
492c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  }
502c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun
512c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  virtual void OnDataReceived(const char* buffer, int bytes) {
522c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  }
532c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun
542c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  virtual void OnDataSent(int length) {
552c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  }
562c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun
572c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  virtual void OnClose(int status) {
582c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun    OldCompletionCallback* callback = callback_;
592c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun    callback_ = NULL;
602c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun    callback->Run(OK);
612c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  }
622c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun
632c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  virtual void set_chunk_callback(net::ChunkCallback *) {}
642c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun
652c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun private:
662c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  OldCompletionCallback* callback_;
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
69731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test the SpdyIOBuffer class.
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(SpdySessionTest, SpdyIOBuffer) {
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::priority_queue<SpdyIOBuffer> queue_;
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const size_t kQueueSize = 100;
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Insert 100 items; pri 100 to 1.
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t index = 0; index < kQueueSize; ++index) {
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    SpdyIOBuffer buffer(new IOBuffer(), 0, kQueueSize - index, NULL);
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    queue_.push(buffer);
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Insert several priority 0 items last.
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const size_t kNumDuplicates = 12;
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  IOBufferWithSize* buffers[kNumDuplicates];
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t index = 0; index < kNumDuplicates; ++index) {
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    buffers[index] = new IOBufferWithSize(index+1);
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    queue_.push(SpdyIOBuffer(buffers[index], buffers[index]->size(), 0, NULL));
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(kQueueSize + kNumDuplicates, queue_.size());
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Verify the P0 items come out in FIFO order.
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t index = 0; index < kNumDuplicates; ++index) {
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    SpdyIOBuffer buffer = queue_.top();
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(0, buffer.priority());
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(index + 1, buffer.size());
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    queue_.pop();
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int priority = 1;
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  while (queue_.size()) {
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    SpdyIOBuffer buffer = queue_.top();
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(priority++, buffer.priority());
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    queue_.pop();
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(SpdySessionTest, GoAway) {
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SpdySessionDependencies session_deps;
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  session_deps.host_resolver->set_synchronous_mode(true);
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockConnect connect_data(false, OK);
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<spdy::SpdyFrame> goaway(ConstructSpdyGoAway());
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockRead reads[] = {
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CreateMockRead(*goaway),
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MockRead(false, 0, 0)  // EOF
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  data.set_connect_data(connect_data);
1193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  session_deps.socket_factory->AddSocketDataProvider(&data);
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SSLSocketDataProvider ssl(false, OK);
1223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<HttpNetworkSession> http_session(
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      SpdySessionDependencies::SpdyCreateSession(&session_deps));
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const std::string kTestHost("www.foo.com");
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const int kTestPort = 80;
1293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  HostPortPair test_host_port_pair(kTestHost, kTestPort);
1303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
132731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
1333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<SpdySession> session =
135dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      spdy_session_pool->Get(pair, BoundNetLog());
1363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(spdy_session_pool->HasSession(pair));
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
138ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_refptr<TransportSocketParams> transport_params(
139ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      new TransportSocketParams(test_host_port_pair,
140ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                MEDIUM,
141ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                GURL(),
142ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                false,
143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                false));
1443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
1453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(OK,
146ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            connection->Init(test_host_port_pair.ToString(),
147ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                             transport_params, MEDIUM,
148ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                             NULL, http_session->transport_socket_pool(),
149ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                             BoundNetLog()));
1503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Flush the SpdySession::OnReadComplete() task.
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->RunAllPending();
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<SpdySession> session2 =
158dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      spdy_session_pool->Get(pair, BoundNetLog());
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Delete the first session.
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  session = NULL;
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Delete the second session.
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  spdy_session_pool->Remove(session2);
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  session2 = NULL;
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1682c4085b2006233b5e3a3fe507d62642377b5dc2eSelim GurunTEST_F(SpdySessionTest, Ping) {
1692c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  SpdySessionDependencies session_deps;
1702c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  session_deps.host_resolver->set_synchronous_mode(true);
1712c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun
1722c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  MockConnect connect_data(false, OK);
1732c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  scoped_ptr<spdy::SpdyFrame> read_ping(ConstructSpdyPing());
1742c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  MockRead reads[] = {
1752c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun    CreateMockRead(*read_ping),
1762c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun    CreateMockRead(*read_ping),
1772c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun    MockRead(false, 0, 0)  // EOF
1782c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  };
1792c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  scoped_ptr<spdy::SpdyFrame> write_ping(ConstructSpdyPing());
1802c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  MockRead writes[] = {
1812c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun    CreateMockRead(*write_ping),
1822c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun    CreateMockRead(*write_ping),
1832c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  };
1842c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  StaticSocketDataProvider data(
1852c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun      reads, arraysize(reads), writes, arraysize(writes));
1862c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  data.set_connect_data(connect_data);
1872c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  session_deps.socket_factory->AddSocketDataProvider(&data);
1882c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun
1892c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  SSLSocketDataProvider ssl(false, OK);
1902c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
1912c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun
1922c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  scoped_refptr<HttpNetworkSession> http_session(
1932c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun      SpdySessionDependencies::SpdyCreateSession(&session_deps));
1942c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun
1952c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  static const char kStreamUrl[] = "http://www.google.com/";
1962c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  GURL url(kStreamUrl);
1972c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun
1982c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  const std::string kTestHost("www.google.com");
1992c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  const int kTestPort = 80;
2002c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  HostPortPair test_host_port_pair(kTestHost, kTestPort);
2012c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
2022c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun
2032c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
2042c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
2052c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  scoped_refptr<SpdySession> session =
2062c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun      spdy_session_pool->Get(pair, BoundNetLog());
2072c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  EXPECT_TRUE(spdy_session_pool->HasSession(pair));
2082c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun
2092c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun
2102c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  scoped_refptr<TransportSocketParams> transport_params(
2112c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun      new TransportSocketParams(test_host_port_pair,
2122c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun                                MEDIUM,
2132c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun                                GURL(),
2142c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun                                false,
2152c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun                                false));
2162c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
2172c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  EXPECT_EQ(OK,
2182c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun            connection->Init(test_host_port_pair.ToString(),
2192c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun                             transport_params,
2202c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun                             MEDIUM,
2212c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun                             NULL,
2222c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun                             http_session->transport_socket_pool(),
2232c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun                             BoundNetLog()));
2242c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
2252c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun
2262c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  scoped_refptr<SpdyStream> spdy_stream1;
2272c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  TestOldCompletionCallback callback1;
2282c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  EXPECT_EQ(OK, session->CreateStream(url,
2292c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun                                      MEDIUM,
2302c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun                                      &spdy_stream1,
2312c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun                                      BoundNetLog(),
2322c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun                                      &callback1));
2332c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  scoped_ptr<TestSpdyStreamDelegate> delegate(
2342c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun      new TestSpdyStreamDelegate(&callback1));
2352c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  spdy_stream1->SetDelegate(delegate.get());
2362c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun
2372c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  base::TimeTicks before_ping_time = base::TimeTicks::Now();
2382c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun
2392c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  // Enable sending of PING.
2402c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  SpdySession::set_enable_ping_based_connection_checking(true);
2412c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  SpdySession::set_connection_at_risk_of_loss_ms(0);
2422c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  SpdySession::set_trailing_ping_delay_time_ms(0);
2432c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  SpdySession::set_hung_interval_ms(50);
2442c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun
2452c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  session->SendPrefacePingIfNoneInFlight();
2462c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun
2472c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  EXPECT_EQ(OK, callback1.WaitForResult());
2482c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun
2492c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  EXPECT_EQ(0, session->pings_in_flight());
2502c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  EXPECT_GT(session->next_ping_id(), static_cast<uint32>(1));
2512c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  EXPECT_FALSE(session->trailing_ping_pending());
2522c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  // TODO(rtenneti): check_ping_status_pending works in debug mode with
2532c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  // breakpoints, but fails if run in stand alone mode.
2542c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  // EXPECT_FALSE(session->check_ping_status_pending());
2552c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  EXPECT_GE(session->received_data_time(), before_ping_time);
2562c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun
2572c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
2582c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun
2592c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  // Delete the first session.
2602c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun  session = NULL;
2612c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun}
2622c4085b2006233b5e3a3fe507d62642377b5dc2eSelim Gurun
263731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickclass StreamReleaserCallback : public CallbackRunner<Tuple1<int> > {
264731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick public:
265731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  StreamReleaserCallback(SpdySession* session,
266731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                         SpdyStream* first_stream)
267731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      : session_(session), first_stream_(first_stream) {}
268731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ~StreamReleaserCallback() {}
269731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
270731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  int WaitForResult() { return callback_.WaitForResult(); }
271731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
272731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  virtual void RunWithParams(const Tuple1<int>& params) {
273731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    session_->CloseSessionOnError(ERR_FAILED, false);
274731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    session_ = NULL;
275731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    first_stream_->Cancel();
276731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    first_stream_ = NULL;
277731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    stream_->Cancel();
278731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    stream_ = NULL;
279731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    callback_.RunWithParams(params);
280731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
281731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
282731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_refptr<SpdyStream>* stream() { return &stream_; }
283731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
284731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick private:
285731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_refptr<SpdySession> session_;
286731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_refptr<SpdyStream> first_stream_;
287731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_refptr<SpdyStream> stream_;
288731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  TestCompletionCallback callback_;
289731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick};
290731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
291731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Start with max concurrent streams set to 1.  Request two streams.  Receive a
292731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// settings frame setting max concurrent streams to 2.  Have the callback
293731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// release the stream, which releases its reference (the last) to the session.
294731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Make sure nothing blows up.
295731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// http://crbug.com/57331
296731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(SpdySessionTest, OnSettings) {
297731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  SpdySessionDependencies session_deps;
298731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  session_deps.host_resolver->set_synchronous_mode(true);
299731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
300731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  spdy::SpdySettings new_settings;
301731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  spdy::SettingsFlagsAndId id(spdy::SETTINGS_MAX_CONCURRENT_STREAMS);
302731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  id.set_id(spdy::SETTINGS_MAX_CONCURRENT_STREAMS);
303731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  const size_t max_concurrent_streams = 2;
304731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  new_settings.push_back(spdy::SpdySetting(id, max_concurrent_streams));
305731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
306731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Set up the socket so we read a SETTINGS frame that raises max concurrent
307731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // streams to 2.
308731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockConnect connect_data(false, OK);
309731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<spdy::SpdyFrame> settings_frame(
310731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      ConstructSpdySettings(new_settings));
311731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockRead reads[] = {
312731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    CreateMockRead(*settings_frame),
313731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    MockRead(false, 0, 0)  // EOF
314731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
315731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
316731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
317731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  data.set_connect_data(connect_data);
318731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  session_deps.socket_factory->AddSocketDataProvider(&data);
319731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
320731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  SSLSocketDataProvider ssl(false, OK);
321731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
322731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
323731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_refptr<HttpNetworkSession> http_session(
324731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      SpdySessionDependencies::SpdyCreateSession(&session_deps));
325731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
326731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  const std::string kTestHost("www.foo.com");
327731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  const int kTestPort = 80;
328731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  HostPortPair test_host_port_pair(kTestHost, kTestPort);
329731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
330731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
331731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Initialize the SpdySettingsStorage with 1 max concurrent streams.
332dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
333731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  spdy::SpdySettings old_settings;
334731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  id.set_flags(spdy::SETTINGS_FLAG_PLEASE_PERSIST);
335731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  old_settings.push_back(spdy::SpdySetting(id, 1));
336dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  spdy_session_pool->mutable_spdy_settings()->Set(
337731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      test_host_port_pair, old_settings);
338731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
339731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Create a session.
340731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
341731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_refptr<SpdySession> session =
342dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      spdy_session_pool->Get(pair, BoundNetLog());
343731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_TRUE(spdy_session_pool->HasSession(pair));
344731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
345ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_refptr<TransportSocketParams> transport_params(
346ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      new TransportSocketParams(test_host_port_pair,
347ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                MEDIUM,
348ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                GURL(),
349ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                false,
350ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                false));
351731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
352731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(OK,
353ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            connection->Init(test_host_port_pair.ToString(),
354ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                             transport_params, MEDIUM,
355ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                             NULL, http_session->transport_socket_pool(),
356ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                             BoundNetLog()));
357731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
358731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
359731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Create 2 streams.  First will succeed.  Second will be pending.
360731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_refptr<SpdyStream> spdy_stream1;
361731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  TestCompletionCallback callback1;
362731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  GURL url("http://www.google.com");
363731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(OK,
364731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick            session->CreateStream(url,
365731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                  MEDIUM, /* priority, not important */
366731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                  &spdy_stream1,
367731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                  BoundNetLog(),
368731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                  &callback1));
369731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
370731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  StreamReleaserCallback stream_releaser(session, spdy_stream1);
371731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
372731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_EQ(ERR_IO_PENDING,
373731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick            session->CreateStream(url,
374731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                  MEDIUM, /* priority, not important */
375731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                  stream_releaser.stream(),
376731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                  BoundNetLog(),
377731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                  &stream_releaser));
378731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
379731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Make sure |stream_releaser| holds the last refs.
380731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  session = NULL;
381731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  spdy_stream1 = NULL;
382731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
383731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(OK, stream_releaser.WaitForResult());
384731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
385731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
386201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// Start with max concurrent streams set to 1.  Request two streams.  When the
387201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// first completes, have the callback close itself, which should trigger the
388201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// second stream creation.  Then cancel that one immediately.  Don't crash.
389201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// http://crbug.com/63532
390201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben MurdochTEST_F(SpdySessionTest, CancelPendingCreateStream) {
391201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  SpdySessionDependencies session_deps;
392201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  session_deps.host_resolver->set_synchronous_mode(true);
393201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
394201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  MockRead reads[] = {
395201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    MockRead(false, ERR_IO_PENDING)  // Stall forever.
396201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  };
397201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
398201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
399201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  MockConnect connect_data(false, OK);
400201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
401201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  data.set_connect_data(connect_data);
402201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  session_deps.socket_factory->AddSocketDataProvider(&data);
403201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
404201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  SSLSocketDataProvider ssl(false, OK);
405201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
406201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
407201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  scoped_refptr<HttpNetworkSession> http_session(
408201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      SpdySessionDependencies::SpdyCreateSession(&session_deps));
409201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
410201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  const std::string kTestHost("www.foo.com");
411201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  const int kTestPort = 80;
412201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  HostPortPair test_host_port_pair(kTestHost, kTestPort);
413201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
414201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
415201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Initialize the SpdySettingsStorage with 1 max concurrent streams.
416dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
417201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  spdy::SpdySettings settings;
418201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  spdy::SettingsFlagsAndId id(spdy::SETTINGS_MAX_CONCURRENT_STREAMS);
419201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  id.set_id(spdy::SETTINGS_MAX_CONCURRENT_STREAMS);
420201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  id.set_flags(spdy::SETTINGS_FLAG_PLEASE_PERSIST);
421201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  settings.push_back(spdy::SpdySetting(id, 1));
422dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  spdy_session_pool->mutable_spdy_settings()->Set(
423dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      test_host_port_pair, settings);
424201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
425201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Create a session.
426201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
427201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  scoped_refptr<SpdySession> session =
428dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      spdy_session_pool->Get(pair, BoundNetLog());
429201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ASSERT_TRUE(spdy_session_pool->HasSession(pair));
430201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
431ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_refptr<TransportSocketParams> transport_params(
432ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      new TransportSocketParams(test_host_port_pair,
433ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                MEDIUM,
434ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                GURL(),
435ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                false,
436ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                false));
437201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
438201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(OK,
439ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            connection->Init(test_host_port_pair.ToString(),
440ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                             transport_params, MEDIUM,
441ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                             NULL, http_session->transport_socket_pool(),
442ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                             BoundNetLog()));
443201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
444201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
445201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Use scoped_ptr to let us invalidate the memory when we want to, to trigger
446201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // a valgrind error if the callback is invoked when it's not supposed to be.
447201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  scoped_ptr<TestCompletionCallback> callback(new TestCompletionCallback);
448201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
449201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Create 2 streams.  First will succeed.  Second will be pending.
450201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  scoped_refptr<SpdyStream> spdy_stream1;
451201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  GURL url("http://www.google.com");
452201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ASSERT_EQ(OK,
453201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch            session->CreateStream(url,
454201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                  MEDIUM, /* priority, not important */
455201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                  &spdy_stream1,
456201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                  BoundNetLog(),
457201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                  callback.get()));
458201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
459201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  scoped_refptr<SpdyStream> spdy_stream2;
460201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ASSERT_EQ(ERR_IO_PENDING,
461201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch            session->CreateStream(url,
462201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                  MEDIUM, /* priority, not important */
463201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                  &spdy_stream2,
464201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                  BoundNetLog(),
465201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                  callback.get()));
466201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
467201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Release the first one, this will allow the second to be created.
468201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  spdy_stream1->Cancel();
469201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  spdy_stream1 = NULL;
470201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
471201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  session->CancelPendingCreateStreams(&spdy_stream2);
472201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  callback.reset();
473201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
474201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Should not crash when running the pending callback.
475201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  MessageLoop::current()->RunAllPending();
476201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
477201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
478201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben MurdochTEST_F(SpdySessionTest, SendSettingsOnNewSession) {
479201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  SpdySessionDependencies session_deps;
480201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  session_deps.host_resolver->set_synchronous_mode(true);
481201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
482201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  MockRead reads[] = {
483201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    MockRead(false, ERR_IO_PENDING)  // Stall forever.
484201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  };
485201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
486201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Create the bogus setting that we want to verify is sent out.
487201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Note that it will be marked as SETTINGS_FLAG_PERSISTED when sent out.  But
488201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // to set it into the SpdySettingsStorage, we need to mark as
489201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // SETTINGS_FLAG_PLEASE_PERSIST.
490201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  spdy::SpdySettings settings;
491201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  const uint32 kBogusSettingId = 0xABAB;
492201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  const uint32 kBogusSettingValue = 0xCDCD;
493201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  spdy::SettingsFlagsAndId id(kBogusSettingId);
494201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  id.set_id(kBogusSettingId);
495201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  id.set_flags(spdy::SETTINGS_FLAG_PERSISTED);
496201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  settings.push_back(spdy::SpdySetting(id, kBogusSettingValue));
497201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  MockConnect connect_data(false, OK);
498201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  scoped_ptr<spdy::SpdyFrame> settings_frame(
499201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      ConstructSpdySettings(settings));
500201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  MockWrite writes[] = {
501201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    CreateMockWrite(*settings_frame),
502201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  };
503201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
504201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  StaticSocketDataProvider data(
505201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      reads, arraysize(reads), writes, arraysize(writes));
506201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  data.set_connect_data(connect_data);
507201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  session_deps.socket_factory->AddSocketDataProvider(&data);
508201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
509201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  SSLSocketDataProvider ssl(false, OK);
510201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
511201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
512201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  scoped_refptr<HttpNetworkSession> http_session(
513201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      SpdySessionDependencies::SpdyCreateSession(&session_deps));
514201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
515201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  const std::string kTestHost("www.foo.com");
516201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  const int kTestPort = 80;
517201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  HostPortPair test_host_port_pair(kTestHost, kTestPort);
518201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  HostPortProxyPair pair(test_host_port_pair, ProxyServer::Direct());
519201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
520201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  id.set_flags(spdy::SETTINGS_FLAG_PLEASE_PERSIST);
521201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  settings.clear();
522201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  settings.push_back(spdy::SpdySetting(id, kBogusSettingValue));
523201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
524dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  spdy_session_pool->mutable_spdy_settings()->Set(
525dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      test_host_port_pair, settings);
526201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_FALSE(spdy_session_pool->HasSession(pair));
527201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  scoped_refptr<SpdySession> session =
528dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      spdy_session_pool->Get(pair, BoundNetLog());
529201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_TRUE(spdy_session_pool->HasSession(pair));
530201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
531ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_refptr<TransportSocketParams> transport_params(
532ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      new TransportSocketParams(test_host_port_pair,
533ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                MEDIUM,
534ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                GURL(),
535ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                false,
536ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                false));
537201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
538201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(OK,
539ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            connection->Init(test_host_port_pair.ToString(),
540ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                             transport_params, MEDIUM,
541ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                             NULL, http_session->transport_socket_pool(),
542ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                             BoundNetLog()));
543201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
544201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  MessageLoop::current()->RunAllPending();
545201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_TRUE(data.at_write_eof());
546201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
547201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
548ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// This test has two variants, one for each style of closing the connection.
549ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// If |clean_via_close_current_sessions| is false, the sessions are closed
550ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// manually, calling SpdySessionPool::Remove() directly.  If it is true,
551ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// sessions are closed with SpdySessionPool::CloseCurrentSessions().
552ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid IPPoolingTest(bool clean_via_close_current_sessions) {
553ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  const int kTestPort = 80;
554ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  struct TestHosts {
555ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    std::string name;
556ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    std::string iplist;
557ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    HostPortProxyPair pair;
558ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  } test_hosts[] = {
559ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { "www.foo.com",    "192.168.0.1,192.168.0.5" },
560ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { "images.foo.com", "192.168.0.2,192.168.0.3,192.168.0.5" },
561ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { "js.foo.com",     "192.168.0.4,192.168.0.3" },
562ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
563ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
564ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  SpdySessionDependencies session_deps;
565ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  session_deps.host_resolver->set_synchronous_mode(true);
566ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_hosts); i++) {
567ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    session_deps.host_resolver->rules()->AddIPLiteralRule(test_hosts[i].name,
568ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        test_hosts[i].iplist, "");
569ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
570ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // This test requires that the HostResolver cache be populated.  Normal
571ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // code would have done this already, but we do it manually.
572ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    HostResolver::RequestInfo info(HostPortPair(test_hosts[i].name, kTestPort));
573ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    AddressList result;
574ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    session_deps.host_resolver->Resolve(
575ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        info, &result, NULL, NULL, BoundNetLog());
576ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
577ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Setup a HostPortProxyPair
578ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    test_hosts[i].pair = HostPortProxyPair(
579ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        HostPortPair(test_hosts[i].name, kTestPort), ProxyServer::Direct());
580ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
581ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
582ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  MockConnect connect_data(false, OK);
583ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  MockRead reads[] = {
584ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    MockRead(false, ERR_IO_PENDING)  // Stall forever.
585ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
586ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
587ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
588ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  data.set_connect_data(connect_data);
589ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  session_deps.socket_factory->AddSocketDataProvider(&data);
590ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
591ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  SSLSocketDataProvider ssl(false, OK);
592ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  session_deps.socket_factory->AddSSLSocketDataProvider(&ssl);
593ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
594ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_refptr<HttpNetworkSession> http_session(
595ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      SpdySessionDependencies::SpdyCreateSession(&session_deps));
596ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
597ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Setup the first session to the first host.
598ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool());
599ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[0].pair));
600ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_refptr<SpdySession> session =
601ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      spdy_session_pool->Get(test_hosts[0].pair, BoundNetLog());
602ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[0].pair));
603ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
604ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  HostPortPair test_host_port_pair(test_hosts[0].name, kTestPort);
605ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_refptr<TransportSocketParams> transport_params(
606ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      new TransportSocketParams(test_host_port_pair,
607ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                          MEDIUM,
608ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                          GURL(),
609ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                          false,
610ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                          false));
611ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
612ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(OK,
613ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            connection->Init(test_host_port_pair.ToString(),
614ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                             transport_params, MEDIUM,
615ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                             NULL, http_session->transport_socket_pool(),
616ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                             BoundNetLog()));
617ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), false, OK));
618ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
619ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Flush the SpdySession::OnReadComplete() task.
620ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  MessageLoop::current()->RunAllPending();
621ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
622ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // The third host has no overlap with the first, so it can't pool IPs.
623ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[2].pair));
624ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
625ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // The second host overlaps with the first, and should IP pool.
626ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[1].pair));
627ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
628ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Verify that the second host, through a proxy, won't share the IP.
629ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  HostPortProxyPair proxy_pair(test_hosts[1].pair.first,
630ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      ProxyServer::FromPacString("HTTP http://proxy.foo.com/"));
631ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(spdy_session_pool->HasSession(proxy_pair));
632ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
633ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Overlap between 2 and 3 does is not transitive to 1.
634ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[2].pair));
635ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
636ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Create a new session to host 2.
637ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_refptr<SpdySession> session2 =
638ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      spdy_session_pool->Get(test_hosts[2].pair, BoundNetLog());
639ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
640ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Verify that we have sessions for everything.
641ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[0].pair));
642ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[1].pair));
643ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(spdy_session_pool->HasSession(test_hosts[2].pair));
644ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
645ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Cleanup the sessions.
646ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!clean_via_close_current_sessions) {
647ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    spdy_session_pool->Remove(session);
648ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    session = NULL;
649ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    spdy_session_pool->Remove(session2);
650ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    session2 = NULL;
651ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  } else {
652ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    spdy_session_pool->CloseCurrentSessions();
653ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
654ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
655ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Verify that the map is all cleaned up.
656ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[0].pair));
657ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[1].pair));
658ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(spdy_session_pool->HasSession(test_hosts[2].pair));
659ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
660ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
661ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(SpdySessionTest, IPPooling) {
662ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  IPPoolingTest(false);
663ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
664ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
665ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(SpdySessionTest, IPPoolingCloseCurrentSessions) {
666ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  IPPoolingTest(true);
667ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
668ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
669c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace net
670