vasilvv | 097f372 | 2019-10-23 13:36:16 -0700 | [diff] [blame] | 1 | // Copyright (c) 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 | // An integration test that covers interactions between QuicTransport client and |
| 6 | // server sessions. |
| 7 | |
| 8 | #include <memory> |
vasilvv | d88f162 | 2019-11-04 13:50:53 -0800 | [diff] [blame] | 9 | #include <vector> |
vasilvv | 097f372 | 2019-10-23 13:36:16 -0700 | [diff] [blame] | 10 | |
| 11 | #include "url/gurl.h" |
| 12 | #include "url/origin.h" |
| 13 | #include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.h" |
| 14 | #include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.h" |
vasilvv | 2b0ab24 | 2020-01-07 07:32:09 -0800 | [diff] [blame] | 15 | #include "net/third_party/quiche/src/quic/core/quic_buffer_allocator.h" |
vasilvv | 097f372 | 2019-10-23 13:36:16 -0700 | [diff] [blame] | 16 | #include "net/third_party/quiche/src/quic/core/quic_connection.h" |
| 17 | #include "net/third_party/quiche/src/quic/core/quic_error_codes.h" |
| 18 | #include "net/third_party/quiche/src/quic/core/quic_types.h" |
| 19 | #include "net/third_party/quiche/src/quic/core/quic_versions.h" |
vasilvv | d88f162 | 2019-11-04 13:50:53 -0800 | [diff] [blame] | 20 | #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" |
vasilvv | 2b0ab24 | 2020-01-07 07:32:09 -0800 | [diff] [blame] | 21 | #include "net/third_party/quiche/src/quic/platform/api/quic_optional.h" |
vasilvv | 097f372 | 2019-10-23 13:36:16 -0700 | [diff] [blame] | 22 | #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" |
| 23 | #include "net/third_party/quiche/src/quic/quic_transport/quic_transport_client_session.h" |
| 24 | #include "net/third_party/quiche/src/quic/quic_transport/quic_transport_server_session.h" |
vasilvv | d88f162 | 2019-11-04 13:50:53 -0800 | [diff] [blame] | 25 | #include "net/third_party/quiche/src/quic/quic_transport/quic_transport_stream.h" |
vasilvv | 097f372 | 2019-10-23 13:36:16 -0700 | [diff] [blame] | 26 | #include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h" |
| 27 | #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" |
vasilvv | dfbd3df | 2019-11-01 11:58:43 -0700 | [diff] [blame] | 28 | #include "net/third_party/quiche/src/quic/test_tools/quic_transport_test_tools.h" |
vasilvv | 097f372 | 2019-10-23 13:36:16 -0700 | [diff] [blame] | 29 | #include "net/third_party/quiche/src/quic/test_tools/simulator/link.h" |
| 30 | #include "net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint_base.h" |
| 31 | #include "net/third_party/quiche/src/quic/test_tools/simulator/simulator.h" |
| 32 | #include "net/third_party/quiche/src/quic/test_tools/simulator/switch.h" |
vasilvv | d88f162 | 2019-11-04 13:50:53 -0800 | [diff] [blame] | 33 | #include "net/third_party/quiche/src/quic/tools/quic_transport_simple_server_session.h" |
vasilvv | da373d4 | 2020-01-16 12:36:27 -0800 | [diff] [blame] | 34 | #include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" |
vasilvv | 097f372 | 2019-10-23 13:36:16 -0700 | [diff] [blame] | 35 | |
| 36 | namespace quic { |
| 37 | namespace test { |
| 38 | namespace { |
| 39 | |
| 40 | using simulator::QuicEndpointBase; |
| 41 | using simulator::Simulator; |
vasilvv | da373d4 | 2020-01-16 12:36:27 -0800 | [diff] [blame] | 42 | using testing::_; |
vasilvv | d88f162 | 2019-11-04 13:50:53 -0800 | [diff] [blame] | 43 | using testing::Assign; |
vasilvv | da373d4 | 2020-01-16 12:36:27 -0800 | [diff] [blame] | 44 | using testing::Eq; |
vasilvv | 097f372 | 2019-10-23 13:36:16 -0700 | [diff] [blame] | 45 | |
| 46 | url::Origin GetTestOrigin() { |
| 47 | constexpr char kTestOrigin[] = "https://test-origin.test"; |
| 48 | GURL origin_url(kTestOrigin); |
| 49 | return url::Origin::Create(origin_url); |
| 50 | } |
| 51 | |
| 52 | ParsedQuicVersionVector GetVersions() { |
| 53 | return {ParsedQuicVersion{PROTOCOL_TLS1_3, QUIC_VERSION_99}}; |
| 54 | } |
| 55 | |
| 56 | class QuicTransportEndpointBase : public QuicEndpointBase { |
| 57 | public: |
| 58 | QuicTransportEndpointBase(Simulator* simulator, |
| 59 | const std::string& name, |
| 60 | const std::string& peer_name, |
| 61 | Perspective perspective) |
| 62 | : QuicEndpointBase(simulator, name, peer_name) { |
| 63 | connection_ = std::make_unique<QuicConnection>( |
| 64 | TestConnectionId(0x10), simulator::GetAddressFromName(peer_name), |
| 65 | simulator, simulator->GetAlarmFactory(), &writer_, |
| 66 | /*owns_writer=*/false, perspective, GetVersions()); |
| 67 | connection_->SetSelfAddress(simulator::GetAddressFromName(name)); |
vasilvv | 097f372 | 2019-10-23 13:36:16 -0700 | [diff] [blame] | 68 | } |
| 69 | }; |
| 70 | |
| 71 | class QuicTransportClientEndpoint : public QuicTransportEndpointBase { |
| 72 | public: |
| 73 | QuicTransportClientEndpoint(Simulator* simulator, |
| 74 | const std::string& name, |
| 75 | const std::string& peer_name, |
vasilvv | ec038f1 | 2020-01-07 11:58:08 -0800 | [diff] [blame] | 76 | const QuicConfig& config, |
vasilvv | d7692cd | 2019-12-06 08:06:31 -0800 | [diff] [blame] | 77 | url::Origin origin, |
| 78 | const std::string& path) |
vasilvv | 097f372 | 2019-10-23 13:36:16 -0700 | [diff] [blame] | 79 | : QuicTransportEndpointBase(simulator, |
| 80 | name, |
| 81 | peer_name, |
| 82 | Perspective::IS_CLIENT), |
| 83 | crypto_config_(crypto_test_utils::ProofVerifierForTesting()), |
| 84 | session_(connection_.get(), |
| 85 | nullptr, |
vasilvv | ec038f1 | 2020-01-07 11:58:08 -0800 | [diff] [blame] | 86 | config, |
vasilvv | 097f372 | 2019-10-23 13:36:16 -0700 | [diff] [blame] | 87 | GetVersions(), |
vasilvv | d7692cd | 2019-12-06 08:06:31 -0800 | [diff] [blame] | 88 | GURL("quic-transport://test.example.com:50000" + path), |
vasilvv | 097f372 | 2019-10-23 13:36:16 -0700 | [diff] [blame] | 89 | &crypto_config_, |
vasilvv | dfbd3df | 2019-11-01 11:58:43 -0700 | [diff] [blame] | 90 | origin, |
| 91 | &visitor_) { |
vasilvv | 097f372 | 2019-10-23 13:36:16 -0700 | [diff] [blame] | 92 | session_.Initialize(); |
| 93 | } |
| 94 | |
| 95 | QuicTransportClientSession* session() { return &session_; } |
vasilvv | d88f162 | 2019-11-04 13:50:53 -0800 | [diff] [blame] | 96 | MockClientVisitor* visitor() { return &visitor_; } |
vasilvv | 097f372 | 2019-10-23 13:36:16 -0700 | [diff] [blame] | 97 | |
| 98 | private: |
| 99 | QuicCryptoClientConfig crypto_config_; |
vasilvv | dfbd3df | 2019-11-01 11:58:43 -0700 | [diff] [blame] | 100 | MockClientVisitor visitor_; |
vasilvv | 097f372 | 2019-10-23 13:36:16 -0700 | [diff] [blame] | 101 | QuicTransportClientSession session_; |
| 102 | }; |
| 103 | |
vasilvv | 097f372 | 2019-10-23 13:36:16 -0700 | [diff] [blame] | 104 | class QuicTransportServerEndpoint : public QuicTransportEndpointBase { |
| 105 | public: |
| 106 | QuicTransportServerEndpoint(Simulator* simulator, |
| 107 | const std::string& name, |
vasilvv | d88f162 | 2019-11-04 13:50:53 -0800 | [diff] [blame] | 108 | const std::string& peer_name, |
vasilvv | ec038f1 | 2020-01-07 11:58:08 -0800 | [diff] [blame] | 109 | const QuicConfig& config, |
vasilvv | d88f162 | 2019-11-04 13:50:53 -0800 | [diff] [blame] | 110 | std::vector<url::Origin> accepted_origins) |
vasilvv | 097f372 | 2019-10-23 13:36:16 -0700 | [diff] [blame] | 111 | : QuicTransportEndpointBase(simulator, |
| 112 | name, |
| 113 | peer_name, |
| 114 | Perspective::IS_SERVER), |
| 115 | crypto_config_(QuicCryptoServerConfig::TESTING, |
| 116 | QuicRandom::GetInstance(), |
| 117 | crypto_test_utils::ProofSourceForTesting(), |
| 118 | KeyExchangeSource::Default()), |
| 119 | compressed_certs_cache_( |
| 120 | QuicCompressedCertsCache::kQuicCompressedCertsCacheSize), |
| 121 | session_(connection_.get(), |
vasilvv | d88f162 | 2019-11-04 13:50:53 -0800 | [diff] [blame] | 122 | /*owns_connection=*/false, |
vasilvv | 097f372 | 2019-10-23 13:36:16 -0700 | [diff] [blame] | 123 | nullptr, |
vasilvv | ec038f1 | 2020-01-07 11:58:08 -0800 | [diff] [blame] | 124 | config, |
vasilvv | 097f372 | 2019-10-23 13:36:16 -0700 | [diff] [blame] | 125 | GetVersions(), |
| 126 | &crypto_config_, |
| 127 | &compressed_certs_cache_, |
vasilvv | d88f162 | 2019-11-04 13:50:53 -0800 | [diff] [blame] | 128 | accepted_origins) { |
vasilvv | 097f372 | 2019-10-23 13:36:16 -0700 | [diff] [blame] | 129 | session_.Initialize(); |
| 130 | } |
| 131 | |
| 132 | QuicTransportServerSession* session() { return &session_; } |
vasilvv | 097f372 | 2019-10-23 13:36:16 -0700 | [diff] [blame] | 133 | |
| 134 | private: |
| 135 | QuicCryptoServerConfig crypto_config_; |
| 136 | QuicCompressedCertsCache compressed_certs_cache_; |
vasilvv | d88f162 | 2019-11-04 13:50:53 -0800 | [diff] [blame] | 137 | QuicTransportSimpleServerSession session_; |
vasilvv | 097f372 | 2019-10-23 13:36:16 -0700 | [diff] [blame] | 138 | }; |
| 139 | |
vasilvv | d88f162 | 2019-11-04 13:50:53 -0800 | [diff] [blame] | 140 | std::unique_ptr<MockStreamVisitor> VisitorExpectingFin() { |
| 141 | auto visitor = std::make_unique<MockStreamVisitor>(); |
| 142 | EXPECT_CALL(*visitor, OnFinRead()); |
| 143 | return visitor; |
| 144 | } |
| 145 | |
vasilvv | 097f372 | 2019-10-23 13:36:16 -0700 | [diff] [blame] | 146 | constexpr QuicBandwidth kClientBandwidth = |
| 147 | QuicBandwidth::FromKBitsPerSecond(10000); |
| 148 | constexpr QuicTime::Delta kClientPropagationDelay = |
| 149 | QuicTime::Delta::FromMilliseconds(2); |
| 150 | constexpr QuicBandwidth kServerBandwidth = |
| 151 | QuicBandwidth::FromKBitsPerSecond(4000); |
| 152 | constexpr QuicTime::Delta kServerPropagationDelay = |
| 153 | QuicTime::Delta::FromMilliseconds(50); |
| 154 | const QuicTime::Delta kTransferTime = |
| 155 | kClientBandwidth.TransferTime(kMaxOutgoingPacketSize) + |
| 156 | kServerBandwidth.TransferTime(kMaxOutgoingPacketSize); |
| 157 | const QuicTime::Delta kRtt = |
| 158 | (kClientPropagationDelay + kServerPropagationDelay + kTransferTime) * 2; |
| 159 | const QuicByteCount kBdp = kRtt * kServerBandwidth; |
| 160 | |
vasilvv | d88f162 | 2019-11-04 13:50:53 -0800 | [diff] [blame] | 161 | constexpr QuicTime::Delta kDefaultTimeout = QuicTime::Delta::FromSeconds(3); |
vasilvv | 097f372 | 2019-10-23 13:36:16 -0700 | [diff] [blame] | 162 | |
| 163 | class QuicTransportIntegrationTest : public QuicTest { |
| 164 | public: |
| 165 | QuicTransportIntegrationTest() |
| 166 | : switch_(&simulator_, "Switch", 8, 2 * kBdp) {} |
| 167 | |
vasilvv | d7692cd | 2019-12-06 08:06:31 -0800 | [diff] [blame] | 168 | void CreateDefaultEndpoints(const std::string& path) { |
vasilvv | 097f372 | 2019-10-23 13:36:16 -0700 | [diff] [blame] | 169 | client_ = std::make_unique<QuicTransportClientEndpoint>( |
vasilvv | ec038f1 | 2020-01-07 11:58:08 -0800 | [diff] [blame] | 170 | &simulator_, "Client", "Server", client_config_, GetTestOrigin(), path); |
vasilvv | d88f162 | 2019-11-04 13:50:53 -0800 | [diff] [blame] | 171 | server_ = std::make_unique<QuicTransportServerEndpoint>( |
vasilvv | ec038f1 | 2020-01-07 11:58:08 -0800 | [diff] [blame] | 172 | &simulator_, "Server", "Client", server_config_, accepted_origins_); |
vasilvv | 097f372 | 2019-10-23 13:36:16 -0700 | [diff] [blame] | 173 | } |
| 174 | |
| 175 | void WireUpEndpoints() { |
| 176 | client_link_ = std::make_unique<simulator::SymmetricLink>( |
| 177 | client_.get(), switch_.port(1), kClientBandwidth, |
| 178 | kClientPropagationDelay); |
| 179 | server_link_ = std::make_unique<simulator::SymmetricLink>( |
| 180 | server_.get(), switch_.port(2), kServerBandwidth, |
| 181 | kServerPropagationDelay); |
| 182 | } |
| 183 | |
| 184 | void RunHandshake() { |
| 185 | client_->session()->CryptoConnect(); |
| 186 | bool result = simulator_.RunUntilOrTimeout( |
| 187 | [this]() { |
| 188 | return IsHandshakeDone(client_->session()) && |
| 189 | IsHandshakeDone(server_->session()); |
| 190 | }, |
vasilvv | d88f162 | 2019-11-04 13:50:53 -0800 | [diff] [blame] | 191 | kDefaultTimeout); |
vasilvv | 097f372 | 2019-10-23 13:36:16 -0700 | [diff] [blame] | 192 | EXPECT_TRUE(result); |
| 193 | } |
| 194 | |
| 195 | protected: |
| 196 | template <class Session> |
| 197 | static bool IsHandshakeDone(const Session* session) { |
| 198 | return session->IsSessionReady() || session->error() != QUIC_NO_ERROR; |
| 199 | } |
| 200 | |
vasilvv | ec038f1 | 2020-01-07 11:58:08 -0800 | [diff] [blame] | 201 | QuicConfig client_config_ = DefaultQuicConfig(); |
| 202 | QuicConfig server_config_ = DefaultQuicConfig(); |
| 203 | |
vasilvv | 097f372 | 2019-10-23 13:36:16 -0700 | [diff] [blame] | 204 | Simulator simulator_; |
| 205 | simulator::Switch switch_; |
| 206 | std::unique_ptr<simulator::SymmetricLink> client_link_; |
| 207 | std::unique_ptr<simulator::SymmetricLink> server_link_; |
| 208 | |
| 209 | std::unique_ptr<QuicTransportClientEndpoint> client_; |
| 210 | std::unique_ptr<QuicTransportServerEndpoint> server_; |
vasilvv | d88f162 | 2019-11-04 13:50:53 -0800 | [diff] [blame] | 211 | |
| 212 | std::vector<url::Origin> accepted_origins_ = {GetTestOrigin()}; |
vasilvv | 097f372 | 2019-10-23 13:36:16 -0700 | [diff] [blame] | 213 | }; |
| 214 | |
| 215 | TEST_F(QuicTransportIntegrationTest, SuccessfulHandshake) { |
vasilvv | d7692cd | 2019-12-06 08:06:31 -0800 | [diff] [blame] | 216 | CreateDefaultEndpoints("/discard"); |
vasilvv | 097f372 | 2019-10-23 13:36:16 -0700 | [diff] [blame] | 217 | WireUpEndpoints(); |
vasilvv | 467b422 | 2019-12-09 16:22:11 -0800 | [diff] [blame] | 218 | EXPECT_CALL(*client_->visitor(), OnSessionReady()); |
vasilvv | 097f372 | 2019-10-23 13:36:16 -0700 | [diff] [blame] | 219 | RunHandshake(); |
| 220 | EXPECT_TRUE(client_->session()->IsSessionReady()); |
| 221 | EXPECT_TRUE(server_->session()->IsSessionReady()); |
| 222 | } |
| 223 | |
| 224 | TEST_F(QuicTransportIntegrationTest, OriginMismatch) { |
vasilvv | d88f162 | 2019-11-04 13:50:53 -0800 | [diff] [blame] | 225 | accepted_origins_ = {url::Origin::Create(GURL{"https://wrong-origin.test"})}; |
vasilvv | d7692cd | 2019-12-06 08:06:31 -0800 | [diff] [blame] | 226 | CreateDefaultEndpoints("/discard"); |
vasilvv | 097f372 | 2019-10-23 13:36:16 -0700 | [diff] [blame] | 227 | WireUpEndpoints(); |
vasilvv | 097f372 | 2019-10-23 13:36:16 -0700 | [diff] [blame] | 228 | RunHandshake(); |
| 229 | // Wait until the client receives CONNECTION_CLOSE. |
| 230 | simulator_.RunUntilOrTimeout( |
| 231 | [this]() { return !client_->session()->connection()->connected(); }, |
vasilvv | d88f162 | 2019-11-04 13:50:53 -0800 | [diff] [blame] | 232 | kDefaultTimeout); |
vasilvv | 097f372 | 2019-10-23 13:36:16 -0700 | [diff] [blame] | 233 | EXPECT_TRUE(client_->session()->IsSessionReady()); |
| 234 | EXPECT_FALSE(server_->session()->IsSessionReady()); |
| 235 | EXPECT_FALSE(client_->session()->connection()->connected()); |
| 236 | EXPECT_FALSE(server_->session()->connection()->connected()); |
bnc | a6cd688 | 2019-11-27 08:46:01 -0800 | [diff] [blame] | 237 | EXPECT_THAT(client_->session()->error(), |
| 238 | IsError(QUIC_TRANSPORT_INVALID_CLIENT_INDICATION)); |
| 239 | EXPECT_THAT(server_->session()->error(), |
| 240 | IsError(QUIC_TRANSPORT_INVALID_CLIENT_INDICATION)); |
vasilvv | 097f372 | 2019-10-23 13:36:16 -0700 | [diff] [blame] | 241 | } |
| 242 | |
vasilvv | d88f162 | 2019-11-04 13:50:53 -0800 | [diff] [blame] | 243 | TEST_F(QuicTransportIntegrationTest, SendOutgoingStreams) { |
vasilvv | d7692cd | 2019-12-06 08:06:31 -0800 | [diff] [blame] | 244 | CreateDefaultEndpoints("/discard"); |
vasilvv | d88f162 | 2019-11-04 13:50:53 -0800 | [diff] [blame] | 245 | WireUpEndpoints(); |
| 246 | RunHandshake(); |
| 247 | |
| 248 | std::vector<QuicTransportStream*> streams; |
| 249 | for (int i = 0; i < 10; i++) { |
| 250 | QuicTransportStream* stream = |
| 251 | client_->session()->OpenOutgoingUnidirectionalStream(); |
| 252 | ASSERT_TRUE(stream->Write("test")); |
| 253 | streams.push_back(stream); |
| 254 | } |
| 255 | ASSERT_TRUE(simulator_.RunUntilOrTimeout( |
| 256 | [this]() { |
| 257 | return server_->session()->GetNumOpenIncomingStreams() == 10; |
| 258 | }, |
| 259 | kDefaultTimeout)); |
| 260 | |
| 261 | for (QuicTransportStream* stream : streams) { |
| 262 | ASSERT_TRUE(stream->SendFin()); |
| 263 | } |
| 264 | ASSERT_TRUE(simulator_.RunUntilOrTimeout( |
| 265 | [this]() { return server_->session()->GetNumOpenIncomingStreams() == 0; }, |
| 266 | kDefaultTimeout)); |
| 267 | } |
| 268 | |
| 269 | TEST_F(QuicTransportIntegrationTest, EchoBidirectionalStreams) { |
vasilvv | d7692cd | 2019-12-06 08:06:31 -0800 | [diff] [blame] | 270 | CreateDefaultEndpoints("/echo"); |
vasilvv | d88f162 | 2019-11-04 13:50:53 -0800 | [diff] [blame] | 271 | WireUpEndpoints(); |
| 272 | RunHandshake(); |
| 273 | |
| 274 | QuicTransportStream* stream = |
| 275 | client_->session()->OpenOutgoingBidirectionalStream(); |
| 276 | EXPECT_TRUE(stream->Write("Hello!")); |
| 277 | |
| 278 | ASSERT_TRUE(simulator_.RunUntilOrTimeout( |
| 279 | [stream]() { return stream->ReadableBytes() == strlen("Hello!"); }, |
| 280 | kDefaultTimeout)); |
| 281 | std::string received; |
| 282 | EXPECT_EQ(stream->Read(&received), strlen("Hello!")); |
| 283 | EXPECT_EQ(received, "Hello!"); |
| 284 | |
| 285 | EXPECT_TRUE(stream->SendFin()); |
| 286 | ASSERT_TRUE(simulator_.RunUntilOrTimeout( |
| 287 | [this]() { return server_->session()->GetNumOpenIncomingStreams() == 0; }, |
| 288 | kDefaultTimeout)); |
| 289 | } |
| 290 | |
| 291 | TEST_F(QuicTransportIntegrationTest, EchoUnidirectionalStreams) { |
vasilvv | d7692cd | 2019-12-06 08:06:31 -0800 | [diff] [blame] | 292 | CreateDefaultEndpoints("/echo"); |
vasilvv | d88f162 | 2019-11-04 13:50:53 -0800 | [diff] [blame] | 293 | WireUpEndpoints(); |
| 294 | RunHandshake(); |
| 295 | |
| 296 | // Send two streams, but only send FIN on the second one. |
| 297 | QuicTransportStream* stream1 = |
| 298 | client_->session()->OpenOutgoingUnidirectionalStream(); |
| 299 | EXPECT_TRUE(stream1->Write("Stream One")); |
| 300 | QuicTransportStream* stream2 = |
| 301 | client_->session()->OpenOutgoingUnidirectionalStream(); |
| 302 | EXPECT_TRUE(stream2->Write("Stream Two")); |
| 303 | EXPECT_TRUE(stream2->SendFin()); |
| 304 | |
| 305 | // Wait until a stream is received. |
| 306 | bool stream_received = false; |
| 307 | EXPECT_CALL(*client_->visitor(), OnIncomingUnidirectionalStreamAvailable()) |
| 308 | .Times(2) |
| 309 | .WillRepeatedly(Assign(&stream_received, true)); |
| 310 | ASSERT_TRUE(simulator_.RunUntilOrTimeout( |
| 311 | [&stream_received]() { return stream_received; }, kDefaultTimeout)); |
| 312 | |
| 313 | // Receive a reply stream and expect it to be the second one. |
| 314 | QuicTransportStream* reply = |
| 315 | client_->session()->AcceptIncomingUnidirectionalStream(); |
| 316 | ASSERT_TRUE(reply != nullptr); |
| 317 | std::string buffer; |
| 318 | reply->set_visitor(VisitorExpectingFin()); |
| 319 | EXPECT_GT(reply->Read(&buffer), 0u); |
| 320 | EXPECT_EQ(buffer, "Stream Two"); |
| 321 | |
| 322 | // Reset reply-related variables. |
| 323 | stream_received = false; |
| 324 | buffer = ""; |
| 325 | |
| 326 | // Send FIN on the first stream, and expect to receive it back. |
| 327 | EXPECT_TRUE(stream1->SendFin()); |
| 328 | ASSERT_TRUE(simulator_.RunUntilOrTimeout( |
| 329 | [&stream_received]() { return stream_received; }, kDefaultTimeout)); |
| 330 | reply = client_->session()->AcceptIncomingUnidirectionalStream(); |
| 331 | ASSERT_TRUE(reply != nullptr); |
| 332 | reply->set_visitor(VisitorExpectingFin()); |
| 333 | EXPECT_GT(reply->Read(&buffer), 0u); |
| 334 | EXPECT_EQ(buffer, "Stream One"); |
| 335 | } |
| 336 | |
vasilvv | 2b0ab24 | 2020-01-07 07:32:09 -0800 | [diff] [blame] | 337 | TEST_F(QuicTransportIntegrationTest, EchoDatagram) { |
| 338 | CreateDefaultEndpoints("/echo"); |
| 339 | WireUpEndpoints(); |
| 340 | RunHandshake(); |
| 341 | |
| 342 | client_->session()->datagram_queue()->SendOrQueueDatagram( |
| 343 | MemSliceFromString("test")); |
| 344 | |
| 345 | bool datagram_received = false; |
vasilvv | da373d4 | 2020-01-16 12:36:27 -0800 | [diff] [blame] | 346 | EXPECT_CALL(*client_->visitor(), OnDatagramReceived(Eq("test"))) |
vasilvv | 2b0ab24 | 2020-01-07 07:32:09 -0800 | [diff] [blame] | 347 | .WillOnce(Assign(&datagram_received, true)); |
| 348 | ASSERT_TRUE(simulator_.RunUntilOrTimeout( |
| 349 | [&datagram_received]() { return datagram_received; }, kDefaultTimeout)); |
vasilvv | 2b0ab24 | 2020-01-07 07:32:09 -0800 | [diff] [blame] | 350 | } |
| 351 | |
| 352 | // This test sets the datagram queue to an nearly-infinte queueing time, and |
| 353 | // then sends 1000 datagrams. We expect to receive most of them back, since the |
| 354 | // datagrams would be paced out by the congestion controller. |
| 355 | TEST_F(QuicTransportIntegrationTest, EchoALotOfDatagrams) { |
| 356 | CreateDefaultEndpoints("/echo"); |
| 357 | WireUpEndpoints(); |
| 358 | RunHandshake(); |
| 359 | |
| 360 | // Set the datagrams to effectively never expire. |
| 361 | client_->session()->datagram_queue()->SetMaxTimeInQueue(10000 * kRtt); |
| 362 | for (int i = 0; i < 1000; i++) { |
| 363 | client_->session()->datagram_queue()->SendOrQueueDatagram( |
| 364 | MemSliceFromString(std::string( |
| 365 | client_->session()->GetGuaranteedLargestMessagePayload(), 'a'))); |
| 366 | } |
| 367 | |
| 368 | size_t received = 0; |
vasilvv | da373d4 | 2020-01-16 12:36:27 -0800 | [diff] [blame] | 369 | EXPECT_CALL(*client_->visitor(), OnDatagramReceived(_)) |
| 370 | .WillRepeatedly( |
| 371 | [&received](quiche::QuicheStringPiece /*datagram*/) { received++; }); |
vasilvv | 2b0ab24 | 2020-01-07 07:32:09 -0800 | [diff] [blame] | 372 | ASSERT_TRUE(simulator_.RunUntilOrTimeout( |
| 373 | [this]() { return client_->session()->datagram_queue()->empty(); }, |
| 374 | 3 * kServerBandwidth.TransferTime(1000 * kMaxOutgoingPacketSize))); |
| 375 | // Allow extra round-trips for the final flight of datagrams to arrive back. |
| 376 | simulator_.RunFor(2 * kRtt); |
| 377 | |
| 378 | EXPECT_GT(received, 500u); |
| 379 | EXPECT_LT(received, 1000u); |
| 380 | } |
| 381 | |
vasilvv | ec038f1 | 2020-01-07 11:58:08 -0800 | [diff] [blame] | 382 | TEST_F(QuicTransportIntegrationTest, OutgoingStreamFlowControlBlocked) { |
| 383 | server_config_.SetMaxUnidirectionalStreamsToSend(4); |
| 384 | CreateDefaultEndpoints("/discard"); |
| 385 | WireUpEndpoints(); |
| 386 | RunHandshake(); |
| 387 | |
| 388 | QuicTransportStream* stream; |
| 389 | // Note that since we've already used one stream for client indication, we can |
| 390 | // only send three streams at once. |
| 391 | for (int i = 0; i < 3; i++) { |
| 392 | ASSERT_TRUE(client_->session()->CanOpenNextOutgoingUnidirectionalStream()); |
| 393 | stream = client_->session()->OpenOutgoingUnidirectionalStream(); |
| 394 | ASSERT_TRUE(stream != nullptr); |
| 395 | ASSERT_TRUE(stream->SendFin()); |
| 396 | } |
| 397 | EXPECT_FALSE(client_->session()->CanOpenNextOutgoingUnidirectionalStream()); |
| 398 | |
| 399 | // Receiving FINs for the streams we've just opened will cause the server to |
| 400 | // let us open more streams. |
| 401 | bool can_create_new_stream = false; |
| 402 | EXPECT_CALL(*client_->visitor(), OnCanCreateNewOutgoingUnidirectionalStream()) |
| 403 | .WillOnce(Assign(&can_create_new_stream, true)); |
| 404 | ASSERT_TRUE(simulator_.RunUntilOrTimeout( |
| 405 | [&can_create_new_stream]() { return can_create_new_stream; }, |
| 406 | kDefaultTimeout)); |
| 407 | EXPECT_TRUE(client_->session()->CanOpenNextOutgoingUnidirectionalStream()); |
| 408 | } |
| 409 | |
vasilvv | 097f372 | 2019-10-23 13:36:16 -0700 | [diff] [blame] | 410 | } // namespace |
| 411 | } // namespace test |
| 412 | } // namespace quic |