| Index: net/http/http_pipelined_network_transaction_unittest.cc
|
| diff --git a/net/http/http_pipelined_network_transaction_unittest.cc b/net/http/http_pipelined_network_transaction_unittest.cc
|
| index c4e42a0fa16edbc6a6cc4ce193d20b0c251aef3a..5bbfc67c46f74f37e03f46d9412ba73aa76a444d 100644
|
| --- a/net/http/http_pipelined_network_transaction_unittest.cc
|
| +++ b/net/http/http_pipelined_network_transaction_unittest.cc
|
| @@ -52,6 +52,9 @@ class HttpPipelinedNetworkTransactionTest : public testing::Test {
|
| }
|
|
|
| void Initialize() {
|
| + // Normally, this code could just go in SetUp(). For a few of these tests,
|
| + // we change the default number of sockets per group. That needs to be done
|
| + // before we construct the HttpNetworkSession.
|
| proxy_service_.reset(ProxyService::CreateDirect());
|
| ssl_config_ = new SSLConfigServiceDefaults;
|
| auth_handler_factory_.reset(new HttpAuthHandlerMock::Factory());
|
| @@ -78,7 +81,7 @@ class HttpPipelinedNetworkTransactionTest : public testing::Test {
|
| data_vector_.push_back(data);
|
| }
|
|
|
| - const HttpRequestInfo* GetRequestInfo(const char* filename) {
|
| + HttpRequestInfo* GetRequestInfo(const char* filename) {
|
| std::string url = StringPrintf("http://localhost/%s", filename);
|
| HttpRequestInfo* request_info = new HttpRequestInfo;
|
| request_info->url = GURL(url);
|
| @@ -88,11 +91,19 @@ class HttpPipelinedNetworkTransactionTest : public testing::Test {
|
| }
|
|
|
| void ExpectResponse(const std::string& expected,
|
| - HttpNetworkTransaction& transaction) {
|
| + HttpNetworkTransaction& transaction,
|
| + bool async) {
|
| scoped_refptr<IOBuffer> buffer(new IOBuffer(expected.size()));
|
| - EXPECT_EQ(static_cast<int>(expected.size()),
|
| - transaction.Read(buffer.get(), expected.size(),
|
| - callback_.callback()));
|
| + if (async) {
|
| + EXPECT_EQ(ERR_IO_PENDING, transaction.Read(buffer.get(), expected.size(),
|
| + callback_.callback()));
|
| + data_vector_[0]->RunFor(1);
|
| + EXPECT_EQ(static_cast<int>(expected.length()), callback_.WaitForResult());
|
| + } else {
|
| + EXPECT_EQ(static_cast<int>(expected.size()),
|
| + transaction.Read(buffer.get(), expected.size(),
|
| + callback_.callback()));
|
| + }
|
| std::string actual(buffer->data(), expected.size());
|
| EXPECT_THAT(actual, StrEq(expected));
|
| EXPECT_EQ(OK, transaction.Read(buffer.get(), expected.size(),
|
| @@ -130,7 +141,7 @@ class HttpPipelinedNetworkTransactionTest : public testing::Test {
|
| one_read_callback.callback()));
|
|
|
| EXPECT_EQ(OK, two_callback.WaitForResult());
|
| - ExpectResponse("two.html", two_transaction);
|
| + ExpectResponse("two.html", two_transaction, false);
|
| }
|
|
|
| void CompleteFourRequests() {
|
| @@ -161,15 +172,15 @@ class HttpPipelinedNetworkTransactionTest : public testing::Test {
|
| four_transaction.Start(GetRequestInfo("four.html"),
|
| four_callback.callback(), BoundNetLog()));
|
|
|
| - ExpectResponse("one.html", *one_transaction.get());
|
| + ExpectResponse("one.html", *one_transaction.get(), false);
|
| EXPECT_EQ(OK, two_callback.WaitForResult());
|
| - ExpectResponse("two.html", two_transaction);
|
| + ExpectResponse("two.html", two_transaction, false);
|
| EXPECT_EQ(OK, three_callback.WaitForResult());
|
| - ExpectResponse("three.html", three_transaction);
|
| + ExpectResponse("three.html", three_transaction, false);
|
|
|
| one_transaction.reset();
|
| EXPECT_EQ(OK, four_callback.WaitForResult());
|
| - ExpectResponse("four.html", four_transaction);
|
| + ExpectResponse("four.html", four_transaction, false);
|
| }
|
|
|
| DeterministicMockClientSocketFactory factory_;
|
| @@ -208,7 +219,7 @@ TEST_F(HttpPipelinedNetworkTransactionTest, OneRequest) {
|
| transaction.Start(GetRequestInfo("test.html"), callback_.callback(),
|
| BoundNetLog()));
|
| EXPECT_EQ(OK, callback_.WaitForResult());
|
| - ExpectResponse("test.html", transaction);
|
| + ExpectResponse("test.html", transaction, false);
|
| }
|
|
|
| TEST_F(HttpPipelinedNetworkTransactionTest, ReusePipeline) {
|
| @@ -385,7 +396,7 @@ TEST_F(HttpPipelinedNetworkTransactionTest, ErrorEvictsToNewPipeline) {
|
| EXPECT_EQ(ERR_FAILED,
|
| one_transaction.Read(buffer.get(), 1, callback_.callback()));
|
| EXPECT_EQ(OK, two_callback.WaitForResult());
|
| - ExpectResponse("two.html", two_transaction);
|
| + ExpectResponse("two.html", two_transaction, false);
|
| }
|
|
|
| TEST_F(HttpPipelinedNetworkTransactionTest, SendErrorEvictsToNewPipeline) {
|
| @@ -424,7 +435,7 @@ TEST_F(HttpPipelinedNetworkTransactionTest, SendErrorEvictsToNewPipeline) {
|
| EXPECT_EQ(ERR_FAILED, one_callback.WaitForResult());
|
|
|
| EXPECT_EQ(OK, two_callback.WaitForResult());
|
| - ExpectResponse("two.html", two_transaction);
|
| + ExpectResponse("two.html", two_transaction, false);
|
| }
|
|
|
| TEST_F(HttpPipelinedNetworkTransactionTest, RedirectDrained) {
|
| @@ -467,7 +478,7 @@ TEST_F(HttpPipelinedNetworkTransactionTest, RedirectDrained) {
|
| data_vector_[0]->SetStop(10);
|
|
|
| EXPECT_EQ(OK, two_callback.WaitForResult());
|
| - ExpectResponse("two.html", two_transaction);
|
| + ExpectResponse("two.html", two_transaction, false);
|
| }
|
|
|
| TEST_F(HttpPipelinedNetworkTransactionTest, BasicHttpAuthentication) {
|
| @@ -513,7 +524,7 @@ TEST_F(HttpPipelinedNetworkTransactionTest, BasicHttpAuthentication) {
|
| AuthCredentials credentials(ASCIIToUTF16("user"), ASCIIToUTF16("pass"));
|
| EXPECT_EQ(OK, transaction.RestartWithAuth(credentials, callback_.callback()));
|
|
|
| - ExpectResponse("one.html", transaction);
|
| + ExpectResponse("one.html", transaction, false);
|
| }
|
|
|
| TEST_F(HttpPipelinedNetworkTransactionTest, OldVersionDisablesPipelining) {
|
| @@ -563,7 +574,7 @@ TEST_F(HttpPipelinedNetworkTransactionTest, OldVersionDisablesPipelining) {
|
| one_transaction.Start(GetRequestInfo("pipelined.html"),
|
| one_callback.callback(), BoundNetLog()));
|
| EXPECT_EQ(OK, one_callback.WaitForResult());
|
| - ExpectResponse("pipelined.html", one_transaction);
|
| + ExpectResponse("pipelined.html", one_transaction, false);
|
|
|
| CompleteTwoRequests(1, 4);
|
| }
|
| @@ -639,9 +650,9 @@ TEST_F(HttpPipelinedNetworkTransactionTest, PipelinesImmediatelyIfKnownGood) {
|
| data_vector_[0]->RunFor(3);
|
| EXPECT_EQ(OK, second_one_callback.WaitForResult());
|
| data_vector_[0]->StopAfter(100);
|
| - ExpectResponse("second-pipeline-one.html", second_one_transaction);
|
| + ExpectResponse("second-pipeline-one.html", second_one_transaction, false);
|
| EXPECT_EQ(OK, second_two_callback.WaitForResult());
|
| - ExpectResponse("second-pipeline-two.html", second_two_transaction);
|
| + ExpectResponse("second-pipeline-two.html", second_two_transaction, false);
|
|
|
| ClientSocketPoolManager::set_max_sockets_per_group(old_max_sockets);
|
| }
|
| @@ -734,9 +745,127 @@ TEST_F(HttpPipelinedNetworkTransactionTest, OpenPipelinesWhileBinding) {
|
| data_vector_[0]->SetStop(10);
|
|
|
| EXPECT_EQ(OK, one_callback.WaitForResult());
|
| - ExpectResponse("one.html", one_transaction);
|
| + ExpectResponse("one.html", one_transaction, false);
|
| + EXPECT_EQ(OK, two_callback.WaitForResult());
|
| + ExpectResponse("two.html", two_transaction, false);
|
| +}
|
| +
|
| +TEST_F(HttpPipelinedNetworkTransactionTest, ForcedPipelineSharesConnection) {
|
| + Initialize();
|
| +
|
| + MockWrite writes[] = {
|
| + MockWrite(true, 0, "GET /one.html HTTP/1.1\r\n"
|
| + "Host: localhost\r\n"
|
| + "Connection: keep-alive\r\n\r\n"
|
| + "GET /two.html HTTP/1.1\r\n"
|
| + "Host: localhost\r\n"
|
| + "Connection: keep-alive\r\n\r\n"),
|
| + };
|
| + MockRead reads[] = {
|
| + MockRead(true, 1, "HTTP/1.1 200 OK\r\n"),
|
| + MockRead(true, 2, "Content-Length: 8\r\n\r\n"),
|
| + MockRead(true, 3, "one.html"),
|
| + MockRead(true, 4, "HTTP/1.1 200 OK\r\n"),
|
| + MockRead(true, 5, "Content-Length: 8\r\n\r\n"),
|
| + MockRead(true, 6, "two.html"),
|
| + };
|
| + AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes));
|
| +
|
| + scoped_ptr<HttpNetworkTransaction> one_transaction(
|
| + new HttpNetworkTransaction(session_.get()));
|
| + TestCompletionCallback one_callback;
|
| + HttpRequestInfo* one_info = GetRequestInfo("one.html");
|
| + one_info->load_flags |= LOAD_FORCE_HTTP_PIPELINING;
|
| + EXPECT_EQ(ERR_IO_PENDING,
|
| + one_transaction->Start(one_info,
|
| + one_callback.callback(), BoundNetLog()));
|
| +
|
| + HttpNetworkTransaction two_transaction(session_.get());
|
| + TestCompletionCallback two_callback;
|
| + HttpRequestInfo* two_info = GetRequestInfo("two.html");
|
| + two_info->load_flags |= LOAD_FORCE_HTTP_PIPELINING;
|
| + EXPECT_EQ(ERR_IO_PENDING,
|
| + two_transaction.Start(two_info,
|
| + two_callback.callback(), BoundNetLog()));
|
| +
|
| + data_vector_[0]->RunFor(3); // Send + 2 lines of headers.
|
| + EXPECT_EQ(OK, one_callback.WaitForResult());
|
| + ExpectResponse("one.html", *one_transaction.get(), true);
|
| + one_transaction.reset();
|
| +
|
| + data_vector_[0]->RunFor(2); // 2 lines of headers.
|
| EXPECT_EQ(OK, two_callback.WaitForResult());
|
| - ExpectResponse("two.html", two_transaction);
|
| + ExpectResponse("two.html", two_transaction, true);
|
| +}
|
| +
|
| +TEST_F(HttpPipelinedNetworkTransactionTest,
|
| + ForcedPipelineConnectionErrorFailsBoth) {
|
| + Initialize();
|
| +
|
| + scoped_refptr<DeterministicSocketData> data(
|
| + new DeterministicSocketData(NULL, 0, NULL, 0));
|
| + data->set_connect_data(MockConnect(ASYNC, ERR_FAILED));
|
| + factory_.AddSocketDataProvider(data);
|
| +
|
| + scoped_ptr<HttpNetworkTransaction> one_transaction(
|
| + new HttpNetworkTransaction(session_.get()));
|
| + TestCompletionCallback one_callback;
|
| + HttpRequestInfo* one_info = GetRequestInfo("one.html");
|
| + one_info->load_flags |= LOAD_FORCE_HTTP_PIPELINING;
|
| + EXPECT_EQ(ERR_IO_PENDING,
|
| + one_transaction->Start(one_info,
|
| + one_callback.callback(), BoundNetLog()));
|
| +
|
| + HttpNetworkTransaction two_transaction(session_.get());
|
| + TestCompletionCallback two_callback;
|
| + HttpRequestInfo* two_info = GetRequestInfo("two.html");
|
| + two_info->load_flags |= LOAD_FORCE_HTTP_PIPELINING;
|
| + EXPECT_EQ(ERR_IO_PENDING,
|
| + two_transaction.Start(two_info,
|
| + two_callback.callback(), BoundNetLog()));
|
| +
|
| + data->Run();
|
| + EXPECT_EQ(ERR_FAILED, one_callback.WaitForResult());
|
| + EXPECT_EQ(ERR_FAILED, two_callback.WaitForResult());
|
| +}
|
| +
|
| +TEST_F(HttpPipelinedNetworkTransactionTest, ForcedPipelineEvictionIsFatal) {
|
| + Initialize();
|
| +
|
| + MockWrite writes[] = {
|
| + MockWrite(true, 0, "GET /one.html HTTP/1.1\r\n"
|
| + "Host: localhost\r\n"
|
| + "Connection: keep-alive\r\n\r\n"
|
| + "GET /two.html HTTP/1.1\r\n"
|
| + "Host: localhost\r\n"
|
| + "Connection: keep-alive\r\n\r\n"),
|
| + };
|
| + MockRead reads[] = {
|
| + MockRead(true, ERR_FAILED, 1),
|
| + };
|
| + AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes));
|
| +
|
| + scoped_ptr<HttpNetworkTransaction> one_transaction(
|
| + new HttpNetworkTransaction(session_.get()));
|
| + TestCompletionCallback one_callback;
|
| + HttpRequestInfo* one_info = GetRequestInfo("one.html");
|
| + one_info->load_flags |= LOAD_FORCE_HTTP_PIPELINING;
|
| + EXPECT_EQ(ERR_IO_PENDING,
|
| + one_transaction->Start(one_info,
|
| + one_callback.callback(), BoundNetLog()));
|
| +
|
| + HttpNetworkTransaction two_transaction(session_.get());
|
| + TestCompletionCallback two_callback;
|
| + HttpRequestInfo* two_info = GetRequestInfo("two.html");
|
| + two_info->load_flags |= LOAD_FORCE_HTTP_PIPELINING;
|
| + EXPECT_EQ(ERR_IO_PENDING,
|
| + two_transaction.Start(two_info,
|
| + two_callback.callback(), BoundNetLog()));
|
| +
|
| + data_vector_[0]->RunFor(2);
|
| + EXPECT_EQ(ERR_FAILED, one_callback.WaitForResult());
|
| + one_transaction.reset();
|
| + EXPECT_EQ(ERR_PIPELINE_EVICTION, two_callback.WaitForResult());
|
| }
|
|
|
| } // anonymous namespace
|
|
|