// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <string>

#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "net/base/address_list.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/base/net_util.h"
#include "net/base/request_priority.h"
#include "net/dns/host_cache.h"
#include "net/dns/mock_host_resolver.h"
#include "net/http/http_auth_handler_mock.h"
#include "net/http/http_network_session.h"
#include "net/http/http_network_transaction.h"
#include "net/http/http_request_info.h"
#include "net/http/http_server_properties_impl.h"
#include "net/proxy/proxy_config_service.h"
#include "net/proxy/proxy_service.h"
#include "net/socket/client_socket_handle.h"
#include "net/socket/client_socket_pool_histograms.h"
#include "net/socket/client_socket_pool_manager.h"
#include "net/socket/socket_test_util.h"
#include "net/ssl/ssl_config_service_defaults.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using testing::StrEq;

namespace net {

namespace {

class SimpleProxyConfigService : public ProxyConfigService {
 public:
  virtual void AddObserver(Observer* observer) OVERRIDE {
    observer_ = observer;
  }

  virtual void RemoveObserver(Observer* observer) OVERRIDE {
    if (observer_ == observer) {
      observer_ = NULL;
    }
  }

  virtual ConfigAvailability GetLatestProxyConfig(
      ProxyConfig* config) OVERRIDE {
    *config = config_;
    return CONFIG_VALID;
  }

  void IncrementConfigId() {
    config_.set_id(config_.id() + 1);
    observer_->OnProxyConfigChanged(config_, ProxyConfigService::CONFIG_VALID);
  }

 private:
  ProxyConfig config_;
  Observer* observer_;
};

class HttpPipelinedNetworkTransactionTest : public testing::Test {
 public:
  HttpPipelinedNetworkTransactionTest()
      : histograms_("a"),
        pool_(1, 1, &histograms_, &factory_) {
  }

  void Initialize(bool force_http_pipelining) {
    // 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_config_service_ = new SimpleProxyConfigService();
    proxy_service_.reset(new ProxyService(proxy_config_service_, NULL, NULL));
    ssl_config_ = new SSLConfigServiceDefaults;
    auth_handler_factory_.reset(new HttpAuthHandlerMock::Factory());

    HttpNetworkSession::Params session_params;
    session_params.client_socket_factory = &factory_;
    session_params.proxy_service = proxy_service_.get();
    session_params.host_resolver = &mock_resolver_;
    session_params.ssl_config_service = ssl_config_.get();
    session_params.http_auth_handler_factory = auth_handler_factory_.get();
    session_params.http_server_properties =
        http_server_properties_.GetWeakPtr();
    session_params.force_http_pipelining = force_http_pipelining;
    session_params.http_pipelining_enabled = true;
    session_ = new HttpNetworkSession(session_params);
  }

  void AddExpectedConnection(MockRead* reads, size_t reads_count,
                             MockWrite* writes, size_t writes_count) {
    DeterministicSocketData* data = new DeterministicSocketData(
        reads, reads_count, writes, writes_count);
    data->set_connect_data(MockConnect(SYNCHRONOUS, OK));
    if (reads_count || writes_count) {
      data->StopAfter(reads_count + writes_count);
    }
    factory_.AddSocketDataProvider(data);
    data_vector_.push_back(data);
  }

  enum RequestInfoOptions {
    REQUEST_DEFAULT,
    REQUEST_MAIN_RESOURCE,
  };

  HttpRequestInfo* GetRequestInfo(
      const char* filename, RequestInfoOptions options = REQUEST_DEFAULT) {
    std::string url = base::StringPrintf("http://localhost/%s", filename);
    HttpRequestInfo* request_info = new HttpRequestInfo;
    request_info->url = GURL(url);
    request_info->method = "GET";
    if (options == REQUEST_MAIN_RESOURCE) {
      request_info->load_flags = LOAD_MAIN_FRAME;
    }
    request_info_vector_.push_back(request_info);
    return request_info;
  }

  void ExpectResponse(const std::string& expected,
                      HttpNetworkTransaction& transaction,
                      IoMode io_mode) {
    scoped_refptr<IOBuffer> buffer(new IOBuffer(expected.size()));
    if (io_mode == 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(),
                                   callback_.callback()));
  }

