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, "") { | |
ramant (doing other things)
2014/08/21 17:02:31
Hi Ryan,
Implemented EqualsProto to compare ever
Ryan Hamilton
2014/08/21 22:11:36
As discussed offline, this SGTM.
| |
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 |