| OLD | NEW |
| (Empty) |
| 1 // Copyright 2013 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 "net/tools/quic/quic_server_session.h" | |
| 6 | |
| 7 #include "net/quic/crypto/cached_network_parameters.h" | |
| 8 #include "net/quic/crypto/quic_crypto_server_config.h" | |
| 9 #include "net/quic/crypto/quic_random.h" | |
| 10 #include "net/quic/quic_connection.h" | |
| 11 #include "net/quic/quic_crypto_server_stream.h" | |
| 12 #include "net/quic/quic_flags.h" | |
| 13 #include "net/quic/quic_utils.h" | |
| 14 #include "net/quic/test_tools/quic_config_peer.h" | |
| 15 #include "net/quic/test_tools/quic_connection_peer.h" | |
| 16 #include "net/quic/test_tools/quic_data_stream_peer.h" | |
| 17 #include "net/quic/test_tools/quic_sent_packet_manager_peer.h" | |
| 18 #include "net/quic/test_tools/quic_session_peer.h" | |
| 19 #include "net/quic/test_tools/quic_sustained_bandwidth_recorder_peer.h" | |
| 20 #include "net/quic/test_tools/quic_test_utils.h" | |
| 21 #include "net/tools/quic/quic_spdy_server_stream.h" | |
| 22 #include "net/tools/quic/test_tools/quic_test_utils.h" | |
| 23 #include "testing/gmock/include/gmock/gmock.h" | |
| 24 #include "testing/gtest/include/gtest/gtest.h" | |
| 25 | |
| 26 using __gnu_cxx::vector; | |
| 27 using net::test::MockConnection; | |
| 28 using net::test::QuicConfigPeer; | |
| 29 using net::test::QuicConnectionPeer; | |
| 30 using net::test::QuicDataStreamPeer; | |
| 31 using net::test::QuicSentPacketManagerPeer; | |
| 32 using net::test::QuicSessionPeer; | |
| 33 using net::test::QuicSustainedBandwidthRecorderPeer; | |
| 34 using net::test::SupportedVersions; | |
| 35 using net::test::ValueRestore; | |
| 36 using net::test::kClientDataStreamId1; | |
| 37 using net::test::kClientDataStreamId2; | |
| 38 using net::test::kClientDataStreamId3; | |
| 39 using net::test::kClientDataStreamId4; | |
| 40 using std::string; | |
| 41 using testing::StrictMock; | |
| 42 using testing::_; | |
| 43 | |
| 44 namespace net { | |
| 45 namespace tools { | |
| 46 namespace test { | |
| 47 | |
| 48 class QuicServerSessionPeer { | |
| 49 public: | |
| 50 static QuicDataStream* GetIncomingDataStream( | |
| 51 QuicServerSession* s, QuicStreamId id) { | |
| 52 return s->GetIncomingDataStream(id); | |
| 53 } | |
| 54 static QuicDataStream* GetDataStream(QuicServerSession* s, QuicStreamId id) { | |
| 55 return s->GetDataStream(id); | |
| 56 } | |
| 57 static void SetCryptoStream(QuicServerSession* s, | |
| 58 QuicCryptoServerStream* crypto_stream) { | |
| 59 s->crypto_stream_.reset(crypto_stream); | |
| 60 } | |
| 61 }; | |
| 62 | |
| 63 namespace { | |
| 64 | |
| 65 const size_t kMaxStreamsForTest = 10; | |
| 66 | |
| 67 class QuicServerSessionTest : public ::testing::TestWithParam<QuicVersion> { | |
| 68 protected: | |
| 69 QuicServerSessionTest() | |
| 70 : crypto_config_(QuicCryptoServerConfig::TESTING, | |
| 71 QuicRandom::GetInstance()) { | |
| 72 config_.SetMaxStreamsPerConnection(kMaxStreamsForTest, | |
| 73 kMaxStreamsForTest); | |
| 74 config_.SetInitialStreamFlowControlWindowToSend( | |
| 75 kInitialStreamFlowControlWindowForTest); | |
| 76 config_.SetInitialSessionFlowControlWindowToSend( | |
| 77 kInitialSessionFlowControlWindowForTest); | |
| 78 | |
| 79 connection_ = | |
| 80 new StrictMock<MockConnection>(true, SupportedVersions(GetParam())); | |
| 81 session_.reset(new QuicServerSession(config_, connection_, &owner_)); | |
| 82 MockClock clock; | |
| 83 handshake_message_.reset(crypto_config_.AddDefaultConfig( | |
| 84 QuicRandom::GetInstance(), &clock, | |
| 85 QuicCryptoServerConfig::ConfigOptions())); | |
| 86 session_->InitializeSession(crypto_config_); | |
| 87 visitor_ = QuicConnectionPeer::GetVisitor(connection_); | |
| 88 } | |
| 89 | |
| 90 QuicVersion version() const { return connection_->version(); } | |
| 91 | |
| 92 StrictMock<MockQuicServerSessionVisitor> owner_; | |
| 93 StrictMock<MockConnection>* connection_; | |
| 94 QuicConfig config_; | |
| 95 QuicCryptoServerConfig crypto_config_; | |
| 96 scoped_ptr<QuicServerSession> session_; | |
| 97 scoped_ptr<CryptoHandshakeMessage> handshake_message_; | |
| 98 QuicConnectionVisitorInterface* visitor_; | |
| 99 }; | |
| 100 | |
| 101 // Compares CachedNetworkParameters. | |
| 102 MATCHER_P(EqualsProto, network_params, "") { | |
| 103 CachedNetworkParameters reference(network_params); | |
| 104 return (arg->bandwidth_estimate_bytes_per_second() == | |
| 105 reference.bandwidth_estimate_bytes_per_second() && | |
| 106 arg->bandwidth_estimate_bytes_per_second() == | |
| 107 reference.bandwidth_estimate_bytes_per_second() && | |
| 108 arg->max_bandwidth_estimate_bytes_per_second() == | |
| 109 reference.max_bandwidth_estimate_bytes_per_second() && | |
| 110 arg->max_bandwidth_timestamp_seconds() == | |
| 111 reference.max_bandwidth_timestamp_seconds() && | |
| 112 arg->min_rtt_ms() == reference.min_rtt_ms() && | |
| 113 arg->previous_connection_state() == | |
| 114 reference.previous_connection_state()); | |
| 115 } | |
| 116 | |
| 117 INSTANTIATE_TEST_CASE_P(Tests, QuicServerSessionTest, | |
| 118 ::testing::ValuesIn(QuicSupportedVersions())); | |
| 119 | |
| 120 TEST_P(QuicServerSessionTest, CloseStreamDueToReset) { | |
| 121 // Open a stream, then reset it. | |
| 122 // Send two bytes of payload to open it. | |
| 123 QuicStreamFrame data1(kClientDataStreamId1, false, 0, MakeIOVector("HT")); | |
| 124 vector<QuicStreamFrame> frames; | |
| 125 frames.push_back(data1); | |
| 126 session_->OnStreamFrames(frames); | |
| 127 EXPECT_EQ(1u, session_->GetNumOpenStreams()); | |
| 128 | |
| 129 // Send a reset (and expect the peer to send a RST in response). | |
| 130 QuicRstStreamFrame rst1(kClientDataStreamId1, QUIC_STREAM_NO_ERROR, 0); | |
| 131 EXPECT_CALL(*connection_, | |
| 132 SendRstStream(kClientDataStreamId1, QUIC_RST_ACKNOWLEDGEMENT, 0)); | |
| 133 visitor_->OnRstStream(rst1); | |
| 134 EXPECT_EQ(0u, session_->GetNumOpenStreams()); | |
| 135 | |
| 136 // Send the same two bytes of payload in a new packet. | |
| 137 visitor_->OnStreamFrames(frames); | |
| 138 | |
| 139 // The stream should not be re-opened. | |
| 140 EXPECT_EQ(0u, session_->GetNumOpenStreams()); | |
| 141 EXPECT_TRUE(connection_->connected()); | |
| 142 } | |
| 143 | |
| 144 TEST_P(QuicServerSessionTest, NeverOpenStreamDueToReset) { | |
| 145 // Send a reset (and expect the peer to send a RST in response). | |
| 146 QuicRstStreamFrame rst1(kClientDataStreamId1, QUIC_STREAM_NO_ERROR, 0); | |
| 147 EXPECT_CALL(*connection_, | |
| 148 SendRstStream(kClientDataStreamId1, QUIC_RST_ACKNOWLEDGEMENT, 0)); | |
| 149 visitor_->OnRstStream(rst1); | |
| 150 EXPECT_EQ(0u, session_->GetNumOpenStreams()); | |
| 151 | |
| 152 // Send two bytes of payload. | |
| 153 QuicStreamFrame data1(kClientDataStreamId1, false, 0, MakeIOVector("HT")); | |
| 154 vector<QuicStreamFrame> frames; | |
| 155 frames.push_back(data1); | |
| 156 visitor_->OnStreamFrames(frames); | |
| 157 | |
| 158 // The stream should never be opened, now that the reset is received. | |
| 159 EXPECT_EQ(0u, session_->GetNumOpenStreams()); | |
| 160 EXPECT_TRUE(connection_->connected()); | |
| 161 } | |
| 162 | |
| 163 TEST_P(QuicServerSessionTest, AcceptClosedStream) { | |
| 164 vector<QuicStreamFrame> frames; | |
| 165 // Send (empty) compressed headers followed by two bytes of data. | |
| 166 frames.push_back(QuicStreamFrame(kClientDataStreamId1, false, 0, | |
| 167 MakeIOVector("\1\0\0\0\0\0\0\0HT"))); | |
| 168 frames.push_back(QuicStreamFrame(kClientDataStreamId2, false, 0, | |
| 169 MakeIOVector("\2\0\0\0\0\0\0\0HT"))); | |
| 170 visitor_->OnStreamFrames(frames); | |
| 171 EXPECT_EQ(2u, session_->GetNumOpenStreams()); | |
| 172 | |
| 173 // Send a reset (and expect the peer to send a RST in response). | |
| 174 QuicRstStreamFrame rst(kClientDataStreamId1, QUIC_STREAM_NO_ERROR, 0); | |
| 175 EXPECT_CALL(*connection_, | |
| 176 SendRstStream(kClientDataStreamId1, QUIC_RST_ACKNOWLEDGEMENT, 0)); | |
| 177 visitor_->OnRstStream(rst); | |
| 178 | |
| 179 // If we were tracking, we'd probably want to reject this because it's data | |
| 180 // past the reset point of stream 3. As it's a closed stream we just drop the | |
| 181 // data on the floor, but accept the packet because it has data for stream 5. | |
| 182 frames.clear(); | |
| 183 frames.push_back( | |
| 184 QuicStreamFrame(kClientDataStreamId1, false, 2, MakeIOVector("TP"))); | |
| 185 frames.push_back( | |
| 186 QuicStreamFrame(kClientDataStreamId2, false, 2, MakeIOVector("TP"))); | |
| 187 visitor_->OnStreamFrames(frames); | |
| 188 // The stream should never be opened, now that the reset is received. | |
| 189 EXPECT_EQ(1u, session_->GetNumOpenStreams()); | |
| 190 EXPECT_TRUE(connection_->connected()); | |
| 191 } | |
| 192 | |
| 193 TEST_P(QuicServerSessionTest, MaxOpenStreams) { | |
| 194 // Test that the server closes the connection if a client attempts to open too | |
| 195 // many data streams. The server accepts slightly more than the negotiated | |
| 196 // stream limit to deal with rare cases where a client FIN/RST is lost. | |
| 197 | |
| 198 // The slightly increased stream limit is set during config negotiation. It | |
| 199 // should be either an increase of 10 over negotiated limit, or a fixed | |
| 200 // percentage scaling, whichever is larger. Test both before continuing. | |
| 201 EXPECT_EQ(kMaxStreamsForTest, session_->get_max_open_streams()); | |
| 202 session_->OnConfigNegotiated(); | |
| 203 EXPECT_LT(kMaxStreamsMultiplier * kMaxStreamsForTest, | |
| 204 kMaxStreamsForTest + kMaxStreamsMinimumIncrement); | |
| 205 EXPECT_EQ(kMaxStreamsForTest + kMaxStreamsMinimumIncrement, | |
| 206 session_->get_max_open_streams()); | |
| 207 EXPECT_EQ(0u, session_->GetNumOpenStreams()); | |
| 208 QuicStreamId stream_id = kClientDataStreamId1; | |
| 209 // Open the max configured number of streams, should be no problem. | |
| 210 for (size_t i = 0; i < kMaxStreamsForTest; ++i) { | |
| 211 EXPECT_TRUE(QuicServerSessionPeer::GetIncomingDataStream(session_.get(), | |
| 212 stream_id)); | |
| 213 stream_id += 2; | |
| 214 } | |
| 215 | |
| 216 // Open more streams: server should accept slightly more than the limit. | |
| 217 for (size_t i = 0; i < kMaxStreamsMinimumIncrement; ++i) { | |
| 218 EXPECT_TRUE(QuicServerSessionPeer::GetIncomingDataStream(session_.get(), | |
| 219 stream_id)); | |
| 220 stream_id += 2; | |
| 221 } | |
| 222 | |
| 223 // Now violate the server's internal stream limit. | |
| 224 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_TOO_MANY_OPEN_STREAMS)); | |
| 225 stream_id += 2; | |
| 226 EXPECT_FALSE( | |
| 227 QuicServerSessionPeer::GetIncomingDataStream(session_.get(), stream_id)); | |
| 228 } | |
| 229 | |
| 230 TEST_P(QuicServerSessionTest, MaxOpenStreamsImplicit) { | |
| 231 // Test that the server closes the connection if a client attempts to open too | |
| 232 // many data streams implicitly. The server accepts slightly more than the | |
| 233 // negotiated stream limit to deal with rare cases where a client FIN/RST is | |
| 234 // lost. | |
| 235 | |
| 236 // The slightly increased stream limit is set during config negotiation. | |
| 237 EXPECT_EQ(kMaxStreamsForTest, session_->get_max_open_streams()); | |
| 238 session_->OnConfigNegotiated(); | |
| 239 EXPECT_LT(kMaxStreamsMultiplier * kMaxStreamsForTest, | |
| 240 kMaxStreamsForTest + kMaxStreamsMinimumIncrement); | |
| 241 EXPECT_EQ(kMaxStreamsForTest + kMaxStreamsMinimumIncrement, | |
| 242 session_->get_max_open_streams()); | |
| 243 | |
| 244 EXPECT_EQ(0u, session_->GetNumOpenStreams()); | |
| 245 EXPECT_TRUE(QuicServerSessionPeer::GetIncomingDataStream( | |
| 246 session_.get(), kClientDataStreamId1)); | |
| 247 // Implicitly open streams up to the server's limit. | |
| 248 const int kActualMaxStreams = | |
| 249 kMaxStreamsForTest + kMaxStreamsMinimumIncrement; | |
| 250 const int kMaxValidStreamId = | |
| 251 kClientDataStreamId1 + (kActualMaxStreams - 1) * 2; | |
| 252 EXPECT_TRUE(QuicServerSessionPeer::GetIncomingDataStream( | |
| 253 session_.get(), kMaxValidStreamId)); | |
| 254 | |
| 255 // Opening a further stream will result in connection close. | |
| 256 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_TOO_MANY_OPEN_STREAMS)); | |
| 257 EXPECT_FALSE(QuicServerSessionPeer::GetIncomingDataStream( | |
| 258 session_.get(), kMaxValidStreamId + 2)); | |
| 259 } | |
| 260 | |
| 261 TEST_P(QuicServerSessionTest, GetEvenIncomingError) { | |
| 262 // Incoming streams on the server session must be odd. | |
| 263 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_INVALID_STREAM_ID)); | |
| 264 EXPECT_EQ(nullptr, | |
| 265 QuicServerSessionPeer::GetIncomingDataStream(session_.get(), 4)); | |
| 266 } | |
| 267 | |
| 268 TEST_P(QuicServerSessionTest, SetFecProtectionFromConfig) { | |
| 269 ValueRestore<bool> old_flag(&FLAGS_enable_quic_fec, true); | |
| 270 | |
| 271 // Set received config to have FEC connection option. | |
| 272 QuicTagVector copt; | |
| 273 copt.push_back(kFHDR); | |
| 274 QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt); | |
| 275 session_->OnConfigNegotiated(); | |
| 276 | |
| 277 // Verify that headers stream is always protected and data streams are | |
| 278 // optionally protected. | |
| 279 EXPECT_EQ(FEC_PROTECT_ALWAYS, | |
| 280 QuicSessionPeer::GetHeadersStream(session_.get())->fec_policy()); | |
| 281 QuicDataStream* stream = QuicServerSessionPeer::GetIncomingDataStream( | |
| 282 session_.get(), kClientDataStreamId1); | |
| 283 ASSERT_TRUE(stream); | |
| 284 EXPECT_EQ(FEC_PROTECT_OPTIONAL, stream->fec_policy()); | |
| 285 } | |
| 286 | |
| 287 class MockQuicCryptoServerStream : public QuicCryptoServerStream { | |
| 288 public: | |
| 289 explicit MockQuicCryptoServerStream( | |
| 290 const QuicCryptoServerConfig& crypto_config, QuicSession* session) | |
| 291 : QuicCryptoServerStream(crypto_config, session) {} | |
| 292 ~MockQuicCryptoServerStream() override {} | |
| 293 | |
| 294 MOCK_METHOD1(SendServerConfigUpdate, | |
| 295 void(const CachedNetworkParameters* cached_network_parameters)); | |
| 296 | |
| 297 private: | |
| 298 DISALLOW_COPY_AND_ASSIGN(MockQuicCryptoServerStream); | |
| 299 }; | |
| 300 | |
| 301 TEST_P(QuicServerSessionTest, BandwidthEstimates) { | |
| 302 // Test that bandwidth estimate updates are sent to the client, only after the | |
| 303 // bandwidth estimate has changes sufficiently, and enough time has passed, | |
| 304 // and we don't have any other data to write. | |
| 305 | |
| 306 int32 bandwidth_estimate_kbytes_per_second = 123; | |
| 307 int32 max_bandwidth_estimate_kbytes_per_second = 134; | |
| 308 int32 max_bandwidth_estimate_timestamp = 1122334455; | |
| 309 const string serving_region = "not a real region"; | |
| 310 session_->set_serving_region(serving_region); | |
| 311 | |
| 312 MockQuicCryptoServerStream* crypto_stream = | |
| 313 new MockQuicCryptoServerStream(crypto_config_, session_.get()); | |
| 314 QuicServerSessionPeer::SetCryptoStream(session_.get(), crypto_stream); | |
| 315 | |
| 316 // Set some initial bandwidth values. | |
| 317 QuicSentPacketManager* sent_packet_manager = | |
| 318 QuicConnectionPeer::GetSentPacketManager(session_->connection()); | |
| 319 QuicSustainedBandwidthRecorder& bandwidth_recorder = | |
| 320 QuicSentPacketManagerPeer::GetBandwidthRecorder(sent_packet_manager); | |
| 321 // Seed an rtt measurement equal to the initial default rtt. | |
| 322 RttStats* rtt_stats = | |
| 323 QuicSentPacketManagerPeer::GetRttStats(sent_packet_manager); | |
| 324 rtt_stats->UpdateRtt(QuicTime::Delta::FromMicroseconds( | |
| 325 rtt_stats->initial_rtt_us()), QuicTime::Delta::Zero(), QuicTime::Zero()); | |
| 326 QuicSustainedBandwidthRecorderPeer::SetBandwidthEstimate( | |
| 327 &bandwidth_recorder, bandwidth_estimate_kbytes_per_second); | |
| 328 QuicSustainedBandwidthRecorderPeer::SetMaxBandwidthEstimate( | |
| 329 &bandwidth_recorder, max_bandwidth_estimate_kbytes_per_second, | |
| 330 max_bandwidth_estimate_timestamp); | |
| 331 // Queue up some pending data. | |
| 332 session_->MarkWriteBlocked(kCryptoStreamId, | |
| 333 QuicWriteBlockedList::kHighestPriority); | |
| 334 EXPECT_TRUE(session_->HasDataToWrite()); | |
| 335 | |
| 336 // There will be no update sent yet - not enough time has passed. | |
| 337 QuicTime now = QuicTime::Zero(); | |
| 338 session_->OnCongestionWindowChange(now); | |
| 339 | |
| 340 // Bandwidth estimate has now changed sufficiently but not enough time has | |
| 341 // passed to send a Server Config Update. | |
| 342 bandwidth_estimate_kbytes_per_second = | |
| 343 bandwidth_estimate_kbytes_per_second * 1.6; | |
| 344 session_->OnCongestionWindowChange(now); | |
| 345 | |
| 346 // Bandwidth estimate has now changed sufficiently and enough time has passed, | |
| 347 // but not enough packets have been sent. | |
| 348 int64 srtt_ms = | |
| 349 sent_packet_manager->GetRttStats()->smoothed_rtt().ToMilliseconds(); | |
| 350 now = now.Add(QuicTime::Delta::FromMilliseconds( | |
| 351 kMinIntervalBetweenServerConfigUpdatesRTTs * srtt_ms)); | |
| 352 session_->OnCongestionWindowChange(now); | |
| 353 | |
| 354 // The connection no longer has pending data to be written. | |
| 355 session_->OnCanWrite(); | |
| 356 EXPECT_FALSE(session_->HasDataToWrite()); | |
| 357 session_->OnCongestionWindowChange(now); | |
| 358 | |
| 359 // Bandwidth estimate has now changed sufficiently, enough time has passed, | |
| 360 // and enough packets have been sent. | |
| 361 QuicConnectionPeer::SetSequenceNumberOfLastSentPacket( | |
| 362 session_->connection(), kMinPacketsBetweenServerConfigUpdates); | |
| 363 | |
| 364 // Verify that the proto has exactly the values we expect. | |
| 365 CachedNetworkParameters expected_network_params; | |
| 366 expected_network_params.set_bandwidth_estimate_bytes_per_second( | |
| 367 bandwidth_recorder.BandwidthEstimate().ToBytesPerSecond()); | |
| 368 expected_network_params.set_max_bandwidth_estimate_bytes_per_second( | |
| 369 bandwidth_recorder.MaxBandwidthEstimate().ToBytesPerSecond()); | |
| 370 expected_network_params.set_max_bandwidth_timestamp_seconds( | |
| 371 bandwidth_recorder.MaxBandwidthTimestamp()); | |
| 372 expected_network_params.set_min_rtt_ms(session_->connection() | |
| 373 ->sent_packet_manager() | |
| 374 .GetRttStats() | |
| 375 ->min_rtt() | |
| 376 .ToMilliseconds()); | |
| 377 expected_network_params.set_previous_connection_state( | |
| 378 CachedNetworkParameters::CONGESTION_AVOIDANCE); | |
| 379 expected_network_params.set_timestamp( | |
| 380 session_->connection()->clock()->WallNow().ToUNIXSeconds()); | |
| 381 expected_network_params.set_serving_region(serving_region); | |
| 382 | |
| 383 EXPECT_CALL(*crypto_stream, | |
| 384 SendServerConfigUpdate(EqualsProto(expected_network_params))) | |
| 385 .Times(1); | |
| 386 session_->OnCongestionWindowChange(now); | |
| 387 } | |
| 388 | |
| 389 TEST_P(QuicServerSessionTest, BandwidthResumptionExperiment) { | |
| 390 ValueRestore<bool> old_flag( | |
| 391 &FLAGS_quic_enable_bandwidth_resumption_experiment, true); | |
| 392 | |
| 393 // Test that if a client provides a CachedNetworkParameters with the same | |
| 394 // serving region as the current server, that this data is passed down to the | |
| 395 // send algorithm. | |
| 396 | |
| 397 // Client has sent kBWRE connection option to trigger bandwidth resumption. | |
| 398 QuicTagVector copt; | |
| 399 copt.push_back(kBWRE); | |
| 400 QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt); | |
| 401 | |
| 402 const string kTestServingRegion = "a serving region"; | |
| 403 session_->set_serving_region(kTestServingRegion); | |
| 404 | |
| 405 QuicCryptoServerStream* crypto_stream = | |
| 406 static_cast<QuicCryptoServerStream*>( | |
| 407 QuicSessionPeer::GetCryptoStream(session_.get())); | |
| 408 | |
| 409 // No effect if no CachedNetworkParameters provided. | |
| 410 EXPECT_CALL(*connection_, ResumeConnectionState(_)).Times(0); | |
| 411 session_->OnConfigNegotiated(); | |
| 412 | |
| 413 // No effect if CachedNetworkParameters provided, but different serving | |
| 414 // regions. | |
| 415 CachedNetworkParameters cached_network_params; | |
| 416 cached_network_params.set_bandwidth_estimate_bytes_per_second(1); | |
| 417 cached_network_params.set_serving_region("different serving region"); | |
| 418 crypto_stream->set_previous_cached_network_params(cached_network_params); | |
| 419 EXPECT_CALL(*connection_, ResumeConnectionState(_)).Times(0); | |
| 420 session_->OnConfigNegotiated(); | |
| 421 | |
| 422 // Same serving region results in CachedNetworkParameters being stored. | |
| 423 cached_network_params.set_serving_region(kTestServingRegion); | |
| 424 crypto_stream->set_previous_cached_network_params(cached_network_params); | |
| 425 EXPECT_CALL(*connection_, ResumeConnectionState(_)).Times(1); | |
| 426 session_->OnConfigNegotiated(); | |
| 427 } | |
| 428 | |
| 429 } // namespace | |
| 430 } // namespace test | |
| 431 } // namespace tools | |
| 432 } // namespace net | |
| OLD | NEW |