  void CompleteTwoRequests(int data_index, int stop_at_step) {
    scoped_ptr<HttpNetworkTransaction> one_transaction(
        new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
    TestCompletionCallback one_callback;
    EXPECT_EQ(ERR_IO_PENDING,
              one_transaction->Start(GetRequestInfo("one.html"),
                                     one_callback.callback(), BoundNetLog()));
    EXPECT_EQ(OK, one_callback.WaitForResult());

    HttpNetworkTransaction two_transaction(DEFAULT_PRIORITY, session_.get());
    TestCompletionCallback two_callback;
    EXPECT_EQ(ERR_IO_PENDING,
              two_transaction.Start(GetRequestInfo("two.html"),
                                    two_callback.callback(), BoundNetLog()));

    TestCompletionCallback one_read_callback;
    scoped_refptr<IOBuffer> buffer(new IOBuffer(8));
    EXPECT_EQ(ERR_IO_PENDING,
              one_transaction->Read(buffer.get(), 8,
                                    one_read_callback.callback()));

    data_vector_[data_index]->SetStop(stop_at_step);
    data_vector_[data_index]->Run();
    EXPECT_EQ(8, one_read_callback.WaitForResult());
    data_vector_[data_index]->SetStop(10);
    std::string actual(buffer->data(), 8);
    EXPECT_THAT(actual, StrEq("one.html"));
    EXPECT_EQ(OK, one_transaction->Read(buffer.get(), 8,
                                        one_read_callback.callback()));

    EXPECT_EQ(OK, two_callback.WaitForResult());
    ExpectResponse("two.html", two_transaction, SYNCHRONOUS);
  }

  void CompleteFourRequests(RequestInfoOptions options) {
    scoped_ptr<HttpNetworkTransaction> one_transaction(
        new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
    TestCompletionCallback one_callback;
    EXPECT_EQ(ERR_IO_PENDING,
              one_transaction->Start(GetRequestInfo("one.html", options),
                                     one_callback.callback(), BoundNetLog()));
    EXPECT_EQ(OK, one_callback.WaitForResult());

    HttpNetworkTransaction two_transaction(DEFAULT_PRIORITY, session_.get());
    TestCompletionCallback two_callback;
    EXPECT_EQ(ERR_IO_PENDING,
              two_transaction.Start(GetRequestInfo("two.html", options),
                                    two_callback.callback(), BoundNetLog()));

    HttpNetworkTransaction three_transaction(DEFAULT_PRIORITY, session_.get());
    TestCompletionCallback three_callback;
    EXPECT_EQ(ERR_IO_PENDING,
              three_transaction.Start(GetRequestInfo("three.html", options),
                                      three_callback.callback(),
                                      BoundNetLog()));

    HttpNetworkTransaction four_transaction(DEFAULT_PRIORITY, session_.get());
    TestCompletionCallback four_callback;
    EXPECT_EQ(ERR_IO_PENDING,
              four_transaction.Start(GetRequestInfo("four.html", options),
                                     four_callback.callback(), BoundNetLog()));

    ExpectResponse("one.html", *one_transaction.get(), SYNCHRONOUS);
    EXPECT_EQ(OK, two_callback.WaitForResult());
    ExpectResponse("two.html", two_transaction, SYNCHRONOUS);
    EXPECT_EQ(OK, three_callback.WaitForResult());
    ExpectResponse("three.html", three_transaction, SYNCHRONOUS);

    one_transaction.reset();
    EXPECT_EQ(OK, four_callback.WaitForResult());
    ExpectResponse("four.html", four_transaction, SYNCHRONOUS);
  }

  DeterministicMockClientSocketFactory factory_;
  ClientSocketPoolHistograms histograms_;
  MockTransportClientSocketPool pool_;
  ScopedVector<DeterministicSocketData> data_vector_;
  TestCompletionCallback callback_;
  ScopedVector<HttpRequestInfo> request_info_vector_;

  SimpleProxyConfigService* proxy_config_service_;
  scoped_ptr<ProxyService> proxy_service_;
  MockHostResolver mock_resolver_;
  scoped_refptr<SSLConfigService> ssl_config_;
  scoped_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory_;
  HttpServerPropertiesImpl http_server_properties_;
  scoped_refptr<HttpNetworkSession> session_;
};

TEST_F(HttpPipelinedNetworkTransactionTest, OneRequest) {
  Initialize(false);

  MockWrite writes[] = {
    MockWrite(SYNCHRONOUS, 0, "GET /test.html HTTP/1.1\r\n"
              "Host: localhost\r\n"
              "Connection: keep-alive\r\n\r\n"),
  };
  MockRead reads[] = {
    MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
    MockRead(SYNCHRONOUS, 2, "Content-Length: 9\r\n\r\n"),
    MockRead(SYNCHRONOUS, 3, "test.html"),
  };
  AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes));

  HttpNetworkTransaction transaction(DEFAULT_PRIORITY, session_.get());
  EXPECT_EQ(ERR_IO_PENDING,
            transaction.Start(GetRequestInfo("test.html"), callback_.callback(),
                              BoundNetLog()));
  EXPECT_EQ(OK, callback_.WaitForResult());
  ExpectResponse("test.html", transaction, SYNCHRONOUS);
}

TEST_F(HttpPipelinedNetworkTransactionTest, ReusePipeline) {
  Initialize(false);

  MockWrite writes[] = {
    MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n"
              "Host: localhost\r\n"
              "Connection: keep-alive\r\n\r\n"),
    MockWrite(SYNCHRONOUS, 3, "GET /two.html HTTP/1.1\r\n"
              "Host: localhost\r\n"
              "Connection: keep-alive\r\n\r\n"),
  };
  MockRead reads[] = {
    MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
    MockRead(SYNCHRONOUS, 2, "Content-Length: 8\r\n\r\n"),
    MockRead(ASYNC, 4, "one.html"),
    MockRead(SYNCHRONOUS, 5, "HTTP/1.1 200 OK\r\n"),
    MockRead(SYNCHRONOUS, 6, "Content-Length: 8\r\n\r\n"),
    MockRead(SYNCHRONOUS, 7, "two.html"),
  };
  AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes));

  CompleteTwoRequests(0, 5);
}

