Fix "#if defined(DEBUG)" statements
[chromium-blink-merge.git] / net / tools / quic / quic_server_session_test.cc
blob0c25f815e170f4d13a2225ed61427215e1980621
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/crypto/source_address_token.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 testing::StrictMock;
41 using testing::_;
43 namespace net {
44 namespace tools {
45 namespace test {
47 class QuicServerSessionPeer {
48 public:
49 static QuicDataStream* GetIncomingDataStream(
50 QuicServerSession* s, QuicStreamId id) {
51 return s->GetIncomingDataStream(id);
53 static QuicDataStream* GetDataStream(QuicServerSession* s, QuicStreamId id) {
54 return s->GetDataStream(id);
56 static void SetCryptoStream(QuicServerSession* s,
57 QuicCryptoServerStream* crypto_stream) {
58 s->crypto_stream_.reset(crypto_stream);
62 namespace {
64 const size_t kMaxStreamsForTest = 10;
66 class QuicServerSessionTest : public ::testing::TestWithParam<QuicVersion> {
67 protected:
68 QuicServerSessionTest()
69 : crypto_config_(QuicCryptoServerConfig::TESTING,
70 QuicRandom::GetInstance()) {
71 config_.SetMaxStreamsPerConnection(kMaxStreamsForTest,
72 kMaxStreamsForTest);
73 config_.SetInitialFlowControlWindowToSend(
74 kInitialSessionFlowControlWindowForTest);
75 config_.SetInitialStreamFlowControlWindowToSend(
76 kInitialStreamFlowControlWindowForTest);
77 config_.SetInitialSessionFlowControlWindowToSend(
78 kInitialSessionFlowControlWindowForTest);
80 connection_ =
81 new StrictMock<MockConnection>(true, SupportedVersions(GetParam()));
82 session_.reset(new QuicServerSession(config_, connection_, &owner_));
83 MockClock clock;
84 handshake_message_.reset(crypto_config_.AddDefaultConfig(
85 QuicRandom::GetInstance(), &clock,
86 QuicCryptoServerConfig::ConfigOptions()));
87 session_->InitializeSession(crypto_config_);
88 visitor_ = QuicConnectionPeer::GetVisitor(connection_);
91 QuicVersion version() const { return connection_->version(); }
93 StrictMock<MockQuicServerSessionVisitor> owner_;
94 StrictMock<MockConnection>* connection_;
95 QuicConfig config_;
96 QuicCryptoServerConfig crypto_config_;
97 scoped_ptr<QuicServerSession> session_;
98 scoped_ptr<CryptoHandshakeMessage> handshake_message_;
99 QuicConnectionVisitorInterface* visitor_;
102 // Compares CachedNetworkParameters.
103 MATCHER_P(EqualsProto, network_params, "") {
104 CachedNetworkParameters reference(network_params);
105 return (arg->bandwidth_estimate_bytes_per_second() ==
106 reference.bandwidth_estimate_bytes_per_second() &&
107 arg->bandwidth_estimate_bytes_per_second() ==
108 reference.bandwidth_estimate_bytes_per_second() &&
109 arg->max_bandwidth_estimate_bytes_per_second() ==
110 reference.max_bandwidth_estimate_bytes_per_second() &&
111 arg->max_bandwidth_timestamp_seconds() ==
112 reference.max_bandwidth_timestamp_seconds() &&
113 arg->min_rtt_ms() == reference.min_rtt_ms() &&
114 arg->previous_connection_state() ==
115 reference.previous_connection_state());
118 INSTANTIATE_TEST_CASE_P(Tests, QuicServerSessionTest,
119 ::testing::ValuesIn(QuicSupportedVersions()));
121 TEST_P(QuicServerSessionTest, CloseStreamDueToReset) {
122 // Open a stream, then reset it.
123 // Send two bytes of payload to open it.
124 QuicStreamFrame data1(kClientDataStreamId1, false, 0, MakeIOVector("HT"));
125 vector<QuicStreamFrame> frames;
126 frames.push_back(data1);
127 session_->OnStreamFrames(frames);
128 EXPECT_EQ(1u, session_->GetNumOpenStreams());
130 // Send a reset (and expect the peer to send a RST in response).
131 QuicRstStreamFrame rst1(kClientDataStreamId1, QUIC_STREAM_NO_ERROR, 0);
132 EXPECT_CALL(*connection_, SendRstStream(kClientDataStreamId1,
133 QUIC_RST_FLOW_CONTROL_ACCOUNTING, 0));
134 visitor_->OnRstStream(rst1);
135 EXPECT_EQ(0u, session_->GetNumOpenStreams());
137 // Send the same two bytes of payload in a new packet.
138 visitor_->OnStreamFrames(frames);
140 // The stream should not be re-opened.
141 EXPECT_EQ(0u, session_->GetNumOpenStreams());
142 EXPECT_TRUE(connection_->connected());
145 TEST_P(QuicServerSessionTest, NeverOpenStreamDueToReset) {
146 // Send a reset (and expect the peer to send a RST in response).
147 QuicRstStreamFrame rst1(kClientDataStreamId1, QUIC_STREAM_NO_ERROR, 0);
148 EXPECT_CALL(*connection_, SendRstStream(kClientDataStreamId1,
149 QUIC_RST_FLOW_CONTROL_ACCOUNTING, 0));
150 visitor_->OnRstStream(rst1);
151 EXPECT_EQ(0u, session_->GetNumOpenStreams());
153 // Send two bytes of payload.
154 QuicStreamFrame data1(kClientDataStreamId1, false, 0, MakeIOVector("HT"));
155 vector<QuicStreamFrame> frames;
156 frames.push_back(data1);
157 visitor_->OnStreamFrames(frames);
159 // The stream should never be opened, now that the reset is received.
160 EXPECT_EQ(0u, session_->GetNumOpenStreams());
161 EXPECT_TRUE(connection_->connected());
164 TEST_P(QuicServerSessionTest, AcceptClosedStream) {
165 vector<QuicStreamFrame> frames;
166 // Send (empty) compressed headers followed by two bytes of data.
167 frames.push_back(QuicStreamFrame(kClientDataStreamId1, false, 0,
168 MakeIOVector("\1\0\0\0\0\0\0\0HT")));
169 frames.push_back(QuicStreamFrame(kClientDataStreamId2, false, 0,
170 MakeIOVector("\2\0\0\0\0\0\0\0HT")));
171 visitor_->OnStreamFrames(frames);
172 EXPECT_EQ(2u, session_->GetNumOpenStreams());
174 // Send a reset (and expect the peer to send a RST in response).
175 QuicRstStreamFrame rst(kClientDataStreamId1, QUIC_STREAM_NO_ERROR, 0);
176 EXPECT_CALL(*connection_, SendRstStream(kClientDataStreamId1,
177 QUIC_RST_FLOW_CONTROL_ACCOUNTING, 0));
178 visitor_->OnRstStream(rst);
180 // If we were tracking, we'd probably want to reject this because it's data
181 // past the reset point of stream 3. As it's a closed stream we just drop the
182 // data on the floor, but accept the packet because it has data for stream 5.
183 frames.clear();
184 frames.push_back(
185 QuicStreamFrame(kClientDataStreamId1, false, 2, MakeIOVector("TP")));
186 frames.push_back(
187 QuicStreamFrame(kClientDataStreamId2, false, 2, MakeIOVector("TP")));
188 visitor_->OnStreamFrames(frames);
189 // The stream should never be opened, now that the reset is received.
190 EXPECT_EQ(1u, session_->GetNumOpenStreams());
191 EXPECT_TRUE(connection_->connected());
194 TEST_P(QuicServerSessionTest, MaxOpenStreams) {
195 ValueRestore<bool> old_flag(&FLAGS_quic_allow_more_open_streams, true);
196 // Test that the server closes the connection if a client attempts to open too
197 // many data streams. The server accepts slightly more than the negotiated
198 // stream limit to deal with rare cases where a client FIN/RST is lost.
200 // The slightly increased stream limit is set during config negotiation. It
201 // should be either an increase of 10 over negotiated limit, or a fixed
202 // percentage scaling, whichever is larger. Test both before continuing.
203 EXPECT_EQ(kMaxStreamsForTest, session_->get_max_open_streams());
204 session_->OnConfigNegotiated();
205 EXPECT_LT(kMaxStreamsMultiplier * kMaxStreamsForTest,
206 kMaxStreamsForTest + kMaxStreamsMinimumIncrement);
207 EXPECT_EQ(kMaxStreamsForTest + kMaxStreamsMinimumIncrement,
208 session_->get_max_open_streams());
209 EXPECT_EQ(0u, session_->GetNumOpenStreams());
210 QuicStreamId stream_id = kClientDataStreamId1;
211 // Open the max configured number of streams, should be no problem.
212 for (size_t i = 0; i < kMaxStreamsForTest; ++i) {
213 EXPECT_TRUE(QuicServerSessionPeer::GetIncomingDataStream(session_.get(),
214 stream_id));
215 stream_id += 2;
218 // Open more streams: server should accept slightly more than the limit.
219 for (size_t i = 0; i < kMaxStreamsMinimumIncrement; ++i) {
220 EXPECT_TRUE(QuicServerSessionPeer::GetIncomingDataStream(session_.get(),
221 stream_id));
222 stream_id += 2;
225 // Now violate the server's internal stream limit.
226 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_TOO_MANY_OPEN_STREAMS));
227 stream_id += 2;
228 EXPECT_FALSE(
229 QuicServerSessionPeer::GetIncomingDataStream(session_.get(), stream_id));
232 TEST_P(QuicServerSessionTest, MaxOpenStreamsImplicit) {
233 ValueRestore<bool> old_flag(&FLAGS_quic_allow_more_open_streams, true);
234 // Test that the server closes the connection if a client attempts to open too
235 // many data streams implicitly. The server accepts slightly more than the
236 // negotiated stream limit to deal with rare cases where a client FIN/RST is
237 // lost.
239 // The slightly increased stream limit is set during config negotiation.
240 EXPECT_EQ(kMaxStreamsForTest, session_->get_max_open_streams());
241 session_->OnConfigNegotiated();
242 EXPECT_LT(kMaxStreamsMultiplier * kMaxStreamsForTest,
243 kMaxStreamsForTest + kMaxStreamsMinimumIncrement);
244 EXPECT_EQ(kMaxStreamsForTest + kMaxStreamsMinimumIncrement,
245 session_->get_max_open_streams());
247 EXPECT_EQ(0u, session_->GetNumOpenStreams());
248 EXPECT_TRUE(QuicServerSessionPeer::GetIncomingDataStream(
249 session_.get(), kClientDataStreamId1));
250 // Implicitly open streams up to the server's limit.
251 const int kActualMaxStreams =
252 kMaxStreamsForTest + kMaxStreamsMinimumIncrement;
253 const int kMaxValidStreamId =
254 kClientDataStreamId1 + (kActualMaxStreams - 1) * 2;
255 EXPECT_TRUE(QuicServerSessionPeer::GetIncomingDataStream(
256 session_.get(), kMaxValidStreamId));
258 // Opening a further stream will result in connection close.
259 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_TOO_MANY_OPEN_STREAMS));
260 EXPECT_FALSE(QuicServerSessionPeer::GetIncomingDataStream(
261 session_.get(), kMaxValidStreamId + 2));
264 TEST_P(QuicServerSessionTest, GetEvenIncomingError) {
265 // Incoming streams on the server session must be odd.
266 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_INVALID_STREAM_ID));
267 EXPECT_EQ(nullptr,
268 QuicServerSessionPeer::GetIncomingDataStream(session_.get(), 4));
271 TEST_P(QuicServerSessionTest, SetFecProtectionFromConfig) {
272 ValueRestore<bool> old_flag(&FLAGS_enable_quic_fec, true);
274 // Set received config to have FEC connection option.
275 QuicTagVector copt;
276 copt.push_back(kFHDR);
277 QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt);
278 session_->OnConfigNegotiated();
280 // Verify that headers stream is always protected and data streams are
281 // optionally protected.
282 EXPECT_EQ(FEC_PROTECT_ALWAYS,
283 QuicSessionPeer::GetHeadersStream(session_.get())->fec_policy());
284 QuicDataStream* stream = QuicServerSessionPeer::GetIncomingDataStream(
285 session_.get(), kClientDataStreamId1);
286 ASSERT_TRUE(stream);
287 EXPECT_EQ(FEC_PROTECT_OPTIONAL, stream->fec_policy());
290 class MockQuicCryptoServerStream : public QuicCryptoServerStream {
291 public:
292 explicit MockQuicCryptoServerStream(
293 const QuicCryptoServerConfig& crypto_config, QuicSession* session)
294 : QuicCryptoServerStream(crypto_config, session) {}
295 virtual ~MockQuicCryptoServerStream() {}
297 MOCK_METHOD2(SendServerConfigUpdate,
298 void(const CachedNetworkParameters* cached_network_parameters,
299 bool on_handshake_complete));
301 private:
302 DISALLOW_COPY_AND_ASSIGN(MockQuicCryptoServerStream);
305 TEST_P(QuicServerSessionTest, BandwidthEstimates) {
306 if (version() <= QUIC_VERSION_21) {
307 return;
309 // Test that bandwidth estimate updates are sent to the client, only after the
310 // bandwidth estimate has changes sufficiently, and enough time has passed.
312 int32 bandwidth_estimate_kbytes_per_second = 123;
313 int32 max_bandwidth_estimate_kbytes_per_second = 134;
314 int32 max_bandwidth_estimate_timestamp = 1122334455;
315 const string serving_region = "not a real region";
316 session_->set_serving_region(serving_region);
318 MockQuicCryptoServerStream* crypto_stream =
319 new MockQuicCryptoServerStream(crypto_config_, session_.get());
320 QuicServerSessionPeer::SetCryptoStream(session_.get(), crypto_stream);
322 // Set some initial bandwidth values.
323 QuicSentPacketManager* sent_packet_manager =
324 QuicConnectionPeer::GetSentPacketManager(session_->connection());
325 QuicSustainedBandwidthRecorder& bandwidth_recorder =
326 QuicSentPacketManagerPeer::GetBandwidthRecorder(sent_packet_manager);
327 QuicSustainedBandwidthRecorderPeer::SetBandwidthEstimate(
328 &bandwidth_recorder, bandwidth_estimate_kbytes_per_second);
329 QuicSustainedBandwidthRecorderPeer::SetMaxBandwidthEstimate(
330 &bandwidth_recorder, max_bandwidth_estimate_kbytes_per_second,
331 max_bandwidth_estimate_timestamp);
333 // There will be no update sent yet - not enough time has passed.
334 QuicTime now = QuicTime::Zero();
335 session_->OnCongestionWindowChange(now);
337 // Bandwidth estimate has now changed sufficiently but not enough time has
338 // passed to send a Server Config Update.
339 bandwidth_estimate_kbytes_per_second =
340 bandwidth_estimate_kbytes_per_second * 1.6;
341 session_->OnCongestionWindowChange(now);
343 // Bandwidth estimate has now changed sufficiently and enough time has passed.
344 int64 srtt_ms =
345 sent_packet_manager->GetRttStats()->SmoothedRtt().ToMilliseconds();
346 now = now.Add(QuicTime::Delta::FromMilliseconds(
347 kMinIntervalBetweenServerConfigUpdatesRTTs * srtt_ms));
349 // Verify that the proto has exactly the values we expect.
350 CachedNetworkParameters expected_network_params;
351 expected_network_params.set_bandwidth_estimate_bytes_per_second(
352 bandwidth_recorder.BandwidthEstimate().ToBytesPerSecond());
353 expected_network_params.set_max_bandwidth_estimate_bytes_per_second(
354 bandwidth_recorder.MaxBandwidthEstimate().ToBytesPerSecond());
355 expected_network_params.set_max_bandwidth_timestamp_seconds(
356 bandwidth_recorder.MaxBandwidthTimestamp());
357 expected_network_params.set_min_rtt_ms(session_->connection()
358 ->sent_packet_manager()
359 .GetRttStats()
360 ->MinRtt()
361 .ToMilliseconds());
362 expected_network_params.set_previous_connection_state(
363 CachedNetworkParameters::CONGESTION_AVOIDANCE);
364 expected_network_params.set_timestamp(
365 session_->connection()->clock()->WallNow().ToUNIXSeconds());
366 expected_network_params.set_serving_region(serving_region);
368 EXPECT_CALL(*crypto_stream,
369 SendServerConfigUpdate(EqualsProto(expected_network_params), _))
370 .Times(1);
371 session_->OnCongestionWindowChange(now);
374 } // namespace
375 } // namespace test
376 } // namespace tools
377 } // namespace net