1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "quiche/quic/core/qpack/qpack_send_stream.h"
6
7 #include "absl/strings/str_cat.h"
8 #include "absl/strings/string_view.h"
9 #include "quiche/quic/core/crypto/null_encrypter.h"
10 #include "quiche/quic/core/http/http_constants.h"
11 #include "quiche/quic/platform/api/quic_test.h"
12 #include "quiche/quic/test_tools/quic_config_peer.h"
13 #include "quiche/quic/test_tools/quic_connection_peer.h"
14 #include "quiche/quic/test_tools/quic_spdy_session_peer.h"
15 #include "quiche/quic/test_tools/quic_test_utils.h"
16
17 namespace quic {
18 namespace test {
19
20 namespace {
21 using ::testing::_;
22 using ::testing::AnyNumber;
23 using ::testing::Invoke;
24 using ::testing::StrictMock;
25
26 struct TestParams {
TestParamsquic::test::__anon151da4520111::TestParams27 TestParams(const ParsedQuicVersion& version, Perspective perspective)
28 : version(version), perspective(perspective) {
29 QUIC_LOG(INFO) << "TestParams: version: "
30 << ParsedQuicVersionToString(version)
31 << ", perspective: " << perspective;
32 }
33
TestParamsquic::test::__anon151da4520111::TestParams34 TestParams(const TestParams& other)
35 : version(other.version), perspective(other.perspective) {}
36
37 ParsedQuicVersion version;
38 Perspective perspective;
39 };
40
41 // Used by ::testing::PrintToStringParamName().
PrintToString(const TestParams & tp)42 std::string PrintToString(const TestParams& tp) {
43 return absl::StrCat(
44 ParsedQuicVersionToString(tp.version), "_",
45 (tp.perspective == Perspective::IS_CLIENT ? "client" : "server"));
46 }
47
GetTestParams()48 std::vector<TestParams> GetTestParams() {
49 std::vector<TestParams> params;
50 ParsedQuicVersionVector all_supported_versions = AllSupportedVersions();
51 for (const auto& version : AllSupportedVersions()) {
52 if (!VersionUsesHttp3(version.transport_version)) {
53 continue;
54 }
55 for (Perspective p : {Perspective::IS_SERVER, Perspective::IS_CLIENT}) {
56 params.emplace_back(version, p);
57 }
58 }
59 return params;
60 }
61
62 class QpackSendStreamTest : public QuicTestWithParam<TestParams> {
63 public:
QpackSendStreamTest()64 QpackSendStreamTest()
65 : connection_(new StrictMock<MockQuicConnection>(
66 &helper_, &alarm_factory_, perspective(),
67 SupportedVersions(GetParam().version))),
68 session_(connection_) {
69 EXPECT_CALL(session_, OnCongestionWindowChange(_)).Times(AnyNumber());
70 session_.Initialize();
71 connection_->SetEncrypter(
72 ENCRYPTION_FORWARD_SECURE,
73 std::make_unique<NullEncrypter>(connection_->perspective()));
74 if (connection_->version().SupportsAntiAmplificationLimit()) {
75 QuicConnectionPeer::SetAddressValidated(connection_);
76 }
77 QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
78 session_.config(), kMinimumFlowControlSendWindow);
79 QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesUnidirectional(
80 session_.config(), kMinimumFlowControlSendWindow);
81 QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(session_.config(), 3);
82 session_.OnConfigNegotiated();
83
84 qpack_send_stream_ =
85 QuicSpdySessionPeer::GetQpackDecoderSendStream(&session_);
86
87 ON_CALL(session_, WritevData(_, _, _, _, _, _))
88 .WillByDefault(Invoke(&session_, &MockQuicSpdySession::ConsumeData));
89 }
90
perspective() const91 Perspective perspective() const { return GetParam().perspective; }
92
93 MockQuicConnectionHelper helper_;
94 MockAlarmFactory alarm_factory_;
95 StrictMock<MockQuicConnection>* connection_;
96 StrictMock<MockQuicSpdySession> session_;
97 QpackSendStream* qpack_send_stream_;
98 };
99
100 INSTANTIATE_TEST_SUITE_P(Tests, QpackSendStreamTest,
101 ::testing::ValuesIn(GetTestParams()),
102 ::testing::PrintToStringParamName());
103
TEST_P(QpackSendStreamTest,WriteStreamTypeOnlyFirstTime)104 TEST_P(QpackSendStreamTest, WriteStreamTypeOnlyFirstTime) {
105 std::string data = "data";
106 EXPECT_CALL(session_, WritevData(_, 1, _, _, _, _));
107 EXPECT_CALL(session_, WritevData(_, data.length(), _, _, _, _));
108 qpack_send_stream_->WriteStreamData(absl::string_view(data));
109
110 EXPECT_CALL(session_, WritevData(_, data.length(), _, _, _, _));
111 qpack_send_stream_->WriteStreamData(absl::string_view(data));
112 EXPECT_CALL(session_, WritevData(_, _, _, _, _, _)).Times(0);
113 qpack_send_stream_->MaybeSendStreamType();
114 }
115
TEST_P(QpackSendStreamTest,StopSendingQpackStream)116 TEST_P(QpackSendStreamTest, StopSendingQpackStream) {
117 EXPECT_CALL(*connection_,
118 CloseConnection(QUIC_HTTP_CLOSED_CRITICAL_STREAM, _, _));
119 qpack_send_stream_->OnStopSending(
120 QuicResetStreamError::FromInternal(QUIC_STREAM_CANCELLED));
121 }
122
TEST_P(QpackSendStreamTest,ReceiveDataOnSendStream)123 TEST_P(QpackSendStreamTest, ReceiveDataOnSendStream) {
124 QuicStreamFrame frame(qpack_send_stream_->id(), false, 0, "test");
125 EXPECT_CALL(
126 *connection_,
127 CloseConnection(QUIC_DATA_RECEIVED_ON_WRITE_UNIDIRECTIONAL_STREAM, _, _));
128 qpack_send_stream_->OnStreamFrame(frame);
129 }
130
131 } // namespace
132 } // namespace test
133 } // namespace quic
134