Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(502)

Unified Diff: net/quic/quic_headers_stream_test.cc

Issue 2193073003: Move shared files in net/quic/ into net/quic/core/ (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: io_thread_unittest.cc Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/quic/quic_headers_stream.cc ('k') | net/quic/quic_http_utils.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/quic/quic_headers_stream_test.cc
diff --git a/net/quic/quic_headers_stream_test.cc b/net/quic/quic_headers_stream_test.cc
deleted file mode 100644
index 10bc5c864854f740d7e928cd9f6b06747bcd7529..0000000000000000000000000000000000000000
--- a/net/quic/quic_headers_stream_test.cc
+++ /dev/null
@@ -1,977 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "net/quic/quic_headers_stream.h"
-
-#include <string>
-
-#include "base/strings/string_number_conversions.h"
-#include "net/quic/quic_bug_tracker.h"
-#include "net/quic/quic_utils.h"
-#include "net/quic/spdy_utils.h"
-#include "net/quic/test_tools/quic_connection_peer.h"
-#include "net/quic/test_tools/quic_headers_stream_peer.h"
-#include "net/quic/test_tools/quic_spdy_session_peer.h"
-#include "net/quic/test_tools/quic_test_utils.h"
-#include "net/quic/test_tools/reliable_quic_stream_peer.h"
-#include "net/spdy/spdy_alt_svc_wire_format.h"
-#include "net/spdy/spdy_flags.h"
-#include "net/spdy/spdy_protocol.h"
-#include "net/spdy/spdy_test_utils.h"
-#include "net/test/gtest_util.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using base::StringPiece;
-using std::ostream;
-using std::string;
-using std::vector;
-using testing::ElementsAre;
-using testing::_;
-using testing::AtLeast;
-using testing::HasSubstr;
-using testing::InSequence;
-using testing::Invoke;
-using testing::Return;
-using testing::StrictMock;
-using testing::WithArgs;
-using testing::_;
-
-// TODO(bnc): Merge these correctly.
-bool FLAGS_use_http2_frame_decoder_adapter;
-bool FLAGS_spdy_use_hpack_decoder2;
-bool FLAGS_spdy_framer_use_new_methods2;
-
-namespace net {
-namespace test {
-
-class MockHpackDebugVisitor : public QuicHeadersStream::HpackDebugVisitor {
- public:
- explicit MockHpackDebugVisitor() : HpackDebugVisitor() {}
-
- MOCK_METHOD1(OnUseEntry, void(QuicTime::Delta elapsed));
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MockHpackDebugVisitor);
-};
-
-namespace {
-
-// TODO(ckrasic): this workaround is due to absence of std::initializer_list
-const bool kFins[] = {false, true};
-
-class MockVisitor : public SpdyFramerVisitorInterface {
- public:
- MOCK_METHOD1(OnError, void(SpdyFramer* framer));
- MOCK_METHOD3(OnDataFrameHeader,
- void(SpdyStreamId stream_id, size_t length, bool fin));
- MOCK_METHOD3(OnStreamFrameData,
- void(SpdyStreamId stream_id, const char* data, size_t len));
- MOCK_METHOD1(OnStreamEnd, void(SpdyStreamId stream_id));
- MOCK_METHOD2(OnStreamPadding, void(SpdyStreamId stream_id, size_t len));
- MOCK_METHOD1(OnHeaderFrameStart,
- SpdyHeadersHandlerInterface*(SpdyStreamId stream_id));
- MOCK_METHOD2(OnHeaderFrameEnd, void(SpdyStreamId stream_id, bool end));
- MOCK_METHOD3(OnControlFrameHeaderData,
- bool(SpdyStreamId stream_id,
- const char* header_data,
- size_t len));
- MOCK_METHOD5(OnSynStream,
- void(SpdyStreamId stream_id,
- SpdyStreamId associated_stream_id,
- SpdyPriority priority,
- bool fin,
- bool unidirectional));
- MOCK_METHOD2(OnSynReply, void(SpdyStreamId stream_id, bool fin));
- MOCK_METHOD2(OnRstStream,
- void(SpdyStreamId stream_id, SpdyRstStreamStatus status));
- MOCK_METHOD1(OnSettings, void(bool clear_persisted));
- MOCK_METHOD3(OnSetting,
- void(SpdySettingsIds id, uint8_t flags, uint32_t value));
- MOCK_METHOD0(OnSettingsAck, void());
- MOCK_METHOD0(OnSettingsEnd, void());
- MOCK_METHOD2(OnPing, void(SpdyPingId unique_id, bool is_ack));
- MOCK_METHOD2(OnGoAway,
- void(SpdyStreamId last_accepted_stream_id,
- SpdyGoAwayStatus status));
- MOCK_METHOD7(OnHeaders,
- void(SpdyStreamId stream_id,
- bool has_priority,
- int weight,
- SpdyStreamId parent_stream_id,
- bool exclusive,
- bool fin,
- bool end));
- MOCK_METHOD2(OnWindowUpdate,
- void(SpdyStreamId stream_id, int delta_window_size));
- MOCK_METHOD1(OnBlocked, void(SpdyStreamId stream_id));
- MOCK_METHOD3(OnPushPromise,
- void(SpdyStreamId stream_id,
- SpdyStreamId promised_stream_id,
- bool end));
- MOCK_METHOD2(OnContinuation, void(SpdyStreamId stream_id, bool end));
- MOCK_METHOD4(OnPriority,
- void(SpdyStreamId stream_id,
- SpdyStreamId parent_id,
- int weight,
- bool exclusive));
- MOCK_METHOD3(OnAltSvc,
- void(SpdyStreamId stream_id,
- StringPiece origin,
- const SpdyAltSvcWireFormat::AlternativeServiceVector&
- altsvc_vector));
- MOCK_METHOD2(OnUnknownFrame, bool(SpdyStreamId stream_id, int frame_type));
-};
-
-class ForceHolAckListener : public QuicAckListenerInterface {
- public:
- ForceHolAckListener() : total_acked_bytes_(0) {}
-
- void OnPacketAcked(int acked_bytes, QuicTime::Delta ack_delay_time) override {
- total_acked_bytes_ += acked_bytes;
- }
-
- void OnPacketRetransmitted(int retransmitted_bytes) override {}
-
- size_t total_acked_bytes() { return total_acked_bytes_; }
-
- private:
- ~ForceHolAckListener() override {}
-
- size_t total_acked_bytes_;
-
- DISALLOW_COPY_AND_ASSIGN(ForceHolAckListener);
-};
-
-enum Http2DecoderChoice {
- HTTP2_DECODER_SPDY,
- HTTP2_DECODER_NESTED_SPDY,
- HTTP2_DECODER_NEW
-};
-ostream& operator<<(ostream& os, Http2DecoderChoice v) {
- switch (v) {
- case HTTP2_DECODER_SPDY:
- return os << "SPDY";
- case HTTP2_DECODER_NESTED_SPDY:
- return os << "NESTED_SPDY";
- case HTTP2_DECODER_NEW:
- return os << "NEW";
- }
- return os;
-}
-
-enum HpackDecoderChoice { HPACK_DECODER_SPDY, HPACK_DECODER_NEW };
-ostream& operator<<(ostream& os, HpackDecoderChoice v) {
- switch (v) {
- case HPACK_DECODER_SPDY:
- return os << "SPDY";
- case HPACK_DECODER_NEW:
- return os << "NEW";
- }
- return os;
-}
-
-typedef std::
- tuple<QuicVersion, Perspective, Http2DecoderChoice, HpackDecoderChoice>
- TestParamsTuple;
-
-struct TestParams {
- explicit TestParams(TestParamsTuple params)
- : version(std::get<0>(params)),
- perspective(std::get<1>(params)),
- http2_decoder(std::get<2>(params)),
- hpack_decoder(std::get<3>(params)) {
- switch (http2_decoder) {
- case HTTP2_DECODER_SPDY:
- FLAGS_use_nested_spdy_framer_decoder = false;
- FLAGS_use_http2_frame_decoder_adapter = false;
- break;
- case HTTP2_DECODER_NESTED_SPDY:
- FLAGS_use_nested_spdy_framer_decoder = true;
- FLAGS_use_http2_frame_decoder_adapter = false;
- break;
- case HTTP2_DECODER_NEW:
- FLAGS_use_nested_spdy_framer_decoder = false;
- FLAGS_use_http2_frame_decoder_adapter = true;
- // Http2FrameDecoderAdapter needs the new header methods, else
- // --use_http2_frame_decoder_adapter=true will be ignored.
- FLAGS_spdy_framer_use_new_methods2 = true;
- break;
- }
- switch (hpack_decoder) {
- case HPACK_DECODER_SPDY:
- FLAGS_spdy_use_hpack_decoder2 = false;
- break;
- case HPACK_DECODER_NEW:
- FLAGS_spdy_use_hpack_decoder2 = true;
- // Needs new header methods to be used.
- FLAGS_spdy_framer_use_new_methods2 = true;
- break;
- }
- FLAGS_quic_supports_push_promise = true;
- FLAGS_quic_always_log_bugs_for_tests = true;
- VLOG(1) << "TestParams: version: " << QuicVersionToString(version)
- << ", perspective: " << perspective
- << ", http2_decoder: " << http2_decoder
- << ", hpack_decoder: " << hpack_decoder;
- }
-
- QuicVersion version;
- Perspective perspective;
- Http2DecoderChoice http2_decoder;
- HpackDecoderChoice hpack_decoder;
-};
-
-class QuicHeadersStreamTest : public ::testing::TestWithParam<TestParamsTuple> {
- public:
- // Constructing the test_params_ object will set the necessary flags before
- // the MockQuicConnection is constructed, which we need because the latter
- // will construct a SpdyFramer that will use those flags to decide whether
- // to construct a decoder adapter.
- QuicHeadersStreamTest()
- : test_params_(GetParam()),
- connection_(new StrictMock<MockQuicConnection>(&helper_,
- &alarm_factory_,
- perspective(),
- GetVersion())),
- session_(connection_),
- headers_stream_(QuicSpdySessionPeer::GetHeadersStream(&session_)),
- body_("hello world"),
- hpack_encoder_visitor_(new StrictMock<MockHpackDebugVisitor>),
- hpack_decoder_visitor_(new StrictMock<MockHpackDebugVisitor>),
- stream_frame_(kHeadersStreamId, /*fin=*/false, /*offset=*/0, ""),
- next_promised_stream_id_(2) {
- headers_[":version"] = "HTTP/1.1";
- headers_[":status"] = "200 Ok";
- headers_["content-length"] = "11";
- framer_ = std::unique_ptr<SpdyFramer>(new SpdyFramer(HTTP2));
- framer_->set_visitor(&visitor_);
- EXPECT_EQ(version(), session_.connection()->version());
- EXPECT_TRUE(headers_stream_ != nullptr);
- connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
- }
-
- QuicConsumedData SaveIov(const QuicIOVector& data) {
- const iovec* iov = data.iov;
- int count = data.iov_count;
- int consumed = 0;
- for (int i = 0; i < count; ++i) {
- saved_data_.append(static_cast<char*>(iov[i].iov_base), iov[i].iov_len);
- consumed += iov[i].iov_len;
- }
- return QuicConsumedData(consumed, false);
- }
-
- QuicConsumedData SaveIovAndNotifyAckListener(
- const QuicIOVector& data,
- QuicAckListenerInterface* ack_listener) {
- QuicConsumedData result = SaveIov(data);
- if (ack_listener) {
- ack_listener->OnPacketAcked(result.bytes_consumed,
- QuicTime::Delta::Zero());
- }
- return result;
- }
-
- void SavePayload(const char* data, size_t len) {
- saved_payloads_.append(data, len);
- }
-
- bool SaveHeaderData(const char* data, int len) {
- saved_header_data_.append(data, len);
- return true;
- }
-
- void SaveHeaderDataStringPiece(StringPiece data) {
- saved_header_data_.append(data.data(), data.length());
- }
-
- void SavePromiseHeaderList(QuicStreamId /* stream_id */,
- QuicStreamId /* promised_stream_id */,
- size_t size,
- const QuicHeaderList& header_list) {
- SaveToHandler(size, header_list);
- }
-
- void SaveHeaderList(QuicStreamId /* stream_id */,
- bool /* fin */,
- size_t size,
- const QuicHeaderList& header_list) {
- SaveToHandler(size, header_list);
- }
-
- void SaveToHandler(size_t size, const QuicHeaderList& header_list) {
- headers_handler_.reset(new TestHeadersHandler);
- headers_handler_->OnHeaderBlockStart();
- for (const auto& p : header_list) {
- headers_handler_->OnHeader(p.first, p.second);
- }
- headers_handler_->OnHeaderBlockEnd(size);
- }
-
- void WriteHeadersAndExpectSynStream(QuicStreamId stream_id,
- bool fin,
- SpdyPriority priority) {
- WriteHeadersAndCheckData(stream_id, fin, priority, SYN_STREAM);
- }
-
- void WriteHeadersAndExpectSynReply(QuicStreamId stream_id, bool fin) {
- WriteHeadersAndCheckData(stream_id, fin, 0, SYN_REPLY);
- }
-
- void WriteHeadersAndCheckData(QuicStreamId stream_id,
- bool fin,
- SpdyPriority priority,
- SpdyFrameType type) {
- // Write the headers and capture the outgoing data
- EXPECT_CALL(session_, WritevData(headers_stream_, kHeadersStreamId, _, _,
- false, nullptr))
- .WillOnce(WithArgs<2>(Invoke(this, &QuicHeadersStreamTest::SaveIov)));
- headers_stream_->WriteHeaders(stream_id, headers_.Clone(), fin, priority,
- nullptr);
-
- // Parse the outgoing data and check that it matches was was written.
- if (type == SYN_STREAM) {
- EXPECT_CALL(visitor_,
- OnHeaders(stream_id, kHasPriority,
- Spdy3PriorityToHttp2Weight(priority),
- /*parent_stream_id=*/0,
- /*exclusive=*/false, fin, kFrameComplete));
- } else {
- EXPECT_CALL(visitor_,
- OnHeaders(stream_id, !kHasPriority,
- /*priority=*/0,
- /*parent_stream_id=*/0,
- /*exclusive=*/false, fin, kFrameComplete));
- }
- headers_handler_.reset(new TestHeadersHandler);
- EXPECT_CALL(visitor_, OnHeaderFrameStart(stream_id))
- .WillOnce(Return(headers_handler_.get()));
- EXPECT_CALL(visitor_, OnHeaderFrameEnd(stream_id, true)).Times(1);
- if (fin) {
- EXPECT_CALL(visitor_, OnStreamEnd(stream_id));
- }
- framer_->ProcessInput(saved_data_.data(), saved_data_.length());
- EXPECT_FALSE(framer_->HasError())
- << SpdyFramer::ErrorCodeToString(framer_->error_code());
-
- CheckHeaders();
- saved_data_.clear();
- }
-
- void CheckHeaders() {
- EXPECT_EQ(headers_, headers_handler_->decoded_block());
- headers_handler_.reset();
- }
-
- Perspective perspective() const { return test_params_.perspective; }
-
- QuicVersion version() const { return test_params_.version; }
-
- QuicVersionVector GetVersion() {
- QuicVersionVector versions;
- versions.push_back(version());
- return versions;
- }
-
- void TearDownLocalConnectionState() {
- QuicConnectionPeer::TearDownLocalConnectionState(connection_);
- }
-
- QuicStreamId NextPromisedStreamId() { return next_promised_stream_id_ += 2; }
-
- static const bool kFrameComplete = true;
- static const bool kHasPriority = true;
-
- const TestParams test_params_;
- MockQuicConnectionHelper helper_;
- MockAlarmFactory alarm_factory_;
- StrictMock<MockQuicConnection>* connection_;
- StrictMock<MockQuicSpdySession> session_;
- QuicHeadersStream* headers_stream_;
- SpdyHeaderBlock headers_;
- std::unique_ptr<TestHeadersHandler> headers_handler_;
- string body_;
- string saved_data_;
- string saved_header_data_;
- string saved_payloads_;
- std::unique_ptr<SpdyFramer> framer_;
- StrictMock<MockVisitor> visitor_;
- std::unique_ptr<StrictMock<MockHpackDebugVisitor>> hpack_encoder_visitor_;
- std::unique_ptr<StrictMock<MockHpackDebugVisitor>> hpack_decoder_visitor_;
- QuicStreamFrame stream_frame_;
- QuicStreamId next_promised_stream_id_;
-};
-
-// Run all tests with each version, perspective (client or server),
-// HTTP/2 and HPACK decoder.
-INSTANTIATE_TEST_CASE_P(
- Tests,
- QuicHeadersStreamTest,
- ::testing::Combine(
- ::testing::ValuesIn(QuicSupportedVersions()),
- ::testing::Values(Perspective::IS_CLIENT, Perspective::IS_SERVER),
- ::testing::Values(HTTP2_DECODER_SPDY,
- HTTP2_DECODER_NESTED_SPDY,
- HTTP2_DECODER_NEW),
- ::testing::Values(HPACK_DECODER_SPDY, HPACK_DECODER_NEW)));
-
-TEST_P(QuicHeadersStreamTest, StreamId) {
- EXPECT_EQ(3u, headers_stream_->id());
-}
-
-TEST_P(QuicHeadersStreamTest, WriteHeaders) {
- for (QuicStreamId stream_id = kClientDataStreamId1;
- stream_id < kClientDataStreamId3; stream_id += 2) {
- for (bool fin : kFins) {
- if (perspective() == Perspective::IS_SERVER) {
- WriteHeadersAndExpectSynReply(stream_id, fin);
- } else {
- for (SpdyPriority priority = 0; priority < 7; ++priority) {
- // TODO(rch): implement priorities correctly.
- WriteHeadersAndExpectSynStream(stream_id, fin, 0);
- }
- }
- }
- }
-}
-
-TEST_P(QuicHeadersStreamTest, WritePushPromises) {
- for (QuicStreamId stream_id = kClientDataStreamId1;
- stream_id < kClientDataStreamId3; stream_id += 2) {
- QuicStreamId promised_stream_id = NextPromisedStreamId();
- if (perspective() == Perspective::IS_SERVER) {
- // Write the headers and capture the outgoing data
- EXPECT_CALL(session_, WritevData(headers_stream_, kHeadersStreamId, _, _,
- false, nullptr))
- .WillOnce(WithArgs<2>(Invoke(this, &QuicHeadersStreamTest::SaveIov)));
- headers_stream_->WritePushPromise(stream_id, promised_stream_id,
- headers_.Clone(), nullptr);
-
- // Parse the outgoing data and check that it matches was was written.
- EXPECT_CALL(visitor_,
- OnPushPromise(stream_id, promised_stream_id, kFrameComplete));
- headers_handler_.reset(new TestHeadersHandler);
- EXPECT_CALL(visitor_, OnHeaderFrameStart(stream_id))
- .WillOnce(Return(headers_handler_.get()));
- EXPECT_CALL(visitor_, OnHeaderFrameEnd(stream_id, true)).Times(1);
- framer_->ProcessInput(saved_data_.data(), saved_data_.length());
- EXPECT_FALSE(framer_->HasError())
- << SpdyFramer::ErrorCodeToString(framer_->error_code());
- CheckHeaders();
- saved_data_.clear();
- } else {
- EXPECT_DFATAL(
- headers_stream_->WritePushPromise(stream_id, promised_stream_id,
- headers_.Clone(), nullptr),
- "Client shouldn't send PUSH_PROMISE");
- }
- }
-}
-
-TEST_P(QuicHeadersStreamTest, ProcessRawData) {
- for (QuicStreamId stream_id = kClientDataStreamId1;
- stream_id < kClientDataStreamId3; stream_id += 2) {
- for (bool fin : {false, true}) {
- for (SpdyPriority priority = 0; priority < 7; ++priority) {
- // Replace with "WriteHeadersAndSaveData"
- SpdySerializedFrame frame;
- if (perspective() == Perspective::IS_SERVER) {
- SpdyHeadersIR headers_frame(stream_id, headers_.Clone());
- headers_frame.set_fin(fin);
- headers_frame.set_has_priority(true);
- headers_frame.set_weight(Spdy3PriorityToHttp2Weight(0));
- frame = framer_->SerializeFrame(headers_frame);
- EXPECT_CALL(session_, OnStreamHeadersPriority(stream_id, 0));
- } else {
- SpdyHeadersIR headers_frame(stream_id, headers_.Clone());
- headers_frame.set_fin(fin);
- frame = framer_->SerializeFrame(headers_frame);
- }
- EXPECT_CALL(session_,
- OnStreamHeaderList(stream_id, fin, frame.size(), _))
- .WillOnce(Invoke(this, &QuicHeadersStreamTest::SaveHeaderList));
- stream_frame_.data_buffer = frame.data();
- stream_frame_.data_length = frame.size();
- headers_stream_->OnStreamFrame(stream_frame_);
- stream_frame_.offset += frame.size();
- CheckHeaders();
- }
- }
- }
-}
-
-TEST_P(QuicHeadersStreamTest, ProcessPushPromise) {
- if (perspective() == Perspective::IS_SERVER)
- return;
- for (QuicStreamId stream_id = kClientDataStreamId1;
- stream_id < kClientDataStreamId3; stream_id += 2) {
- QuicStreamId promised_stream_id = NextPromisedStreamId();
- SpdyPushPromiseIR push_promise(stream_id, promised_stream_id,
- headers_.Clone());
- SpdySerializedFrame frame(framer_->SerializeFrame(push_promise));
- if (perspective() == Perspective::IS_SERVER) {
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
- "PUSH_PROMISE not supported.", _))
- .WillRepeatedly(InvokeWithoutArgs(
- this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
- } else {
- EXPECT_CALL(session_, OnPromiseHeaderList(stream_id, promised_stream_id,
- frame.size(), _))
- .WillOnce(
- Invoke(this, &QuicHeadersStreamTest::SavePromiseHeaderList));
- }
- stream_frame_.data_buffer = frame.data();
- stream_frame_.data_length = frame.size();
- headers_stream_->OnStreamFrame(stream_frame_);
- if (perspective() == Perspective::IS_CLIENT) {
- stream_frame_.offset += frame.size();
- CheckHeaders();
- }
- }
-}
-
-TEST_P(QuicHeadersStreamTest, EmptyHeaderHOLBlockedTime) {
- if (!FLAGS_quic_measure_headers_hol_blocking_time) {
- return;
- }
- EXPECT_CALL(session_, OnHeadersHeadOfLineBlocking(_)).Times(0);
- testing::InSequence seq;
- bool fin = true;
- for (int stream_num = 0; stream_num < 10; stream_num++) {
- QuicStreamId stream_id = QuicClientDataStreamId(stream_num);
- // Replace with "WriteHeadersAndSaveData"
- SpdySerializedFrame frame;
- if (perspective() == Perspective::IS_SERVER) {
- SpdyHeadersIR headers_frame(stream_id, headers_.Clone());
- headers_frame.set_fin(fin);
- headers_frame.set_has_priority(true);
- headers_frame.set_weight(Spdy3PriorityToHttp2Weight(0));
- frame = framer_->SerializeFrame(headers_frame);
- EXPECT_CALL(session_, OnStreamHeadersPriority(stream_id, 0));
- } else {
- SpdyHeadersIR headers_frame(stream_id, headers_.Clone());
- headers_frame.set_fin(fin);
- frame = framer_->SerializeFrame(headers_frame);
- }
- EXPECT_CALL(session_, OnStreamHeaderList(stream_id, fin, frame.size(), _))
- .Times(1);
- stream_frame_.data_buffer = frame.data();
- stream_frame_.data_length = frame.size();
- headers_stream_->OnStreamFrame(stream_frame_);
- connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
- stream_frame_.offset += frame.size();
- }
-}
-
-TEST_P(QuicHeadersStreamTest, NonEmptyHeaderHOLBlockedTime) {
- QuicStreamId stream_id;
- bool fin = true;
- QuicStreamFrame stream_frames[10];
- SpdySerializedFrame frames[10];
- // First create all the frames in order
- {
- InSequence seq;
- for (int stream_num = 0; stream_num < 10; ++stream_num) {
- stream_id = QuicClientDataStreamId(stream_num);
- if (perspective() == Perspective::IS_SERVER) {
- SpdyHeadersIR headers_frame(stream_id, headers_.Clone());
- headers_frame.set_fin(fin);
- headers_frame.set_has_priority(true);
- headers_frame.set_weight(Spdy3PriorityToHttp2Weight(0));
- frames[stream_num] = framer_->SerializeFrame(headers_frame);
- EXPECT_CALL(session_, OnStreamHeadersPriority(stream_id, 0)).Times(1);
- } else {
- SpdyHeadersIR headers_frame(stream_id, headers_.Clone());
- headers_frame.set_fin(fin);
- frames[stream_num] = framer_->SerializeFrame(headers_frame);
- }
- stream_frames[stream_num].stream_id = stream_frame_.stream_id;
- stream_frames[stream_num].offset = stream_frame_.offset;
- stream_frames[stream_num].data_buffer = frames[stream_num].data();
- stream_frames[stream_num].data_length = frames[stream_num].size();
- DVLOG(1) << "make frame for stream " << stream_num << " offset "
- << stream_frames[stream_num].offset;
- stream_frame_.offset += frames[stream_num].size();
- EXPECT_CALL(session_, OnStreamHeaderList(stream_id, fin, _, _)).Times(1);
- }
- }
-
- // Actually writing the frames in reverse order will cause HOL blocking.
- EXPECT_CALL(session_, OnHeadersHeadOfLineBlocking(_)).Times(9);
-
- for (int stream_num = 9; stream_num >= 0; --stream_num) {
- DVLOG(1) << "OnStreamFrame for stream " << stream_num << " offset "
- << stream_frames[stream_num].offset;
- headers_stream_->OnStreamFrame(stream_frames[stream_num]);
- connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
- }
-}
-
-TEST_P(QuicHeadersStreamTest, ProcessLargeRawData) {
- // We want to create a frame that is more than the SPDY Framer's max control
- // frame size, which is 16K, but less than the HPACK decoders max decode
- // buffer size, which is 32K.
- headers_["key0"] = string(1 << 13, '.');
- headers_["key1"] = string(1 << 13, '.');
- headers_["key2"] = string(1 << 13, '.');
- for (QuicStreamId stream_id = kClientDataStreamId1;
- stream_id < kClientDataStreamId3; stream_id += 2) {
- for (bool fin : {false, true}) {
- for (SpdyPriority priority = 0; priority < 7; ++priority) {
- // Replace with "WriteHeadersAndSaveData"
- SpdySerializedFrame frame;
- if (perspective() == Perspective::IS_SERVER) {
- SpdyHeadersIR headers_frame(stream_id, headers_.Clone());
- headers_frame.set_fin(fin);
- headers_frame.set_has_priority(true);
- headers_frame.set_weight(Spdy3PriorityToHttp2Weight(0));
- frame = framer_->SerializeFrame(headers_frame);
- EXPECT_CALL(session_, OnStreamHeadersPriority(stream_id, 0));
- } else {
- SpdyHeadersIR headers_frame(stream_id, headers_.Clone());
- headers_frame.set_fin(fin);
- frame = framer_->SerializeFrame(headers_frame);
- }
- EXPECT_CALL(session_,
- OnStreamHeaderList(stream_id, fin, frame.size(), _))
- .WillOnce(Invoke(this, &QuicHeadersStreamTest::SaveHeaderList));
- stream_frame_.data_buffer = frame.data();
- stream_frame_.data_length = frame.size();
- headers_stream_->OnStreamFrame(stream_frame_);
- stream_frame_.offset += frame.size();
- CheckHeaders();
- }
- }
- }
-}
-
-TEST_P(QuicHeadersStreamTest, ProcessBadData) {
- const char kBadData[] = "blah blah blah";
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _))
- .Times(::testing::AnyNumber());
- stream_frame_.data_buffer = kBadData;
- stream_frame_.data_length = strlen(kBadData);
- headers_stream_->OnStreamFrame(stream_frame_);
-}
-
-TEST_P(QuicHeadersStreamTest, ProcessSpdyDataFrame) {
- SpdyDataIR data(2, "ping");
- SpdySerializedFrame frame(framer_->SerializeFrame(data));
-
- EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
- "SPDY DATA frame received.", _))
- .WillOnce(InvokeWithoutArgs(
- this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
- stream_frame_.data_buffer = frame.data();
- stream_frame_.data_length = frame.size();
- headers_stream_->OnStreamFrame(stream_frame_);
-}
-
-TEST_P(QuicHeadersStreamTest, ProcessSpdyDataFrameForceHolBlocking) {
- if (version() <= QUIC_VERSION_35) {
- return;
- }
- QuicSpdySessionPeer::SetForceHolBlocking(&session_, true);
- SpdyDataIR data(2, "ping");
- SpdySerializedFrame frame(framer_->SerializeFrame(data));
- EXPECT_CALL(session_, OnStreamFrameData(2, _, 4, false));
- stream_frame_.data_buffer = frame.data();
- stream_frame_.data_length = frame.size();
- headers_stream_->OnStreamFrame(stream_frame_);
-}
-
-TEST_P(QuicHeadersStreamTest, ProcessSpdyDataFrameEmptyWithFin) {
- if (version() <= QUIC_VERSION_35) {
- return;
- }
- QuicSpdySessionPeer::SetForceHolBlocking(&session_, true);
- SpdyDataIR data(2, "");
- data.set_fin(true);
- SpdySerializedFrame frame(framer_->SerializeFrame(data));
- EXPECT_CALL(session_, OnStreamFrameData(2, _, 0, true));
- stream_frame_.data_buffer = frame.data();
- stream_frame_.data_length = frame.size();
- headers_stream_->OnStreamFrame(stream_frame_);
-}
-
-TEST_P(QuicHeadersStreamTest, ProcessSpdyRstStreamFrame) {
- SpdyRstStreamIR data(2, RST_STREAM_PROTOCOL_ERROR);
- SpdySerializedFrame frame(framer_->SerializeFrame(data));
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
- "SPDY RST_STREAM frame received.", _))
- .WillOnce(InvokeWithoutArgs(
- this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
- stream_frame_.data_buffer = frame.data();
- stream_frame_.data_length = frame.size();
- headers_stream_->OnStreamFrame(stream_frame_);
-}
-
-TEST_P(QuicHeadersStreamTest, ProcessSpdySettingsFrame) {
- FLAGS_quic_respect_http2_settings_frame = false;
- SpdySettingsIR data;
- data.AddSetting(SETTINGS_HEADER_TABLE_SIZE, true, true, 0);
- SpdySerializedFrame frame(framer_->SerializeFrame(data));
- EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
- "SPDY SETTINGS frame received.", _))
- .WillOnce(InvokeWithoutArgs(
- this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
- stream_frame_.data_buffer = frame.data();
- stream_frame_.data_length = frame.size();
- headers_stream_->OnStreamFrame(stream_frame_);
-}
-
-TEST_P(QuicHeadersStreamTest, RespectHttp2SettingsFrameSupportedFields) {
- FLAGS_quic_respect_http2_settings_frame = true;
- const uint32_t kTestHeaderTableSize = 1000;
- SpdySettingsIR data;
- // Respect supported settings frames SETTINGS_HEADER_TABLE_SIZE.
- data.AddSetting(SETTINGS_HEADER_TABLE_SIZE, true, true, kTestHeaderTableSize);
- SpdySerializedFrame frame(framer_->SerializeFrame(data));
- stream_frame_.data_buffer = frame.data();
- stream_frame_.data_length = frame.size();
- headers_stream_->OnStreamFrame(stream_frame_);
- EXPECT_EQ(kTestHeaderTableSize,
- QuicHeadersStreamPeer::GetSpdyFramer(headers_stream_)
- .header_encoder_table_size());
-}
-
-TEST_P(QuicHeadersStreamTest, RespectHttp2SettingsFrameUnsupportedFields) {
- FLAGS_quic_respect_http2_settings_frame = true;
- SpdySettingsIR data;
- // Does not support SETTINGS_MAX_HEADER_LIST_SIZE,
- // SETTINGS_MAX_CONCURRENT_STREAMS, SETTINGS_INITIAL_WINDOW_SIZE,
- // SETTINGS_ENABLE_PUSH and SETTINGS_MAX_FRAME_SIZE.
- data.AddSetting(SETTINGS_MAX_HEADER_LIST_SIZE, true, true, 2000);
- data.AddSetting(SETTINGS_MAX_CONCURRENT_STREAMS, true, true, 100);
- data.AddSetting(SETTINGS_INITIAL_WINDOW_SIZE, true, true, 100);
- data.AddSetting(SETTINGS_ENABLE_PUSH, true, true, 1);
- data.AddSetting(SETTINGS_MAX_FRAME_SIZE, true, true, 1250);
- SpdySerializedFrame frame(framer_->SerializeFrame(data));
- EXPECT_CALL(
- *connection_,
- CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
- "Unsupported field of HTTP/2 SETTINGS frame: " +
- base::IntToString(SETTINGS_MAX_HEADER_LIST_SIZE),
- _));
- EXPECT_CALL(
- *connection_,
- CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
- "Unsupported field of HTTP/2 SETTINGS frame: " +
- base::IntToString(SETTINGS_MAX_CONCURRENT_STREAMS),
- _));
- EXPECT_CALL(
- *connection_,
- CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
- "Unsupported field of HTTP/2 SETTINGS frame: " +
- base::IntToString(SETTINGS_INITIAL_WINDOW_SIZE),
- _));
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
- "Unsupported field of HTTP/2 SETTINGS frame: " +
- base::IntToString(SETTINGS_ENABLE_PUSH),
- _));
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
- "Unsupported field of HTTP/2 SETTINGS frame: " +
- base::IntToString(SETTINGS_MAX_FRAME_SIZE),
- _));
- stream_frame_.data_buffer = frame.data();
- stream_frame_.data_length = frame.size();
- headers_stream_->OnStreamFrame(stream_frame_);
-}
-
-TEST_P(QuicHeadersStreamTest, ProcessSpdyPingFrame) {
- SpdyPingIR data(1);
- SpdySerializedFrame frame(framer_->SerializeFrame(data));
- EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
- "SPDY PING frame received.", _))
- .WillOnce(InvokeWithoutArgs(
- this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
- stream_frame_.data_buffer = frame.data();
- stream_frame_.data_length = frame.size();
- headers_stream_->OnStreamFrame(stream_frame_);
-}
-
-TEST_P(QuicHeadersStreamTest, ProcessSpdyGoAwayFrame) {
- SpdyGoAwayIR data(1, GOAWAY_PROTOCOL_ERROR, "go away");
- SpdySerializedFrame frame(framer_->SerializeFrame(data));
- EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
- "SPDY GOAWAY frame received.", _))
- .WillOnce(InvokeWithoutArgs(
- this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
- stream_frame_.data_buffer = frame.data();
- stream_frame_.data_length = frame.size();
- headers_stream_->OnStreamFrame(stream_frame_);
-}
-
-TEST_P(QuicHeadersStreamTest, ProcessSpdyWindowUpdateFrame) {
- SpdyWindowUpdateIR data(1, 1);
- SpdySerializedFrame frame(framer_->SerializeFrame(data));
- EXPECT_CALL(*connection_,
- CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
- "SPDY WINDOW_UPDATE frame received.", _))
- .WillOnce(InvokeWithoutArgs(
- this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
- stream_frame_.data_buffer = frame.data();
- stream_frame_.data_length = frame.size();
- headers_stream_->OnStreamFrame(stream_frame_);
-}
-
-TEST_P(QuicHeadersStreamTest, NoConnectionLevelFlowControl) {
- EXPECT_FALSE(ReliableQuicStreamPeer::StreamContributesToConnectionFlowControl(
- headers_stream_));
-}
-
-TEST_P(QuicHeadersStreamTest, HpackDecoderDebugVisitor) {
- if (FLAGS_use_nested_spdy_framer_decoder)
- return;
-
- StrictMock<MockHpackDebugVisitor>* hpack_decoder_visitor =
- hpack_decoder_visitor_.get();
- headers_stream_->SetHpackDecoderDebugVisitor(
- std::move(hpack_decoder_visitor_));
-
- // Create some headers we expect to generate entries in HPACK's
- // dynamic table, in addition to content-length.
- headers_["key0"] = string(1 << 1, '.');
- headers_["key1"] = string(1 << 2, '.');
- headers_["key2"] = string(1 << 3, '.');
- {
- testing::InSequence seq;
- // Number of indexed representations generated in headers below.
- for (int i = 1; i < 28; i++) {
- EXPECT_CALL(*hpack_decoder_visitor,
- OnUseEntry(QuicTime::Delta::FromMilliseconds(i)))
- .Times(4);
- }
- }
- for (QuicStreamId stream_id = kClientDataStreamId1;
- stream_id < kClientDataStreamId3; stream_id += 2) {
- for (bool fin : {false, true}) {
- for (SpdyPriority priority = 0; priority < 7; ++priority) {
- // Replace with "WriteHeadersAndSaveData"
- SpdySerializedFrame frame;
- if (perspective() == Perspective::IS_SERVER) {
- SpdyHeadersIR headers_frame(stream_id, headers_.Clone());
- headers_frame.set_fin(fin);
- headers_frame.set_has_priority(true);
- headers_frame.set_weight(Spdy3PriorityToHttp2Weight(0));
- frame = framer_->SerializeFrame(headers_frame);
- EXPECT_CALL(session_, OnStreamHeadersPriority(stream_id, 0));
- } else {
- SpdyHeadersIR headers_frame(stream_id, headers_.Clone());
- headers_frame.set_fin(fin);
- frame = framer_->SerializeFrame(headers_frame);
- }
- EXPECT_CALL(session_,
- OnStreamHeaderList(stream_id, fin, frame.size(), _))
- .WillOnce(Invoke(this, &QuicHeadersStreamTest::SaveHeaderList));
- stream_frame_.data_buffer = frame.data();
- stream_frame_.data_length = frame.size();
- connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
- headers_stream_->OnStreamFrame(stream_frame_);
- stream_frame_.offset += frame.size();
- CheckHeaders();
- }
- }
- }
-}
-
-TEST_P(QuicHeadersStreamTest, HpackEncoderDebugVisitor) {
- StrictMock<MockHpackDebugVisitor>* hpack_encoder_visitor =
- hpack_encoder_visitor_.get();
- headers_stream_->SetHpackEncoderDebugVisitor(
- std::move(hpack_encoder_visitor_));
-
- if (perspective() == Perspective::IS_SERVER) {
- testing::InSequence seq;
- for (int i = 1; i < 4; i++) {
- EXPECT_CALL(*hpack_encoder_visitor,
- OnUseEntry(QuicTime::Delta::FromMilliseconds(i)));
- }
- } else {
- testing::InSequence seq;
- for (int i = 1; i < 28; i++) {
- EXPECT_CALL(*hpack_encoder_visitor,
- OnUseEntry(QuicTime::Delta::FromMilliseconds(i)));
- }
- }
- for (QuicStreamId stream_id = kClientDataStreamId1;
- stream_id < kClientDataStreamId3; stream_id += 2) {
- for (bool fin : {false, true}) {
- if (perspective() == Perspective::IS_SERVER) {
- WriteHeadersAndExpectSynReply(stream_id, fin);
- connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
- } else {
- for (SpdyPriority priority = 0; priority < 7; ++priority) {
- // TODO(rch): implement priorities correctly.
- WriteHeadersAndExpectSynStream(stream_id, fin, 0);
- connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
- }
- }
- }
- }
-}
-
-TEST_P(QuicHeadersStreamTest, WritevStreamData) {
- QuicStreamId id = kClientDataStreamId1;
- QuicStreamOffset offset = 0;
- struct iovec iov;
- string data;
-
- // This test will issue a write that will require fragmenting into
- // multiple HTTP/2 DATA frames.
- const int kMinDataFrames = 4;
- const size_t data_len =
- kSpdyInitialFrameSizeLimit * kMinDataFrames + 1024;
- // Set headers stream send window large enough for data written below.
- headers_stream_->flow_controller()->UpdateSendWindowOffset(data_len * 2 * 4);
- test::GenerateBody(&data, data_len);
-
- for (bool fin : {true, false}) {
- for (bool use_ack_listener : {true, false}) {
- scoped_refptr<ForceHolAckListener> ack_listener;
- if (use_ack_listener) {
- ack_listener = new ForceHolAckListener();
- }
- EXPECT_CALL(session_,
- WritevData(headers_stream_, kHeadersStreamId, _, _, false, _))
- .WillRepeatedly(WithArgs<2, 5>(Invoke(
- this, &QuicHeadersStreamTest::SaveIovAndNotifyAckListener)));
-
- QuicConsumedData consumed_data = headers_stream_->WritevStreamData(
- id, MakeIOVector(data, &iov), offset, fin, ack_listener.get());
-
- EXPECT_EQ(consumed_data.bytes_consumed, data_len);
- EXPECT_EQ(consumed_data.fin_consumed, fin);
- // Now process the written data with the SPDY framer, and verify
- // that the original data is unchanged.
- EXPECT_CALL(visitor_, OnDataFrameHeader(id, _, _))
- .Times(AtLeast(kMinDataFrames));
- EXPECT_CALL(visitor_, OnStreamFrameData(id, _, _))
- .WillRepeatedly(WithArgs<1, 2>(
- Invoke(this, &QuicHeadersStreamTest::SavePayload)));
- if (fin) {
- EXPECT_CALL(visitor_, OnStreamEnd(id));
- }
- framer_->ProcessInput(saved_data_.data(), saved_data_.length());
- EXPECT_EQ(saved_payloads_, data);
-
- if (use_ack_listener) {
- // Notice, acked bytes doesn't include extra bytes used by
- // HTTP/2 DATA frame headers.
- EXPECT_EQ(ack_listener->total_acked_bytes(), data_len);
- }
- saved_data_.clear();
- saved_payloads_.clear();
- }
- }
-}
-
-} // namespace
-} // namespace test
-} // namespace net
« no previous file with comments | « net/quic/quic_headers_stream.cc ('k') | net/quic/quic_http_utils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698