| // Copyright 2019 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 "quiche/quic/core/qpack/qpack_send_stream.h" |
| |
| #include "absl/strings/str_cat.h" |
| #include "absl/strings/string_view.h" |
| #include "quiche/quic/core/crypto/null_encrypter.h" |
| #include "quiche/quic/core/http/http_constants.h" |
| #include "quiche/quic/platform/api/quic_test.h" |
| #include "quiche/quic/test_tools/quic_config_peer.h" |
| #include "quiche/quic/test_tools/quic_connection_peer.h" |
| #include "quiche/quic/test_tools/quic_spdy_session_peer.h" |
| #include "quiche/quic/test_tools/quic_test_utils.h" |
| |
| namespace quic { |
| namespace test { |
| |
| namespace { |
| using ::testing::_; |
| using ::testing::AnyNumber; |
| using ::testing::Invoke; |
| using ::testing::StrictMock; |
| |
| struct TestParams { |
| TestParams(const ParsedQuicVersion& version, Perspective perspective) |
| : version(version), perspective(perspective) { |
| QUIC_LOG(INFO) << "TestParams: version: " |
| << ParsedQuicVersionToString(version) |
| << ", perspective: " << perspective; |
| } |
| |
| TestParams(const TestParams& other) |
| : version(other.version), perspective(other.perspective) {} |
| |
| ParsedQuicVersion version; |
| Perspective perspective; |
| }; |
| |
| // Used by ::testing::PrintToStringParamName(). |
| std::string PrintToString(const TestParams& tp) { |
| return absl::StrCat( |
| ParsedQuicVersionToString(tp.version), "_", |
| (tp.perspective == Perspective::IS_CLIENT ? "client" : "server")); |
| } |
| |
| std::vector<TestParams> GetTestParams() { |
| std::vector<TestParams> params; |
| ParsedQuicVersionVector all_supported_versions = AllSupportedVersions(); |
| for (const auto& version : AllSupportedVersions()) { |
| if (!VersionUsesHttp3(version.transport_version)) { |
| continue; |
| } |
| for (Perspective p : {Perspective::IS_SERVER, Perspective::IS_CLIENT}) { |
| params.emplace_back(version, p); |
| } |
| } |
| return params; |
| } |
| |
| class QpackSendStreamTest : public QuicTestWithParam<TestParams> { |
| public: |
| QpackSendStreamTest() |
| : connection_(new StrictMock<MockQuicConnection>( |
| &helper_, &alarm_factory_, perspective(), |
| SupportedVersions(GetParam().version))), |
| session_(connection_) { |
| EXPECT_CALL(session_, OnCongestionWindowChange(_)).Times(AnyNumber()); |
| session_.Initialize(); |
| connection_->SetEncrypter( |
| ENCRYPTION_FORWARD_SECURE, |
| std::make_unique<NullEncrypter>(connection_->perspective())); |
| if (connection_->version().SupportsAntiAmplificationLimit()) { |
| QuicConnectionPeer::SetAddressValidated(connection_); |
| } |
| QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow( |
| session_.config(), kMinimumFlowControlSendWindow); |
| QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesUnidirectional( |
| session_.config(), kMinimumFlowControlSendWindow); |
| QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(session_.config(), 3); |
| session_.OnConfigNegotiated(); |
| |
| qpack_send_stream_ = |
| QuicSpdySessionPeer::GetQpackDecoderSendStream(&session_); |
| |
| ON_CALL(session_, WritevData(_, _, _, _, _, _)) |
| .WillByDefault(Invoke(&session_, &MockQuicSpdySession::ConsumeData)); |
| } |
| |
| Perspective perspective() const { return GetParam().perspective; } |
| |
| MockQuicConnectionHelper helper_; |
| MockAlarmFactory alarm_factory_; |
| StrictMock<MockQuicConnection>* connection_; |
| StrictMock<MockQuicSpdySession> session_; |
| QpackSendStream* qpack_send_stream_; |
| }; |
| |
| INSTANTIATE_TEST_SUITE_P(Tests, QpackSendStreamTest, |
| ::testing::ValuesIn(GetTestParams()), |
| ::testing::PrintToStringParamName()); |
| |
| TEST_P(QpackSendStreamTest, WriteStreamTypeOnlyFirstTime) { |
| std::string data = "data"; |
| EXPECT_CALL(session_, WritevData(_, 1, _, _, _, _)); |
| EXPECT_CALL(session_, WritevData(_, data.length(), _, _, _, _)); |
| qpack_send_stream_->WriteStreamData(absl::string_view(data)); |
| |
| EXPECT_CALL(session_, WritevData(_, data.length(), _, _, _, _)); |
| qpack_send_stream_->WriteStreamData(absl::string_view(data)); |
| EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)).Times(0); |
| qpack_send_stream_->MaybeSendStreamType(); |
| } |
| |
| TEST_P(QpackSendStreamTest, StopSendingQpackStream) { |
| EXPECT_CALL(*connection_, |
| CloseConnection(QUIC_HTTP_CLOSED_CRITICAL_STREAM, _, _)); |
| qpack_send_stream_->OnStopSending( |
| QuicResetStreamError::FromInternal(QUIC_STREAM_CANCELLED)); |
| } |
| |
| TEST_P(QpackSendStreamTest, ReceiveDataOnSendStream) { |
| QuicStreamFrame frame(qpack_send_stream_->id(), false, 0, "test"); |
| EXPECT_CALL( |
| *connection_, |
| CloseConnection(QUIC_DATA_RECEIVED_ON_WRITE_UNIDIRECTIONAL_STREAM, _, _)); |
| qpack_send_stream_->OnStreamFrame(frame); |
| } |
| |
| } // namespace |
| } // namespace test |
| } // namespace quic |