TEST_F(HttpPipelinedNetworkTransactionTest, ReusesOnSpaceAvailable) {
  int old_max_sockets = ClientSocketPoolManager::max_sockets_per_group(
      HttpNetworkSession::NORMAL_SOCKET_POOL);
  ClientSocketPoolManager::set_max_sockets_per_group(
      HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
  Initialize(false);

  MockWrite writes[] = {
    MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n"
              "Host: localhost\r\n"
              "Connection: keep-alive\r\n\r\n"),
    MockWrite(SYNCHRONOUS, 4, "GET /two.html HTTP/1.1\r\n"
              "Host: localhost\r\n"
              "Connection: keep-alive\r\n\r\n"),
    MockWrite(SYNCHRONOUS, 7, "GET /three.html HTTP/1.1\r\n"
              "Host: localhost\r\n"
              "Connection: keep-alive\r\n\r\n"),
    MockWrite(SYNCHRONOUS, 12, "GET /four.html HTTP/1.1\r\n"
              "Host: localhost\r\n"
              "Connection: keep-alive\r\n\r\n"),
  };
  MockRead reads[] = {
    MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
    MockRead(SYNCHRONOUS, 2, "Content-Length: 8\r\n\r\n"),
    MockRead(SYNCHRONOUS, 3, "one.html"),
    MockRead(SYNCHRONOUS, 5, "HTTP/1.1 200 OK\r\n"),
    MockRead(SYNCHRONOUS, 6, "Content-Length: 8\r\n\r\n"),
    MockRead(SYNCHRONOUS, 8, "two.html"),
    MockRead(SYNCHRONOUS, 9, "HTTP/1.1 200 OK\r\n"),
    MockRead(SYNCHRONOUS, 10, "Content-Length: 10\r\n\r\n"),
    MockRead(SYNCHRONOUS, 11, "three.html"),
    MockRead(SYNCHRONOUS, 13, "HTTP/1.1 200 OK\r\n"),
    MockRead(SYNCHRONOUS, 14, "Content-Length: 9\r\n\r\n"),
    MockRead(SYNCHRONOUS, 15, "four.html"),
  };
  AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes));

  CompleteFourRequests(REQUEST_DEFAULT);

  ClientSocketPoolManager::set_max_sockets_per_group(
      HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_sockets);
}

TEST_F(HttpPipelinedNetworkTransactionTest, WontPipelineMainResource) {
  int old_max_sockets = ClientSocketPoolManager::max_sockets_per_group(
      HttpNetworkSession::NORMAL_SOCKET_POOL);
  ClientSocketPoolManager::set_max_sockets_per_group(
      HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
  Initialize(false);

  MockWrite writes[] = {
    MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n"
              "Host: localhost\r\n"
              "Connection: keep-alive\r\n\r\n"),
    MockWrite(SYNCHRONOUS, 4, "GET /two.html HTTP/1.1\r\n"
              "Host: localhost\r\n"
              "Connection: keep-alive\r\n\r\n"),
    MockWrite(SYNCHRONOUS, 8, "GET /three.html HTTP/1.1\r\n"
              "Host: localhost\r\n"
              "Connection: keep-alive\r\n\r\n"),
    MockWrite(SYNCHRONOUS, 12, "GET /four.html HTTP/1.1\r\n"
              "Host: localhost\r\n"
              "Connection: keep-alive\r\n\r\n"),
  };
  MockRead reads[] = {
    MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
    MockRead(SYNCHRONOUS, 2, "Content-Length: 8\r\n\r\n"),
    MockRead(SYNCHRONOUS, 3, "one.html"),
    MockRead(SYNCHRONOUS, 5, "HTTP/1.1 200 OK\r\n"),
    MockRead(SYNCHRONOUS, 6, "Content-Length: 8\r\n\r\n"),
    MockRead(SYNCHRONOUS, 7, "two.html"),
    MockRead(SYNCHRONOUS, 9, "HTTP/1.1 200 OK\r\n"),
    MockRead(SYNCHRONOUS, 10, "Content-Length: 10\r\n\r\n"),
    MockRead(SYNCHRONOUS, 11, "three.html"),
    MockRead(SYNCHRONOUS, 13, "HTTP/1.1 200 OK\r\n"),
    MockRead(SYNCHRONOUS, 14, "Content-Length: 9\r\n\r\n"),
    MockRead(SYNCHRONOUS, 15, "four.html"),
  };
  AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes));

  CompleteFourRequests(REQUEST_MAIN_RESOURCE);

  ClientSocketPoolManager::set_max_sockets_per_group(
      HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_sockets);
}

TEST_F(HttpPipelinedNetworkTransactionTest, UnknownSizeEvictsToNewPipeline) {
  Initialize(false);

  MockWrite writes[] = {
    MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n"
              "Host: localhost\r\n"
              "Connection: keep-alive\r\n\r\n"),
  };
  MockRead reads[] = {
    MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n\r\n"),
    MockRead(ASYNC, 2, "one.html"),
    MockRead(SYNCHRONOUS, OK, 3),
  };
  AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes));

  MockWrite writes2[] = {
    MockWrite(SYNCHRONOUS, 0, "GET /two.html HTTP/1.1\r\n"
              "Host: localhost\r\n"
              "Connection: keep-alive\r\n\r\n"),
  };
  MockRead reads2[] = {
    MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
    MockRead(SYNCHRONOUS, 2, "Content-Length: 8\r\n\r\n"),
    MockRead(SYNCHRONOUS, 3, "two.html"),
  };
  AddExpectedConnection(reads2, arraysize(reads2), writes2, arraysize(writes2));

  CompleteTwoRequests(0, 3);
}

