Add more checks to investigate SupervisedUserPrefStore crash at startup.
[chromium-blink-merge.git] / net / tools / quic / quic_server_session_test.cc
blob71c2b42854db0baaa82b52c52a7829ec5a7584e8
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/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"
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::_;
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 QuicDataStream* GetDataStream(QuicServerSession* s, QuicStreamId id) {
55 return s->GetDataStream(id);
57 static void SetCryptoStream(QuicServerSession* s,
58 QuicCryptoServerStream* crypto_stream) {
59 s->crypto_stream_.reset(crypto_stream);
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_ =
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_);
90 QuicVersion version() const { return connection_->version(); }
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_;
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());
117 INSTANTIATE_TEST_CASE_P(Tests, QuicServerSessionTest,
118 ::testing::ValuesIn(QuicSupportedVersions()));
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());
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());
136 // Send the same two bytes of payload in a new packet.
137 visitor_->OnStreamFrames(frames);
139 // The stream should not be re-opened.
140 EXPECT_EQ(0u, session_->GetNumOpenStreams());
141 EXPECT_TRUE(connection_->connected());
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());
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);
158 // The stream should never be opened, now that the reset is received.
159 EXPECT_EQ(0u, session_->GetNumOpenStreams());
160 EXPECT_TRUE(connection_->connected());
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());
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);
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());
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.
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;
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;
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));
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.
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());
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));
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));
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));
268 TEST_P(QuicServerSessionTest, SetFecProtectionFromConfig) {
269 ValueRestore<bool> old_flag(&FLAGS_enable_quic_fec, true);
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();
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());
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 {}
294 MOCK_METHOD1(SendServerConfigUpdate,
295 void(const CachedNetworkParameters* cached_network_parameters));
297 private:
298 DISALLOW_COPY_AND_ASSIGN(MockQuicCryptoServerStream);
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.
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);
312 MockQuicCryptoServerStream* crypto_stream =
313 new MockQuicCryptoServerStream(crypto_config_, session_.get());
314 QuicServerSessionPeer::SetCryptoStream(session_.get(), crypto_stream);
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());
336 // There will be no update sent yet - not enough time has passed.
337 QuicTime now = QuicTime::Zero();
338 session_->OnCongestionWindowChange(now);
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);
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);
354 // The connection no longer has pending data to be written.
355 session_->OnCanWrite();
356 EXPECT_FALSE(session_->HasDataToWrite());
357 session_->OnCongestionWindowChange(now);
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);
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);
383 EXPECT_CALL(*crypto_stream,
384 SendServerConfigUpdate(EqualsProto(expected_network_params)))
385 .Times(1);
386 session_->OnCongestionWindowChange(now);
389 TEST_P(QuicServerSessionTest, BandwidthResumptionExperiment) {
390 ValueRestore<bool> old_flag(
391 &FLAGS_quic_enable_bandwidth_resumption_experiment, true);
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.
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);
402 const string kTestServingRegion = "a serving region";
403 session_->set_serving_region(kTestServingRegion);
405 QuicCryptoServerStream* crypto_stream =
406 static_cast<QuicCryptoServerStream*>(
407 QuicSessionPeer::GetCryptoStream(session_.get()));
409 // No effect if no CachedNetworkParameters provided.
410 EXPECT_CALL(*connection_, ResumeConnectionState(_)).Times(0);
411 session_->OnConfigNegotiated();
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();
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();
429 } // namespace
430 } // namespace test
431 } // namespace tools
432 } // namespace net