1// Copyright 2014 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.
4
5#include "base/command_line.h"
6#include "chrome/browser/io_thread.h"
7#include "net/http/http_network_session.h"
8#include "net/http/http_server_properties_impl.h"
9#include "net/quic/quic_protocol.h"
10#include "testing/gmock/include/gmock/gmock.h"
11#include "testing/gtest/include/gtest/gtest.h"
12
13namespace test {
14
15using ::testing::ElementsAre;
16
17class IOThreadPeer {
18 public:
19  static void ConfigureQuicGlobals(
20      const base::CommandLine& command_line,
21      base::StringPiece quic_trial_group,
22      const std::map<std::string, std::string>& quic_trial_params,
23      IOThread::Globals* globals) {
24    IOThread::ConfigureQuicGlobals(command_line, quic_trial_group,
25                                   quic_trial_params, globals);
26  }
27
28  static void InitializeNetworkSessionParamsFromGlobals(
29      const IOThread::Globals& globals,
30      net::HttpNetworkSession::Params* params) {
31    IOThread::InitializeNetworkSessionParamsFromGlobals(globals, params);
32  }
33
34  static void ConfigureSpdyFromTrial(const std::string& trial_group,
35                                     IOThread::Globals* globals) {
36    IOThread::ConfigureSpdyFromTrial(trial_group, globals);
37  }
38};
39
40class IOThreadTest : public testing::Test {
41 public:
42  IOThreadTest() : command_line_(base::CommandLine::NO_PROGRAM) {
43    globals_.http_server_properties.reset(new net::HttpServerPropertiesImpl());
44  }
45
46  void ConfigureQuicGlobals() {
47    IOThreadPeer::ConfigureQuicGlobals(command_line_, field_trial_group_,
48                                       field_trial_params_, &globals_);
49  }
50
51  void InitializeNetworkSessionParams(net::HttpNetworkSession::Params* params) {
52    IOThreadPeer::InitializeNetworkSessionParamsFromGlobals(globals_, params);
53  }
54
55  base::CommandLine command_line_;
56  IOThread::Globals globals_;
57  std::string field_trial_group_;
58  std::map<std::string, std::string> field_trial_params_;
59};
60
61TEST_F(IOThreadTest, InitializeNetworkSessionParamsFromGlobals) {
62  globals_.quic_connection_options.push_back(net::kPACE);
63  globals_.quic_connection_options.push_back(net::kTBBR);
64  globals_.quic_connection_options.push_back(net::kTIME);
65
66  net::HttpNetworkSession::Params params;
67  InitializeNetworkSessionParams(&params);
68  EXPECT_EQ(globals_.quic_connection_options,
69            params.quic_connection_options);
70}
71
72TEST_F(IOThreadTest, SpdyFieldTrialHoldbackEnabled) {
73  net::HttpStreamFactory::set_spdy_enabled(true);
74  IOThreadPeer::ConfigureSpdyFromTrial("SpdyDisabled", &globals_);
75  EXPECT_FALSE(net::HttpStreamFactory::spdy_enabled());
76}
77
78TEST_F(IOThreadTest, SpdyFieldTrialHoldbackControl) {
79  bool use_alternate_protocols = false;
80  IOThreadPeer::ConfigureSpdyFromTrial("Control", &globals_);
81  EXPECT_THAT(globals_.next_protos,
82              ElementsAre(net::kProtoHTTP11,
83                          net::kProtoQUIC1SPDY3,
84                          net::kProtoSPDY3,
85                          net::kProtoSPDY31));
86  globals_.use_alternate_protocols.CopyToIfSet(&use_alternate_protocols);
87  EXPECT_TRUE(use_alternate_protocols);
88}
89
90TEST_F(IOThreadTest, SpdyFieldTrialSpdy4Enabled) {
91  bool use_alternate_protocols = false;
92  IOThreadPeer::ConfigureSpdyFromTrial("Spdy4Enabled", &globals_);
93  EXPECT_THAT(globals_.next_protos,
94              ElementsAre(net::kProtoHTTP11,
95                          net::kProtoQUIC1SPDY3,
96                          net::kProtoSPDY3,
97                          net::kProtoSPDY31,
98                          net::kProtoSPDY4));
99  globals_.use_alternate_protocols.CopyToIfSet(&use_alternate_protocols);
100  EXPECT_TRUE(use_alternate_protocols);
101}
102
103TEST_F(IOThreadTest, SpdyFieldTrialSpdy4Control) {
104  bool use_alternate_protocols = false;
105  IOThreadPeer::ConfigureSpdyFromTrial("Spdy4Control", &globals_);
106  EXPECT_THAT(globals_.next_protos,
107              ElementsAre(net::kProtoHTTP11,
108                          net::kProtoQUIC1SPDY3,
109                          net::kProtoSPDY3,
110                          net::kProtoSPDY31));
111  globals_.use_alternate_protocols.CopyToIfSet(&use_alternate_protocols);
112  EXPECT_TRUE(use_alternate_protocols);
113}
114
115TEST_F(IOThreadTest, DisableQuicByDefault) {
116  ConfigureQuicGlobals();
117  net::HttpNetworkSession::Params params;
118  InitializeNetworkSessionParams(&params);
119  EXPECT_FALSE(params.enable_quic);
120}
121
122TEST_F(IOThreadTest, EnableQuicFromFieldTrialGroup) {
123  field_trial_group_ = "Enabled";
124
125  ConfigureQuicGlobals();
126  net::HttpNetworkSession::Params default_params;
127  net::HttpNetworkSession::Params params;
128  InitializeNetworkSessionParams(&params);
129  EXPECT_TRUE(params.enable_quic);
130  EXPECT_FALSE(params.enable_quic_time_based_loss_detection);
131  EXPECT_EQ(1350u, params.quic_max_packet_length);
132  EXPECT_EQ(1.0, params.alternate_protocol_probability_threshold);
133  EXPECT_EQ(default_params.quic_supported_versions,
134            params.quic_supported_versions);
135  EXPECT_EQ(net::QuicTagVector(), params.quic_connection_options);
136  EXPECT_FALSE(params.quic_always_require_handshake_confirmation);
137  EXPECT_FALSE(params.quic_disable_connection_pooling);
138}
139
140TEST_F(IOThreadTest, EnableQuicFromCommandLine) {
141  command_line_.AppendSwitch("enable-quic");
142
143  ConfigureQuicGlobals();
144  net::HttpNetworkSession::Params params;
145  InitializeNetworkSessionParams(&params);
146  EXPECT_TRUE(params.enable_quic);
147}
148
149TEST_F(IOThreadTest, EnablePacingFromCommandLine) {
150  command_line_.AppendSwitch("enable-quic");
151  command_line_.AppendSwitch("enable-quic-pacing");
152
153  ConfigureQuicGlobals();
154  net::HttpNetworkSession::Params params;
155  InitializeNetworkSessionParams(&params);
156  net::QuicTagVector options;
157  options.push_back(net::kPACE);
158  EXPECT_EQ(options, params.quic_connection_options);
159}
160
161TEST_F(IOThreadTest, EnablePacingFromFieldTrialGroup) {
162  field_trial_group_ = "EnabledWithPacing";
163
164  ConfigureQuicGlobals();
165  net::HttpNetworkSession::Params params;
166  InitializeNetworkSessionParams(&params);
167  net::QuicTagVector options;
168  options.push_back(net::kPACE);
169  EXPECT_EQ(options, params.quic_connection_options);
170}
171
172TEST_F(IOThreadTest, EnablePacingFromFieldTrialParams) {
173  field_trial_group_ = "Enabled";
174  field_trial_params_["enable_pacing"] = "true";
175
176  ConfigureQuicGlobals();
177  net::HttpNetworkSession::Params params;
178  InitializeNetworkSessionParams(&params);
179  net::QuicTagVector options;
180  options.push_back(net::kPACE);
181  EXPECT_EQ(options, params.quic_connection_options);
182}
183
184TEST_F(IOThreadTest, EnableTimeBasedLossDetectionFromCommandLine) {
185  command_line_.AppendSwitch("enable-quic");
186  command_line_.AppendSwitch("enable-quic-time-based-loss-detection");
187
188  ConfigureQuicGlobals();
189  net::HttpNetworkSession::Params params;
190  InitializeNetworkSessionParams(&params);
191  EXPECT_TRUE(params.enable_quic_time_based_loss_detection);
192}
193
194TEST_F(IOThreadTest, EnableTimeBasedLossDetectionFromFieldTrialGroup) {
195  field_trial_group_ = "EnabledWithTimeBasedLossDetection";
196
197  ConfigureQuicGlobals();
198  net::HttpNetworkSession::Params params;
199  InitializeNetworkSessionParams(&params);
200  EXPECT_TRUE(params.enable_quic_time_based_loss_detection);
201}
202
203TEST_F(IOThreadTest, EnableTimeBasedLossDetectionFromFieldTrialParams) {
204  field_trial_group_ = "Enabled";
205  field_trial_params_["enable_time_based_loss_detection"] = "true";
206
207  ConfigureQuicGlobals();
208  net::HttpNetworkSession::Params params;
209  InitializeNetworkSessionParams(&params);
210  EXPECT_TRUE(params.enable_quic_time_based_loss_detection);
211}
212
213TEST_F(IOThreadTest, PacketLengthFromCommandLine) {
214  command_line_.AppendSwitch("enable-quic");
215  command_line_.AppendSwitchASCII("quic-max-packet-length", "1350");
216
217  ConfigureQuicGlobals();
218  net::HttpNetworkSession::Params params;
219  InitializeNetworkSessionParams(&params);
220  EXPECT_EQ(1350u, params.quic_max_packet_length);
221}
222
223TEST_F(IOThreadTest, PacketLengthFromFieldTrialGroup) {
224  field_trial_group_ = "Enabled1350BytePackets";
225
226  ConfigureQuicGlobals();
227  net::HttpNetworkSession::Params params;
228  InitializeNetworkSessionParams(&params);
229  EXPECT_EQ(1350u, params.quic_max_packet_length);
230}
231
232TEST_F(IOThreadTest, PacketLengthFromFieldTrialParams) {
233  field_trial_group_ = "Enabled";
234  field_trial_params_["max_packet_length"] = "1350";
235
236  ConfigureQuicGlobals();
237  net::HttpNetworkSession::Params params;
238  InitializeNetworkSessionParams(&params);
239  EXPECT_EQ(1350u, params.quic_max_packet_length);
240}
241
242TEST_F(IOThreadTest, QuicVersionFromCommandLine) {
243  command_line_.AppendSwitch("enable-quic");
244  std::string version =
245      net::QuicVersionToString(net::QuicSupportedVersions().back());
246  command_line_.AppendSwitchASCII("quic-version", version);
247
248  ConfigureQuicGlobals();
249  net::HttpNetworkSession::Params params;
250  InitializeNetworkSessionParams(&params);
251  net::QuicVersionVector supported_versions;
252  supported_versions.push_back(net::QuicSupportedVersions().back());
253  EXPECT_EQ(supported_versions,
254            params.quic_supported_versions);
255}
256
257TEST_F(IOThreadTest, QuicVersionFromFieldTrialParams) {
258  field_trial_group_ = "Enabled";
259  field_trial_params_["quic_version"] =
260      net::QuicVersionToString(net::QuicSupportedVersions().back());
261
262  ConfigureQuicGlobals();
263  net::HttpNetworkSession::Params params;
264  InitializeNetworkSessionParams(&params);
265  net::QuicVersionVector supported_versions;
266  supported_versions.push_back(net::QuicSupportedVersions().back());
267  EXPECT_EQ(supported_versions,
268            params.quic_supported_versions);
269}
270
271TEST_F(IOThreadTest, QuicConnectionOptionsFromCommandLine) {
272  command_line_.AppendSwitch("enable-quic");
273  command_line_.AppendSwitchASCII("quic-connection-options",
274                                  "PACE,TIME,TBBR,REJ");
275
276  ConfigureQuicGlobals();
277  net::HttpNetworkSession::Params params;
278  InitializeNetworkSessionParams(&params);
279
280  net::QuicTagVector options;
281  options.push_back(net::kPACE);
282  options.push_back(net::kTIME);
283  options.push_back(net::kTBBR);
284  options.push_back(net::kREJ);
285  EXPECT_EQ(options, params.quic_connection_options);
286}
287
288TEST_F(IOThreadTest, QuicConnectionOptionsFromFieldTrialParams) {
289  field_trial_group_ = "Enabled";
290  field_trial_params_["connection_options"] = "PACE,TIME,TBBR,REJ";
291
292  ConfigureQuicGlobals();
293  net::HttpNetworkSession::Params params;
294  InitializeNetworkSessionParams(&params);
295
296  net::QuicTagVector options;
297  options.push_back(net::kPACE);
298  options.push_back(net::kTIME);
299  options.push_back(net::kTBBR);
300  options.push_back(net::kREJ);
301  EXPECT_EQ(options, params.quic_connection_options);
302}
303
304TEST_F(IOThreadTest, QuicConnectionOptionsFromDeprecatedFieldTrialParams) {
305  field_trial_group_ = "Enabled";
306  field_trial_params_["congestion_options"] = "PACE,TIME,TBBR,REJ";
307
308  ConfigureQuicGlobals();
309  net::HttpNetworkSession::Params params;
310  InitializeNetworkSessionParams(&params);
311
312  net::QuicTagVector options;
313  options.push_back(net::kPACE);
314  options.push_back(net::kTIME);
315  options.push_back(net::kTBBR);
316  options.push_back(net::kREJ);
317  EXPECT_EQ(options, params.quic_connection_options);
318}
319
320TEST_F(IOThreadTest,
321       QuicAlwaysRequireHandshakeConfirmationFromFieldTrialParams) {
322  field_trial_group_ = "Enabled";
323  field_trial_params_["always_require_handshake_confirmation"] = "true";
324  ConfigureQuicGlobals();
325  net::HttpNetworkSession::Params params;
326  InitializeNetworkSessionParams(&params);
327  EXPECT_TRUE(params.quic_always_require_handshake_confirmation);
328}
329
330TEST_F(IOThreadTest,
331       QuicDisableConnectionPoolingFromFieldTrialParams) {
332  field_trial_group_ = "Enabled";
333  field_trial_params_["disable_connection_pooling"] = "true";
334  ConfigureQuicGlobals();
335  net::HttpNetworkSession::Params params;
336  InitializeNetworkSessionParams(&params);
337  EXPECT_TRUE(params.quic_disable_connection_pooling);
338}
339
340TEST_F(IOThreadTest,
341       AlternateProtocolProbabilityThresholdFromFlag) {
342  command_line_.AppendSwitchASCII("alternate-protocol-probability-threshold",
343                                  ".5");
344
345  ConfigureQuicGlobals();
346  net::HttpNetworkSession::Params params;
347  InitializeNetworkSessionParams(&params);
348  EXPECT_EQ(.5, params.alternate_protocol_probability_threshold);
349}
350
351TEST_F(IOThreadTest,
352       AlternateProtocolProbabilityThresholdFromEnableQuicFlag) {
353  command_line_.AppendSwitch("enable-quic");
354
355  ConfigureQuicGlobals();
356  net::HttpNetworkSession::Params params;
357  InitializeNetworkSessionParams(&params);
358  EXPECT_EQ(0, params.alternate_protocol_probability_threshold);
359}
360
361TEST_F(IOThreadTest,
362       AlternateProtocolProbabilityThresholdFromParams) {
363  field_trial_group_ = "Enabled";
364  field_trial_params_["alternate_protocol_probability_threshold"] = ".5";
365
366  ConfigureQuicGlobals();
367  net::HttpNetworkSession::Params params;
368  InitializeNetworkSessionParams(&params);
369  EXPECT_EQ(.5, params.alternate_protocol_probability_threshold);
370}
371
372}  // namespace test
373