TEST_F(HttpPipelinedNetworkTransactionTest, ConnectionCloseEvictToNewPipeline) {
  Initialize(false);

  MockWrite writes[] = {
    MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n"
              "Host: localhost\r\n"
              "Connection: keep-alive\r\n\r\n"),
    MockWrite(SYNCHRONOUS, 3, "GET /two.html HTTP/1.1\r\n"
              "Host: localhost\r\n"
              "Connection: keep-alive\r\n\r\n"),
  };
  MockRead reads[] = {
    MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
    MockRead(SYNCHRONOUS, 2, "Content-Length: 8\r\n\r\n"),
    MockRead(ASYNC, 4, "one.html"),
    MockRead(SYNCHRONOUS, ERR_SOCKET_NOT_CONNECTED, 5),
  };
  AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes));

  MockWrite writes2[] = {
    MockWrite(SYNCHRONOUS, 0, "GET /two.html HTTP/1.1\r\n"
              "Host: localhost\r\n"
              "Connection: keep-alive\r\n\r\n"),
  };
  MockRead reads2[] = {
    MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
    MockRead(SYNCHRONOUS, 2, "Content-Length: 8\r\n\r\n"),
    MockRead(SYNCHRONOUS, 3, "two.html"),
  };
  AddExpectedConnection(reads2, arraysize(reads2), writes2, arraysize(writes2));

  CompleteTwoRequests(0, 5);
}

TEST_F(HttpPipelinedNetworkTransactionTest, ErrorEvictsToNewPipeline) {
  Initialize(false);

  MockWrite writes[] = {
    MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n"
              "Host: localhost\r\n"
              "Connection: keep-alive\r\n\r\n"),
    MockWrite(SYNCHRONOUS, 3, "GET /two.html HTTP/1.1\r\n"
              "Host: localhost\r\n"
              "Connection: keep-alive\r\n\r\n"),
  };
  MockRead reads[] = {
    MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n\r\n"),
    MockRead(SYNCHRONOUS, ERR_FAILED, 2),
  };
  AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes));

  MockWrite writes2[] = {
    MockWrite(SYNCHRONOUS, 0, "GET /two.html HTTP/1.1\r\n"
              "Host: localhost\r\n"
              "Connection: keep-alive\r\n\r\n"),
  };
  MockRead reads2[] = {
    MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
    MockRead(SYNCHRONOUS, 2, "Content-Length: 8\r\n\r\n"),
    MockRead(SYNCHRONOUS, 3, "two.html"),
  };
  AddExpectedConnection(reads2, arraysize(reads2), writes2, arraysize(writes2));

  HttpNetworkTransaction one_transaction(DEFAULT_PRIORITY, session_.get());
  TestCompletionCallback one_callback;
  EXPECT_EQ(ERR_IO_PENDING,
            one_transaction.Start(GetRequestInfo("one.html"),
                                  one_callback.callback(), BoundNetLog()));
  EXPECT_EQ(OK, one_callback.WaitForResult());

  HttpNetworkTransaction two_transaction(DEFAULT_PRIORITY, session_.get());
  TestCompletionCallback two_callback;
  EXPECT_EQ(ERR_IO_PENDING,
            two_transaction.Start(GetRequestInfo("two.html"),
                                  two_callback.callback(), BoundNetLog()));

  scoped_refptr<IOBuffer> buffer(new IOBuffer(1));
  EXPECT_EQ(ERR_FAILED,
            one_transaction.Read(buffer.get(), 1, callback_.callback()));
  EXPECT_EQ(OK, two_callback.WaitForResult());
  ExpectResponse("two.html", two_transaction, SYNCHRONOUS);
}

TEST_F(HttpPipelinedNetworkTransactionTest, SendErrorEvictsToNewPipeline) {
  Initialize(false);

  MockWrite writes[] = {
    MockWrite(ASYNC, ERR_FAILED, 0),
  };
  AddExpectedConnection(NULL, 0, writes, arraysize(writes));

  MockWrite writes2[] = {
    MockWrite(SYNCHRONOUS, 0, "GET /two.html HTTP/1.1\r\n"
              "Host: localhost\r\n"
              "Connection: keep-alive\r\n\r\n"),
  };
  MockRead reads2[] = {
    MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
    MockRead(SYNCHRONOUS, 2, "Content-Length: 8\r\n\r\n"),
    MockRead(SYNCHRONOUS, 3, "two.html"),
  };
  AddExpectedConnection(reads2, arraysize(reads2), writes2, arraysize(writes2));

  HttpNetworkTransaction one_transaction(DEFAULT_PRIORITY, session_.get());
  TestCompletionCallback one_callback;
  EXPECT_EQ(ERR_IO_PENDING,
            one_transaction.Start(GetRequestInfo("one.html"),
                                  one_callback.callback(), BoundNetLog()));

  HttpNetworkTransaction two_transaction(DEFAULT_PRIORITY, session_.get());
  TestCompletionCallback two_callback;
  EXPECT_EQ(ERR_IO_PENDING,
            two_transaction.Start(GetRequestInfo("two.html"),
                                  two_callback.callback(), BoundNetLog()));

  data_vector_[0]->RunFor(1);
  EXPECT_EQ(ERR_FAILED, one_callback.WaitForResult());

  EXPECT_EQ(OK, two_callback.WaitForResult());
  ExpectResponse("two.html", two_transaction, SYNCHRONOUS);
}

