OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/tools/quic/quic_server_session.h" | 5 #include "net/tools/quic/quic_server_session.h" |
6 | 6 |
7 #include "net/quic/crypto/quic_crypto_server_config.h" | 7 #include "net/quic/crypto/quic_crypto_server_config.h" |
8 #include "net/quic/crypto/quic_random.h" | 8 #include "net/quic/crypto/quic_random.h" |
| 9 #include "net/quic/crypto/source_address_token.h" |
9 #include "net/quic/quic_connection.h" | 10 #include "net/quic/quic_connection.h" |
| 11 #include "net/quic/quic_crypto_server_stream.h" |
10 #include "net/quic/quic_flags.h" | 12 #include "net/quic/quic_flags.h" |
11 #include "net/quic/quic_utils.h" | 13 #include "net/quic/quic_utils.h" |
12 #include "net/quic/test_tools/quic_config_peer.h" | 14 #include "net/quic/test_tools/quic_config_peer.h" |
13 #include "net/quic/test_tools/quic_connection_peer.h" | 15 #include "net/quic/test_tools/quic_connection_peer.h" |
14 #include "net/quic/test_tools/quic_data_stream_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" |
15 #include "net/quic/test_tools/quic_session_peer.h" | 18 #include "net/quic/test_tools/quic_session_peer.h" |
| 19 #include "net/quic/test_tools/quic_sustained_bandwidth_recorder_peer.h" |
16 #include "net/quic/test_tools/quic_test_utils.h" | 20 #include "net/quic/test_tools/quic_test_utils.h" |
17 #include "net/tools/quic/quic_spdy_server_stream.h" | 21 #include "net/tools/quic/quic_spdy_server_stream.h" |
18 #include "net/tools/quic/test_tools/quic_test_utils.h" | 22 #include "net/tools/quic/test_tools/quic_test_utils.h" |
19 #include "testing/gmock/include/gmock/gmock.h" | 23 #include "testing/gmock/include/gmock/gmock.h" |
20 #include "testing/gtest/include/gtest/gtest.h" | 24 #include "testing/gtest/include/gtest/gtest.h" |
21 | 25 |
22 using __gnu_cxx::vector; | 26 using __gnu_cxx::vector; |
23 using net::test::MockConnection; | 27 using net::test::MockConnection; |
24 using net::test::QuicConfigPeer; | 28 using net::test::QuicConfigPeer; |
25 using net::test::QuicConnectionPeer; | 29 using net::test::QuicConnectionPeer; |
26 using net::test::QuicDataStreamPeer; | 30 using net::test::QuicDataStreamPeer; |
| 31 using net::test::QuicSentPacketManagerPeer; |
27 using net::test::QuicSessionPeer; | 32 using net::test::QuicSessionPeer; |
| 33 using net::test::QuicSustainedBandwidthRecorderPeer; |
28 using net::test::SupportedVersions; | 34 using net::test::SupportedVersions; |
29 using net::test::ValueRestore; | 35 using net::test::ValueRestore; |
30 using net::test::kClientDataStreamId1; | 36 using net::test::kClientDataStreamId1; |
31 using net::test::kClientDataStreamId2; | 37 using net::test::kClientDataStreamId2; |
32 using net::test::kClientDataStreamId3; | 38 using net::test::kClientDataStreamId3; |
33 using net::test::kClientDataStreamId4; | 39 using net::test::kClientDataStreamId4; |
34 using testing::StrictMock; | 40 using testing::StrictMock; |
35 using testing::_; | 41 using testing::_; |
36 | 42 |
37 namespace net { | 43 namespace net { |
38 namespace tools { | 44 namespace tools { |
39 namespace test { | 45 namespace test { |
40 | 46 |
41 class QuicServerSessionPeer { | 47 class QuicServerSessionPeer { |
42 public: | 48 public: |
43 static QuicDataStream* GetIncomingDataStream( | 49 static QuicDataStream* GetIncomingDataStream( |
44 QuicServerSession* s, QuicStreamId id) { | 50 QuicServerSession* s, QuicStreamId id) { |
45 return s->GetIncomingDataStream(id); | 51 return s->GetIncomingDataStream(id); |
46 } | 52 } |
47 static QuicDataStream* GetDataStream(QuicServerSession* s, QuicStreamId id) { | 53 static QuicDataStream* GetDataStream(QuicServerSession* s, QuicStreamId id) { |
48 return s->GetDataStream(id); | 54 return s->GetDataStream(id); |
49 } | 55 } |
| 56 static void SetCryptoStream(QuicServerSession* s, |
| 57 QuicCryptoServerStream* crypto_stream) { |
| 58 s->crypto_stream_.reset(crypto_stream); |
| 59 } |
50 }; | 60 }; |
51 | 61 |
52 namespace { | 62 namespace { |
53 | 63 |
54 class QuicServerSessionTest : public ::testing::TestWithParam<QuicVersion> { | 64 class QuicServerSessionTest : public ::testing::TestWithParam<QuicVersion> { |
55 protected: | 65 protected: |
56 QuicServerSessionTest() | 66 QuicServerSessionTest() |
57 : crypto_config_(QuicCryptoServerConfig::TESTING, | 67 : crypto_config_(QuicCryptoServerConfig::TESTING, |
58 QuicRandom::GetInstance()) { | 68 QuicRandom::GetInstance()) { |
59 config_.SetDefaults(); | 69 config_.SetDefaults(); |
60 config_.set_max_streams_per_connection(3, 3); | 70 config_.set_max_streams_per_connection(3, 3); |
61 config_.SetInitialFlowControlWindowToSend( | 71 config_.SetInitialFlowControlWindowToSend( |
62 kInitialSessionFlowControlWindowForTest); | 72 kInitialSessionFlowControlWindowForTest); |
63 config_.SetInitialStreamFlowControlWindowToSend( | 73 config_.SetInitialStreamFlowControlWindowToSend( |
64 kInitialStreamFlowControlWindowForTest); | 74 kInitialStreamFlowControlWindowForTest); |
65 config_.SetInitialSessionFlowControlWindowToSend( | 75 config_.SetInitialSessionFlowControlWindowToSend( |
66 kInitialSessionFlowControlWindowForTest); | 76 kInitialSessionFlowControlWindowForTest); |
67 | 77 |
68 connection_ = | 78 connection_ = |
69 new StrictMock<MockConnection>(true, SupportedVersions(GetParam())); | 79 new StrictMock<MockConnection>(true, SupportedVersions(GetParam())); |
70 session_.reset(new QuicServerSession(config_, connection_, &owner_)); | 80 session_.reset(new QuicServerSession(config_, connection_, &owner_)); |
| 81 MockClock clock; |
| 82 handshake_message_.reset(crypto_config_.AddDefaultConfig( |
| 83 QuicRandom::GetInstance(), &clock, |
| 84 QuicCryptoServerConfig::ConfigOptions())); |
71 session_->InitializeSession(crypto_config_); | 85 session_->InitializeSession(crypto_config_); |
72 visitor_ = QuicConnectionPeer::GetVisitor(connection_); | 86 visitor_ = QuicConnectionPeer::GetVisitor(connection_); |
73 } | 87 } |
74 | 88 |
75 QuicVersion version() const { return connection_->version(); } | 89 QuicVersion version() const { return connection_->version(); } |
76 | 90 |
77 StrictMock<MockQuicServerSessionVisitor> owner_; | 91 StrictMock<MockQuicServerSessionVisitor> owner_; |
78 StrictMock<MockConnection>* connection_; | 92 StrictMock<MockConnection>* connection_; |
79 QuicConfig config_; | 93 QuicConfig config_; |
80 QuicCryptoServerConfig crypto_config_; | 94 QuicCryptoServerConfig crypto_config_; |
81 scoped_ptr<QuicServerSession> session_; | 95 scoped_ptr<QuicServerSession> session_; |
| 96 scoped_ptr<CryptoHandshakeMessage> handshake_message_; |
82 QuicConnectionVisitorInterface* visitor_; | 97 QuicConnectionVisitorInterface* visitor_; |
83 }; | 98 }; |
84 | 99 |
| 100 // Compares CachedNetworkParameters. |
| 101 MATCHER_P(EqualsProto, network_params, "") { |
| 102 CachedNetworkParameters reference(network_params); |
| 103 return (arg->bandwidth_estimate_bytes_per_second() == |
| 104 reference.bandwidth_estimate_bytes_per_second() && |
| 105 arg->bandwidth_estimate_bytes_per_second() == |
| 106 reference.bandwidth_estimate_bytes_per_second() && |
| 107 arg->max_bandwidth_estimate_bytes_per_second() == |
| 108 reference.max_bandwidth_estimate_bytes_per_second() && |
| 109 arg->max_bandwidth_timestamp_seconds() == |
| 110 reference.max_bandwidth_timestamp_seconds() && |
| 111 arg->min_rtt_ms() == reference.min_rtt_ms() && |
| 112 arg->previous_connection_state() == |
| 113 reference.previous_connection_state()); |
| 114 } |
| 115 |
85 INSTANTIATE_TEST_CASE_P(Tests, QuicServerSessionTest, | 116 INSTANTIATE_TEST_CASE_P(Tests, QuicServerSessionTest, |
86 ::testing::ValuesIn(QuicSupportedVersions())); | 117 ::testing::ValuesIn(QuicSupportedVersions())); |
87 | 118 |
88 TEST_P(QuicServerSessionTest, CloseStreamDueToReset) { | 119 TEST_P(QuicServerSessionTest, CloseStreamDueToReset) { |
89 // Open a stream, then reset it. | 120 // Open a stream, then reset it. |
90 // Send two bytes of payload to open it. | 121 // Send two bytes of payload to open it. |
91 QuicStreamFrame data1(kClientDataStreamId1, false, 0, MakeIOVector("HT")); | 122 QuicStreamFrame data1(kClientDataStreamId1, false, 0, MakeIOVector("HT")); |
92 vector<QuicStreamFrame> frames; | 123 vector<QuicStreamFrame> frames; |
93 frames.push_back(data1); | 124 frames.push_back(data1); |
94 session_->OnStreamFrames(frames); | 125 session_->OnStreamFrames(frames); |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 // Verify that headers stream is always protected and data streams are | 231 // Verify that headers stream is always protected and data streams are |
201 // optionally protected. | 232 // optionally protected. |
202 EXPECT_EQ(FEC_PROTECT_ALWAYS, | 233 EXPECT_EQ(FEC_PROTECT_ALWAYS, |
203 QuicSessionPeer::GetHeadersStream(session_.get())->fec_policy()); | 234 QuicSessionPeer::GetHeadersStream(session_.get())->fec_policy()); |
204 QuicDataStream* stream = QuicServerSessionPeer::GetIncomingDataStream( | 235 QuicDataStream* stream = QuicServerSessionPeer::GetIncomingDataStream( |
205 session_.get(), kClientDataStreamId1); | 236 session_.get(), kClientDataStreamId1); |
206 ASSERT_TRUE(stream); | 237 ASSERT_TRUE(stream); |
207 EXPECT_EQ(FEC_PROTECT_OPTIONAL, stream->fec_policy()); | 238 EXPECT_EQ(FEC_PROTECT_OPTIONAL, stream->fec_policy()); |
208 } | 239 } |
209 | 240 |
| 241 class MockQuicCryptoServerStream : public QuicCryptoServerStream { |
| 242 public: |
| 243 explicit MockQuicCryptoServerStream( |
| 244 const QuicCryptoServerConfig& crypto_config, QuicSession* session) |
| 245 : QuicCryptoServerStream(crypto_config, session) {} |
| 246 virtual ~MockQuicCryptoServerStream() {} |
| 247 |
| 248 MOCK_METHOD1(SendServerConfigUpdate, |
| 249 void(const CachedNetworkParameters* cached_network_parameters)); |
| 250 private: |
| 251 DISALLOW_COPY_AND_ASSIGN(MockQuicCryptoServerStream); |
| 252 }; |
| 253 |
| 254 TEST_P(QuicServerSessionTest, BandwidthEstimates) { |
| 255 if (version() <= QUIC_VERSION_21) { |
| 256 return; |
| 257 } |
| 258 // Test that bandwidth estimate updates are sent to the client, only after the |
| 259 // bandwidth estimate has changes sufficiently, and enough time has passed. |
| 260 |
| 261 int32 bandwidth_estimate_kbytes_per_second = 123; |
| 262 int32 max_bandwidth_estimate_kbytes_per_second = 134; |
| 263 int32 max_bandwidth_estimate_timestamp = 1122334455; |
| 264 const string serving_region = "not a real region"; |
| 265 session_->set_serving_region(serving_region); |
| 266 |
| 267 MockQuicCryptoServerStream* crypto_stream = |
| 268 new MockQuicCryptoServerStream(crypto_config_, session_.get()); |
| 269 QuicServerSessionPeer::SetCryptoStream(session_.get(), crypto_stream); |
| 270 |
| 271 // Set some initial bandwidth values. |
| 272 QuicSentPacketManager* sent_packet_manager = |
| 273 QuicConnectionPeer::GetSentPacketManager(session_->connection()); |
| 274 QuicSustainedBandwidthRecorder& bandwidth_recorder = |
| 275 QuicSentPacketManagerPeer::GetBandwidthRecorder(sent_packet_manager); |
| 276 QuicSustainedBandwidthRecorderPeer::SetBandwidthEstimate( |
| 277 &bandwidth_recorder, bandwidth_estimate_kbytes_per_second); |
| 278 QuicSustainedBandwidthRecorderPeer::SetMaxBandwidthEstimate( |
| 279 &bandwidth_recorder, max_bandwidth_estimate_kbytes_per_second, |
| 280 max_bandwidth_estimate_timestamp); |
| 281 |
| 282 // There will be no update sent yet - not enough time has passed. |
| 283 QuicTime now = QuicTime::Zero(); |
| 284 session_->OnCongestionWindowChange(now); |
| 285 |
| 286 // Bandwidth estimate has now changed sufficiently but not enough time has |
| 287 // passed to send a Server Config Update. |
| 288 bandwidth_estimate_kbytes_per_second = |
| 289 bandwidth_estimate_kbytes_per_second * 1.6; |
| 290 session_->OnCongestionWindowChange(now); |
| 291 |
| 292 // Bandwidth estimate has now changed sufficiently and enough time has passed. |
| 293 int64 srtt_ms = |
| 294 sent_packet_manager->GetRttStats()->SmoothedRtt().ToMilliseconds(); |
| 295 now = now.Add(QuicTime::Delta::FromMilliseconds( |
| 296 kMinIntervalBetweenServerConfigUpdatesRTTs * srtt_ms)); |
| 297 |
| 298 // Verify that the proto has exactly the values we expect. |
| 299 CachedNetworkParameters expected_network_params; |
| 300 expected_network_params.set_bandwidth_estimate_bytes_per_second( |
| 301 bandwidth_recorder.BandwidthEstimate().ToBytesPerSecond()); |
| 302 expected_network_params.set_max_bandwidth_estimate_bytes_per_second( |
| 303 bandwidth_recorder.MaxBandwidthEstimate().ToBytesPerSecond()); |
| 304 expected_network_params.set_max_bandwidth_timestamp_seconds( |
| 305 bandwidth_recorder.MaxBandwidthTimestamp()); |
| 306 expected_network_params.set_min_rtt_ms(session_->connection() |
| 307 ->sent_packet_manager() |
| 308 .GetRttStats() |
| 309 ->min_rtt() |
| 310 .ToMilliseconds()); |
| 311 expected_network_params.set_previous_connection_state( |
| 312 CachedNetworkParameters::CONGESTION_AVOIDANCE); |
| 313 expected_network_params.set_serving_region(serving_region); |
| 314 |
| 315 EXPECT_CALL(*crypto_stream, |
| 316 SendServerConfigUpdate(EqualsProto(expected_network_params))) |
| 317 .Times(1); |
| 318 session_->OnCongestionWindowChange(now); |
| 319 } |
| 320 |
210 } // namespace | 321 } // namespace |
211 } // namespace test | 322 } // namespace test |
212 } // namespace tools | 323 } // namespace tools |
213 } // namespace net | 324 } // namespace net |
OLD | NEW |