13551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
23551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
33551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// found in the LICENSE file.
43551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
53551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "net/tools/flip_server/spdy_interface.h"
63551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
73551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include <list>
83551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
93551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/strings/string_piece.h"
113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "net/spdy/buffered_spdy_framer.h"
124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "net/tools/balsa/balsa_enums.h"
134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "net/tools/balsa/balsa_headers.h"
143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "net/tools/flip_server/flip_config.h"
153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "net/tools/flip_server/flip_test_utils.h"
163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "net/tools/flip_server/mem_cache.h"
173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)namespace net {
213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)using ::base::StringPiece;
233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)using ::testing::_;
243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)using ::testing::InSequence;
253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)using ::testing::InvokeWithoutArgs;
263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)using ::testing::Return;
273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)using ::testing::SaveArg;
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using ::testing::Values;
293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)namespace {
313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)struct StringSaver {
333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public:
343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  StringSaver() : data(NULL), size(0) {}
35a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void Save() { string = std::string(data, size); }
363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const char* data;
383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  size_t size;
393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::string string;
403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)};
413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class SpdyFramerVisitor : public BufferedSpdyFramerVisitorInterface {
433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public:
443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual ~SpdyFramerVisitor() {}
453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MOCK_METHOD1(OnError, void(SpdyFramer::SpdyError));
463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MOCK_METHOD2(OnStreamError, void(SpdyStreamId, const std::string&));
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MOCK_METHOD6(OnSynStream,
48a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)               void(SpdyStreamId,
49a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    SpdyStreamId,
50a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    SpdyPriority,
51a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    bool,
52a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    bool,
53a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    const SpdyHeaderBlock&));
543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MOCK_METHOD3(OnSynReply, void(SpdyStreamId, bool, const SpdyHeaderBlock&));
553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MOCK_METHOD3(OnHeaders, void(SpdyStreamId, bool, const SpdyHeaderBlock&));
56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  MOCK_METHOD3(OnDataFrameHeader, void(SpdyStreamId, size_t, bool));
573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MOCK_METHOD4(OnStreamFrameData, void(SpdyStreamId,
583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                       const char*,
593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                       size_t,
603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                       bool));
61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  MOCK_METHOD1(OnSettings, void(bool clear_persisted));
623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MOCK_METHOD3(OnSetting, void(SpdySettingsIds, uint8, uint32));
63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  MOCK_METHOD2(OnPing, void(SpdyPingId unique_id, bool is_ack));
643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MOCK_METHOD2(OnRstStream, void(SpdyStreamId, SpdyRstStreamStatus));
653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MOCK_METHOD2(OnGoAway, void(SpdyStreamId, SpdyGoAwayStatus));
663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MOCK_METHOD2(OnWindowUpdate, void(SpdyStreamId, uint32));
67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  MOCK_METHOD3(OnPushPromise,
68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)               void(SpdyStreamId, SpdyStreamId, const SpdyHeaderBlock&));
6903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  MOCK_METHOD2(OnUnknownFrame, bool(SpdyStreamId stream_id, int frame_type));
703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)};
713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class FakeSMConnection : public SMConnection {
733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public:
743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FakeSMConnection(EpollServer* epoll_server,
753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                   SSLState* ssl_state,
763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                   MemoryCache* memory_cache,
773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                   FlipAcceptor* acceptor,
783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                   std::string log_prefix)
793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      : SMConnection(epoll_server,
803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                     ssl_state,
813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                     memory_cache,
823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                     acceptor,
833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                     log_prefix) {}
843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MOCK_METHOD0(Cleanup, void());
86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  MOCK_METHOD8(InitSMConnection,
87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)               void(SMConnectionPoolInterface*,
88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    SMInterface*,
89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    EpollServer*,
90a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    int,
91a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    std::string,
92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    std::string,
93a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    std::string,
94a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    bool));
953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)};
963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// This class is almost SpdySM, except one function.
98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// This class is the test target of tests in this file.
99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class TestSpdySM : public SpdySM {
1003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public:
101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual ~TestSpdySM() {}
102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  TestSpdySM(SMConnection* connection,
103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)             SMInterface* sm_http_interface,
104a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)             EpollServer* epoll_server,
105a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)             MemoryCache* memory_cache,
106a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)             FlipAcceptor* acceptor,
107a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)             SpdyMajorVersion version)
1083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      : SpdySM(connection,
1093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)               sm_http_interface,
1103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)               epoll_server,
1113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)               memory_cache,
112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)               acceptor,
113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)               version) {}
1143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MOCK_METHOD2(FindOrMakeNewSMConnectionInterface,
1163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)               SMInterface*(const std::string&, const std::string&));
1173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)};
1183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class SpdySMTestBase : public ::testing::TestWithParam<SpdyMajorVersion> {
1203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public:
121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  explicit SpdySMTestBase(FlipHandlerType type) {
1223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    SSLState* ssl_state = NULL;
1233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    mock_another_interface_.reset(new MockSMInterface);
1243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    memory_cache_.reset(new MemoryCache);
1253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    acceptor_.reset(new FlipAcceptor(type,
1263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                     "127.0.0.1",
1273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                     "8941",
1283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                     "ssl_cert_filename",
1293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                     "ssl_key_filename",
1303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                     "127.0.0.1",
1313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                     "8942",
1323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                     "127.0.0.1",
1333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                     "8943",
1343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                     1,
1353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                     0,
1363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                     true,
1373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                     1,
1383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                     false,
1393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                     true,
1403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                     NULL));
1413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    epoll_server_.reset(new EpollServer);
1423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    connection_.reset(new FakeSMConnection(epoll_server_.get(),
1433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                           ssl_state,
1443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                           memory_cache_.get(),
1453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                           acceptor_.get(),
1463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                           "log_prefix"));
1473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    interface_.reset(new TestSpdySM(connection_.get(),
149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    mock_another_interface_.get(),
150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    epoll_server_.get(),
151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    memory_cache_.get(),
152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    acceptor_.get(),
153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    GetParam()));
1543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    spdy_framer_.reset(new BufferedSpdyFramer(GetParam(), true));
1563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    spdy_framer_visitor_.reset(new SpdyFramerVisitor);
1573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    spdy_framer_->set_visitor(spdy_framer_visitor_.get());
1583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
1593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual ~SpdySMTestBase() {
1613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (acceptor_->listen_fd_ >= 0) {
1623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      epoll_server_->UnregisterFD(acceptor_->listen_fd_);
1633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      close(acceptor_->listen_fd_);
1643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      acceptor_->listen_fd_ = -1;
1653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
1663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    OutputList& output_list = *connection_->output_list();
1673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    for (OutputList::const_iterator i = output_list.begin();
1683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)         i != output_list.end();
1693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)         ++i) {
1703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      delete *i;
1713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
1723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    output_list.clear();
1733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
1743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  bool HasStream(uint32 stream_id) {
1763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return interface_->output_ordering().ExistsInPriorityMaps(stream_id);
1773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
1783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) protected:
1803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<MockSMInterface> mock_another_interface_;
1813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<MemoryCache> memory_cache_;
1823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<FlipAcceptor> acceptor_;
1833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<EpollServer> epoll_server_;
1843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<FakeSMConnection> connection_;
185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<TestSpdySM> interface_;
1863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<BufferedSpdyFramer> spdy_framer_;
1873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<SpdyFramerVisitor> spdy_framer_visitor_;
1883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)};
1893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class SpdySMProxyTest : public SpdySMTestBase {
1913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public:
192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SpdySMProxyTest() : SpdySMTestBase(FLIP_HANDLER_PROXY) {}
193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual ~SpdySMProxyTest() {}
1943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)};
1953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
196f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class SpdySMServerTest : public SpdySMTestBase {
1973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public:
198a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SpdySMServerTest() : SpdySMTestBase(FLIP_HANDLER_SPDY_SERVER) {}
199f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual ~SpdySMServerTest() {}
2003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)};
2013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)INSTANTIATE_TEST_CASE_P(SpdySMProxyTest,
203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                        SpdySMProxyTest,
204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                        Values(SPDY2, SPDY3, SPDY4));
205a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)INSTANTIATE_TEST_CASE_P(SpdySMServerTest, SpdySMServerTest, Values(SPDY2));
206f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
207f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_P(SpdySMProxyTest, InitSMConnection) {
2083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {
2093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    InSequence s;
2103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    EXPECT_CALL(*connection_, InitSMConnection(_, _, _, _, _, _, _, _));
2113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
212a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  interface_->InitSMConnection(
213a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      NULL, NULL, epoll_server_.get(), -1, "", "", "", false);
2143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
2153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
216a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_P(SpdySMProxyTest, OnSynStream_SPDY2) {
217a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (GetParam() != SPDY2) {
218a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // This test case is for SPDY2.
219a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
220a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
2213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  BufferedSpdyFramerVisitorInterface* visitor = interface_.get();
2223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<MockSMInterface> mock_interface(new MockSMInterface);
2233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  uint32 stream_id = 92;
2243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  uint32 associated_id = 43;
2253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::string expected = "GET /path HTTP/1.0\r\n"
226a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "Host: 127.0.0.1\r\n"
227a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "hoge: fuga\r\n\r\n";
2283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  SpdyHeaderBlock block;
2293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  block["method"] = "GET";
230a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  block["url"] = "/path";
2313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  block["scheme"] = "http";
2323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  block["version"] = "HTTP/1.0";
233a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  block["hoge"] = "fuga";
234a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  StringSaver saver;
235a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  {
236a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    InSequence s;
237a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_CALL(*interface_, FindOrMakeNewSMConnectionInterface(_, _))
238a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        .WillOnce(Return(mock_interface.get()));
239a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_CALL(*mock_interface, SetStreamID(stream_id));
240a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_CALL(*mock_interface, ProcessWriteInput(_, _))
241a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        .WillOnce(DoAll(SaveArg<0>(&saver.data),
242a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                        SaveArg<1>(&saver.size),
243a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                        InvokeWithoutArgs(&saver, &StringSaver::Save),
244a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                        Return(0)));
245a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  visitor->OnSynStream(stream_id, associated_id, 0, false, false, block);
247a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(expected, saver.string);
248a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
249a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
250a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_P(SpdySMProxyTest, OnSynStream) {
251a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (GetParam() == SPDY2) {
252a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // This test case is not for SPDY2.
253a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
254a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
255a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  BufferedSpdyFramerVisitorInterface* visitor = interface_.get();
256a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_ptr<MockSMInterface> mock_interface(new MockSMInterface);
257a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  uint32 stream_id = 92;
258a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  uint32 associated_id = 43;
259a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::string expected = "GET /path HTTP/1.1\r\n"
260a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "Host: 127.0.0.1\r\n"
261a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "foo: bar\r\n\r\n";
262a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SpdyHeaderBlock block;
263a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  block[":method"] = "GET";
264a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  block[":host"] = "www.example.com";
265a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  block[":path"] = "/path";
266a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  block[":scheme"] = "http";
267a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  block["foo"] = "bar";
2683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  StringSaver saver;
2693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {
2703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    InSequence s;
2713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    EXPECT_CALL(*interface_,
2723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                FindOrMakeNewSMConnectionInterface(_, _))
2733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        .WillOnce(Return(mock_interface.get()));
2743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    EXPECT_CALL(*mock_interface, SetStreamID(stream_id));
2753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    EXPECT_CALL(*mock_interface, ProcessWriteInput(_, _))
2763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        .WillOnce(DoAll(SaveArg<0>(&saver.data),
2773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                        SaveArg<1>(&saver.size),
2783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                        InvokeWithoutArgs(&saver, &StringSaver::Save),
2793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                        Return(0)));
2803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  visitor->OnSynStream(stream_id, associated_id, 0, false, false, block);
2823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(expected, saver.string);
2833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
2843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
285a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_P(SpdySMProxyTest, OnStreamFrameData_SPDY2) {
286a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (GetParam() != SPDY2) {
287a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // This test case is for SPDY2.
288a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
289a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
2903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  BufferedSpdyFramerVisitorInterface* visitor = interface_.get();
2913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<MockSMInterface> mock_interface(new MockSMInterface);
2923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  uint32 stream_id = 92;
2933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  uint32 associated_id = 43;
2943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  SpdyHeaderBlock block;
295f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  testing::MockFunction<void(int)> checkpoint;  // NOLINT
2963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
297a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<SpdyFrame> frame(spdy_framer_->CreatePingFrame(12, false));
2983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  block["method"] = "GET";
2993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  block["url"] = "http://www.example.com/path";
3003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  block["scheme"] = "http";
3013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  block["version"] = "HTTP/1.0";
3023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {
3033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    InSequence s;
304a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_CALL(*interface_, FindOrMakeNewSMConnectionInterface(_, _))
305a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        .WillOnce(Return(mock_interface.get()));
306a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_CALL(*mock_interface, SetStreamID(stream_id));
307a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_CALL(*mock_interface, ProcessWriteInput(_, _)).Times(1);
308a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_CALL(checkpoint, Call(0));
309a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_CALL(*mock_interface,
310a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                ProcessWriteInput(frame->data(), frame->size())).Times(1);
311a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
312a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  visitor->OnSynStream(stream_id, associated_id, 0, false, false, block);
314a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  checkpoint.Call(0);
315a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  visitor->OnStreamFrameData(stream_id, frame->data(), frame->size(), true);
316a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
317a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
318a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_P(SpdySMProxyTest, OnStreamFrameData) {
319a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (GetParam() == SPDY2) {
320a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // This test case is not for SPDY2.
321a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
322a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
323a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  BufferedSpdyFramerVisitorInterface* visitor = interface_.get();
324a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_ptr<MockSMInterface> mock_interface(new MockSMInterface);
325a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  uint32 stream_id = 92;
326a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  uint32 associated_id = 43;
327a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SpdyHeaderBlock block;
328a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  testing::MockFunction<void(int)> checkpoint;  // NOLINT
329a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
330a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<SpdyFrame> frame(spdy_framer_->CreatePingFrame(12, false));
331a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  block[":method"] = "GET";
332a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  block[":host"] = "www.example.com";
333a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  block[":path"] = "/path";
334a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  block[":scheme"] = "http";
335a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  block["foo"] = "bar";
336a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  {
337a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    InSequence s;
3383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    EXPECT_CALL(*interface_,
3393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                FindOrMakeNewSMConnectionInterface(_, _))
3403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        .WillOnce(Return(mock_interface.get()));
3413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    EXPECT_CALL(*mock_interface, SetStreamID(stream_id));
3423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    EXPECT_CALL(*mock_interface, ProcessWriteInput(_, _)).Times(1);
3433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    EXPECT_CALL(checkpoint, Call(0));
3443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    EXPECT_CALL(*mock_interface,
3453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                ProcessWriteInput(frame->data(), frame->size())).Times(1);
3463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
3473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  visitor->OnSynStream(stream_id, associated_id, 0, false, false, block);
3493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  checkpoint.Call(0);
3503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  visitor->OnStreamFrameData(stream_id, frame->data(), frame->size(), true);
3513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
3523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
353f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_P(SpdySMProxyTest, OnRstStream) {
3543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  BufferedSpdyFramerVisitorInterface* visitor = interface_.get();
3553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  uint32 stream_id = 82;
3563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MemCacheIter mci;
3573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  mci.stream_id = stream_id;
3583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {
3603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    BalsaHeaders headers;
3613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    std::string filename = "foobar";
3623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    memory_cache_->InsertFile(&headers, filename, "");
3633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    mci.file_data = memory_cache_->GetFileData(filename);
3643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
3653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  interface_->AddToOutputOrder(mci);
3673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_TRUE(HasStream(stream_id));
3683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  visitor->OnRstStream(stream_id, RST_STREAM_INVALID);
3693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_FALSE(HasStream(stream_id));
3703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
3713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
372f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_P(SpdySMProxyTest, ProcessReadInput) {
3733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(SpdyFramer::SPDY_RESET, interface_->spdy_framer()->state());
3743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  interface_->ProcessReadInput("", 1);
3753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(SpdyFramer::SPDY_READING_COMMON_HEADER,
3763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            interface_->spdy_framer()->state());
3773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
3783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
379f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_P(SpdySMProxyTest, ResetForNewConnection) {
3803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  uint32 stream_id = 13;
3813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MemCacheIter mci;
3823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  mci.stream_id = stream_id;
3833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // incomplete input
3843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const char input[] = {'\0', '\0', '\0'};
3853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {
3873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    BalsaHeaders headers;
3883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    std::string filename = "foobar";
3893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    memory_cache_->InsertFile(&headers, filename, "");
3903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    mci.file_data = memory_cache_->GetFileData(filename);
3913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
3923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  interface_->AddToOutputOrder(mci);
3943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_TRUE(HasStream(stream_id));
3953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  interface_->ProcessReadInput(input, sizeof(input));
3963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_NE(SpdyFramer::SPDY_RESET, interface_->spdy_framer()->state());
3973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  interface_->ResetForNewConnection();
3993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_FALSE(HasStream(stream_id));
400a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(interface_->spdy_framer() == NULL);
401a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
402a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
403a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_P(SpdySMProxyTest, CreateFramer) {
404a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  interface_->ResetForNewConnection();
405a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  interface_->CreateFramer(SPDY2);
406a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(interface_->spdy_framer() != NULL);
407a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(interface_->spdy_version(), SPDY2);
408a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
409a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  interface_->ResetForNewConnection();
410a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  interface_->CreateFramer(SPDY3);
411a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(interface_->spdy_framer() != NULL);
412a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(interface_->spdy_version(), SPDY3);
4133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
4143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
415f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_P(SpdySMProxyTest, PostAcceptHook) {
4163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  interface_->PostAcceptHook();
4173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(1u, connection_->output_list()->size());
4193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::list<DataFrame*>::const_iterator i = connection_->output_list()->begin();
4203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DataFrame* df = *i++;
4213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {
4233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    InSequence s;
4243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    EXPECT_CALL(*spdy_framer_visitor_, OnSettings(false));
425a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_CALL(*spdy_framer_visitor_,
426a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                OnSetting(SETTINGS_MAX_CONCURRENT_STREAMS, 0u, 100u));
4273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
4283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  spdy_framer_->ProcessInput(df->data, df->size);
4293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
4303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
431f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_P(SpdySMProxyTest, NewStream) {
4323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // TODO(yhirano): SpdySM::NewStream leads to crash when
4333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // acceptor_->flip_handler_type_ != FLIP_HANDLER_SPDY_SERVER.
4343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // It should be fixed though I don't know the solution now.
4353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
4363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
437f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_P(SpdySMProxyTest, AddToOutputOrder) {
4383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  uint32 stream_id = 13;
4393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MemCacheIter mci;
4403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  mci.stream_id = stream_id;
4413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {
4433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    BalsaHeaders headers;
4443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    std::string filename = "foobar";
4453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    memory_cache_->InsertFile(&headers, filename, "");
4463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    mci.file_data = memory_cache_->GetFileData(filename);
4473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
4483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  interface_->AddToOutputOrder(mci);
4503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_TRUE(HasStream(stream_id));
4513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
4523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
453a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_P(SpdySMProxyTest, SendErrorNotFound_SPDY2) {
454a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (GetParam() != SPDY2) {
455a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // This test is for SPDY2.
456a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
457a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
458a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  uint32 stream_id = 82;
459a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SpdyHeaderBlock actual_header_block;
460a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const char* actual_data;
461a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  size_t actual_size;
462a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  testing::MockFunction<void(int)> checkpoint;  // NOLINT
463a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
464a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  interface_->SendErrorNotFound(stream_id);
465a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
466a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(2u, connection_->output_list()->size());
467a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
468a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  {
469a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    InSequence s;
4705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (GetParam() < SPDY4) {
4715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_CALL(*spdy_framer_visitor_, OnSynReply(stream_id, false, _))
4725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          .WillOnce(SaveArg<2>(&actual_header_block));
4735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else {
4745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_CALL(*spdy_framer_visitor_, OnHeaders(stream_id, false, _))
4755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          .WillOnce(SaveArg<2>(&actual_header_block));
4765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
477a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_CALL(checkpoint, Call(0));
478a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_CALL(*spdy_framer_visitor_,
479a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                OnDataFrameHeader(stream_id, _, true));
480a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_CALL(*spdy_framer_visitor_,
481a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                OnStreamFrameData(stream_id, _, _, false)).Times(1)
482a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        .WillOnce(DoAll(SaveArg<1>(&actual_data),
483a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                        SaveArg<2>(&actual_size)));
484a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_CALL(*spdy_framer_visitor_,
485a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                OnStreamFrameData(stream_id, NULL, 0, true)).Times(1);
486a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
487a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
488a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::list<DataFrame*>::const_iterator i = connection_->output_list()->begin();
489a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DataFrame* df = *i++;
490a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  spdy_framer_->ProcessInput(df->data, df->size);
491a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  checkpoint.Call(0);
492a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  df = *i++;
493a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  spdy_framer_->ProcessInput(df->data, df->size);
494a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
495a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(2, spdy_framer_->frames_received());
496a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(2u, actual_header_block.size());
497a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ("404 Not Found", actual_header_block["status"]);
498a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ("HTTP/1.1", actual_header_block["version"]);
499a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ("wtf?", StringPiece(actual_data, actual_size));
500a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
501a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
502f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_P(SpdySMProxyTest, SendErrorNotFound) {
503a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (GetParam() == SPDY2) {
504a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // This test is not for SPDY2.
505a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
506a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
5073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  uint32 stream_id = 82;
5083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  SpdyHeaderBlock actual_header_block;
5093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const char* actual_data;
5103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  size_t actual_size;
511f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  testing::MockFunction<void(int)> checkpoint;  // NOLINT
5123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  interface_->SendErrorNotFound(stream_id);
5143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(2u, connection_->output_list()->size());
5163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {
5183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    InSequence s;
5195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (GetParam() < SPDY4) {
5205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_CALL(*spdy_framer_visitor_,
5215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                  OnSynReply(stream_id, false, _))
5225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          .WillOnce(SaveArg<2>(&actual_header_block));
5235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else {
5245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_CALL(*spdy_framer_visitor_,
5255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                  OnHeaders(stream_id, false, _))
5265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          .WillOnce(SaveArg<2>(&actual_header_block));
5275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
5283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    EXPECT_CALL(checkpoint, Call(0));
5293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    EXPECT_CALL(*spdy_framer_visitor_,
530a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                OnDataFrameHeader(stream_id, _, true));
531a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_CALL(*spdy_framer_visitor_,
5323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                OnStreamFrameData(stream_id, _, _, false)).Times(1)
5333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        .WillOnce(DoAll(SaveArg<1>(&actual_data),
5343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                        SaveArg<2>(&actual_size)));
5353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    EXPECT_CALL(*spdy_framer_visitor_,
5363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                OnStreamFrameData(stream_id, NULL, 0, true)).Times(1);
5373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
5383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::list<DataFrame*>::const_iterator i = connection_->output_list()->begin();
5403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DataFrame* df = *i++;
5413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  spdy_framer_->ProcessInput(df->data, df->size);
5423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  checkpoint.Call(0);
5433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  df = *i++;
5443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  spdy_framer_->ProcessInput(df->data, df->size);
5453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(2, spdy_framer_->frames_received());
5473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(2u, actual_header_block.size());
548a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ("404 Not Found", actual_header_block[":status"]);
549a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ("HTTP/1.1", actual_header_block[":version"]);
5503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ("wtf?", StringPiece(actual_data, actual_size));
5513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
5523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
553a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_P(SpdySMProxyTest, SendSynStream_SPDY2) {
554a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (GetParam() != SPDY2) {
555a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // This test is for SPDY2.
556a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
557a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
5583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  uint32 stream_id = 82;
5593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  BalsaHeaders headers;
5603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  SpdyHeaderBlock actual_header_block;
5613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  headers.AppendHeader("key1", "value1");
5623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  headers.SetRequestFirstlineFromStringPieces("GET", "/path", "HTTP/1.0");
5633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  interface_->SendSynStream(stream_id, headers);
5653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(1u, connection_->output_list()->size());
5673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::list<DataFrame*>::const_iterator i = connection_->output_list()->begin();
5683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DataFrame* df = *i++;
5693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {
5713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    InSequence s;
5723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    EXPECT_CALL(*spdy_framer_visitor_,
5735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                OnSynStream(stream_id, 0, _, false, false, _))
5745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        .WillOnce(SaveArg<5>(&actual_header_block));
5753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
5763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  spdy_framer_->ProcessInput(df->data, df->size);
5783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(1, spdy_framer_->frames_received());
5793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(4u, actual_header_block.size());
5803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ("GET", actual_header_block["method"]);
5813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ("HTTP/1.0", actual_header_block["version"]);
5823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ("/path", actual_header_block["url"]);
5833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ("value1", actual_header_block["key1"]);
5843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
5853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
586a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_P(SpdySMProxyTest, SendSynStream) {
587a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (GetParam() == SPDY2) {
588a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // This test is not for SPDY2.
589a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
590a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
591a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  uint32 stream_id = 82;
592a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  BalsaHeaders headers;
593a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SpdyHeaderBlock actual_header_block;
594a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  headers.AppendHeader("key1", "value1");
595a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  headers.AppendHeader("Host", "www.example.com");
596a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  headers.SetRequestFirstlineFromStringPieces("GET", "/path", "HTTP/1.1");
597a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
598a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  interface_->SendSynStream(stream_id, headers);
599a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
600a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(1u, connection_->output_list()->size());
601a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::list<DataFrame*>::const_iterator i = connection_->output_list()->begin();
602a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DataFrame* df = *i++;
603a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
604a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  {
605a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    InSequence s;
606a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_CALL(*spdy_framer_visitor_,
6075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                OnSynStream(stream_id, 0, _, false, false, _))
6085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        .WillOnce(SaveArg<5>(&actual_header_block));
609a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
610a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
611a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  spdy_framer_->ProcessInput(df->data, df->size);
612a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(1, spdy_framer_->frames_received());
613a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(5u, actual_header_block.size());
614a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ("GET", actual_header_block[":method"]);
615a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ("HTTP/1.1", actual_header_block[":version"]);
616a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ("/path", actual_header_block[":path"]);
617a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ("www.example.com", actual_header_block[":host"]);
618a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ("value1", actual_header_block["key1"]);
619a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
620a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
621a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_P(SpdySMProxyTest, SendSynReply_SPDY2) {
622a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (GetParam() != SPDY2) {
623a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // This test is for SPDY2.
624a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
625a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
6263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  uint32 stream_id = 82;
6273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  BalsaHeaders headers;
6283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  SpdyHeaderBlock actual_header_block;
6293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  headers.AppendHeader("key1", "value1");
6303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  headers.SetResponseFirstlineFromStringPieces("HTTP/1.1", "200", "OK");
6313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
6323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  interface_->SendSynReply(stream_id, headers);
6333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
6343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(1u, connection_->output_list()->size());
6353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::list<DataFrame*>::const_iterator i = connection_->output_list()->begin();
6363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DataFrame* df = *i++;
6373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
6383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {
6393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    InSequence s;
6405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (GetParam() < SPDY4) {
6415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_CALL(*spdy_framer_visitor_, OnSynReply(stream_id, false, _))
6425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          .WillOnce(SaveArg<2>(&actual_header_block));
6435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else {
6445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_CALL(*spdy_framer_visitor_, OnHeaders(stream_id, false, _))
6455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          .WillOnce(SaveArg<2>(&actual_header_block));
6465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
6473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
6483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
6493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  spdy_framer_->ProcessInput(df->data, df->size);
6503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(1, spdy_framer_->frames_received());
6513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(3u, actual_header_block.size());
6523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ("200 OK", actual_header_block["status"]);
6533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ("HTTP/1.1", actual_header_block["version"]);
6543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ("value1", actual_header_block["key1"]);
6553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
6563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
657a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_P(SpdySMProxyTest, SendSynReply) {
658a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (GetParam() == SPDY2) {
659a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // This test is not for SPDY2.
660a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
661a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
662a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  uint32 stream_id = 82;
663a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  BalsaHeaders headers;
664a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SpdyHeaderBlock actual_header_block;
665a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  headers.AppendHeader("key1", "value1");
666a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  headers.SetResponseFirstlineFromStringPieces("HTTP/1.1", "200", "OK");
667a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
668a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  interface_->SendSynReply(stream_id, headers);
669a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
670a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(1u, connection_->output_list()->size());
671a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::list<DataFrame*>::const_iterator i = connection_->output_list()->begin();
672a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DataFrame* df = *i++;
673a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
674a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  {
675a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    InSequence s;
6765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (GetParam() < SPDY4) {
6775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_CALL(*spdy_framer_visitor_, OnSynReply(stream_id, false, _))
6785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          .WillOnce(SaveArg<2>(&actual_header_block));
6795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else {
6805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_CALL(*spdy_framer_visitor_, OnHeaders(stream_id, false, _))
6815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          .WillOnce(SaveArg<2>(&actual_header_block));
6825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
683a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
684a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
685a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  spdy_framer_->ProcessInput(df->data, df->size);
686a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(1, spdy_framer_->frames_received());
687a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(3u, actual_header_block.size());
688a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ("200 OK", actual_header_block[":status"]);
689a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ("HTTP/1.1", actual_header_block[":version"]);
690a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ("value1", actual_header_block["key1"]);
691a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
692a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
693f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_P(SpdySMProxyTest, SendDataFrame) {
6943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  uint32 stream_id = 133;
6953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  SpdyDataFlags flags = DATA_FLAG_NONE;
6963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const char* actual_data;
6973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  size_t actual_size;
6983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
6993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  interface_->SendDataFrame(stream_id, "hello", 5, flags, true);
7003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
7013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(1u, connection_->output_list()->size());
7023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::list<DataFrame*>::const_iterator i = connection_->output_list()->begin();
7033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DataFrame* df = *i++;
7043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
7053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {
7063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    InSequence s;
7073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    EXPECT_CALL(*spdy_framer_visitor_,
708a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                OnDataFrameHeader(stream_id, _, false));
709a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_CALL(*spdy_framer_visitor_,
7103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                OnStreamFrameData(stream_id, _, _, false))
711a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        .WillOnce(DoAll(SaveArg<1>(&actual_data), SaveArg<2>(&actual_size)));
7123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
7133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
7143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  spdy_framer_->ProcessInput(df->data, df->size);
7153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(1, spdy_framer_->frames_received());
7163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ("hello", StringPiece(actual_data, actual_size));
7173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
7183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
719f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_P(SpdySMProxyTest, SendLongDataFrame) {
7203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  uint32 stream_id = 133;
7213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  SpdyDataFlags flags = DATA_FLAG_NONE;
7223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const char* actual_data;
7233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  size_t actual_size;
7243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
725a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::string data = std::string(kSpdySegmentSize, 'a') +
726a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     std::string(kSpdySegmentSize, 'b') + "c";
7273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  interface_->SendDataFrame(stream_id, data.data(), data.size(), flags, true);
7283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
7293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {
7303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    InSequence s;
731a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    for (int i = 0; i < 3; ++i) {
732a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        EXPECT_CALL(*spdy_framer_visitor_,
733a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    OnDataFrameHeader(stream_id, _, false));
734a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        EXPECT_CALL(*spdy_framer_visitor_,
735a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    OnStreamFrameData(stream_id, _, _, false))
736a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            .WillOnce(DoAll(SaveArg<1>(&actual_data),
737a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                            SaveArg<2>(&actual_size)));
738a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
7393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
7403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
7413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(3u, connection_->output_list()->size());
7423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::list<DataFrame*>::const_iterator i = connection_->output_list()->begin();
7433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DataFrame* df = *i++;
7443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  spdy_framer_->ProcessInput(df->data, df->size);
7453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(std::string(kSpdySegmentSize, 'a'),
7463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            StringPiece(actual_data, actual_size));
7473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
7483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  df = *i++;
7493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  spdy_framer_->ProcessInput(df->data, df->size);
7503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(std::string(kSpdySegmentSize, 'b'),
7513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            StringPiece(actual_data, actual_size));
7523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
7533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  df = *i++;
7543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  spdy_framer_->ProcessInput(df->data, df->size);
7553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ("c", StringPiece(actual_data, actual_size));
7563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
7573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
758f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_P(SpdySMProxyTest, SendEOF_SPDY2) {
759f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // This test is for SPDY2.
760f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (GetParam() != SPDY2) {
761f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
762f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
763f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
7643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  uint32 stream_id = 82;
7653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // SPDY2 data frame
7663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  char empty_data_frame[] = {'\0', '\0', '\0', '\x52', '\x1', '\0', '\0', '\0'};
7673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MemCacheIter mci;
7683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  mci.stream_id = stream_id;
7693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
7703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {
7713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    BalsaHeaders headers;
7723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    std::string filename = "foobar";
7733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    memory_cache_->InsertFile(&headers, filename, "");
7743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    mci.file_data = memory_cache_->GetFileData(filename);
7753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
7763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
7773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  interface_->AddToOutputOrder(mci);
7783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_TRUE(HasStream(stream_id));
7793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  interface_->SendEOF(stream_id);
7803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_FALSE(HasStream(stream_id));
7813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
7823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(1u, connection_->output_list()->size());
7833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::list<DataFrame*>::const_iterator i = connection_->output_list()->begin();
7843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DataFrame* df = *i++;
7853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(StringPiece(empty_data_frame, sizeof(empty_data_frame)),
7863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            StringPiece(df->data, df->size));
7873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
7883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
789f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_P(SpdySMProxyTest, SendEmptyDataFrame_SPDY2) {
790f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // This test is for SPDY2.
791f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (GetParam() != SPDY2) {
792f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
793f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
794f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
7953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  uint32 stream_id = 133;
7963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  SpdyDataFlags flags = DATA_FLAG_NONE;
7973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // SPDY2 data frame
7983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  char expected[] = {'\0', '\0', '\0', '\x85', '\0', '\0', '\0', '\0'};
7993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
8003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  interface_->SendDataFrame(stream_id, "hello", 0, flags, true);
8013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
8023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(1u, connection_->output_list()->size());
8033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::list<DataFrame*>::const_iterator i = connection_->output_list()->begin();
8043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DataFrame* df = *i++;
8053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
8063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(StringPiece(expected, sizeof(expected)),
8073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            StringPiece(df->data, df->size));
8083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
8093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
810f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_P(SpdySMServerTest, OnSynStream) {
8113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  BufferedSpdyFramerVisitorInterface* visitor = interface_.get();
8123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  uint32 stream_id = 82;
8133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  SpdyHeaderBlock spdy_headers;
8143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  spdy_headers["url"] = "http://www.example.com/path";
8153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  spdy_headers["method"] = "GET";
8163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  spdy_headers["scheme"] = "http";
817a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  spdy_headers["version"] = "HTTP/1.1";
8183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
8193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {
8203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    BalsaHeaders headers;
8213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    memory_cache_->InsertFile(&headers, "GET_/path", "");
8223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
8235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  visitor->OnSynStream(stream_id, 0, 0, true, true, spdy_headers);
8243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_TRUE(HasStream(stream_id));
8253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
8263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
827f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_P(SpdySMServerTest, NewStream) {
8283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  uint32 stream_id = 13;
8293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::string filename = "foobar";
8303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
8313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {
8323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    BalsaHeaders headers;
8333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    memory_cache_->InsertFile(&headers, filename, "");
8343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
8353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
8363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  interface_->NewStream(stream_id, 0, filename);
8373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_TRUE(HasStream(stream_id));
8383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
8393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
840f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_P(SpdySMServerTest, NewStreamError) {
8413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  uint32 stream_id = 82;
8423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  SpdyHeaderBlock actual_header_block;
8433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const char* actual_data;
8443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  size_t actual_size;
845f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  testing::MockFunction<void(int)> checkpoint;  // NOLINT
8463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
8473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  interface_->NewStream(stream_id, 0, "nonexistingfile");
8483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
8493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(2u, connection_->output_list()->size());
8503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
8513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {
8523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    InSequence s;
8535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (GetParam() < SPDY4) {
8545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_CALL(*spdy_framer_visitor_, OnSynReply(stream_id, false, _))
8555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          .WillOnce(SaveArg<2>(&actual_header_block));
8565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else {
8575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_CALL(*spdy_framer_visitor_, OnHeaders(stream_id, false, _))
8585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          .WillOnce(SaveArg<2>(&actual_header_block));
8595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
8603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    EXPECT_CALL(checkpoint, Call(0));
8613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    EXPECT_CALL(*spdy_framer_visitor_,
862a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                OnDataFrameHeader(stream_id, _, true));
863a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_CALL(*spdy_framer_visitor_,
8643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                OnStreamFrameData(stream_id, _, _, false)).Times(1)
8653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        .WillOnce(DoAll(SaveArg<1>(&actual_data),
8663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                        SaveArg<2>(&actual_size)));
8673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    EXPECT_CALL(*spdy_framer_visitor_,
8683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                OnStreamFrameData(stream_id, NULL, 0, true)).Times(1);
8693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
8703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
8713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::list<DataFrame*>::const_iterator i = connection_->output_list()->begin();
8723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DataFrame* df = *i++;
8733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  spdy_framer_->ProcessInput(df->data, df->size);
8743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  checkpoint.Call(0);
8753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  df = *i++;
8763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  spdy_framer_->ProcessInput(df->data, df->size);
8773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
8783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(2, spdy_framer_->frames_received());
8793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(2u, actual_header_block.size());
8803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ("404 Not Found", actual_header_block["status"]);
8813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ("HTTP/1.1", actual_header_block["version"]);
8823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ("wtf?", StringPiece(actual_data, actual_size));
8833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
8843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
8853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}  // namespace
8863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
8873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}  // namespace net
888