TEST_F(HttpPipelinedNetworkTransactionTest, RedirectDrained) {
  Initialize(false);

  MockWrite writes[] = {
    MockWrite(SYNCHRONOUS, 0, "GET /redirect.html HTTP/1.1\r\n"
              "Host: localhost\r\n"
              "Connection: keep-alive\r\n\r\n"),
    MockWrite(SYNCHRONOUS, 3, "GET /two.html HTTP/1.1\r\n"
              "Host: localhost\r\n"
              "Connection: keep-alive\r\n\r\n"),
  };
  MockRead reads[] = {
    MockRead(SYNCHRONOUS, 1, "HTTP/1.1 302 OK\r\n"),
    MockRead(SYNCHRONOUS, 2, "Content-Length: 8\r\n\r\n"),
    MockRead(ASYNC, 4, "redirect"),
    MockRead(SYNCHRONOUS, 5, "HTTP/1.1 200 OK\r\n"),
    MockRead(SYNCHRONOUS, 6, "Content-Length: 8\r\n\r\n"),
    MockRead(SYNCHRONOUS, 7, "two.html"),
  };
  AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes));

  scoped_ptr<HttpNetworkTransaction> one_transaction(
      new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
  TestCompletionCallback one_callback;
  EXPECT_EQ(ERR_IO_PENDING,
            one_transaction->Start(GetRequestInfo("redirect.html"),
                                   one_callback.callback(), BoundNetLog()));
  EXPECT_EQ(OK, one_callback.WaitForResult());

  HttpNetworkTransaction two_transaction(DEFAULT_PRIORITY, session_.get());
  TestCompletionCallback two_callback;
  EXPECT_EQ(ERR_IO_PENDING,
            two_transaction.Start(GetRequestInfo("two.html"),
                                  two_callback.callback(), BoundNetLog()));

  one_transaction.reset();
  data_vector_[0]->RunFor(2);
  data_vector_[0]->SetStop(10);

  EXPECT_EQ(OK, two_callback.WaitForResult());
  ExpectResponse("two.html", two_transaction, SYNCHRONOUS);
}

TEST_F(HttpPipelinedNetworkTransactionTest, BasicHttpAuthentication) {
  Initialize(false);

  MockWrite writes[] = {
    MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n"
              "Host: localhost\r\n"
              "Connection: keep-alive\r\n\r\n"),
    MockWrite(SYNCHRONOUS, 5, "GET /one.html HTTP/1.1\r\n"
              "Host: localhost\r\n"
              "Connection: keep-alive\r\n"
              "Authorization: auth_token\r\n\r\n"),
  };
  MockRead reads[] = {
    MockRead(SYNCHRONOUS, 1, "HTTP/1.1 401 Authentication Required\r\n"),
    MockRead(SYNCHRONOUS, 2,
             "WWW-Authenticate: Basic realm=\"Secure Area\"\r\n"),
    MockRead(SYNCHRONOUS, 3, "Content-Length: 20\r\n\r\n"),
    MockRead(SYNCHRONOUS, 4, "needs authentication"),
    MockRead(SYNCHRONOUS, 6, "HTTP/1.1 200 OK\r\n"),
    MockRead(SYNCHRONOUS, 7, "Content-Length: 8\r\n\r\n"),
    MockRead(SYNCHRONOUS, 8, "one.html"),
  };
  AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes));

  HttpAuthHandlerMock* mock_auth = new HttpAuthHandlerMock;
  std::string challenge_text = "Basic";
  HttpAuth::ChallengeTokenizer challenge(challenge_text.begin(),
                                         challenge_text.end());
  GURL origin("localhost");
  EXPECT_TRUE(mock_auth->InitFromChallenge(&challenge,
                                           HttpAuth::AUTH_SERVER,
                                           origin,
                                           BoundNetLog()));
  auth_handler_factory_->AddMockHandler(mock_auth, HttpAuth::AUTH_SERVER);

  HttpNetworkTransaction transaction(DEFAULT_PRIORITY, session_.get());
  EXPECT_EQ(ERR_IO_PENDING,
            transaction.Start(GetRequestInfo("one.html"),
                              callback_.callback(),
                              BoundNetLog()));
  EXPECT_EQ(OK, callback_.WaitForResult());

  AuthCredentials credentials(ASCIIToUTF16("user"), ASCIIToUTF16("pass"));
  EXPECT_EQ(OK, transaction.RestartWithAuth(credentials, callback_.callback()));

  ExpectResponse("one.html", transaction, SYNCHRONOUS);
}

TEST_F(HttpPipelinedNetworkTransactionTest, OldVersionDisablesPipelining) {
  Initialize(false);

  MockWrite writes[] = {
    MockWrite(SYNCHRONOUS, 0, "GET /pipelined.html HTTP/1.1\r\n"
              "Host: localhost\r\n"
              "Connection: keep-alive\r\n\r\n"),
  };
  MockRead reads[] = {
    MockRead(SYNCHRONOUS, 1, "HTTP/1.0 200 OK\r\n"),
    MockRead(SYNCHRONOUS, 2, "Content-Length: 14\r\n\r\n"),
    MockRead(SYNCHRONOUS, 3, "pipelined.html"),
  };
  AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes));

  MockWrite writes2[] = {
    MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n"
              "Host: localhost\r\n"
              "Connection: keep-alive\r\n\r\n"),
  };
  MockRead reads2[] = {
    MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
    MockRead(SYNCHRONOUS, 2, "Content-Length: 8\r\n\r\n"),
    MockRead(ASYNC, 3, "one.html"),
    MockRead(SYNCHRONOUS, OK, 4),
  };
  AddExpectedConnection(reads2, arraysize(reads2), writes2, arraysize(writes2));

  MockWrite writes3[] = {
    MockWrite(SYNCHRONOUS, 0, "GET /two.html HTTP/1.1\r\n"
              "Host: localhost\r\n"
              "Connection: keep-alive\r\n\r\n"),
  };
  MockRead reads3[] = {
    MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
    MockRead(SYNCHRONOUS, 2, "Content-Length: 8\r\n\r\n"),
    MockRead(SYNCHRONOUS, 3, "two.html"),
    MockRead(SYNCHRONOUS, OK, 4),
  };
  AddExpectedConnection(reads3, arraysize(reads3), writes3, arraysize(writes3));

  HttpNetworkTransaction one_transaction(DEFAULT_PRIORITY, session_.get());
  TestCompletionCallback one_callback;
  EXPECT_EQ(ERR_IO_PENDING,
            one_transaction.Start(GetRequestInfo("pipelined.html"),
                                  one_callback.callback(), BoundNetLog()));
  EXPECT_EQ(OK, one_callback.WaitForResult());
  ExpectResponse("pipelined.html", one_transaction, SYNCHRONOUS);

  CompleteTwoRequests(1, 4);
}

