Call InvalidationController#refreshRegisteredTypes() on Chrome startup
[chromium-blink-merge.git] / net / tools / quic / quic_server_session_test.cc
blob1df0dc672976ba811f2dd6ccf1d2b44fbf3a5250
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.
5 #include "net/tools/quic/quic_server_session.h"
7 #include "net/quic/crypto/quic_crypto_server_config.h"
8 #include "net/quic/crypto/quic_random.h"
9 #include "net/quic/proto/cached_network_parameters.pb.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/test/gtest_util.h"
22 #include "net/tools/quic/quic_spdy_server_stream.h"
23 #include "net/tools/quic/test_tools/quic_test_utils.h"
24 #include "testing/gmock/include/gmock/gmock.h"
25 #include "testing/gtest/include/gtest/gtest.h"
27 using __gnu_cxx::vector;
28 using net::test::MockConnection;
29 using net::test::QuicConfigPeer;
30 using net::test::QuicConnectionPeer;
31 using net::test::QuicDataStreamPeer;
32 using net::test::QuicSentPacketManagerPeer;
33 using net::test::QuicSessionPeer;
34 using net::test::QuicSustainedBandwidthRecorderPeer;
35 using net::test::SupportedVersions;
36 using net::test::ValueRestore;
37 using net::test::kClientDataStreamId1;
38 using net::test::kClientDataStreamId2;
39 using net::test::kClientDataStreamId3;
40 using std::string;
41 using testing::StrictMock;
42 using testing::_;
44 namespace net {
45 namespace tools {
46 namespace test {
48 class QuicServerSessionPeer {
49 public:
50 static QuicDataStream* GetIncomingDataStream(
51 QuicServerSession* s, QuicStreamId id) {
52 return s->GetIncomingDataStream(id);
54 static void SetCryptoStream(QuicServerSession* s,
55 QuicCryptoServerStream* crypto_stream) {
56 s->crypto_stream_.reset(crypto_stream);
58 static bool IsBandwidthResumptionEnabled(QuicServerSession* s) {
59 return s->bandwidth_resumption_enabled_;
63 namespace {
65 const size_t kMaxStreamsForTest = 10;
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);
79 connection_ = new StrictMock<MockConnection>(Perspective::IS_SERVER,
80 SupportedVersions(GetParam()));
81 session_.reset(
82 new QuicServerSession(config_, connection_, &owner_, &crypto_config_));
83 MockClock clock;
84 handshake_message_.reset(crypto_config_.AddDefaultConfig(
85 QuicRandom::GetInstance(), &clock,
86 QuicCryptoServerConfig::ConfigOptions()));
87 session_->Initialize();
88 visitor_ = QuicConnectionPeer::GetVisitor(connection_);
91 StrictMock<MockQuicServerSessionVisitor> owner_;
92 StrictMock<MockConnection>* connection_;
93 QuicConfig config_;
94 QuicCryptoServerConfig crypto_config_;
95 scoped_ptr<QuicServerSession> session_;
96 scoped_ptr<CryptoHandshakeMessage> handshake_message_;
97 QuicConnectionVisitorInterface* visitor_;
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());
116 INSTANTIATE_TEST_CASE_P(Tests, QuicServerSessionTest,
117 ::testing::ValuesIn(QuicSupportedVersions()));
119 TEST_P(QuicServerSessionTest, CloseStreamDueToReset) {
120 // Open a stream, then reset it.
121 // Send two bytes of payload to open it.
122 QuicStreamFrame data1(kClientDataStreamId1, false, 0, StringPiece("HT"));
123 vector<QuicStreamFrame> frames;
124 frames.push_back(data1);
125 session_->OnStreamFrames(frames);
126 EXPECT_EQ(1u, session_->GetNumOpenStreams());
128 // Send a reset (and expect the peer to send a RST in response).
129 QuicRstStreamFrame rst1(kClientDataStreamId1, QUIC_STREAM_NO_ERROR, 0);
130 EXPECT_CALL(*connection_,
131 SendRstStream(kClientDataStreamId1, QUIC_RST_ACKNOWLEDGEMENT, 0));
132 visitor_->OnRstStream(rst1);
133 EXPECT_EQ(0u, session_->GetNumOpenStreams());
135 // Send the same two bytes of payload in a new packet.
136 visitor_->OnStreamFrames(frames);
138 // The stream should not be re-opened.
139 EXPECT_EQ(0u, session_->GetNumOpenStreams());
140 EXPECT_TRUE(connection_->connected());
143 TEST_P(QuicServerSessionTest, NeverOpenStreamDueToReset) {
144 // Send a reset (and expect the peer to send a RST in response).
145 QuicRstStreamFrame rst1(kClientDataStreamId1, QUIC_STREAM_NO_ERROR, 0);
146 EXPECT_CALL(*connection_,
147 SendRstStream(kClientDataStreamId1, QUIC_RST_ACKNOWLEDGEMENT, 0));
148 visitor_->OnRstStream(rst1);
149 EXPECT_EQ(0u, session_->GetNumOpenStreams());
151 // Send two bytes of payload.
152 QuicStreamFrame data1(kClientDataStreamId1, false, 0, StringPiece("HT"));
153 vector<QuicStreamFrame> frames;
154 frames.push_back(data1);
155 visitor_->OnStreamFrames(frames);
157 // The stream should never be opened, now that the reset is received.
158 EXPECT_EQ(0u, session_->GetNumOpenStreams());
159 EXPECT_TRUE(connection_->connected());
162 TEST_P(QuicServerSessionTest, AcceptClosedStream) {
163 vector<QuicStreamFrame> frames;
164 // Send (empty) compressed headers followed by two bytes of data.
165 frames.push_back(QuicStreamFrame(kClientDataStreamId1, false, 0,
166 StringPiece("\1\0\0\0\0\0\0\0HT")));
167 frames.push_back(QuicStreamFrame(kClientDataStreamId2, false, 0,
168 StringPiece("\2\0\0\0\0\0\0\0HT")));
169 visitor_->OnStreamFrames(frames);
170 EXPECT_EQ(2u, session_->GetNumOpenStreams());
172 // Send a reset (and expect the peer to send a RST in response).
173 QuicRstStreamFrame rst(kClientDataStreamId1, QUIC_STREAM_NO_ERROR, 0);
174 EXPECT_CALL(*connection_,
175 SendRstStream(kClientDataStreamId1, QUIC_RST_ACKNOWLEDGEMENT, 0));
176 visitor_->OnRstStream(rst);
178 // If we were tracking, we'd probably want to reject this because it's data
179 // past the reset point of stream 3. As it's a closed stream we just drop the
180 // data on the floor, but accept the packet because it has data for stream 5.
181 frames.clear();
182 frames.push_back(
183 QuicStreamFrame(kClientDataStreamId1, false, 2, StringPiece("TP")));
184 frames.push_back(
185 QuicStreamFrame(kClientDataStreamId2, false, 2, StringPiece("TP")));
186 visitor_->OnStreamFrames(frames);
187 // The stream should never be opened, now that the reset is received.
188 EXPECT_EQ(1u, session_->GetNumOpenStreams());
189 EXPECT_TRUE(connection_->connected());
192 TEST_P(QuicServerSessionTest, MaxOpenStreams) {
193 // Test that the server closes the connection if a client attempts to open too
194 // many data streams. The server accepts slightly more than the negotiated
195 // stream limit to deal with rare cases where a client FIN/RST is lost.
197 // The slightly increased stream limit is set during config negotiation. It
198 // should be either an increase of 10 over negotiated limit, or a fixed
199 // percentage scaling, whichever is larger. Test both before continuing.
200 EXPECT_EQ(kMaxStreamsForTest, session_->get_max_open_streams());
201 session_->OnConfigNegotiated();
202 EXPECT_LT(kMaxStreamsMultiplier * kMaxStreamsForTest,
203 kMaxStreamsForTest + kMaxStreamsMinimumIncrement);
204 EXPECT_EQ(kMaxStreamsForTest + kMaxStreamsMinimumIncrement,
205 session_->get_max_open_streams());
206 EXPECT_EQ(0u, session_->GetNumOpenStreams());
207 QuicStreamId stream_id = kClientDataStreamId1;
208 // Open the max configured number of streams, should be no problem.
209 for (size_t i = 0; i < kMaxStreamsForTest; ++i) {
210 EXPECT_TRUE(QuicServerSessionPeer::GetIncomingDataStream(session_.get(),
211 stream_id));
212 stream_id += 2;
215 // Open more streams: server should accept slightly more than the limit.
216 for (size_t i = 0; i < kMaxStreamsMinimumIncrement; ++i) {
217 EXPECT_TRUE(QuicServerSessionPeer::GetIncomingDataStream(session_.get(),
218 stream_id));
219 stream_id += 2;
222 // Now violate the server's internal stream limit.
223 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_TOO_MANY_OPEN_STREAMS));
224 stream_id += 2;
225 EXPECT_FALSE(
226 QuicServerSessionPeer::GetIncomingDataStream(session_.get(), stream_id));
229 TEST_P(QuicServerSessionTest, MaxOpenStreamsImplicit) {
230 // Test that the server closes the connection if a client attempts to open too
231 // many data streams implicitly. The server accepts slightly more than the
232 // negotiated stream limit to deal with rare cases where a client FIN/RST is
233 // lost.
235 // The slightly increased stream limit is set during config negotiation.
236 EXPECT_EQ(kMaxStreamsForTest, session_->get_max_open_streams());
237 session_->OnConfigNegotiated();
238 EXPECT_LT(kMaxStreamsMultiplier * kMaxStreamsForTest,
239 kMaxStreamsForTest + kMaxStreamsMinimumIncrement);
240 EXPECT_EQ(kMaxStreamsForTest + kMaxStreamsMinimumIncrement,
241 session_->get_max_open_streams());
243 EXPECT_EQ(0u, session_->GetNumOpenStreams());
244 EXPECT_TRUE(QuicServerSessionPeer::GetIncomingDataStream(
245 session_.get(), kClientDataStreamId1));
246 // Implicitly open streams up to the server's limit.
247 const int kActualMaxStreams =
248 kMaxStreamsForTest + kMaxStreamsMinimumIncrement;
249 const int kMaxValidStreamId =
250 kClientDataStreamId1 + (kActualMaxStreams - 1) * 2;
251 EXPECT_TRUE(QuicServerSessionPeer::GetIncomingDataStream(
252 session_.get(), kMaxValidStreamId));
254 // Opening a further stream will result in connection close.
255 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_TOO_MANY_OPEN_STREAMS));
256 EXPECT_FALSE(QuicServerSessionPeer::GetIncomingDataStream(
257 session_.get(), kMaxValidStreamId + 2));
260 TEST_P(QuicServerSessionTest, GetEvenIncomingError) {
261 // Incoming streams on the server session must be odd.
262 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_INVALID_STREAM_ID));
263 EXPECT_EQ(nullptr,
264 QuicServerSessionPeer::GetIncomingDataStream(session_.get(), 4));
267 TEST_P(QuicServerSessionTest, GetStreamDisconnected) {
268 // Don't create new streams if the connection is disconnected.
269 QuicConnectionPeer::CloseConnection(connection_);
270 EXPECT_DFATAL(QuicServerSessionPeer::GetIncomingDataStream(session_.get(), 5),
271 "ShouldCreateIncomingDataStream called when disconnected");
274 TEST_P(QuicServerSessionTest, SetFecProtectionFromConfig) {
275 ValueRestore<bool> old_flag(&FLAGS_enable_quic_fec, true);
277 // Set received config to have FEC connection option.
278 QuicTagVector copt;
279 copt.push_back(kFHDR);
280 QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt);
281 session_->OnConfigNegotiated();
283 // Verify that headers stream is always protected and data streams are
284 // optionally protected.
285 EXPECT_EQ(FEC_PROTECT_ALWAYS,
286 QuicSessionPeer::GetHeadersStream(session_.get())->fec_policy());
287 QuicDataStream* stream = QuicServerSessionPeer::GetIncomingDataStream(
288 session_.get(), kClientDataStreamId1);
289 ASSERT_TRUE(stream);
290 EXPECT_EQ(FEC_PROTECT_OPTIONAL, stream->fec_policy());
293 class MockQuicCryptoServerStream : public QuicCryptoServerStream {
294 public:
295 explicit MockQuicCryptoServerStream(
296 const QuicCryptoServerConfig* crypto_config, QuicSession* session)
297 : QuicCryptoServerStream(crypto_config, session) {}
298 ~MockQuicCryptoServerStream() override {}
300 MOCK_METHOD1(SendServerConfigUpdate,
301 void(const CachedNetworkParameters* cached_network_parameters));
303 private:
304 DISALLOW_COPY_AND_ASSIGN(MockQuicCryptoServerStream);
307 TEST_P(QuicServerSessionTest, BandwidthEstimates) {
308 // Test that bandwidth estimate updates are sent to the client, only when
309 // bandwidth resumption is enabled, the bandwidth estimate has changed
310 // sufficiently, enough time has passed,
311 // and we don't have any other data to write.
313 // Client has sent kBWRE connection option to trigger bandwidth resumption.
314 QuicTagVector copt;
315 copt.push_back(kBWRE);
316 QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt);
317 session_->OnConfigNegotiated();
318 EXPECT_TRUE(
319 QuicServerSessionPeer::IsBandwidthResumptionEnabled(session_.get()));
321 int32 bandwidth_estimate_kbytes_per_second = 123;
322 int32 max_bandwidth_estimate_kbytes_per_second = 134;
323 int32 max_bandwidth_estimate_timestamp = 1122334455;
324 const string serving_region = "not a real region";
325 session_->set_serving_region(serving_region);
327 MockQuicCryptoServerStream* crypto_stream =
328 new MockQuicCryptoServerStream(&crypto_config_, session_.get());
329 QuicServerSessionPeer::SetCryptoStream(session_.get(), crypto_stream);
331 // Set some initial bandwidth values.
332 QuicSentPacketManager* sent_packet_manager =
333 QuicConnectionPeer::GetSentPacketManager(session_->connection());
334 QuicSustainedBandwidthRecorder& bandwidth_recorder =
335 QuicSentPacketManagerPeer::GetBandwidthRecorder(sent_packet_manager);
336 // Seed an rtt measurement equal to the initial default rtt.
337 RttStats* rtt_stats =
338 QuicSentPacketManagerPeer::GetRttStats(sent_packet_manager);
339 rtt_stats->UpdateRtt(QuicTime::Delta::FromMicroseconds(
340 rtt_stats->initial_rtt_us()), QuicTime::Delta::Zero(), QuicTime::Zero());
341 QuicSustainedBandwidthRecorderPeer::SetBandwidthEstimate(
342 &bandwidth_recorder, bandwidth_estimate_kbytes_per_second);
343 QuicSustainedBandwidthRecorderPeer::SetMaxBandwidthEstimate(
344 &bandwidth_recorder, max_bandwidth_estimate_kbytes_per_second,
345 max_bandwidth_estimate_timestamp);
346 // Queue up some pending data.
347 session_->MarkWriteBlocked(kCryptoStreamId,
348 QuicWriteBlockedList::kHighestPriority);
349 EXPECT_TRUE(session_->HasDataToWrite());
351 // There will be no update sent yet - not enough time has passed.
352 QuicTime now = QuicTime::Zero();
353 session_->OnCongestionWindowChange(now);
355 // Bandwidth estimate has now changed sufficiently but not enough time has
356 // passed to send a Server Config Update.
357 bandwidth_estimate_kbytes_per_second =
358 bandwidth_estimate_kbytes_per_second * 1.6;
359 session_->OnCongestionWindowChange(now);
361 // Bandwidth estimate has now changed sufficiently and enough time has passed,
362 // but not enough packets have been sent.
363 int64 srtt_ms =
364 sent_packet_manager->GetRttStats()->smoothed_rtt().ToMilliseconds();
365 now = now.Add(QuicTime::Delta::FromMilliseconds(
366 kMinIntervalBetweenServerConfigUpdatesRTTs * srtt_ms));
367 session_->OnCongestionWindowChange(now);
369 // The connection no longer has pending data to be written.
370 session_->OnCanWrite();
371 EXPECT_FALSE(session_->HasDataToWrite());
372 session_->OnCongestionWindowChange(now);
374 // Bandwidth estimate has now changed sufficiently, enough time has passed,
375 // and enough packets have been sent.
376 QuicConnectionPeer::SetSequenceNumberOfLastSentPacket(
377 session_->connection(), kMinPacketsBetweenServerConfigUpdates);
379 // Verify that the proto has exactly the values we expect.
380 CachedNetworkParameters expected_network_params;
381 expected_network_params.set_bandwidth_estimate_bytes_per_second(
382 bandwidth_recorder.BandwidthEstimate().ToBytesPerSecond());
383 expected_network_params.set_max_bandwidth_estimate_bytes_per_second(
384 bandwidth_recorder.MaxBandwidthEstimate().ToBytesPerSecond());
385 expected_network_params.set_max_bandwidth_timestamp_seconds(
386 bandwidth_recorder.MaxBandwidthTimestamp());
387 expected_network_params.set_min_rtt_ms(session_->connection()
388 ->sent_packet_manager()
389 .GetRttStats()
390 ->min_rtt()
391 .ToMilliseconds());
392 expected_network_params.set_previous_connection_state(
393 CachedNetworkParameters::CONGESTION_AVOIDANCE);
394 expected_network_params.set_timestamp(
395 session_->connection()->clock()->WallNow().ToUNIXSeconds());
396 expected_network_params.set_serving_region(serving_region);
398 EXPECT_CALL(*crypto_stream,
399 SendServerConfigUpdate(EqualsProto(expected_network_params)))
400 .Times(1);
401 EXPECT_CALL(*connection_, OnSendConnectionState(_)).Times(1);
402 session_->OnCongestionWindowChange(now);
405 TEST_P(QuicServerSessionTest, BandwidthResumptionExperiment) {
406 // Test that if a client provides a CachedNetworkParameters with the same
407 // serving region as the current server, that this data is passed down to the
408 // send algorithm.
410 // Client has sent kBWRE connection option to trigger bandwidth resumption.
411 QuicTagVector copt;
412 copt.push_back(kBWRE);
413 QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt);
415 const string kTestServingRegion = "a serving region";
416 session_->set_serving_region(kTestServingRegion);
418 QuicCryptoServerStream* crypto_stream =
419 static_cast<QuicCryptoServerStream*>(
420 QuicSessionPeer::GetCryptoStream(session_.get()));
422 // No effect if no CachedNetworkParameters provided.
423 EXPECT_CALL(*connection_, ResumeConnectionState(_, _)).Times(0);
424 session_->OnConfigNegotiated();
426 // No effect if CachedNetworkParameters provided, but different serving
427 // regions.
428 CachedNetworkParameters cached_network_params;
429 cached_network_params.set_bandwidth_estimate_bytes_per_second(1);
430 cached_network_params.set_serving_region("different serving region");
431 crypto_stream->set_previous_cached_network_params(cached_network_params);
432 EXPECT_CALL(*connection_, ResumeConnectionState(_, _)).Times(0);
433 session_->OnConfigNegotiated();
435 // Same serving region results in CachedNetworkParameters being stored.
436 cached_network_params.set_serving_region(kTestServingRegion);
437 crypto_stream->set_previous_cached_network_params(cached_network_params);
438 EXPECT_CALL(*connection_, ResumeConnectionState(_, _)).Times(1);
439 session_->OnConfigNegotiated();
442 TEST_P(QuicServerSessionTest, BandwidthMaxEnablesResumption) {
443 EXPECT_FALSE(
444 QuicServerSessionPeer::IsBandwidthResumptionEnabled(session_.get()));
446 // Client has sent kBWMX connection option to trigger bandwidth resumption.
447 QuicTagVector copt;
448 copt.push_back(kBWMX);
449 QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt);
450 session_->OnConfigNegotiated();
451 EXPECT_TRUE(
452 QuicServerSessionPeer::IsBandwidthResumptionEnabled(session_.get()));
455 TEST_P(QuicServerSessionTest, NoBandwidthResumptionByDefault) {
456 EXPECT_FALSE(
457 QuicServerSessionPeer::IsBandwidthResumptionEnabled(session_.get()));
458 session_->OnConfigNegotiated();
459 EXPECT_FALSE(
460 QuicServerSessionPeer::IsBandwidthResumptionEnabled(session_.get()));
463 } // namespace
464 } // namespace test
465 } // namespace tools
466 } // namespace net