quic_headers_stream_test.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/quic/quic_headers_stream.h"
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "net/quic/quic_flags.h"
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/quic/quic_utils.h"
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/quic/spdy_utils.h"
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/quic/test_tools/quic_connection_peer.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/quic/test_tools/quic_session_peer.h"
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/quic/test_tools/quic_test_utils.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/spdy/spdy_protocol.h"
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using base::StringPiece;
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using std::string;
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using testing::Invoke;
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using testing::StrictMock;
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using testing::WithArgs;
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using testing::_;
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace net {
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace test {
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace {
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class MockVisitor : public SpdyFramerVisitorInterface {
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MOCK_METHOD1(OnError, void(SpdyFramer* framer));
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MOCK_METHOD3(OnDataFrameHeader, void(SpdyStreamId stream_id,
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       size_t length,
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       bool fin));
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MOCK_METHOD4(OnStreamFrameData, void(SpdyStreamId stream_id,
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       const char* data,
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       size_t len,
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       bool fin));
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MOCK_METHOD3(OnControlFrameHeaderData, bool(SpdyStreamId stream_id,
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                              const char* header_data,
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                              size_t len));
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MOCK_METHOD5(OnSynStream, void(SpdyStreamId stream_id,
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                 SpdyStreamId associated_stream_id,
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                 SpdyPriority priority,
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                 bool fin,
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                 bool unidirectional));
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MOCK_METHOD2(OnSynReply, void(SpdyStreamId stream_id, bool fin));
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MOCK_METHOD2(OnRstStream, void(SpdyStreamId stream_id,
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                 SpdyRstStreamStatus status));
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MOCK_METHOD1(OnSettings, void(bool clear_persisted));
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MOCK_METHOD3(OnSetting, void(SpdySettingsIds id, uint8 flags, uint32 value));
50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  MOCK_METHOD0(OnSettingsAck, void());
51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  MOCK_METHOD0(OnSettingsEnd, void());
52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  MOCK_METHOD2(OnPing, void(SpdyPingId unique_id, bool is_ack));
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MOCK_METHOD2(OnGoAway, void(SpdyStreamId last_accepted_stream_id,
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                              SpdyGoAwayStatus status));
55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  MOCK_METHOD3(OnHeaders, void(SpdyStreamId stream_id, bool fin, bool end));
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MOCK_METHOD2(OnWindowUpdate, void(SpdyStreamId stream_id,
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                    uint32 delta_window_size));
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MOCK_METHOD2(OnCredentialFrameData, bool(const char* credential_data,
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           size_t len));
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MOCK_METHOD1(OnBlocked, void(SpdyStreamId stream_id));
61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  MOCK_METHOD3(OnPushPromise, void(SpdyStreamId stream_id,
62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                   SpdyStreamId promised_stream_id,
63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                   bool end));
64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  MOCK_METHOD2(OnContinuation, void(SpdyStreamId stream_id, bool end));
65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  MOCK_METHOD6(OnAltSvc, void(SpdyStreamId stream_id,
66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                              uint32 max_age,
67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                              uint16 port,
68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                              StringPiece protocol_id,
69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                              StringPiece host,
70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                              StringPiece origin));
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class QuicHeadersStreamTest : public ::testing::TestWithParam<bool> {
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static QuicVersionVector GetVersions() {
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    QuicVersionVector versions;
775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    versions.push_back(QuicVersionMax());
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return versions;
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  QuicHeadersStreamTest()
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : connection_(new StrictMock<MockConnection>(is_server(), GetVersions())),
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        session_(connection_),
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        headers_stream_(QuicSessionPeer::GetHeadersStream(&session_)),
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        body_("hello world"),
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        framer_(SPDY3) {
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    headers_[":version"]  = "HTTP/1.1";
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    headers_[":status"] = "200 Ok";
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    headers_["content-length"] = "11";
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    framer_.set_visitor(&visitor_);
915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    EXPECT_EQ(QuicVersionMax(), session_.connection()->version());
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(headers_stream_ != NULL);
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  QuicConsumedData SaveIov(const IOVector& data) {
96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const iovec* iov = data.iovec();
97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    int count = data.Capacity();
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    for (int i = 0 ; i < count; ++i) {
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      saved_data_.append(static_cast<char*>(iov[i].iov_base), iov[i].iov_len);
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return QuicConsumedData(saved_data_.length(), false);
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool SaveHeaderData(const char* data, int len) {
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    saved_header_data_.append(data, len);
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return true;
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void SaveHeaderDataStringPiece(StringPiece data) {
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    saved_header_data_.append(data.data(), data.length());
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void WriteHeadersAndExpectSynStream(QuicStreamId stream_id,
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      bool fin,
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      QuicPriority priority) {
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    WriteHeadersAndCheckData(stream_id, fin, priority, SYN_STREAM);
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void WriteHeadersAndExpectSynReply(QuicStreamId stream_id,
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                     bool fin) {
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    WriteHeadersAndCheckData(stream_id, fin, 0, SYN_REPLY);
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void WriteHeadersAndCheckData(QuicStreamId stream_id,
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                bool fin,
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                QuicPriority priority,
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                SpdyFrameType type) {
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Write the headers and capture the outgoing data
129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_CALL(session_, WritevData(kHeadersStreamId, _, _, false, NULL))
130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        .WillOnce(WithArgs<1>(Invoke(this, &QuicHeadersStreamTest::SaveIov)));
13123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    headers_stream_->WriteHeaders(stream_id, headers_, fin, NULL);
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Parse the outgoing data and check that it matches was was written.
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (type == SYN_STREAM) {
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_CALL(visitor_, OnSynStream(stream_id, kNoAssociatedStream, 0,
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                        // priority,
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                        fin, kNotUnidirectional));
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else {
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_CALL(visitor_, OnSynReply(stream_id, fin));
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_CALL(visitor_, OnControlFrameHeaderData(stream_id, _, _))
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        .WillRepeatedly(WithArgs<1, 2>(
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            Invoke(this, &QuicHeadersStreamTest::SaveHeaderData)));
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (fin) {
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_CALL(visitor_, OnStreamFrameData(stream_id, NULL, 0, true));
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    framer_.ProcessInput(saved_data_.data(), saved_data_.length());
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_FALSE(framer_.HasError()) << framer_.error_code();
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    CheckHeaders();
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    saved_data_.clear();
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void CheckHeaders() {
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SpdyHeaderBlock headers;
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(saved_header_data_.length(),
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              framer_.ParseHeaderBlockInBuffer(saved_header_data_.data(),
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                               saved_header_data_.length(),
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                               &headers));
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(headers_, headers);
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    saved_header_data_.clear();
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool is_server() {
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return GetParam();
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void CloseConnection() {
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    QuicConnectionPeer::CloseConnection(connection_);
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static const bool kNotUnidirectional = false;
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static const bool kNoAssociatedStream = false;
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  StrictMock<MockConnection>* connection_;
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  StrictMock<MockSession> session_;
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  QuicHeadersStream* headers_stream_;
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SpdyHeaderBlock headers_;
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  string body_;
1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  string saved_data_;
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  string saved_header_data_;
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SpdyFramer framer_;
1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  StrictMock<MockVisitor> visitor_;
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)INSTANTIATE_TEST_CASE_P(Tests, QuicHeadersStreamTest, testing::Bool());
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicHeadersStreamTest, StreamId) {
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(3u, headers_stream_->id());
1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicHeadersStreamTest, EffectivePriority) {
1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(0u, headers_stream_->EffectivePriority());
1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicHeadersStreamTest, WriteHeaders) {
197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (QuicStreamId stream_id = kClientDataStreamId1;
198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)       stream_id < kClientDataStreamId3; stream_id += 2) {
1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    for (int count = 0; count < 2; ++count) {
2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      bool fin = (count == 0);
2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (is_server()) {
2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        WriteHeadersAndExpectSynReply(stream_id, fin);
2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      } else {
2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        for (QuicPriority priority = 0; priority < 7; ++priority) {
2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          WriteHeadersAndExpectSynStream(stream_id, fin, priority);
2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        }
2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      }
2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicHeadersStreamTest, ProcessRawData) {
213cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (QuicStreamId stream_id = kClientDataStreamId1;
214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)       stream_id < kClientDataStreamId3; stream_id += 2) {
2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    for (int count = 0; count < 2; ++count) {
2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      bool fin = (count == 0);
2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      for (QuicPriority priority = 0; priority < 7; ++priority) {
2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        // Replace with "WriteHeadersAndSaveData"
2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        scoped_ptr<SpdySerializedFrame> frame;
2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        if (is_server()) {
2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          SpdySynStreamIR syn_stream(stream_id);
2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          syn_stream.set_name_value_block(headers_);
2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          syn_stream.set_fin(fin);
2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          frame.reset(framer_.SerializeSynStream(syn_stream));
2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          EXPECT_CALL(session_, OnStreamHeadersPriority(stream_id, 0));
2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        } else {
2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          SpdySynReplyIR syn_reply(stream_id);
2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          syn_reply.set_name_value_block(headers_);
2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          syn_reply.set_fin(fin);
2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          frame.reset(framer_.SerializeSynReply(syn_reply));
2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        }
2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        EXPECT_CALL(session_, OnStreamHeaders(stream_id, _))
2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            .WillRepeatedly(WithArgs<1>(
2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                Invoke(this,
2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       &QuicHeadersStreamTest::SaveHeaderDataStringPiece)));
2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        EXPECT_CALL(session_,
2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    OnStreamHeadersComplete(stream_id, fin, frame->size()));
2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        headers_stream_->ProcessRawData(frame->data(), frame->size());
2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        CheckHeaders();
2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      }
2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicHeadersStreamTest, ProcessSpdyDataFrame) {
2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SpdyDataIR data(2, "");
2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<SpdySerializedFrame> frame(framer_.SerializeFrame(data));
2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(*connection_,
2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              SendConnectionCloseWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                             "SPDY DATA frame received."))
2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      .WillOnce(InvokeWithoutArgs(this,
2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                  &QuicHeadersStreamTest::CloseConnection));
2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  headers_stream_->ProcessRawData(frame->data(), frame->size());
2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicHeadersStreamTest, ProcessSpdyRstStreamFrame) {
2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SpdyRstStreamIR data(2, RST_STREAM_PROTOCOL_ERROR, "");
2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<SpdySerializedFrame> frame(framer_.SerializeFrame(data));
2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(*connection_,
2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              SendConnectionCloseWithDetails(
2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                  QUIC_INVALID_HEADERS_STREAM_DATA,
263a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                  "SPDY RST_STREAM frame received."))
2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      .WillOnce(InvokeWithoutArgs(this,
2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                  &QuicHeadersStreamTest::CloseConnection));
2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  headers_stream_->ProcessRawData(frame->data(), frame->size());
2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicHeadersStreamTest, ProcessSpdySettingsFrame) {
2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SpdySettingsIR data;
2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  data.AddSetting(SETTINGS_UPLOAD_BANDWIDTH, true, true, 0);
2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<SpdySerializedFrame> frame(framer_.SerializeFrame(data));
2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(*connection_,
2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              SendConnectionCloseWithDetails(
2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                  QUIC_INVALID_HEADERS_STREAM_DATA,
276a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                  "SPDY SETTINGS frame received."))
2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      .WillOnce(InvokeWithoutArgs(this,
2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                  &QuicHeadersStreamTest::CloseConnection));
2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  headers_stream_->ProcessRawData(frame->data(), frame->size());
2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicHeadersStreamTest, ProcessSpdyPingFrame) {
2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SpdyPingIR data(1);
2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<SpdySerializedFrame> frame(framer_.SerializeFrame(data));
2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(*connection_,
2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              SendConnectionCloseWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
287a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                             "SPDY PING frame received."))
2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      .WillOnce(InvokeWithoutArgs(this,
2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                  &QuicHeadersStreamTest::CloseConnection));
2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  headers_stream_->ProcessRawData(frame->data(), frame->size());
2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicHeadersStreamTest, ProcessSpdyGoAwayFrame) {
2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SpdyGoAwayIR data(1, GOAWAY_PROTOCOL_ERROR, "go away");
2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<SpdySerializedFrame> frame(framer_.SerializeFrame(data));
2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(*connection_,
2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              SendConnectionCloseWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
298a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                             "SPDY GOAWAY frame received."))
2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      .WillOnce(InvokeWithoutArgs(this,
3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                  &QuicHeadersStreamTest::CloseConnection));
3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  headers_stream_->ProcessRawData(frame->data(), frame->size());
3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicHeadersStreamTest, ProcessSpdyHeadersFrame) {
3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SpdyHeadersIR data(1);
3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<SpdySerializedFrame> frame(framer_.SerializeFrame(data));
3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(*connection_,
3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              SendConnectionCloseWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA,
309a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                             "SPDY HEADERS frame received."))
3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      .WillOnce(InvokeWithoutArgs(this,
3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                  &QuicHeadersStreamTest::CloseConnection));
3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  headers_stream_->ProcessRawData(frame->data(), frame->size());
3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicHeadersStreamTest, ProcessSpdyWindowUpdateFrame) {
3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SpdyWindowUpdateIR data(1, 1);
3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<SpdySerializedFrame> frame(framer_.SerializeFrame(data));
3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(*connection_,
3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              SendConnectionCloseWithDetails(
3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                  QUIC_INVALID_HEADERS_STREAM_DATA,
321a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                  "SPDY WINDOW_UPDATE frame received."))
3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      .WillOnce(InvokeWithoutArgs(this,
3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                  &QuicHeadersStreamTest::CloseConnection));
3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  headers_stream_->ProcessRawData(frame->data(), frame->size());
3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
327e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochTEST_P(QuicHeadersStreamTest, NoFlowControl) {
3285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ValueRestore<bool> old_flag(&FLAGS_enable_quic_stream_flow_control_2, true);
3290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_FALSE(headers_stream_->flow_controller()->IsEnabled());
330e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch}
331e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace
3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace test
3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace net
335