TEST_F(HttpPipelinedNetworkTransactionTest, PipelinesImmediatelyIfKnownGood) {
  // The first request gets us an HTTP/1.1. The next 3 test pipelining. When the
  // 3rd request completes, we know pipelining is safe. After the first 4
  // complete, the 5th and 6th should then be immediately sent pipelined on a
  // new HttpPipelinedConnection.
  int old_max_sockets = ClientSocketPoolManager::max_sockets_per_group(
      HttpNetworkSession::NORMAL_SOCKET_POOL);
  ClientSocketPoolManager::set_max_sockets_per_group(
      HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
  Initialize(false);

  MockWrite writes[] = {
    MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n"
              "Host: localhost\r\n"
              "Connection: keep-alive\r\n\r\n"),
    MockWrite(SYNCHRONOUS, 4, "GET /two.html HTTP/1.1\r\n"
              "Host: localhost\r\n"
              "Connection: keep-alive\r\n\r\n"),
    MockWrite(SYNCHRONOUS, 7, "GET /three.html HTTP/1.1\r\n"
              "Host: localhost\r\n"
              "Connection: keep-alive\r\n\r\n"),
    MockWrite(SYNCHRONOUS, 12, "GET /four.html HTTP/1.1\r\n"
              "Host: localhost\r\n"
              "Connection: keep-alive\r\n\r\n"),
    MockWrite(SYNCHRONOUS, 16, "GET /second-pipeline-one.html HTTP/1.1\r\n"
              "Host: localhost\r\n"
              "Connection: keep-alive\r\n\r\n"),
    MockWrite(SYNCHRONOUS, 17, "GET /second-pipeline-two.html HTTP/1.1\r\n"
              "Host: localhost\r\n"
              "Connection: keep-alive\r\n\r\n"),
  };
  MockRead reads[] = {
    MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
    MockRead(SYNCHRONOUS, 2, "Content-Length: 8\r\n\r\n"),
    MockRead(SYNCHRONOUS, 3, "one.html"),
    MockRead(SYNCHRONOUS, 5, "HTTP/1.1 200 OK\r\n"),
    MockRead(SYNCHRONOUS, 6, "Content-Length: 8\r\n\r\n"),
    MockRead(SYNCHRONOUS, 8, "two.html"),
    MockRead(SYNCHRONOUS, 9, "HTTP/1.1 200 OK\r\n"),
    MockRead(SYNCHRONOUS, 10, "Content-Length: 10\r\n\r\n"),
    MockRead(SYNCHRONOUS, 11, "three.html"),
    MockRead(SYNCHRONOUS, 13, "HTTP/1.1 200 OK\r\n"),
    MockRead(SYNCHRONOUS, 14, "Content-Length: 9\r\n\r\n"),
    MockRead(SYNCHRONOUS, 15, "four.html"),
    MockRead(ASYNC, 18, "HTTP/1.1 200 OK\r\n"),
    MockRead(ASYNC, 19, "Content-Length: 24\r\n\r\n"),
    MockRead(SYNCHRONOUS, 20, "second-pipeline-one.html"),
    MockRead(SYNCHRONOUS, 21, "HTTP/1.1 200 OK\r\n"),
    MockRead(SYNCHRONOUS, 22, "Content-Length: 24\r\n\r\n"),
    MockRead(SYNCHRONOUS, 23, "second-pipeline-two.html"),
  };
  AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes));

  CompleteFourRequests(REQUEST_DEFAULT);

  HttpNetworkTransaction second_one_transaction(
      DEFAULT_PRIORITY, session_.get());
  TestCompletionCallback second_one_callback;
  EXPECT_EQ(ERR_IO_PENDING,
            second_one_transaction.Start(
                GetRequestInfo("second-pipeline-one.html"),
                second_one_callback.callback(), BoundNetLog()));
  base::MessageLoop::current()->RunUntilIdle();

  HttpNetworkTransaction second_two_transaction(
      DEFAULT_PRIORITY, session_.get());
  TestCompletionCallback second_two_callback;
  EXPECT_EQ(ERR_IO_PENDING,
            second_two_transaction.Start(
                GetRequestInfo("second-pipeline-two.html"),
                second_two_callback.callback(), BoundNetLog()));

  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,
                 SYNCHRONOUS);
  EXPECT_EQ(OK, second_two_callback.WaitForResult());
  ExpectResponse("second-pipeline-two.html", second_two_transaction,
                 SYNCHRONOUS);

  ClientSocketPoolManager::set_max_sockets_per_group(
      HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_sockets);
}

