15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h"
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/scoped_temp_dir.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_vector.h"
133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/run_loop.h"
14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/stl_util.h"
1523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "base/strings/string_piece.h"
16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/test/test_file_util.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/auth.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_log_unittest.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/request_priority.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/upload_bytes_element_reader.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/upload_data_stream.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/upload_file_element_reader.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_network_session_peer.h"
247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "net/http/http_network_transaction.h"
257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "net/http/http_server_properties.h"
26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/http/http_transaction_test_util.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/client_socket_pool_base.h"
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/socket/next_proto.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/buffered_spdy_framer.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_http_stream.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_http_utils.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_session.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_session_pool.h"
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/spdy/spdy_test_util_common.h"
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/spdy/spdy_test_utils.h"
36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/ssl/ssl_connection_status_flags.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_test_util.h"
3823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/platform_test.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//-----------------------------------------------------------------------------
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
4623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
4723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)using testing::Each;
4823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)using testing::Eq;
4923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kRequestUrl[] = "http://www.google.com/";
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)enum SpdyNetworkTransactionTestSSLType {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SPDYNPN,
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SPDYNOSSL,
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SPDYSSL,
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)struct SpdyNetworkTransactionTestParams {
597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  SpdyNetworkTransactionTestParams()
604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      : protocol(kProtoSPDY3),
617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        ssl_type(SPDYNPN) {}
627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  SpdyNetworkTransactionTestParams(
647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      NextProto protocol,
657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      SpdyNetworkTransactionTestSSLType ssl_type)
667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      : protocol(protocol),
677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        ssl_type(ssl_type) {}
687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  NextProto protocol;
707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  SpdyNetworkTransactionTestSSLType ssl_type;
717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)};
727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void UpdateSpdySessionDependencies(
74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    SpdyNetworkTransactionTestParams test_params,
75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    SpdySessionDependencies* session_deps) {
76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  switch (test_params.ssl_type) {
77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case SPDYNPN:
78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      session_deps->http_server_properties.SetAlternateProtocol(
79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          HostPortPair("www.google.com", 80), 443,
80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          AlternateProtocolFromNextProto(test_params.protocol), 1);
81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      session_deps->use_alternate_protocols = true;
82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      session_deps->next_protos = SpdyNextProtos();
83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      break;
84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case SPDYNOSSL:
85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      session_deps->force_spdy_over_ssl = false;
86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      session_deps->force_spdy_always = true;
87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      break;
88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case SPDYSSL:
89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      session_deps->force_spdy_over_ssl = true;
90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      session_deps->force_spdy_always = true;
91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      break;
92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    default:
93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      NOTREACHED();
94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)SpdySessionDependencies* CreateSpdySessionDependencies(
987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    SpdyNetworkTransactionTestParams test_params) {
99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SpdySessionDependencies* session_deps =
100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      new SpdySessionDependencies(test_params.protocol);
101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  UpdateSpdySessionDependencies(test_params, session_deps);
102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return session_deps;
1037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
1047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)SpdySessionDependencies* CreateSpdySessionDependencies(
1067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    SpdyNetworkTransactionTestParams test_params,
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ProxyService* proxy_service) {
108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SpdySessionDependencies* session_deps =
109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      new SpdySessionDependencies(test_params.protocol, proxy_service);
110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  UpdateSpdySessionDependencies(test_params, session_deps);
111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return session_deps;
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}  // namespace
1157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class SpdyNetworkTransactionTest
1177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    : public ::testing::TestWithParam<SpdyNetworkTransactionTestParams> {
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  SpdyNetworkTransactionTest() : spdy_util_(GetParam().protocol) {
120b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual ~SpdyNetworkTransactionTest() {
1233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // UploadDataStream posts deletion tasks back to the message loop on
1243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // destruction.
1253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    upload_data_stream_.reset();
1263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    base::RunLoop().RunUntilIdle();
1273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
1283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    google_get_request_initialized_ = false;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    google_post_request_initialized_ = false;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    google_chunked_post_request_initialized_ = false;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct TransactionHelperResult {
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string status_line;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string response_data;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpResponseInfo response_info;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A helper class that handles all the initial npn/ssl setup.
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class NormalSpdyTransactionHelper {
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NormalSpdyTransactionHelper(const HttpRequestInfo& request,
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                RequestPriority priority,
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const BoundNetLog& log,
1497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                SpdyNetworkTransactionTestParams test_params,
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                SpdySessionDependencies* session_deps)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        : request_(request),
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          priority_(priority),
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          session_deps_(session_deps == NULL ?
1547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                        CreateSpdySessionDependencies(test_params) :
1557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                        session_deps),
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          session_(SpdySessionDependencies::SpdyCreateSession(
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       session_deps_.get())),
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          log_(log),
1597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          test_params_(test_params),
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          deterministic_(false),
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          spdy_enabled_(true) {
1627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      switch (test_params_.ssl_type) {
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        case SPDYNOSSL:
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        case SPDYSSL:
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          port_ = 80;
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          break;
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        case SPDYNPN:
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          port_ = 443;
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          break;
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        default:
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          NOTREACHED();
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ~NormalSpdyTransactionHelper() {
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Any test which doesn't close the socket by sending it an EOF will
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // have a valid session left open, which leaks the entire session pool.
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // This is just fine - in fact, some of our tests intentionally do this
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // so that we can check consistency of the SpdySessionPool as the test
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // finishes.  If we had put an EOF on the socket, the SpdySession would
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // have closed and we wouldn't be able to check the consistency.
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Forcefully close existing sessions here.
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      session()->spdy_session_pool()->CloseAllSessions();
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void SetDeterministic() {
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      session_ = SpdySessionDependencies::SpdyCreateSessionDeterministic(
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          session_deps_.get());
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      deterministic_ = true;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void SetSpdyDisabled() {
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_enabled_ = false;
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      port_ = 80;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void RunPreTestSetup() {
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!session_deps_.get())
2007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        session_deps_.reset(CreateSpdySessionDependencies(test_params_));
201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (!session_.get()) {
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        session_ = SpdySessionDependencies::SpdyCreateSession(
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            session_deps_.get());
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // We're now ready to use SSL-npn SPDY.
207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      trans_.reset(new HttpNetworkTransaction(priority_, session_.get()));
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Start the transaction, read some data, finish.
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void RunDefaultTest() {
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!StartDefaultTest())
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return;
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FinishDefaultTest();
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool StartDefaultTest() {
218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      output_.rv = trans_->Start(&request_, callback_.callback(), log_);
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // We expect an IO Pending or some sort of error.
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_LT(output_.rv, 0);
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return output_.rv == ERR_IO_PENDING;
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    void FinishDefaultTest() {
226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      output_.rv = callback_.WaitForResult();
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (output_.rv != OK) {
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        session_->spdy_session_pool()->CloseCurrentSessions(net::ERR_ABORTED);
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return;
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Verify responses.
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const HttpResponseInfo* response = trans_->GetResponseInfo();
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ASSERT_TRUE(response != NULL);
235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      ASSERT_TRUE(response->headers.get() != NULL);
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(spdy_enabled_, response->was_fetched_via_spdy);
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (HttpStreamFactory::spdy_enabled()) {
239558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        EXPECT_EQ(
240558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch            HttpResponseInfo::ConnectionInfoFromNextProto(
241558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                test_params_.protocol),
242558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch            response->connection_info);
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      } else {
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1,
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  response->connection_info);
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
2477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      if (test_params_.ssl_type == SPDYNPN && spdy_enabled_) {
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_TRUE(response->was_npn_negotiated);
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_TRUE(!response->was_npn_negotiated);
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // If SPDY is not enabled, a HTTP request should not be diverted
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // over a SSL session.
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!spdy_enabled_) {
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_EQ(request_.url.SchemeIs("https"),
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  response->was_npn_negotiated);
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ("127.0.0.1", response->socket_address.host());
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(port_, response->socket_address.port());
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      output_.status_line = response->headers->GetStatusLine();
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      output_.response_info = *response;  // Make a copy so we can verify.
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      output_.rv = ReadTransaction(trans_.get(), &output_.response_data);
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Most tests will want to call this function. In particular, the MockReads
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // should end with an empty read, and that read needs to be processed to
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // ensure proper deletion of the spdy_session_pool.
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void VerifyDataConsumed() {
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (DataVector::iterator it = data_vector_.begin();
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          it != data_vector_.end(); ++it) {
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_TRUE((*it)->at_read_eof()) << "Read count: "
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          << (*it)->read_count()
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          << " Read index: "
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          << (*it)->read_index();
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_TRUE((*it)->at_write_eof()) << "Write count: "
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           << (*it)->write_count()
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           << " Write index: "
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           << (*it)->write_index();
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Occasionally a test will expect to error out before certain reads are
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // processed. In that case we want to explicitly ensure that the reads were
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // not processed.
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void VerifyDataNotConsumed() {
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (DataVector::iterator it = data_vector_.begin();
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          it != data_vector_.end(); ++it) {
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_TRUE(!(*it)->at_read_eof()) << "Read count: "
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           << (*it)->read_count()
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           << " Read index: "
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           << (*it)->read_index();
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_TRUE(!(*it)->at_write_eof()) << "Write count: "
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            << (*it)->write_count()
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            << " Write index: "
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            << (*it)->write_index();
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void RunToCompletion(StaticSocketDataProvider* data) {
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      RunPreTestSetup();
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AddData(data);
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      RunDefaultTest();
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      VerifyDataConsumed();
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
306cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    void RunToCompletionWithSSLData(
307cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        StaticSocketDataProvider* data,
308cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        scoped_ptr<SSLSocketDataProvider> ssl_provider) {
309cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      RunPreTestSetup();
310cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      AddDataWithSSLSocketDataProvider(data, ssl_provider.Pass());
311cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      RunDefaultTest();
312cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      VerifyDataConsumed();
313cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
314cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void AddData(StaticSocketDataProvider* data) {
316cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      scoped_ptr<SSLSocketDataProvider> ssl_provider(
317cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          new SSLSocketDataProvider(ASYNC, OK));
318cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      AddDataWithSSLSocketDataProvider(data, ssl_provider.Pass());
319cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
320cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
321cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    void AddDataWithSSLSocketDataProvider(
322cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        StaticSocketDataProvider* data,
323cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        scoped_ptr<SSLSocketDataProvider> ssl_provider) {
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(!deterministic_);
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_vector_.push_back(data);
3267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      if (test_params_.ssl_type == SPDYNPN)
3277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        ssl_provider->SetNextProto(test_params_.protocol);
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
329cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (test_params_.ssl_type == SPDYNPN ||
330cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          test_params_.ssl_type == SPDYSSL) {
331cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        session_deps_->socket_factory->AddSSLSocketDataProvider(
332cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            ssl_provider.get());
333cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      }
334cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      ssl_vector_.push_back(ssl_provider.release());
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      session_deps_->socket_factory->AddSocketDataProvider(data);
3377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      if (test_params_.ssl_type == SPDYNPN) {
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        StaticSocketDataProvider* hanging_non_alternate_protocol_socket =
3407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            new StaticSocketDataProvider(NULL, 0, NULL, 0);
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        hanging_non_alternate_protocol_socket->set_connect_data(
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            never_finishing_connect);
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        session_deps_->socket_factory->AddSocketDataProvider(
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            hanging_non_alternate_protocol_socket);
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        alternate_vector_.push_back(hanging_non_alternate_protocol_socket);
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void AddDeterministicData(DeterministicSocketData* data) {
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(deterministic_);
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_vector_.push_back(data);
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SSLSocketDataProvider* ssl_provider =
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          new SSLSocketDataProvider(ASYNC, OK);
3547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      if (test_params_.ssl_type == SPDYNPN)
3557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        ssl_provider->SetNextProto(test_params_.protocol);
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ssl_vector_.push_back(ssl_provider);
3587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      if (test_params_.ssl_type == SPDYNPN ||
3597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          test_params_.ssl_type == SPDYSSL) {
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        session_deps_->deterministic_socket_factory->
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            AddSSLSocketDataProvider(ssl_provider);
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      session_deps_->deterministic_socket_factory->AddSocketDataProvider(data);
3647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      if (test_params_.ssl_type == SPDYNPN) {
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DeterministicSocketData* hanging_non_alternate_protocol_socket =
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            new DeterministicSocketData(NULL, 0, NULL, 0);
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        hanging_non_alternate_protocol_socket->set_connect_data(
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            never_finishing_connect);
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        session_deps_->deterministic_socket_factory->AddSocketDataProvider(
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            hanging_non_alternate_protocol_socket);
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        alternate_deterministic_vector_.push_back(
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            hanging_non_alternate_protocol_socket);
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void SetSession(const scoped_refptr<HttpNetworkSession>& session) {
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      session_ = session;
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpNetworkTransaction* trans() { return trans_.get(); }
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void ResetTrans() { trans_.reset(); }
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TransactionHelperResult& output() { return output_; }
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpRequestInfo& request() const { return request_; }
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const scoped_refptr<HttpNetworkSession>& session() const {
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return session_;
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<SpdySessionDependencies>& session_deps() {
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return session_deps_;
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int port() const { return port_; }
3917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    SpdyNetworkTransactionTestParams test_params() const {
3927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return test_params_;
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   private:
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    typedef std::vector<StaticSocketDataProvider*> DataVector;
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    typedef ScopedVector<SSLSocketDataProvider> SSLVector;
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    typedef ScopedVector<StaticSocketDataProvider> AlternateVector;
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    typedef ScopedVector<DeterministicSocketData> AlternateDeterministicVector;
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request_;
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RequestPriority priority_;
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<SpdySessionDependencies> session_deps_;
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<HttpNetworkSession> session_;
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TransactionHelperResult output_;
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<StaticSocketDataProvider> first_transaction_;
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSLVector ssl_vector_;
407cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    TestCompletionCallback callback_;
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<HttpNetworkTransaction> trans_;
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<HttpNetworkTransaction> trans_http_;
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DataVector data_vector_;
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AlternateVector alternate_vector_;
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AlternateDeterministicVector alternate_deterministic_vector_;
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const BoundNetLog& log_;
4147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    SpdyNetworkTransactionTestParams test_params_;
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int port_;
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool deterministic_;
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool spdy_enabled_;
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             int expected_status);
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ConnectStatusHelper(const MockRead& status);
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpRequestInfo& CreateGetPushRequest() {
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    google_get_push_request_.method = "GET";
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    google_get_push_request_.url = GURL("http://www.google.com/foo.dat");
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    google_get_push_request_.load_flags = 0;
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return google_get_push_request_;
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpRequestInfo& CreateGetRequest() {
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!google_get_request_initialized_) {
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      google_get_request_.method = "GET";
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      google_get_request_.url = GURL(kDefaultURL);
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      google_get_request_.load_flags = 0;
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      google_get_request_initialized_ = true;
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return google_get_request_;
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpRequestInfo& CreateGetRequestWithUserAgent() {
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!google_get_request_initialized_) {
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      google_get_request_.method = "GET";
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      google_get_request_.url = GURL(kDefaultURL);
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      google_get_request_.load_flags = 0;
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      google_get_request_.extra_headers.SetHeader("User-Agent", "Chrome");
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      google_get_request_initialized_ = true;
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return google_get_request_;
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpRequestInfo& CreatePostRequest() {
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!google_post_request_initialized_) {
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ScopedVector<UploadElementReader> element_readers;
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      element_readers.push_back(
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          new UploadBytesElementReader(kUploadData, kUploadDataSize));
45868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      upload_data_stream_.reset(
45968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          new UploadDataStream(element_readers.Pass(), 0));
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      google_post_request_.method = "POST";
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      google_post_request_.url = GURL(kDefaultURL);
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      google_post_request_.upload_data_stream = upload_data_stream_.get();
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      google_post_request_initialized_ = true;
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return google_post_request_;
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpRequestInfo& CreateFilePostRequest() {
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!google_post_request_initialized_) {
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::FilePath file_path;
472a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      CHECK(base::CreateTemporaryFileInDir(temp_dir_.path(), &file_path));
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CHECK_EQ(static_cast<int>(kUploadDataSize),
474a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)               base::WriteFile(file_path, kUploadData, kUploadDataSize));
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ScopedVector<UploadElementReader> element_readers;
4777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      element_readers.push_back(
4787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          new UploadFileElementReader(base::MessageLoopProxy::current().get(),
4797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                      file_path,
4807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                      0,
4817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                      kUploadDataSize,
4827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                      base::Time()));
48368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      upload_data_stream_.reset(
48468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          new UploadDataStream(element_readers.Pass(), 0));
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      google_post_request_.method = "POST";
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      google_post_request_.url = GURL(kDefaultURL);
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      google_post_request_.upload_data_stream = upload_data_stream_.get();
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      google_post_request_initialized_ = true;
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return google_post_request_;
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
494f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const HttpRequestInfo& CreateUnreadableFilePostRequest() {
495f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (google_post_request_initialized_)
496f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return google_post_request_;
497f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
498f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    base::FilePath file_path;
499a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    CHECK(base::CreateTemporaryFileInDir(temp_dir_.path(), &file_path));
500f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    CHECK_EQ(static_cast<int>(kUploadDataSize),
501a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)             base::WriteFile(file_path, kUploadData, kUploadDataSize));
5026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    CHECK(base::MakeFileUnreadable(file_path));
503f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
504f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ScopedVector<UploadElementReader> element_readers;
505f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    element_readers.push_back(
506f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        new UploadFileElementReader(base::MessageLoopProxy::current().get(),
507f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    file_path,
508f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    0,
509f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    kUploadDataSize,
510f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    base::Time()));
511f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    upload_data_stream_.reset(
512f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        new UploadDataStream(element_readers.Pass(), 0));
513f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
514f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    google_post_request_.method = "POST";
515f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    google_post_request_.url = GURL(kDefaultURL);
516f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    google_post_request_.upload_data_stream = upload_data_stream_.get();
517f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    google_post_request_initialized_ = true;
518f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return google_post_request_;
519f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
520f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpRequestInfo& CreateComplexPostRequest() {
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!google_post_request_initialized_) {
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const int kFileRangeOffset = 1;
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const int kFileRangeLength = 3;
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CHECK_LT(kFileRangeOffset + kFileRangeLength, kUploadDataSize);
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::FilePath file_path;
528a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      CHECK(base::CreateTemporaryFileInDir(temp_dir_.path(), &file_path));
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CHECK_EQ(static_cast<int>(kUploadDataSize),
530a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)               base::WriteFile(file_path, kUploadData, kUploadDataSize));
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ScopedVector<UploadElementReader> element_readers;
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      element_readers.push_back(
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          new UploadBytesElementReader(kUploadData, kFileRangeOffset));
5357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      element_readers.push_back(
5367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          new UploadFileElementReader(base::MessageLoopProxy::current().get(),
5377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                      file_path,
5387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                      kFileRangeOffset,
5397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                      kFileRangeLength,
5407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                      base::Time()));
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      element_readers.push_back(new UploadBytesElementReader(
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          kUploadData + kFileRangeOffset + kFileRangeLength,
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          kUploadDataSize - (kFileRangeOffset + kFileRangeLength)));
54468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      upload_data_stream_.reset(
54568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          new UploadDataStream(element_readers.Pass(), 0));
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      google_post_request_.method = "POST";
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      google_post_request_.url = GURL(kDefaultURL);
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      google_post_request_.upload_data_stream = upload_data_stream_.get();
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      google_post_request_initialized_ = true;
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return google_post_request_;
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpRequestInfo& CreateChunkedPostRequest() {
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!google_chunked_post_request_initialized_) {
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      upload_data_stream_.reset(
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          new UploadDataStream(UploadDataStream::CHUNKED, 0));
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      google_chunked_post_request_.method = "POST";
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      google_chunked_post_request_.url = GURL(kDefaultURL);
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      google_chunked_post_request_.upload_data_stream =
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          upload_data_stream_.get();
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      google_chunked_post_request_initialized_ = true;
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return google_chunked_post_request_;
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read the result of a particular transaction, knowing that we've got
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // multiple transactions in the read pipeline; so as we read, we may have
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to skip over data destined for other transactions while we consume
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the data for |trans|.
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int ReadResult(HttpNetworkTransaction* trans,
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 StaticSocketDataProvider* data,
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 std::string* result) {
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int kSize = 3000;
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int bytes_read = 0;
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(kSize));
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (true) {
581868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      int rv = trans->Read(buf.get(), kSize, callback.callback());
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (rv == ERR_IO_PENDING) {
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // Multiple transactions may be in the data set.  Keep pulling off
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // reads until we complete our callback.
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        while (!callback.have_result()) {
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          data->CompleteRead();
5873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          base::RunLoop().RunUntilIdle();
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = callback.WaitForResult();
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else if (rv <= 0) {
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result->append(buf->data(), rv);
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bytes_read += rv;
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return bytes_read;
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void VerifyStreamsClosed(const NormalSpdyTransactionHelper& helper) {
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This lengthy block is reaching into the pool to dig out the active
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // session.  Once we have the session, we verify that the streams are
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // all closed and not leaked at this point.
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& url = helper.request().url;
6047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    int port = helper.test_params().ssl_type == SPDYNPN ? 443 : 80;
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HostPortPair host_port_pair(url.host(), port);
60690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
607e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                       PRIVACY_MODE_DISABLED);
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BoundNetLog log;
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const scoped_refptr<HttpNetworkSession>& session = helper.session();
610ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    base::WeakPtr<SpdySession> spdy_session =
6117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        session->spdy_session_pool()->FindAvailableSession(key, log);
6127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    ASSERT_TRUE(spdy_session != NULL);
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0u, spdy_session->num_active_streams());
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0u, spdy_session->num_unclaimed_pushed_streams());
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RunServerPushTest(OrderedSocketData* data,
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         HttpResponseInfo* response,
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         HttpResponseInfo* push_response,
620eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                         const std::string& expected) {
6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       BoundNetLog(), GetParam(), NULL);
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    helper.RunPreTestSetup();
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    helper.AddData(data);
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpNetworkTransaction* trans = helper.trans();
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Start the transaction with basic parameters.
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &CreateGetRequest(), callback.callback(), BoundNetLog());
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Request the pushed path.
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<HttpNetworkTransaction> trans2(
637868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = trans2->Start(
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &CreateGetPushRequest(), callback.callback(), BoundNetLog());
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
6413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    base::RunLoop().RunUntilIdle();
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // The data for the pushed path may be coming in more than 1 frame. Compile
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the results into a single string.
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Read the server push body.
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string result2;
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReadResult(trans2.get(), data, &result2);
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Read the response body.
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string result;
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReadResult(trans, data, &result);
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Verify that we consumed all test data.
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(data->at_read_eof());
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(data->at_write_eof());
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Verify that the received push data is same as the expected push data.
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(result2.compare(expected), 0) << "Received data: "
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            << result2
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            << "||||| Expected data: "
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            << expected;
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Verify the SYN_REPLY.
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Copy the response info, because trans goes away.
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *response = *trans->GetResponseInfo();
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *push_response = *trans2->GetResponseInfo();
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VerifyStreamsClosed(helper);
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void DeleteSessionCallback(NormalSpdyTransactionHelper* helper,
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    int result) {
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    helper->ResetTrans();
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void StartTransactionCallback(
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const scoped_refptr<HttpNetworkSession>& session,
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int result) {
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<HttpNetworkTransaction> trans(
680868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/");
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback.WaitForResult();
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
691b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  SpdyTestUtil spdy_util_;
692b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<UploadDataStream> upload_data_stream_;
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool google_get_request_initialized_;
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool google_post_request_initialized_;
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool google_chunked_post_request_initialized_;
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo google_get_request_;
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo google_post_request_;
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo google_chunked_post_request_;
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo google_get_push_request_;
7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ScopedTempDir temp_dir_;
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//-----------------------------------------------------------------------------
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// All tests are run with three different connection types: SPDY after NPN
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// negotiation, SPDY without SSL, and SPDY with SSL.
7087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
7097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// TODO(akalin): Use ::testing::Combine() when we are able to use
7107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// <tr1/tuple>.
7117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)INSTANTIATE_TEST_CASE_P(
7127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    Spdy,
7137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    SpdyNetworkTransactionTest,
7147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    ::testing::Values(
7154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        SpdyNetworkTransactionTestParams(kProtoDeprecatedSPDY2, SPDYNOSSL),
7164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        SpdyNetworkTransactionTestParams(kProtoDeprecatedSPDY2, SPDYSSL),
7174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        SpdyNetworkTransactionTestParams(kProtoDeprecatedSPDY2, SPDYNPN),
7187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        SpdyNetworkTransactionTestParams(kProtoSPDY3, SPDYNOSSL),
7197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        SpdyNetworkTransactionTestParams(kProtoSPDY3, SPDYSSL),
7207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        SpdyNetworkTransactionTestParams(kProtoSPDY3, SPDYNPN),
7217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        SpdyNetworkTransactionTestParams(kProtoSPDY31, SPDYNOSSL),
7227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        SpdyNetworkTransactionTestParams(kProtoSPDY31, SPDYSSL),
7237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        SpdyNetworkTransactionTestParams(kProtoSPDY31, SPDYNPN),
724a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        SpdyNetworkTransactionTestParams(kProtoSPDY4, SPDYNOSSL),
725a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        SpdyNetworkTransactionTestParams(kProtoSPDY4, SPDYSSL),
726a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        SpdyNetworkTransactionTestParams(kProtoSPDY4, SPDYNPN)));
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verify HttpNetworkTransaction constructor.
7297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, Constructor) {
730c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<SpdySessionDependencies> session_deps(
7317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      CreateSpdySessionDependencies(GetParam()));
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(
733c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SpdySessionDependencies::SpdyCreateSession(session_deps.get()));
7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
735868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, Get) {
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Construct the request.
74090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
74190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes[] = { CreateMockWrite(*req) };
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
7457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads[] = {
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp),
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body),
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0)  // EOF
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData data(1, reads, arraysize(reads),
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         writes, arraysize(writes));
7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     BoundNetLog(), GetParam(), NULL);
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  helper.RunToCompletion(&data);
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TransactionHelperResult out = helper.output();
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", out.response_data);
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, GetAtEachPriority) {
7648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  for (RequestPriority p = MINIMUM_PRIORITY; p <= MAXIMUM_PRIORITY;
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       p = RequestPriority(p + 1)) {
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Construct the request.
76790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    scoped_ptr<SpdyFrame> req(
76890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, p, true));
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite writes[] = { CreateMockWrite(*req) };
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SpdyPriority spdy_prio = 0;
7727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_TRUE(GetSpdyPriority(spdy_util_.spdy_version(), *req, &spdy_prio));
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // this repeats the RequestPriority-->SpdyPriority mapping from
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // SpdyFramer::ConvertRequestPriorityToSpdyPriority to make
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // sure it's being done right.
7767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (spdy_util_.spdy_version() < SPDY3) {
7777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      switch(p) {
7787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        case HIGHEST:
7797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          EXPECT_EQ(0, spdy_prio);
7807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          break;
7817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        case MEDIUM:
7827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          EXPECT_EQ(1, spdy_prio);
7837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          break;
7847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        case LOW:
7857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        case LOWEST:
7867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          EXPECT_EQ(2, spdy_prio);
7877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          break;
7887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        case IDLE:
7897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          EXPECT_EQ(3, spdy_prio);
7907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          break;
7917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        default:
7927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          FAIL();
7937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      }
7947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    } else {
7957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      switch(p) {
7967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        case HIGHEST:
7977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          EXPECT_EQ(0, spdy_prio);
7987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          break;
7997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        case MEDIUM:
8007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          EXPECT_EQ(1, spdy_prio);
8017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          break;
8027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        case LOW:
8037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          EXPECT_EQ(2, spdy_prio);
8047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          break;
8057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        case LOWEST:
8067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          EXPECT_EQ(3, spdy_prio);
8077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          break;
8087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        case IDLE:
8097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          EXPECT_EQ(4, spdy_prio);
8107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          break;
8117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        default:
8127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          FAIL();
8137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      }
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead reads[] = {
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateMockRead(*resp),
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateMockRead(*body),
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(ASYNC, 0, 0)  // EOF
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DelayedSocketData data(1, reads, arraysize(reads),
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              writes, arraysize(writes));
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo http_req = CreateGetRequest();
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NormalSpdyTransactionHelper helper(http_req, p, BoundNetLog(),
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       GetParam(), NULL);
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    helper.RunToCompletion(&data);
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TransactionHelperResult out = helper.output();
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, out.rv);
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("hello!", out.response_data);
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Start three gets simultaniously; making sure that multiplexed
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// streams work properly.
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This can't use the TransactionHelper method, since it only
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// handles a single transaction, and finishes them as soon
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// as it launches them.
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(gavinp): create a working generalized TransactionHelper that
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// can allow multiple streams in flight.
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, ThreeGets) {
84990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
85090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
8517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
8527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false));
8537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> fbody(spdy_util_.ConstructSpdyBodyFrame(1, true));
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req2(
85690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
8577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
8587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, false));
8597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> fbody2(spdy_util_.ConstructSpdyBodyFrame(3, true));
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req3(
86290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 5, LOWEST, true));
8637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp3(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 5));
8647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(5, false));
8657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> fbody3(spdy_util_.ConstructSpdyBodyFrame(5, true));
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes[] = {
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req),
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req2),
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req3),
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads[] = {
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp, 1),
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body),
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp2, 4),
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body2),
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp3, 7),
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body3),
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*fbody),
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*fbody2),
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*fbody3),
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0),  // EOF
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData data(reads, arraysize(reads),
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         writes, arraysize(writes));
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData data_placeholder(NULL, 0, NULL, 0);
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BoundNetLog log;
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TransactionHelperResult out;
8922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     BoundNetLog(), GetParam(), NULL);
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  helper.RunPreTestSetup();
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  helper.AddData(&data);
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We require placeholder data because three get requests are sent out, so
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // there needs to be three sets of SSL connection data.
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  helper.AddData(&data_placeholder);
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  helper.AddData(&data_placeholder);
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpNetworkTransaction> trans1(
901868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpNetworkTransaction> trans2(
903868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpNetworkTransaction> trans3(
905868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback3;
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo httpreq1 = CreateGetRequest();
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo httpreq2 = CreateGetRequest();
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo httpreq3 = CreateGetRequest();
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.rv = trans1->Start(&httpreq1, callback1.callback(), log);
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(ERR_IO_PENDING, out.rv);
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.rv = trans2->Start(&httpreq2, callback2.callback(), log);
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(ERR_IO_PENDING, out.rv);
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.rv = trans3->Start(&httpreq3, callback3.callback(), log);
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(ERR_IO_PENDING, out.rv);
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.rv = callback1.WaitForResult();
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, out.rv);
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.rv = callback3.WaitForResult();
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, out.rv);
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response1 = trans1->GetResponseInfo();
928868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response1->headers.get() != NULL);
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response1->was_fetched_via_spdy);
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.status_line = response1->headers->GetStatusLine();
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.response_info = *response1;
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans2->GetResponseInfo();
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.rv = ReadTransaction(trans1.get(), &out.response_data);
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  helper.VerifyDataConsumed();
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!hello!", out.response_data);
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, TwoGetsLateBinding) {
94590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
94690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
9477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false));
9497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> fbody(spdy_util_.ConstructSpdyBodyFrame(1, true));
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req2(
95290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
9537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
9547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, false));
9557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> fbody2(spdy_util_.ConstructSpdyBodyFrame(3, true));
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes[] = {
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req),
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req2),
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads[] = {
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp, 1),
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body),
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp2, 4),
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body2),
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*fbody),
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*fbody2),
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0),  // EOF
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData data(reads, arraysize(reads),
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         writes, arraysize(writes));
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData data_placeholder(NULL, 0, NULL, 0);
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_placeholder.set_connect_data(never_finishing_connect);
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BoundNetLog log;
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TransactionHelperResult out;
9802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     BoundNetLog(), GetParam(), NULL);
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  helper.RunPreTestSetup();
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  helper.AddData(&data);
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We require placeholder data because two get requests are sent out, so
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // there needs to be two sets of SSL connection data.
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  helper.AddData(&data_placeholder);
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpNetworkTransaction> trans1(
988868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpNetworkTransaction> trans2(
990868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo httpreq1 = CreateGetRequest();
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo httpreq2 = CreateGetRequest();
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.rv = trans1->Start(&httpreq1, callback1.callback(), log);
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(ERR_IO_PENDING, out.rv);
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.rv = trans2->Start(&httpreq2, callback2.callback(), log);
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(ERR_IO_PENDING, out.rv);
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.rv = callback1.WaitForResult();
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, out.rv);
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.rv = callback2.WaitForResult();
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, out.rv);
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response1 = trans1->GetResponseInfo();
1009868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response1->headers.get() != NULL);
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response1->was_fetched_via_spdy);
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.status_line = response1->headers->GetStatusLine();
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.response_info = *response1;
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.rv = ReadTransaction(trans1.get(), &out.response_data);
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!hello!", out.response_data);
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response2 = trans2->GetResponseInfo();
1019868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response2->headers.get() != NULL);
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response2->was_fetched_via_spdy);
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.status_line = response2->headers->GetStatusLine();
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.response_info = *response2;
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.rv = ReadTransaction(trans2.get(), &out.response_data);
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!hello!", out.response_data);
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  helper.VerifyDataConsumed();
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, TwoGetsLateBindingFromPreconnect) {
103290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
103390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
10347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false));
10367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> fbody(spdy_util_.ConstructSpdyBodyFrame(1, true));
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req2(
103990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
10407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, false));
10427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> fbody2(spdy_util_.ConstructSpdyBodyFrame(3, true));
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes[] = {
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req),
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req2),
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads[] = {
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp, 1),
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body),
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp2, 4),
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body2),
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*fbody),
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*fbody2),
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0),  // EOF
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData preconnect_data(reads, arraysize(reads),
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    writes, arraysize(writes));
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect never_finishing_connect(ASYNC, ERR_IO_PENDING);
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData data_placeholder(NULL, 0, NULL, 0);
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_placeholder.set_connect_data(never_finishing_connect);
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BoundNetLog log;
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TransactionHelperResult out;
10672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     BoundNetLog(), GetParam(), NULL);
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  helper.RunPreTestSetup();
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  helper.AddData(&preconnect_data);
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We require placeholder data because 3 connections are attempted (first is
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the preconnect, 2nd and 3rd are the never finished connections.
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  helper.AddData(&data_placeholder);
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  helper.AddData(&data_placeholder);
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpNetworkTransaction> trans1(
1077868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpNetworkTransaction> trans2(
1079868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo httpreq = CreateGetRequest();
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Preconnect the first.
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLConfig preconnect_ssl_config;
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  helper.session()->ssl_config_service()->GetSSLConfig(&preconnect_ssl_config);
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpStreamFactory* http_stream_factory =
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      helper.session()->http_stream_factory();
1091cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  helper.session()->GetNextProtos(&preconnect_ssl_config.next_protos);
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_stream_factory->PreconnectStreams(
10942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      1, httpreq, DEFAULT_PRIORITY,
10952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      preconnect_ssl_config, preconnect_ssl_config);
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.rv = trans1->Start(&httpreq, callback1.callback(), log);
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(ERR_IO_PENDING, out.rv);
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.rv = trans2->Start(&httpreq, callback2.callback(), log);
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(ERR_IO_PENDING, out.rv);
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.rv = callback1.WaitForResult();
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, out.rv);
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.rv = callback2.WaitForResult();
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, out.rv);
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response1 = trans1->GetResponseInfo();
1108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response1->headers.get() != NULL);
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response1->was_fetched_via_spdy);
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.status_line = response1->headers->GetStatusLine();
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.response_info = *response1;
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.rv = ReadTransaction(trans1.get(), &out.response_data);
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!hello!", out.response_data);
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response2 = trans2->GetResponseInfo();
1118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response2->headers.get() != NULL);
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response2->was_fetched_via_spdy);
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.status_line = response2->headers->GetStatusLine();
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.response_info = *response2;
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.rv = ReadTransaction(trans2.get(), &out.response_data);
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!hello!", out.response_data);
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  helper.VerifyDataConsumed();
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Similar to ThreeGets above, however this test adds a SETTINGS
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// frame.  The SETTINGS frame is read during the IO loop waiting on
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the first transaction completion, and sets a maximum concurrent
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// stream limit of 1.  This means that our IO loop exists after the
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// second transaction completes, so we can assert on read_index().
11357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrent) {
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Construct the request.
113790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
113890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
11397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false));
11417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> fbody(spdy_util_.ConstructSpdyBodyFrame(1, true));
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
114390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req2(
114490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
11457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, false));
11477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> fbody2(spdy_util_.ConstructSpdyBodyFrame(3, true));
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
114990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req3(
115090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 5, LOWEST, true));
11517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp3(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 5));
11527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(5, false));
11537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> fbody3(spdy_util_.ConstructSpdyBodyFrame(5, true));
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SettingsMap settings;
11562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const uint32 max_concurrent_streams = 1;
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
115990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> settings_frame(
116090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdySettings(settings));
1161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<SpdyFrame> settings_ack(spdy_util_.ConstructSpdySettingsAck());
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes[] = {
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req),
1165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    CreateMockWrite(*settings_ack, 2),
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req2),
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req3),
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads[] = {
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*settings_frame, 1),
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp),
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body),
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*fbody),
1175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    CreateMockRead(*resp2, 8),
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body2),
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*fbody2),
1178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    CreateMockRead(*resp3, 13),
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body3),
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*fbody3),
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0),  // EOF
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData data(reads, arraysize(reads),
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         writes, arraysize(writes));
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData data_placeholder(NULL, 0, NULL, 0);
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BoundNetLog log;
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TransactionHelperResult out;
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
11922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       BoundNetLog(), GetParam(), NULL);
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    helper.RunPreTestSetup();
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    helper.AddData(&data);
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We require placeholder data because three get requests are sent out, so
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // there needs to be three sets of SSL connection data.
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    helper.AddData(&data_placeholder);
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    helper.AddData(&data_placeholder);
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<HttpNetworkTransaction> trans1(
1201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<HttpNetworkTransaction> trans2(
1203868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<HttpNetworkTransaction> trans3(
1205868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback1;
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback2;
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback3;
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo httpreq1 = CreateGetRequest();
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo httpreq2 = CreateGetRequest();
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo httpreq3 = CreateGetRequest();
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    out.rv = trans1->Start(&httpreq1, callback1.callback(), log);
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(out.rv, ERR_IO_PENDING);
12177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // Run transaction 1 through quickly to force a read of our SETTINGS
12187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // frame.
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    out.rv = callback1.WaitForResult();
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(OK, out.rv);
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    out.rv = trans2->Start(&httpreq2, callback2.callback(), log);
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(out.rv, ERR_IO_PENDING);
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    out.rv = trans3->Start(&httpreq3, callback3.callback(), log);
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(out.rv, ERR_IO_PENDING);
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    out.rv = callback2.WaitForResult();
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(OK, out.rv);
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(7U, data.read_index());  // i.e. the third trans was queued
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    out.rv = callback3.WaitForResult();
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(OK, out.rv);
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response1 = trans1->GetResponseInfo();
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response1 != NULL);
1235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_TRUE(response1->headers.get() != NULL);
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(response1->was_fetched_via_spdy);
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    out.status_line = response1->headers->GetStatusLine();
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    out.response_info = *response1;
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    out.rv = ReadTransaction(trans1.get(), &out.response_data);
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, out.rv);
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("hello!hello!", out.response_data);
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response2 = trans2->GetResponseInfo();
12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    out.status_line = response2->headers->GetStatusLine();
12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    out.response_info = *response2;
12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    out.rv = ReadTransaction(trans2.get(), &out.response_data);
12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, out.rv);
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("hello!hello!", out.response_data);
12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response3 = trans3->GetResponseInfo();
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    out.status_line = response3->headers->GetStatusLine();
12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    out.response_info = *response3;
12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    out.rv = ReadTransaction(trans3.get(), &out.response_data);
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, out.rv);
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("hello!hello!", out.response_data);
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    helper.VerifyDataConsumed();
12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Similar to ThreeGetsWithMaxConcurrent above, however this test adds
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a fourth transaction.  The third and fourth transactions have
12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// different data ("hello!" vs "hello!hello!") and because of the
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// user specified priority, we expect to see them inverted in
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the response from the server.
12707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, FourGetsWithMaxConcurrentPriority) {
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Construct the request.
127290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
127390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
12747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false));
12767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> fbody(spdy_util_.ConstructSpdyBodyFrame(1, true));
12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
127890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req2(
127990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
12807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
12817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, false));
12827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> fbody2(spdy_util_.ConstructSpdyBodyFrame(3, true));
12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> req4(
128590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 5, HIGHEST, true));
12867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp4(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 5));
12877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> fbody4(spdy_util_.ConstructSpdyBodyFrame(5, true));
12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
128990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req3(
129090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 7, LOWEST, true));
12917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp3(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 7));
12927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(7, false));
12937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> fbody3(spdy_util_.ConstructSpdyBodyFrame(7, true));
12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SettingsMap settings;
12962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const uint32 max_concurrent_streams = 1;
12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
129990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> settings_frame(
130090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdySettings(settings));
1301cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<SpdyFrame> settings_ack(spdy_util_.ConstructSpdySettingsAck());
13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes[] = { CreateMockWrite(*req),
1304cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    CreateMockWrite(*settings_ack, 2),
13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req2),
13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req4),
13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req3),
13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads[] = {
13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*settings_frame, 1),
13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp),
13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body),
13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*fbody),
1314cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    CreateMockRead(*resp2, 8),
13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body2),
13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*fbody2),
1317cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    CreateMockRead(*resp4, 14),
13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*fbody4),
1319cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    CreateMockRead(*resp3, 17),
13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body3),
13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*fbody3),
13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0),  // EOF
13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData data(reads, arraysize(reads),
13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         writes, arraysize(writes));
13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData data_placeholder(NULL, 0, NULL, 0);
13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BoundNetLog log;
13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TransactionHelperResult out;
13322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
13332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     BoundNetLog(), GetParam(), NULL);
13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  helper.RunPreTestSetup();
13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  helper.AddData(&data);
13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We require placeholder data because four get requests are sent out, so
13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // there needs to be four sets of SSL connection data.
13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  helper.AddData(&data_placeholder);
13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  helper.AddData(&data_placeholder);
13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  helper.AddData(&data_placeholder);
13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpNetworkTransaction> trans1(
1342868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpNetworkTransaction> trans2(
1344868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpNetworkTransaction> trans3(
1346868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpNetworkTransaction> trans4(
1348868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(HIGHEST, helper.session().get()));
13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback3;
13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback4;
13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo httpreq1 = CreateGetRequest();
13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo httpreq2 = CreateGetRequest();
13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo httpreq3 = CreateGetRequest();
13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo httpreq4 = CreateGetRequest();
13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.rv = trans1->Start(&httpreq1, callback1.callback(), log);
13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(ERR_IO_PENDING, out.rv);
13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Run transaction 1 through quickly to force a read of our SETTINGS frame.
13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.rv = callback1.WaitForResult();
13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, out.rv);
13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.rv = trans2->Start(&httpreq2, callback2.callback(), log);
13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(ERR_IO_PENDING, out.rv);
13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.rv = trans3->Start(&httpreq3, callback3.callback(), log);
13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(ERR_IO_PENDING, out.rv);
13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.rv = trans4->Start(&httpreq4, callback4.callback(), log);
13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(ERR_IO_PENDING, out.rv);
13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.rv = callback2.WaitForResult();
13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, out.rv);
13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(data.read_index(), 7U);  // i.e. the third & fourth trans queued
13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.rv = callback3.WaitForResult();
13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, out.rv);
13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response1 = trans1->GetResponseInfo();
1381868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response1->headers.get() != NULL);
13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response1->was_fetched_via_spdy);
13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.status_line = response1->headers->GetStatusLine();
13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.response_info = *response1;
13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.rv = ReadTransaction(trans1.get(), &out.response_data);
13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!hello!", out.response_data);
13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response2 = trans2->GetResponseInfo();
13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.status_line = response2->headers->GetStatusLine();
13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.response_info = *response2;
13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.rv = ReadTransaction(trans2.get(), &out.response_data);
13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!hello!", out.response_data);
13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // notice: response3 gets two hellos, response4 gets one
13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // hello, so we know dequeuing priority was respected.
14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response3 = trans3->GetResponseInfo();
14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.status_line = response3->headers->GetStatusLine();
14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.response_info = *response3;
14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.rv = ReadTransaction(trans3.get(), &out.response_data);
14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!hello!", out.response_data);
14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.rv = callback4.WaitForResult();
14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response4 = trans4->GetResponseInfo();
14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.status_line = response4->headers->GetStatusLine();
14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.response_info = *response4;
14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.rv = ReadTransaction(trans4.get(), &out.response_data);
14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", out.response_data);
14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  helper.VerifyDataConsumed();
14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Similar to ThreeGetsMaxConcurrrent above, however, this test
14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// deletes a session in the middle of the transaction to insure
14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that we properly remove pendingcreatestream objects from
14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the spdy_session
14257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrentDelete) {
14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Construct the request.
142790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
142890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
14297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
14307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false));
14317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> fbody(spdy_util_.ConstructSpdyBodyFrame(1, true));
14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
143390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req2(
143490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
14357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
14367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, false));
14377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> fbody2(spdy_util_.ConstructSpdyBodyFrame(3, true));
14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SettingsMap settings;
14402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const uint32 max_concurrent_streams = 1;
14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
144390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> settings_frame(
144490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdySettings(settings));
1445cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<SpdyFrame> settings_ack(spdy_util_.ConstructSpdySettingsAck());
14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1447cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  MockWrite writes[] = {
1448cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    CreateMockWrite(*req),
1449cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    CreateMockWrite(*settings_ack, 2),
14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req2),
14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads[] = {
14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*settings_frame, 1),
14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp),
14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body),
14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*fbody),
1457cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    CreateMockRead(*resp2, 8),
14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body2),
14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*fbody2),
14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0),  // EOF
14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData data(reads, arraysize(reads),
14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         writes, arraysize(writes));
14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData data_placeholder(NULL, 0, NULL, 0);
14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BoundNetLog log;
14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TransactionHelperResult out;
14692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
14702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     BoundNetLog(), GetParam(), NULL);
14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  helper.RunPreTestSetup();
14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  helper.AddData(&data);
14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We require placeholder data because three get requests are sent out, so
14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // there needs to be three sets of SSL connection data.
14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  helper.AddData(&data_placeholder);
14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  helper.AddData(&data_placeholder);
14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpNetworkTransaction> trans1(
1478868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpNetworkTransaction> trans2(
1480868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpNetworkTransaction> trans3(
1482868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback3;
14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo httpreq1 = CreateGetRequest();
14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo httpreq2 = CreateGetRequest();
14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo httpreq3 = CreateGetRequest();
14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.rv = trans1->Start(&httpreq1, callback1.callback(), log);
14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(out.rv, ERR_IO_PENDING);
14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Run transaction 1 through quickly to force a read of our SETTINGS frame.
14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.rv = callback1.WaitForResult();
14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, out.rv);
14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.rv = trans2->Start(&httpreq2, callback2.callback(), log);
14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(out.rv, ERR_IO_PENDING);
15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.rv = trans3->Start(&httpreq3, callback3.callback(), log);
15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete trans3.release();
15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(out.rv, ERR_IO_PENDING);
15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.rv = callback2.WaitForResult();
15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, out.rv);
15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(8U, data.read_index());
15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response1 = trans1->GetResponseInfo();
15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response1 != NULL);
1510868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response1->headers.get() != NULL);
15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response1->was_fetched_via_spdy);
15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.status_line = response1->headers->GetStatusLine();
15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.response_info = *response1;
15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.rv = ReadTransaction(trans1.get(), &out.response_data);
15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!hello!", out.response_data);
15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response2 = trans2->GetResponseInfo();
15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response2 != NULL);
15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.status_line = response2->headers->GetStatusLine();
15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.response_info = *response2;
15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out.rv = ReadTransaction(trans2.get(), &out.response_data);
15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!hello!", out.response_data);
15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  helper.VerifyDataConsumed();
15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The KillerCallback will delete the transaction on error as part of the
15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// callback.
15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class KillerCallback : public TestCompletionCallbackBase {
15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit KillerCallback(HttpNetworkTransaction* transaction)
15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : transaction_(transaction),
1539c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        callback_(base::Bind(&KillerCallback::OnComplete,
1540c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             base::Unretained(this))) {
15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~KillerCallback() {}
15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const CompletionCallback& callback() const { return callback_; }
15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnComplete(int result) {
15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (result < 0)
15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delete transaction_;
15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetResult(result);
15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpNetworkTransaction* transaction_;
15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CompletionCallback callback_;
15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Similar to ThreeGetsMaxConcurrrentDelete above, however, this test
15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// closes the socket while we have a pending transaction waiting for
15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a pending stream creation.  http://crbug.com/52901
15647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrentSocketClose) {
15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Construct the request.
156690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
156790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
15687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
15697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false));
15707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> fin_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
157290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req2(
157390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
15747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SettingsMap settings;
15772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const uint32 max_concurrent_streams = 1;
15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
158090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> settings_frame(
158190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdySettings(settings));
1582cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<SpdyFrame> settings_ack(spdy_util_.ConstructSpdySettingsAck());
15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1584cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  MockWrite writes[] = {
1585cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    CreateMockWrite(*req),
1586cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    CreateMockWrite(*settings_ack, 2),
15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req2),
15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1589