summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormmenke <mmenke@chromium.org>2015-12-07 10:20:18 -0800
committerCommit bot <commit-bot@chromium.org>2015-12-07 18:21:05 +0000
commitcc2298e47b8a20cb279615dd2c80a7e0d93e6eae (patch)
tree801e320ce7e35f50660b83eab30e11edc03cd2a4
parent2e0db32ee1947b7a48e723ad871077be5e385ed0 (diff)
downloadchromium_src-cc2298e47b8a20cb279615dd2c80a7e0d93e6eae.zip
chromium_src-cc2298e47b8a20cb279615dd2c80a7e0d93e6eae.tar.gz
chromium_src-cc2298e47b8a20cb279615dd2c80a7e0d93e6eae.tar.bz2
Add integration tests for HttpStreamParser::CanReuseConnection logic.
This requires modifying a fair number of other tests and test infrastructure to safely handle SocketDataProviders that are destroyed before the mock socket that uses them. BUG=565582,544255 Review URL: https://codereview.chromium.org/1499073002 Cr-Commit-Position: refs/heads/master@{#363516}
-rw-r--r--net/dns/dns_session_unittest.cc1
-rw-r--r--net/dns/dns_transaction_unittest.cc6
-rw-r--r--net/http/http_network_transaction_unittest.cc312
-rw-r--r--net/http/http_stream_parser_unittest.cc1
-rw-r--r--net/socket/socket_test_util.cc127
-rw-r--r--net/socket/socket_test_util.h67
-rw-r--r--net/spdy/spdy_network_transaction_unittest.cc8
-rw-r--r--net/spdy/spdy_session_pool_unittest.cc42
-rw-r--r--net/url_request/url_request_http_job_unittest.cc25
9 files changed, 377 insertions, 212 deletions
diff --git a/net/dns/dns_session_unittest.cc b/net/dns/dns_session_unittest.cc
index 46815e0..9ba920c 100644
--- a/net/dns/dns_session_unittest.cc
+++ b/net/dns/dns_session_unittest.cc
@@ -190,7 +190,6 @@ TestClientSocketFactory::CreateDatagramClientSocket(
data_providers_.push_back(data_provider);
scoped_ptr<MockUDPClientSocket> socket(
new MockUDPClientSocket(data_provider, net_log));
- data_provider->set_socket(socket.get());
return socket.Pass();
}
diff --git a/net/dns/dns_transaction_unittest.cc b/net/dns/dns_transaction_unittest.cc
index e875645..3f82110 100644
--- a/net/dns/dns_transaction_unittest.cc
+++ b/net/dns/dns_transaction_unittest.cc
@@ -196,7 +196,6 @@ class TestSocketFactory : public MockClientSocketFactory {
SocketDataProvider* data_provider = mock_data().GetNext();
scoped_ptr<TestUDPClientSocket> socket(
new TestUDPClientSocket(this, data_provider, net_log));
- data_provider->set_socket(socket.get());
return socket.Pass();
}
@@ -519,11 +518,6 @@ TEST_F(DnsTransactionTest, CancelLookup) {
helper1.StartTransaction(transaction_factory_.get());
helper0.Cancel();
- // Since the transaction has been cancelled, the assocaited socket has been
- // destroyed, so make sure the data provide does not attempt to callback
- // to the socket.
- // TODO(rch): Make the SocketDataProvider and MockSocket do this by default.
- socket_data_[0]->GetProvider()->set_socket(nullptr);
base::MessageLoop::current()->RunUntilIdle();
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc
index 5512f55..bd538f5 100644
--- a/net/http/http_network_transaction_unittest.cc
+++ b/net/http/http_network_transaction_unittest.cc
@@ -1843,50 +1843,76 @@ TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
session_deps_.net_log = &net_log;
scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ const char* request_data =
+ "GET / HTTP/1.1\r\n"
+ "Host: www.foo.com\r\n"
+ "Connection: keep-alive\r\n\r\n";
+ MockWrite data_writes[] = {
+ MockWrite(ASYNC, 0, request_data), MockWrite(ASYNC, 2, request_data),
+ MockWrite(ASYNC, 4, request_data), MockWrite(ASYNC, 6, request_data),
+ MockWrite(ASYNC, 8, request_data), MockWrite(ASYNC, 10, request_data),
+ MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
+ MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
+ };
+
// Note that because all these reads happen in the same
// StaticSocketDataProvider, it shows that the same socket is being reused for
// all transactions.
- MockRead data1_reads[] = {
- MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
- MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"),
- MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
- MockRead("HTTP/1.1 302 Found\r\n"
- "Content-Length: 0\r\n\r\n"),
- MockRead("HTTP/1.1 302 Found\r\n"
- "Content-Length: 5\r\n\r\n"
- "hello"),
- MockRead("HTTP/1.1 301 Moved Permanently\r\n"
- "Content-Length: 0\r\n\r\n"),
- MockRead("HTTP/1.1 301 Moved Permanently\r\n"
- "Content-Length: 5\r\n\r\n"
- "hello"),
- MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
- MockRead("hello"),
- };
- StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
- session_deps_.socket_factory->AddSocketDataProvider(&data1);
-
- MockRead data2_reads[] = {
- MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
+ MockRead data_reads[] = {
+ MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
+ MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
+ MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
+ MockRead(ASYNC, 7,
+ "HTTP/1.1 302 Found\r\n"
+ "Content-Length: 0\r\n\r\n"),
+ MockRead(ASYNC, 9,
+ "HTTP/1.1 302 Found\r\n"
+ "Content-Length: 5\r\n\r\n"
+ "hello"),
+ MockRead(ASYNC, 11,
+ "HTTP/1.1 301 Moved Permanently\r\n"
+ "Content-Length: 0\r\n\r\n"),
+ MockRead(ASYNC, 13,
+ "HTTP/1.1 301 Moved Permanently\r\n"
+ "Content-Length: 5\r\n\r\n"
+ "hello"),
+
+ // In the next two rounds, IsConnectedAndIdle returns false, due to
+ // the set_busy_before_sync_reads(true) call, while the
+ // HttpNetworkTransaction is being shut down, but the socket is still
+ // reuseable. See http://crbug.com/544255.
+ MockRead(ASYNC, 15,
+ "HTTP/1.1 200 Hunky-Dory\r\n"
+ "Content-Length: 5\r\n\r\n"),
+ MockRead(SYNCHRONOUS, 16, "hello"),
+
+ MockRead(ASYNC, 18,
+ "HTTP/1.1 200 Hunky-Dory\r\n"
+ "Content-Length: 5\r\n\r\n"
+ "he"),
+ MockRead(SYNCHRONOUS, 19, "llo"),
+
+ // The body of the final request is actually read.
+ MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
+ MockRead(ASYNC, 22, "hello"),
};
- StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
- session_deps_.socket_factory->AddSocketDataProvider(&data2);
+ SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
+ arraysize(data_writes));
+ data.set_busy_before_sync_reads(true);
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
- const int kNumUnreadBodies = arraysize(data1_reads) - 2;
+ const int kNumUnreadBodies = arraysize(data_writes) - 1;
std::string response_lines[kNumUnreadBodies];
uint32 first_socket_log_id = NetLog::Source::kInvalidId;
- for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) {
+ for (size_t i = 0; i < kNumUnreadBodies; ++i) {
TestCompletionCallback callback;
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
int rv = trans->Start(&request, callback.callback(), BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- rv = callback.WaitForResult();
- EXPECT_EQ(OK, rv);
+ EXPECT_EQ(OK, callback.GetResult(rv));
LoadTimingInfo load_timing_info;
EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
@@ -1899,22 +1925,27 @@ TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
}
const HttpResponseInfo* response = trans->GetResponseInfo();
- ASSERT_TRUE(response != NULL);
+ ASSERT_TRUE(response);
- ASSERT_TRUE(response->headers.get() != NULL);
+ ASSERT_TRUE(response->headers);
response_lines[i] = response->headers->GetStatusLine();
- // We intentionally don't read the response bodies.
+ // Delete the transaction without reading the response bodies. Then spin
+ // the message loop, so the response bodies are drained.
+ trans.reset();
+ base::RunLoop().RunUntilIdle();
}
const char* const kStatusLines[] = {
- "HTTP/1.1 204 No Content",
- "HTTP/1.1 205 Reset Content",
- "HTTP/1.1 304 Not Modified",
- "HTTP/1.1 302 Found",
- "HTTP/1.1 302 Found",
- "HTTP/1.1 301 Moved Permanently",
- "HTTP/1.1 301 Moved Permanently",
+ "HTTP/1.1 204 No Content",
+ "HTTP/1.1 205 Reset Content",
+ "HTTP/1.1 304 Not Modified",
+ "HTTP/1.1 302 Found",
+ "HTTP/1.1 302 Found",
+ "HTTP/1.1 301 Moved Permanently",
+ "HTTP/1.1 301 Moved Permanently",
+ "HTTP/1.1 200 Hunky-Dory",
+ "HTTP/1.1 200 Hunky-Dory",
};
static_assert(kNumUnreadBodies == arraysize(kStatusLines),
@@ -1927,12 +1958,10 @@ TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
int rv = trans->Start(&request, callback.callback(), BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
- rv = callback.WaitForResult();
- EXPECT_EQ(OK, rv);
+ EXPECT_EQ(OK, callback.GetResult(rv));
const HttpResponseInfo* response = trans->GetResponseInfo();
- ASSERT_TRUE(response != NULL);
- ASSERT_TRUE(response->headers.get() != NULL);
+ ASSERT_TRUE(response);
+ ASSERT_TRUE(response->headers);
EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
std::string response_data;
rv = ReadTransaction(trans.get(), &response_data);
@@ -2215,106 +2244,96 @@ TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
// Test the request-challenge-retry sequence for basic auth, over a keep-alive
// connection.
TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
- HttpRequestInfo request;
- request.method = "GET";
- request.url = GURL("http://www.example.org/");
- request.load_flags = 0;
-
- TestNetLog log;
- session_deps_.net_log = &log;
- scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
-
- MockWrite data_writes1[] = {
- MockWrite(
- "GET / HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Connection: keep-alive\r\n\r\n"),
-
- // After calling trans->RestartWithAuth(), this is the request we should
- // be issuing -- the final header line contains the credentials.
- MockWrite(
- "GET / HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Connection: keep-alive\r\n"
- "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
- };
-
- MockRead data_reads1[] = {
- MockRead("HTTP/1.1 401 Unauthorized\r\n"),
- MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
- MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
- MockRead("Content-Length: 14\r\n\r\n"),
- MockRead("Unauthorized\r\n"),
+ // On the second pass, the body read of the auth challenge is synchronous, so
+ // IsConnectedAndIdle returns false. The socket should still be drained and
+ // reused. See http://crbug.com/544255.
+ for (int i = 0; i < 2; ++i) {
+ HttpRequestInfo request;
+ request.method = "GET";
+ request.url = GURL("http://www.example.org/");
+ request.load_flags = 0;
- // Lastly, the server responds with the actual content.
- MockRead("HTTP/1.1 200 OK\r\n"),
- MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
- MockRead("Content-Length: 5\r\n\r\n"),
- MockRead("Hello"),
- };
+ TestNetLog log;
+ session_deps_.net_log = &log;
+ scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
- // If there is a regression where we disconnect a Keep-Alive
- // connection during an auth roundtrip, we'll end up reading this.
- MockRead data_reads2[] = {
- MockRead(SYNCHRONOUS, ERR_FAILED),
- };
+ MockWrite data_writes[] = {
+ MockWrite(ASYNC, 0,
+ "GET / HTTP/1.1\r\n"
+ "Host: www.example.org\r\n"
+ "Connection: keep-alive\r\n\r\n"),
- StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
- data_writes1, arraysize(data_writes1));
- StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
- NULL, 0);
- session_deps_.socket_factory->AddSocketDataProvider(&data1);
- session_deps_.socket_factory->AddSocketDataProvider(&data2);
+ // After calling trans->RestartWithAuth(), this is the request we should
+ // be issuing -- the final header line contains the credentials.
+ MockWrite(ASYNC, 6,
+ "GET / HTTP/1.1\r\n"
+ "Host: www.example.org\r\n"
+ "Connection: keep-alive\r\n"
+ "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
+ };
- TestCompletionCallback callback1;
+ MockRead data_reads[] = {
+ MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
+ MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
+ MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
+ MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
+ MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
+
+ // Lastly, the server responds with the actual content.
+ MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
+ MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
+ MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
+ MockRead(ASYNC, 10, "Hello"),
+ };
- scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
- int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
+ SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
+ arraysize(data_writes));
+ data.set_busy_before_sync_reads(true);
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
- rv = callback1.WaitForResult();
- EXPECT_EQ(OK, rv);
+ TestCompletionCallback callback1;
- LoadTimingInfo load_timing_info1;
- EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
- TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
+ scoped_ptr<HttpTransaction> trans(
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
+ int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
+ ASSERT_EQ(OK, callback1.GetResult(rv));
- const HttpResponseInfo* response = trans->GetResponseInfo();
- ASSERT_TRUE(response != NULL);
- EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
+ LoadTimingInfo load_timing_info1;
+ EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
+ TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
- TestCompletionCallback callback2;
+ const HttpResponseInfo* response = trans->GetResponseInfo();
+ ASSERT_TRUE(response);
+ EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
- rv = trans->RestartWithAuth(
- AuthCredentials(kFoo, kBar), callback2.callback());
- EXPECT_EQ(ERR_IO_PENDING, rv);
+ TestCompletionCallback callback2;
- rv = callback2.WaitForResult();
- EXPECT_EQ(OK, rv);
+ rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
+ callback2.callback());
+ ASSERT_EQ(OK, callback2.GetResult(rv));
- LoadTimingInfo load_timing_info2;
- EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
- TestLoadTimingReused(load_timing_info2);
- // The load timing after restart should have the same socket ID, and times
- // those of the first load timing.
- EXPECT_LE(load_timing_info1.receive_headers_end,
- load_timing_info2.send_start);
- EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
+ LoadTimingInfo load_timing_info2;
+ EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
+ TestLoadTimingReused(load_timing_info2);
+ // The load timing after restart should have the same socket ID, and times
+ // those of the first load timing.
+ EXPECT_LE(load_timing_info1.receive_headers_end,
+ load_timing_info2.send_start);
+ EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
- response = trans->GetResponseInfo();
- ASSERT_TRUE(response != NULL);
- EXPECT_TRUE(response->auth_challenge.get() == NULL);
- EXPECT_EQ(5, response->headers->GetContentLength());
+ response = trans->GetResponseInfo();
+ ASSERT_TRUE(response);
+ EXPECT_FALSE(response->auth_challenge);
+ EXPECT_EQ(5, response->headers->GetContentLength());
- std::string response_data;
- rv = ReadTransaction(trans.get(), &response_data);
- EXPECT_EQ(OK, rv);
+ std::string response_data;
+ EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
- int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
- EXPECT_EQ(writes_size1, trans->GetTotalSentBytes());
- int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
- EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
+ int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
+ EXPECT_EQ(writes_size, trans->GetTotalSentBytes());
+ int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
+ EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes());
+ }
}
// Test the request-challenge-retry sequence for basic auth, over a keep-alive
@@ -5969,9 +5988,6 @@ TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
- scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
-
MockRead data_reads[] = {
MockRead("HTTP/1.1 204 No Content\r\n"
"Content-Length: 0\r\n"
@@ -5983,6 +5999,11 @@ TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
session_deps_.socket_factory->AddSocketDataProvider(&data);
+ // Transaction must be created after the MockReads, so it's destroyed before
+ // them.
+ scoped_ptr<HttpTransaction> trans(
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
+
TestCompletionCallback callback;
int rv = trans->Start(&request, callback.callback(), BoundNetLog());
@@ -10505,13 +10526,15 @@ TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
- StaticSocketDataProvider hanging_socket(
- NULL, 0, NULL, 0);
- hanging_socket.set_connect_data(never_finishing_connect);
+ StaticSocketDataProvider hanging_socket1(NULL, 0, NULL, 0);
+ hanging_socket1.set_connect_data(never_finishing_connect);
// Socket 2 and 3 are the hanging Alternate-Protocol and
// non-Alternate-Protocol jobs from the 2nd transaction.
- session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
- session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
+ session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
+
+ StaticSocketDataProvider hanging_socket2(NULL, 0, NULL, 0);
+ hanging_socket2.set_connect_data(never_finishing_connect);
+ session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
SSLSocketDataProvider ssl(ASYNC, OK);
ssl.SetNextProto(GetProtocol());
@@ -10544,7 +10567,9 @@ TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
// Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
- session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
+ StaticSocketDataProvider hanging_socket3(NULL, 0, NULL, 0);
+ hanging_socket3.set_connect_data(never_finishing_connect);
+ session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
TestCompletionCallback callback1;
@@ -10633,7 +10658,9 @@ TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
&hanging_alternate_protocol_socket);
// 2nd request is just a copy of the first one, over HTTP again.
- session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
+ StaticSocketDataProvider second_transaction(data_reads, arraysize(data_reads),
+ NULL, 0);
+ session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
TestCompletionCallback callback;
@@ -11287,7 +11314,6 @@ TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
request.load_flags = 0;
scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
- HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
@@ -11329,6 +11355,10 @@ TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
data_providers.back());
}
+ // Transaction must be created after DataProviders, so it's destroyed before
+ // they are as well.
+ HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
+
for (int round = 0; round < test_config.num_auth_rounds; ++round) {
const TestRound& read_write_round = test_config.rounds[round];
// Start or restart the transaction.
diff --git a/net/http/http_stream_parser_unittest.cc b/net/http/http_stream_parser_unittest.cc
index fbe964d..77da8b2 100644
--- a/net/http/http_stream_parser_unittest.cc
+++ b/net/http/http_stream_parser_unittest.cc
@@ -52,7 +52,6 @@ scoped_ptr<ClientSocketHandle> CreateConnectedSocketHandle(
scoped_ptr<MockTCPClientSocket> socket(
new MockTCPClientSocket(net::AddressList(), nullptr, data));
- data->set_socket(socket.get());
TestCompletionCallback callback;
EXPECT_EQ(OK, socket->Connect(callback.callback()));
diff --git a/net/socket/socket_test_util.cc b/net/socket/socket_test_util.cc
index 93fcf3d..f4974ac 100644
--- a/net/socket/socket_test_util.cc
+++ b/net/socket/socket_test_util.cc
@@ -143,6 +143,29 @@ MockConnect::MockConnect(IoMode io_mode, int r, IPEndPoint addr) :
MockConnect::~MockConnect() {}
+bool SocketDataProvider::IsIdle() const {
+ return true;
+}
+
+void SocketDataProvider::Initialize(AsyncSocket* socket) {
+ CHECK(!socket_);
+ CHECK(socket);
+ socket_ = socket;
+ Reset();
+}
+
+void SocketDataProvider::DetachSocket() {
+ CHECK(socket_);
+ socket_ = nullptr;
+}
+
+SocketDataProvider::SocketDataProvider() : socket_(nullptr) {}
+
+SocketDataProvider::~SocketDataProvider() {
+ if (socket_)
+ socket_->OnDataProviderDestroyed();
+}
+
StaticSocketDataHelper::StaticSocketDataHelper(MockRead* reads,
size_t reads_count,
MockWrite* writes,
@@ -247,10 +270,6 @@ MockWriteResult StaticSocketDataProvider::OnWrite(const std::string& data) {
return MockWriteResult(next_write.mode, result);
}
-void StaticSocketDataProvider::Reset() {
- helper_.Reset();
-}
-
bool StaticSocketDataProvider::AllReadDataConsumed() const {
return helper_.AllReadDataConsumed();
}
@@ -259,6 +278,10 @@ bool StaticSocketDataProvider::AllWriteDataConsumed() const {
return helper_.AllWriteDataConsumed();
}
+void StaticSocketDataProvider::Reset() {
+ helper_.Reset();
+}
+
SSLSocketDataProvider::SSLSocketDataProvider(IoMode mode, int result)
: connect(mode, result),
next_proto_status(SSLClientSocket::kNextProtoUnsupported),
@@ -288,6 +311,7 @@ SequencedSocketData::SequencedSocketData(MockRead* reads,
sequence_number_(0),
read_state_(IDLE),
write_state_(IDLE),
+ busy_before_sync_reads_(false),
weak_factory_(this) {
// Check that reads and writes have a contiguous set of sequence numbers
// starting from 0 and working their way up, with no repeats and skipping
@@ -411,14 +435,6 @@ MockWriteResult SequencedSocketData::OnWrite(const std::string& data) {
return MockWriteResult(SYNCHRONOUS, ERR_IO_PENDING);
}
-void SequencedSocketData::Reset() {
- helper_.Reset();
- sequence_number_ = 0;
- read_state_ = IDLE;
- write_state_ = IDLE;
- weak_factory_.InvalidateWeakPtrs();
-}
-
bool SequencedSocketData::AllReadDataConsumed() const {
return helper_.AllReadDataConsumed();
}
@@ -427,6 +443,20 @@ bool SequencedSocketData::AllWriteDataConsumed() const {
return helper_.AllWriteDataConsumed();
}
+bool SequencedSocketData::IsIdle() const {
+ // If |busy_before_sync_reads_| is not set, always considered idle. If
+ // no reads left, or the next operation is a write, also consider it idle.
+ if (!busy_before_sync_reads_ || helper_.AllReadDataConsumed() ||
+ helper_.PeekRead().sequence_number != sequence_number_) {
+ return true;
+ }
+
+ // If the next operation is synchronous read, treat the socket as not idle.
+ if (helper_.PeekRead().mode == SYNCHRONOUS)
+ return false;
+ return true;
+}
+
bool SequencedSocketData::IsReadPaused() {
return read_state_ == PAUSED;
}
@@ -486,6 +516,14 @@ void SequencedSocketData::MaybePostWriteCompleteTask() {
write_state_ = COMPLETING;
}
+void SequencedSocketData::Reset() {
+ helper_.Reset();
+ sequence_number_ = 0;
+ read_state_ = IDLE;
+ write_state_ = IDLE;
+ weak_factory_.InvalidateWeakPtrs();
+}
+
void SequencedSocketData::OnReadComplete() {
CHECK_EQ(COMPLETING, read_state_);
NET_TRACE(1, " *** ") << "Completing read for: " << sequence_number_;
@@ -777,7 +815,6 @@ MockClientSocketFactory::CreateDatagramClientSocket(
SocketDataProvider* data_provider = mock_data_.GetNext();
scoped_ptr<MockUDPClientSocket> socket(
new MockUDPClientSocket(data_provider, net_log));
- data_provider->set_socket(socket.get());
if (bind_type == DatagramSocket::RANDOM_BIND)
socket->set_source_port(static_cast<uint16>(rand_int_cb.Run(1025, 65535)));
return socket.Pass();
@@ -790,7 +827,6 @@ scoped_ptr<StreamSocket> MockClientSocketFactory::CreateTransportClientSocket(
SocketDataProvider* data_provider = mock_data_.GetNext();
scoped_ptr<MockTCPClientSocket> socket(
new MockTCPClientSocket(addresses, net_log, data_provider));
- data_provider->set_socket(socket.get());
return socket.Pass();
}
@@ -937,14 +973,17 @@ MockTCPClientSocket::MockTCPClientSocket(const AddressList& addresses,
was_used_to_convey_data_(false) {
DCHECK(data_);
peer_addr_ = data->connect_data().peer_addr;
- data_->Reset();
+ data_->Initialize(this);
}
-MockTCPClientSocket::~MockTCPClientSocket() {}
+MockTCPClientSocket::~MockTCPClientSocket() {
+ if (data_)
+ data_->DetachSocket();
+}
int MockTCPClientSocket::Read(IOBuffer* buf, int buf_len,
const CompletionCallback& callback) {
- if (!connected_)
+ if (!connected_ || !data_)
return ERR_UNEXPECTED;
// If the buffer is already in use, a read is already in progress!
@@ -986,7 +1025,7 @@ int MockTCPClientSocket::Write(IOBuffer* buf, int buf_len,
DCHECK(buf);
DCHECK_GT(buf_len, 0);
- if (!connected_)
+ if (!connected_ || !data_)
return ERR_UNEXPECTED;
std::string data(buf->data(), buf_len);
@@ -1024,6 +1063,9 @@ void MockTCPClientSocket::AddConnectionAttempts(
}
int MockTCPClientSocket::Connect(const CompletionCallback& callback) {
+ if (!data_)
+ return ERR_UNEXPECTED;
+
if (connected_)
return OK;
connected_ = true;
@@ -1055,11 +1097,15 @@ void MockTCPClientSocket::Disconnect() {
}
bool MockTCPClientSocket::IsConnected() const {
+ if (!data_)
+ return false;
return connected_ && !peer_closed_connection_;
}
bool MockTCPClientSocket::IsConnectedAndIdle() const {
- return IsConnected();
+ if (!data_)
+ return false;
+ return IsConnected() && data_->IsIdle();
}
int MockTCPClientSocket::GetPeerAddress(IPEndPoint* address) const {
@@ -1087,6 +1133,10 @@ bool MockTCPClientSocket::GetSSLInfo(SSLInfo* ssl_info) {
}
void MockTCPClientSocket::OnReadComplete(const MockRead& data) {
+ // If |data_| has been destroyed, safest to just do nothing.
+ if (!data_)
+ return;
+
// There must be a read pending.
DCHECK(pending_read_buf_.get());
// You can't complete a read with another ERR_IO_PENDING status code.
@@ -1107,6 +1157,10 @@ void MockTCPClientSocket::OnReadComplete(const MockRead& data) {
}
void MockTCPClientSocket::OnWriteComplete(int rv) {
+ // If |data_| has been destroyed, safest to just do nothing.
+ if (!data_)
+ return;
+
// There must be a read pending.
DCHECK(!pending_write_callback_.is_null());
CompletionCallback callback = pending_write_callback_;
@@ -1114,10 +1168,18 @@ void MockTCPClientSocket::OnWriteComplete(int rv) {
}
void MockTCPClientSocket::OnConnectComplete(const MockConnect& data) {
+ // If |data_| has been destroyed, safest to just do nothing.
+ if (!data_)
+ return;
+
CompletionCallback callback = pending_connect_callback_;
RunCallback(callback, data.result);
}
+void MockTCPClientSocket::OnDataProviderDestroyed() {
+ data_ = nullptr;
+}
+
int MockTCPClientSocket::CompleteRead() {
DCHECK(pending_read_buf_.get());
DCHECK(pending_read_buf_len_ > 0);
@@ -1503,6 +1565,10 @@ bool MockSSLClientSocket::IsConnected() const {
return transport_->socket()->IsConnected();
}
+bool MockSSLClientSocket::IsConnectedAndIdle() const {
+ return transport_->socket()->IsConnectedAndIdle();
+}
+
bool MockSSLClientSocket::WasEverUsed() const {
return transport_->socket()->WasEverUsed();
}
@@ -1571,16 +1637,19 @@ MockUDPClientSocket::MockUDPClientSocket(SocketDataProvider* data,
net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_NONE)),
weak_factory_(this) {
DCHECK(data_);
- data_->Reset();
+ data_->Initialize(this);
peer_addr_ = data->connect_data().peer_addr;
}
-MockUDPClientSocket::~MockUDPClientSocket() {}
+MockUDPClientSocket::~MockUDPClientSocket() {
+ if (data_)
+ data_->DetachSocket();
+}
int MockUDPClientSocket::Read(IOBuffer* buf,
int buf_len,
const CompletionCallback& callback) {
- if (!connected_)
+ if (!connected_ || !data_)
return ERR_UNEXPECTED;
// If the buffer is already in use, a read is already in progress!
@@ -1611,7 +1680,7 @@ int MockUDPClientSocket::Write(IOBuffer* buf, int buf_len,
DCHECK(buf);
DCHECK_GT(buf_len, 0);
- if (!connected_)
+ if (!connected_ || !data_)
return ERR_UNEXPECTED;
std::string data(buf->data(), buf_len);
@@ -1665,12 +1734,17 @@ int MockUDPClientSocket::BindToNetwork(
}
int MockUDPClientSocket::Connect(const IPEndPoint& address) {
+ if (!data_)
+ return ERR_UNEXPECTED;
connected_ = true;
peer_addr_ = address;
return data_->connect_data().result;
}
void MockUDPClientSocket::OnReadComplete(const MockRead& data) {
+ if (!data_)
+ return;
+
// There must be a read pending.
DCHECK(pending_read_buf_.get());
// You can't complete a read with another ERR_IO_PENDING status code.
@@ -1691,6 +1765,9 @@ void MockUDPClientSocket::OnReadComplete(const MockRead& data) {
}
void MockUDPClientSocket::OnWriteComplete(int rv) {
+ if (!data_)
+ return;
+
// There must be a read pending.
DCHECK(!pending_write_callback_.is_null());
CompletionCallback callback = pending_write_callback_;
@@ -1701,6 +1778,10 @@ void MockUDPClientSocket::OnConnectComplete(const MockConnect& data) {
NOTIMPLEMENTED();
}
+void MockUDPClientSocket::OnDataProviderDestroyed() {
+ data_ = nullptr;
+}
+
int MockUDPClientSocket::CompleteRead() {
DCHECK(pending_read_buf_.get());
DCHECK(pending_read_buf_len_ > 0);
diff --git a/net/socket/socket_test_util.h b/net/socket/socket_test_util.h
index 430b522..9d4ecfb 100644
--- a/net/socket/socket_test_util.h
+++ b/net/socket/socket_test_util.h
@@ -187,12 +187,13 @@ struct MockWriteResult {
};
// The SocketDataProvider is an interface used by the MockClientSocket
-// for getting data about individual reads and writes on the socket.
+// for getting data about individual reads and writes on the socket. Can be
+// used with at most one socket at a time.
+// TODO(mmenke): Do these really need to be re-useable?
class SocketDataProvider {
public:
- SocketDataProvider() : socket_(NULL) {}
-
- virtual ~SocketDataProvider() {}
+ SocketDataProvider();
+ virtual ~SocketDataProvider();
// Returns the buffer and result code for the next simulated read.
// If the |MockRead.result| is ERR_IO_PENDING, it informs the caller
@@ -200,18 +201,32 @@ class SocketDataProvider {
// function at a later time.
virtual MockRead OnRead() = 0;
virtual MockWriteResult OnWrite(const std::string& data) = 0;
- virtual void Reset() = 0;
virtual bool AllReadDataConsumed() const = 0;
virtual bool AllWriteDataConsumed() const = 0;
+ // Returns true if the request should be considered idle, for the purposes of
+ // IsConnectedAndIdle.
+ virtual bool IsIdle() const;
+
+ // Initializes the SocketDataProvider for use with |socket|. Must be called
+ // before use
+ void Initialize(AsyncSocket* socket);
+ // Detaches the socket associated with a SocketDataProvider. Must be called
+ // before |socket_| is destroyed, unless the SocketDataProvider has informed
+ // |socket_| it was destroyed. Must also be called before Initialize() may
+ // be called again with a new socket.
+ void DetachSocket();
+
// Accessor for the socket which is using the SocketDataProvider.
AsyncSocket* socket() { return socket_; }
- void set_socket(AsyncSocket* socket) { socket_ = socket; }
MockConnect connect_data() const { return connect_; }
void set_connect_data(const MockConnect& connect) { connect_ = connect; }
private:
+ // Called to inform subclasses of initialization.
+ virtual void Reset() = 0;
+
MockConnect connect_;
AsyncSocket* socket_;
@@ -235,6 +250,11 @@ class AsyncSocket {
// is called to complete the asynchronous read operation.
virtual void OnWriteComplete(int rv) = 0;
virtual void OnConnectComplete(const MockConnect& data) = 0;
+
+ // Called when the SocketDataProvider associated with the socket is destroyed.
+ // The socket may continue to be used after the data provider is destroyed,
+ // so it should be sure not to dereference the provider after this is called.
+ virtual void OnDataProviderDestroyed() = 0;
};
// StaticSocketDataHelper manages a list of reads and writes.
@@ -295,10 +315,9 @@ class StaticSocketDataProvider : public SocketDataProvider {
virtual void CompleteRead() {}
- // SocketDataProvider implementation.
+ // From SocketDataProvider:
MockRead OnRead() override;
MockWriteResult OnWrite(const std::string& data) override;
- void Reset() override;
bool AllReadDataConsumed() const override;
bool AllWriteDataConsumed() const override;
@@ -307,10 +326,10 @@ class StaticSocketDataProvider : public SocketDataProvider {
size_t read_count() const { return helper_.read_count(); }
size_t write_count() const { return helper_.write_count(); }
- protected:
- StaticSocketDataHelper* helper() { return &helper_; }
-
private:
+ // From SocketDataProvider:
+ void Reset() override;
+
StaticSocketDataHelper helper_;
DISALLOW_COPY_AND_ASSIGN(StaticSocketDataProvider);
@@ -358,16 +377,26 @@ class SequencedSocketData : public SocketDataProvider {
~SequencedSocketData() override;
- // SocketDataProviderBase implementation.
+ // From SocketDataProvider:
MockRead OnRead() override;
MockWriteResult OnWrite(const std::string& data) override;
- void Reset() override;
bool AllReadDataConsumed() const override;
bool AllWriteDataConsumed() const override;
+ bool IsIdle() const override;
bool IsReadPaused();
void CompleteRead();
+ // When true, IsConnectedAndIdle() will return false if the next event in the
+ // sequence is a synchronous. Otherwise, the socket claims to be idle as
+ // long as it's connected. Defaults to false.
+ // TODO(mmenke): See if this can be made the default behavior, and consider
+ // removing this mehtod. Need to make sure it doesn't change what code any
+ // tests are targetted at testing.
+ void set_busy_before_sync_reads(bool busy_before_sync_reads) {
+ busy_before_sync_reads_ = busy_before_sync_reads;
+ }
+
private:
// Defines the state for the read or write path.
enum IoState {
@@ -378,6 +407,9 @@ class SequencedSocketData : public SocketDataProvider {
PAUSED, // IO is paused until CompleteRead() is called.
};
+ // From SocketDataProvider:
+ void Reset() override;
+
void OnReadComplete();
void OnWriteComplete();
@@ -389,6 +421,8 @@ class SequencedSocketData : public SocketDataProvider {
IoState read_state_;
IoState write_state_;
+ bool busy_before_sync_reads_;
+
base::WeakPtrFactory<SequencedSocketData> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(SequencedSocketData);
@@ -717,6 +751,7 @@ class MockTCPClientSocket : public MockClientSocket, public AsyncSocket {
void OnReadComplete(const MockRead& data) override;
void OnWriteComplete(int rv) override;
void OnConnectComplete(const MockConnect& data) override;
+ void OnDataProviderDestroyed() override;
private:
int CompleteRead();
@@ -898,6 +933,7 @@ class MockSSLClientSocket : public MockClientSocket, public AsyncSocket {
int Connect(const CompletionCallback& callback) override;
void Disconnect() override;
bool IsConnected() const override;
+ bool IsConnectedAndIdle() const override;
bool WasEverUsed() const override;
bool UsingTCPFastOpen() const override;
int GetPeerAddress(IPEndPoint* address) const override;
@@ -911,6 +947,10 @@ class MockSSLClientSocket : public MockClientSocket, public AsyncSocket {
void OnReadComplete(const MockRead& data) override;
void OnWriteComplete(int rv) override;
void OnConnectComplete(const MockConnect& data) override;
+ // SSL sockets don't need magic to deal with destruction of their data
+ // provider.
+ // TODO(mmenke): Probably a good idea to support it, anyways.
+ void OnDataProviderDestroyed() override {}
ChannelIDService* GetChannelIDService() const override;
@@ -954,6 +994,7 @@ class MockUDPClientSocket : public DatagramClientSocket, public AsyncSocket {
void OnReadComplete(const MockRead& data) override;
void OnWriteComplete(int rv) override;
void OnConnectComplete(const MockConnect& data) override;
+ void OnDataProviderDestroyed() override;
void set_source_port(uint16 port) { source_port_ = port;}
diff --git a/net/spdy/spdy_network_transaction_unittest.cc b/net/spdy/spdy_network_transaction_unittest.cc
index 8a54d72..d79f003 100644
--- a/net/spdy/spdy_network_transaction_unittest.cc
+++ b/net/spdy/spdy_network_transaction_unittest.cc
@@ -901,7 +901,8 @@ TEST_P(SpdyNetworkTransactionTest, ThreeGets) {
MockRead(ASYNC, 0, 12), // EOF
};
SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes));
- SequencedSocketData data_placeholder(NULL, 0, NULL, 0);
+ SequencedSocketData data_placeholder1(NULL, 0, NULL, 0);
+ SequencedSocketData data_placeholder2(NULL, 0, NULL, 0);
BoundNetLog log;
TransactionHelperResult out;
@@ -912,8 +913,8 @@ TEST_P(SpdyNetworkTransactionTest, ThreeGets) {
// We require placeholder data because three get requests are sent out at
// the same time which results in three sockets being connected. The first
// on will negotiate SPDY and will be used for all requests.
- helper.AddData(&data_placeholder);
- helper.AddData(&data_placeholder);
+ helper.AddData(&data_placeholder1);
+ helper.AddData(&data_placeholder2);
scoped_ptr<HttpNetworkTransaction> trans1(
new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session()));
scoped_ptr<HttpNetworkTransaction> trans2(
@@ -3550,7 +3551,6 @@ TEST_P(SpdyNetworkTransactionTest, DecompressFailureOnSynReply) {
helper.RunToCompletion(&data);
TransactionHelperResult out = helper.output();
EXPECT_EQ(ERR_SPDY_COMPRESSION_ERROR, out.rv);
- data.Reset();
}
// Test that the NetLog contains good data for a simple GET request.
diff --git a/net/spdy/spdy_session_pool_unittest.cc b/net/spdy/spdy_session_pool_unittest.cc
index 5543245..dd1e3ba 100644
--- a/net/spdy/spdy_session_pool_unittest.cc
+++ b/net/spdy/spdy_session_pool_unittest.cc
@@ -143,9 +143,9 @@ TEST_P(SpdySessionPoolTest, CloseCurrentIdleSessions) {
session_deps_.host_resolver->set_synchronous_mode(true);
- StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
- data.set_connect_data(connect_data);
- session_deps_.socket_factory->AddSocketDataProvider(&data);
+ StaticSocketDataProvider data1(reads, arraysize(reads), nullptr, 0);
+ data1.set_connect_data(connect_data);
+ session_deps_.socket_factory->AddSocketDataProvider(&data1);
SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
@@ -166,7 +166,9 @@ TEST_P(SpdySessionPoolTest, CloseCurrentIdleSessions) {
ASSERT_TRUE(spdy_stream1.get() != NULL);
// Set up session 2
- session_deps_.socket_factory->AddSocketDataProvider(&data);
+ StaticSocketDataProvider data2(reads, arraysize(reads), nullptr, 0);
+ data2.set_connect_data(connect_data);
+ session_deps_.socket_factory->AddSocketDataProvider(&data2);
const std::string kTestHost2("http://www.b.com");
HostPortPair test_host_port_pair2(kTestHost2, 80);
SpdySessionKey key2(test_host_port_pair2, ProxyServer::Direct(),
@@ -180,7 +182,9 @@ TEST_P(SpdySessionPoolTest, CloseCurrentIdleSessions) {
ASSERT_TRUE(spdy_stream2.get() != NULL);
// Set up session 3
- session_deps_.socket_factory->AddSocketDataProvider(&data);
+ StaticSocketDataProvider data3(reads, arraysize(reads), nullptr, 0);
+ data3.set_connect_data(connect_data);
+ session_deps_.socket_factory->AddSocketDataProvider(&data3);
const std::string kTestHost3("http://www.c.com");
HostPortPair test_host_port_pair3(kTestHost3, 80);
SpdySessionKey key3(test_host_port_pair3, ProxyServer::Direct(),
@@ -363,9 +367,9 @@ void SpdySessionPoolTest::RunIPPoolingTest(
MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
};
- StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
- data.set_connect_data(connect_data);
- session_deps_.socket_factory->AddSocketDataProvider(&data);
+ StaticSocketDataProvider data1(reads, arraysize(reads), NULL, 0);
+ data1.set_connect_data(connect_data);
+ session_deps_.socket_factory->AddSocketDataProvider(&data1);
SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
@@ -395,7 +399,9 @@ void SpdySessionPoolTest::RunIPPoolingTest(
EXPECT_FALSE(HasSpdySession(spdy_session_pool_, test_hosts[2].key));
// Create a new session to host 2.
- session_deps_.socket_factory->AddSocketDataProvider(&data);
+ StaticSocketDataProvider data2(reads, arraysize(reads), NULL, 0);
+ data2.set_connect_data(connect_data);
+ session_deps_.socket_factory->AddSocketDataProvider(&data2);
base::WeakPtr<SpdySession> session2 = CreateInsecureSpdySession(
http_session_.get(), test_hosts[2].key, BoundNetLog());
@@ -523,10 +529,10 @@ TEST_P(SpdySessionPoolTest, IPAddressChanged) {
spdy_util.ConstructSpdyGet("http://www.a.com", false, 1, MEDIUM));
MockWrite writes[] = {CreateMockWrite(*req, 1)};
- StaticSocketDataProvider data(reads, arraysize(reads), writes,
- arraysize(writes));
- data.set_connect_data(connect_data);
- session_deps_.socket_factory->AddSocketDataProvider(&data);
+ StaticSocketDataProvider dataA(reads, arraysize(reads), writes,
+ arraysize(writes));
+ dataA.set_connect_data(connect_data);
+ session_deps_.socket_factory->AddSocketDataProvider(&dataA);
SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
@@ -534,7 +540,6 @@ TEST_P(SpdySessionPoolTest, IPAddressChanged) {
CreateNetworkSession();
// Set up session A: Going away, but with an active stream.
- session_deps_.socket_factory->AddSocketDataProvider(&data);
const std::string kTestHostA("http://www.a.com");
HostPortPair test_host_port_pairA(kTestHostA, 80);
SpdySessionKey keyA(
@@ -561,6 +566,10 @@ TEST_P(SpdySessionPoolTest, IPAddressChanged) {
EXPECT_FALSE(delegateA.StreamIsClosed());
// Set up session B: Available, with a created stream.
+ StaticSocketDataProvider dataB(reads, arraysize(reads), writes,
+ arraysize(writes));
+ dataB.set_connect_data(connect_data);
+ session_deps_.socket_factory->AddSocketDataProvider(&dataB);
const std::string kTestHostB("http://www.b.com");
HostPortPair test_host_port_pairB(kTestHostB, 80);
SpdySessionKey keyB(
@@ -576,7 +585,10 @@ TEST_P(SpdySessionPoolTest, IPAddressChanged) {
spdy_streamB->SetDelegate(&delegateB);
// Set up session C: Draining.
- session_deps_.socket_factory->AddSocketDataProvider(&data);
+ StaticSocketDataProvider dataC(reads, arraysize(reads), writes,
+ arraysize(writes));
+ dataC.set_connect_data(connect_data);
+ session_deps_.socket_factory->AddSocketDataProvider(&dataC);
const std::string kTestHostC("http://www.c.com");
HostPortPair test_host_port_pairC(kTestHostC, 80);
SpdySessionKey keyC(
diff --git a/net/url_request/url_request_http_job_unittest.cc b/net/url_request/url_request_http_job_unittest.cc
index dca3e8e..b4175ae 100644
--- a/net/url_request/url_request_http_job_unittest.cc
+++ b/net/url_request/url_request_http_job_unittest.cc
@@ -414,11 +414,23 @@ TEST_F(URLRequestHttpJobWithMockSocketsTest, BackoffHeaderUserGesture) {
"Connection: keep-alive\r\n"
"User-Agent:\r\n"
"Accept-Encoding: gzip, deflate\r\n"
- "Accept-Language: en-us,fr\r\n\r\n")};
- MockRead reads[] = {MockRead("HTTP/1.1 200 OK\r\n"
- "Backoff: 3600\r\n"
- "Content-Length: 9\r\n\r\n"),
- MockRead("test.html")};
+ "Accept-Language: en-us,fr\r\n\r\n"),
+ MockWrite("GET / HTTP/1.1\r\n"
+ "Host: www.example.com\r\n"
+ "Connection: keep-alive\r\n"
+ "User-Agent:\r\n"
+ "Accept-Encoding: gzip, deflate\r\n"
+ "Accept-Language: en-us,fr\r\n\r\n"),
+ };
+ MockRead reads[] = {
+ MockRead("HTTP/1.1 200 OK\r\n"
+ "Backoff: 3600\r\n"
+ "Content-Length: 9\r\n\r\n"),
+ MockRead("test.html"), MockRead("HTTP/1.1 200 OK\r\n"
+ "Backoff: 3600\r\n"
+ "Content-Length: 9\r\n\r\n"),
+ MockRead("test.html"),
+ };
net::SSLSocketDataProvider ssl_socket_data_provider(net::ASYNC, net::OK);
ssl_socket_data_provider.SetNextProto(kProtoHTTP11);
@@ -445,9 +457,6 @@ TEST_F(URLRequestHttpJobWithMockSocketsTest, BackoffHeaderUserGesture) {
EXPECT_EQ(1, delegate1.received_before_network_start_count());
EXPECT_EQ(1, manager_.GetNumberOfEntriesForTests());
- // Reset socket data provider to replay socket data.
- socket_data.Reset();
-
// Issue a user-initiated request, backoff logic should not apply.
TestDelegate delegate2;
scoped_ptr<URLRequest> request2 =