class DataRunnerObserver : public base::MessageLoop::TaskObserver {
 public:
  DataRunnerObserver(DeterministicSocketData* data, int run_before_task)
      : data_(data),
        run_before_task_(run_before_task),
        current_task_(0) { }

  virtual void WillProcessTask(const base::PendingTask& pending_task) OVERRIDE {
    ++current_task_;
    if (current_task_ == run_before_task_) {
      data_->Run();
      base::MessageLoop::current()->RemoveTaskObserver(this);
    }
  }

  virtual void DidProcessTask(const base::PendingTask& pending_task) OVERRIDE {}

 private:
  DeterministicSocketData* data_;
  int run_before_task_;
  int current_task_;
};

TEST_F(HttpPipelinedNetworkTransactionTest, OpenPipelinesWhileBinding) {
  // There was a racy crash in the pipelining code. This test recreates that
  // race. The steps are:
  // 1. The first request starts a pipeline and requests headers.
  // 2. HttpStreamFactoryImpl::Job tries to bind a pending request to a new
  // pipeline and queues a task to do so.
  // 3. Before that task runs, the first request receives its headers and
  // determines this host is probably capable of pipelining.
  // 4. All of the hosts' pipelines are notified they have capacity in a loop.
  // 5. On the first iteration, the first pipeline is opened up to accept new
  // requests and steals the request from step #2.
  // 6. The pipeline from #2 is deleted because it has no streams.
  // 7. On the second iteration, the host tries to notify the pipeline from step
  // #2 that it has capacity. This is a use-after-free.
  Initialize(false);

  MockWrite writes[] = {
    MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n"
              "Host: localhost\r\n"
              "Connection: keep-alive\r\n\r\n"),
    MockWrite(ASYNC, 3, "GET /two.html HTTP/1.1\r\n"
              "Host: localhost\r\n"
              "Connection: keep-alive\r\n\r\n"),
  };
  MockRead reads[] = {
    MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
    MockRead(ASYNC, 2, "Content-Length: 8\r\n\r\n"),
    MockRead(SYNCHRONOUS, 4, "one.html"),
    MockRead(SYNCHRONOUS, 5, "HTTP/1.1 200 OK\r\n"),
    MockRead(SYNCHRONOUS, 6, "Content-Length: 8\r\n\r\n"),
    MockRead(SYNCHRONOUS, 7, "two.html"),
  };
  AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes));

  AddExpectedConnection(NULL, 0, NULL, 0);

  HttpNetworkTransaction one_transaction(DEFAULT_PRIORITY, session_.get());
  TestCompletionCallback one_callback;
  EXPECT_EQ(ERR_IO_PENDING,
            one_transaction.Start(GetRequestInfo("one.html"),
                                  one_callback.callback(), BoundNetLog()));

  data_vector_[0]->SetStop(2);
  data_vector_[0]->Run();

  HttpNetworkTransaction two_transaction(DEFAULT_PRIORITY, session_.get());
  TestCompletionCallback two_callback;
  EXPECT_EQ(ERR_IO_PENDING,
            two_transaction.Start(GetRequestInfo("two.html"),
                                  two_callback.callback(), BoundNetLog()));
  // Posted tasks should be:
  // 1. MockHostResolverBase::ResolveNow
  // 2. HttpStreamFactoryImpl::Job::OnStreamReadyCallback for job 1
  // 3. HttpStreamFactoryImpl::Job::OnStreamReadyCallback for job 2
  //
  // We need to make sure that the response that triggers OnPipelineFeedback(OK)
  // is called in between when task #3 is scheduled and when it runs. The
  // DataRunnerObserver does that.
  DataRunnerObserver observer(data_vector_[0], 3);
  base::MessageLoop::current()->AddTaskObserver(&observer);
  data_vector_[0]->SetStop(4);
  base::MessageLoop::current()->RunUntilIdle();
  data_vector_[0]->SetStop(10);

  EXPECT_EQ(OK, one_callback.WaitForResult());
  ExpectResponse("one.html", one_transaction, SYNCHRONOUS);
  EXPECT_EQ(OK, two_callback.WaitForResult());
  ExpectResponse("two.html", two_transaction, SYNCHRONOUS);
}

TEST_F(HttpPipelinedNetworkTransactionTest, ProxyChangesWhileConnecting) {
  Initialize(false);

  DeterministicSocketData data(NULL, 0, NULL, 0);
  data.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
  factory_.AddSocketDataProvider(&data);

  DeterministicSocketData data2(NULL, 0, NULL, 0);
  data2.set_connect_data(MockConnect(ASYNC, ERR_FAILED));
  factory_.AddSocketDataProvider(&data2);

  HttpNetworkTransaction transaction(DEFAULT_PRIORITY, session_.get());
  EXPECT_EQ(ERR_IO_PENDING,
            transaction.Start(GetRequestInfo("test.html"), callback_.callback(),
                              BoundNetLog()));

  proxy_config_service_->IncrementConfigId();

  EXPECT_EQ(ERR_FAILED, callback_.WaitForResult());
}

TEST_F(HttpPipelinedNetworkTransactionTest, ForcedPipelineSharesConnection) {
  Initialize(true);

  MockWrite writes[] = {
    MockWrite(ASYNC, 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(ASYNC, 1, "HTTP/1.1 200 OK\r\n"),
    MockRead(ASYNC, 2, "Content-Length: 8\r\n\r\n"),
    MockRead(ASYNC, 3, "one.html"),
    MockRead(ASYNC, 4, "HTTP/1.1 200 OK\r\n"),
    MockRead(ASYNC, 5, "Content-Length: 8\r\n\r\n"),
    MockRead(ASYNC, 6, "two.html"),
  };
  AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes));

  scoped_ptr<HttpNetworkTransaction> one_transaction(
      new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
  TestCompletionCallback one_callback;
  EXPECT_EQ(ERR_IO_PENDING,
            one_transaction->Start(GetRequestInfo("one.html"),
                                   one_callback.callback(), BoundNetLog()));

  HttpNetworkTransaction two_transaction(DEFAULT_PRIORITY, session_.get());
  TestCompletionCallback two_callback;
  EXPECT_EQ(ERR_IO_PENDING,
            two_transaction.Start(GetRequestInfo("two.html"),
                                  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(), ASYNC);
  one_transaction.reset();

  data_vector_[0]->RunFor(2);  // 2 lines of headers.
  EXPECT_EQ(OK, two_callback.WaitForResult());
  ExpectResponse("two.html", two_transaction, ASYNC);
}

TEST_F(HttpPipelinedNetworkTransactionTest,
       ForcedPipelineConnectionErrorFailsBoth) {
  Initialize(true);

  DeterministicSocketData data(NULL, 0, NULL, 0);
  data.set_connect_data(MockConnect(ASYNC, ERR_FAILED));
  factory_.AddSocketDataProvider(&data);

  scoped_ptr<HttpNetworkTransaction> one_transaction(
      new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
  TestCompletionCallback one_callback;
  EXPECT_EQ(ERR_IO_PENDING,
            one_transaction->Start(GetRequestInfo("one.html"),
                                   one_callback.callback(), BoundNetLog()));

  HttpNetworkTransaction two_transaction(DEFAULT_PRIORITY, session_.get());
  TestCompletionCallback two_callback;
  EXPECT_EQ(ERR_IO_PENDING,
            two_transaction.Start(GetRequestInfo("two.html"),
                                  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(true);

  MockWrite writes[] = {
    MockWrite(ASYNC, 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(ASYNC, ERR_FAILED, 1),
  };
  AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes));

  scoped_ptr<HttpNetworkTransaction> one_transaction(
      new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
  TestCompletionCallback one_callback;
  EXPECT_EQ(ERR_IO_PENDING,
            one_transaction->Start(GetRequestInfo("one.html"),
                                   one_callback.callback(), BoundNetLog()));

  HttpNetworkTransaction two_transaction(DEFAULT_PRIORITY, session_.get());
  TestCompletionCallback two_callback;
  EXPECT_EQ(ERR_IO_PENDING,
            two_transaction.Start(GetRequestInfo("two.html"),
                                  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());
}

TEST_F(HttpPipelinedNetworkTransactionTest, ForcedPipelineOrder) {
  Initialize(true);

  MockWrite writes[] = {
    MockWrite(ASYNC, 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"
              "GET /three.html HTTP/1.1\r\n"
              "Host: localhost\r\n"
              "Connection: keep-alive\r\n\r\n"
              "GET /four.html HTTP/1.1\r\n"
              "Host: localhost\r\n"
              "Connection: keep-alive\r\n\r\n"
              ),
  };
  MockRead reads[] = {
    MockRead(ASYNC, ERR_FAILED, 1),
  };
  DeterministicSocketData data(
      reads, arraysize(reads), writes, arraysize(writes));
  data.set_connect_data(MockConnect(ASYNC, OK));
  factory_.AddSocketDataProvider(&data);

  scoped_ptr<HttpNetworkTransaction> one_transaction(
      new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
  TestCompletionCallback one_callback;
  EXPECT_EQ(ERR_IO_PENDING,
            one_transaction->Start(GetRequestInfo("one.html"),
                                   one_callback.callback(), BoundNetLog()));

  scoped_ptr<HttpNetworkTransaction> two_transaction(
      new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
  TestCompletionCallback two_callback;
  EXPECT_EQ(ERR_IO_PENDING,
            two_transaction->Start(GetRequestInfo("two.html"),
                                   two_callback.callback(), BoundNetLog()));

  scoped_ptr<HttpNetworkTransaction> three_transaction(
      new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
  TestCompletionCallback three_callback;
  EXPECT_EQ(ERR_IO_PENDING,
            three_transaction->Start(GetRequestInfo("three.html"),
                                     three_callback.callback(), BoundNetLog()));

  scoped_ptr<HttpNetworkTransaction> four_transaction(
      new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
  TestCompletionCallback four_callback;
  EXPECT_EQ(ERR_IO_PENDING,
            four_transaction->Start(GetRequestInfo("four.html"),
                                    four_callback.callback(), BoundNetLog()));

  data.RunFor(3);
  EXPECT_EQ(ERR_FAILED, one_callback.WaitForResult());
  one_transaction.reset();
  EXPECT_EQ(ERR_PIPELINE_EVICTION, two_callback.WaitForResult());
  two_transaction.reset();
  EXPECT_EQ(ERR_PIPELINE_EVICTION, three_callback.WaitForResult());
  three_transaction.reset();
  EXPECT_EQ(ERR_PIPELINE_EVICTION, four_callback.WaitForResult());
}

}  // anonymous namespace

}  // namespace net
