1 // Copyright (c) 2012 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 "base/basictypes.h"
6 #include "base/message_loop/message_loop.h"
7 #include "chrome/browser/net/network_stats.h"
8 #include "net/base/net_errors.h"
9 #include "net/base/network_change_notifier.h"
10 #include "net/base/test_completion_callback.h"
11 #include "net/dns/host_resolver.h"
12 #include "net/dns/mock_host_resolver.h"
13 #include "net/socket/socket_test_util.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 #include "testing/platform_test.h"
19 namespace chrome_browser_net
{
21 class NetworkStatsTest
: public PlatformTest
{
26 void SetUp() override
{
27 net::NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
28 base::MessageLoop::current()->RunUntilIdle();
33 void TearDown() override
{
34 net::NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
35 // Empty the current queue.
36 base::MessageLoop::current()->RunUntilIdle();
37 PlatformTest::TearDown();
40 void CreateToken(uint64 timestamp_micros
,
42 ProbePacket_Token
* token
) {
43 token
->set_timestamp_micros(timestamp_micros
);
44 token
->mutable_hash()->assign(hash
);
47 // DeterministicMockData defines the exact sequence of the read/write
48 // operations (specified by the last parameter of MockRead/MockWrite).
49 // |io_mode_write| is the IO mode for writing only. Reading is always async.
50 void MakeDeterministicMockData(uint32 max_tests
,
51 uint32 max_probe_packets
,
53 net::IoMode io_mode_write
) {
54 // Only allow 0 or 1 test because the test 2 in NetworkStats is random.
55 DCHECK_LT(max_tests
, 2U);
57 ProbePacket probe_packet
;
58 ProbeMessage probe_message
;
59 probe_message
.SetPacketHeader(ProbePacket_Type_HELLO_REQUEST
,
61 probe_packet
.set_group_id(0);
62 outputs_
[0] = probe_message
.MakeEncodedPacket(probe_packet
);
64 mock_writes_
.push_back(net::MockWrite(
65 io_mode_write
, &outputs_
[0][0], outputs_
[0].size(), 0));
66 // Add one probe_request.
67 probe_packet
= ProbePacket(); // Clear all content.
68 ProbePacket_Token token
;
69 CreateToken(1L, "1010", &token
);
70 probe_message
.GenerateProbeRequest(
71 token
, 1, probe_bytes
, 0, max_probe_packets
, &probe_packet
);
72 outputs_
[1] = probe_message
.MakeEncodedPacket(probe_packet
);
73 mock_writes_
.push_back(net::MockWrite(
74 io_mode_write
, &outputs_
[1][0], outputs_
[1].size(), 2));
79 probe_packet
= ProbePacket(); // Clear all content.
80 probe_message
.SetPacketHeader(ProbePacket_Type_HELLO_REPLY
, &probe_packet
);
81 probe_packet
.set_group_id(0);
82 CreateToken(1L, "1010", probe_packet
.mutable_token());
83 inputs_
[0] = probe_message
.MakeEncodedPacket(probe_packet
);
84 mock_reads_
.push_back(
85 net::MockRead(net::ASYNC
, &inputs_
[0][0], inputs_
[0].size(), 1));
87 for (uint32 i
= 0; i
< max_probe_packets
; ++i
) {
89 probe_packet
= ProbePacket(); // Clear all content.
90 probe_message
.SetPacketHeader(ProbePacket_Type_PROBE_REPLY
,
92 int padding_size
= probe_bytes
- probe_packet
.ByteSize() - 8;
93 probe_packet
.mutable_padding()->append(
94 std::string(std::max(0, padding_size
), 0));
95 probe_packet
.mutable_header()->set_checksum(0);
96 probe_packet
.set_group_id(1);
97 probe_packet
.set_packet_index(i
);
98 inputs_
[1 + i
] = probe_message
.MakeEncodedPacket(probe_packet
);
99 mock_reads_
.push_back(net::MockRead(
100 net::ASYNC
, &inputs_
[1 + i
][0], inputs_
[1 + i
].size(), 3 + i
));
104 // Test NetworkStats::Start(...) method.
105 void TestStart(bool has_proxy
,
107 uint32 max_probe_packets
,
109 net::IoMode io_mode
) {
110 net::DeterministicMockClientSocketFactory mock_socket_factory
;
111 MakeDeterministicMockData(max_tests
, max_probe_packets
, bytes
, io_mode
);
112 net::DeterministicSocketData
test_data(
113 &mock_reads_
[0], mock_reads_
.size(),
114 &mock_writes_
[0], mock_writes_
.size());
115 mock_socket_factory
.AddSocketDataProvider(&test_data
);
116 NetworkStats
* udp_stats_client
= new NetworkStats(&mock_socket_factory
);
117 udp_stats_client
->maximum_tests_
= max_tests
;
118 udp_stats_client
->maximum_sequential_packets_
= max_probe_packets
;
120 net::TestCompletionCallback cb
;
121 scoped_ptr
<net::MockHostResolver
> host_resolver(
122 new net::MockHostResolver());
123 net::HostPortPair host_port_pair
;
124 EXPECT_TRUE(udp_stats_client
->Start(host_resolver
.get(),
131 int num_packets_run
= (max_tests
+ 1) * 2 + max_probe_packets
- 1;
132 test_data
.RunFor(num_packets_run
);
133 int rv
= cb
.WaitForResult();
134 // Check there were no errors during connect/write/read to echo UDP server.
138 // Make one write and then |max_probe_packets| reads.
139 void MakeDelayedMockData(NetworkStats::TestType test_type
,
141 uint32 pacing_interval_micros
,
142 uint32 max_probe_packets
,
143 net::IoMode io_mode
) {
145 ProbePacket probe_packet
;
146 ProbeMessage probe_message
;
147 mock_writes_
.clear();
148 ProbePacket_Token token
;
149 CreateToken(2L, "2a2b", &token
);
151 case NetworkStats::PACKET_SIZE_TEST
:
152 case NetworkStats::NON_PACED_PACKET_TEST
:
153 pacing_interval_micros
= 0;
155 case NetworkStats::NAT_BIND_TEST
:
156 // For NAT_BIND_TEST, we always set this to 1000000 to avoid the
157 // randomness in NetworkStats::SendProbeRequest() and to match
158 // the value chosen in TestStartOneTest() below.
159 pacing_interval_micros
= 1000000;
161 default: {} // Do nothing here.
163 probe_message
.GenerateProbeRequest(token
,
164 1, // current_test_index_ = 1.
166 pacing_interval_micros
,
169 outputs_
[0] = probe_message
.MakeEncodedPacket(probe_packet
);
170 mock_writes_
.push_back(
171 net::MockWrite(io_mode
, &outputs_
[0][0], outputs_
[0].size()));
173 inputs_
.resize(max_probe_packets
);
175 for (uint32 i
= 0; i
< max_probe_packets
; ++i
) {
176 // Add a probe reply.
177 probe_packet
= ProbePacket(); // Clear all content.
178 probe_message
.SetPacketHeader(ProbePacket_Type_PROBE_REPLY
,
180 int padding_size
= probe_bytes
- probe_packet
.ByteSize() - 8;
181 probe_packet
.mutable_padding()->append(
182 std::string(std::max(0, padding_size
), 0));
183 probe_packet
.mutable_header()->set_checksum(0);
184 probe_packet
.set_group_id(1);
185 probe_packet
.set_packet_index(i
);
186 inputs_
[i
] = probe_message
.MakeEncodedPacket(probe_packet
);
187 mock_reads_
.push_back(
188 net::MockRead(io_mode
, &inputs_
[i
][0], inputs_
[i
].size()));
192 // Test NetworkStats::StartOneTest(...) method.
193 void TestStartOneTest(bool has_proxy
,
194 NetworkStats::TestType test_type
,
196 uint32 interval_micros
,
197 uint32 max_probe_packets
,
198 net::IoMode io_mode
) {
200 net::MockClientSocketFactory mock_socket_factory
;
202 test_type
, bytes
, interval_micros
, max_probe_packets
, io_mode
);
203 net::DelayedSocketData
test_data(1,
207 mock_writes_
.size());
208 mock_socket_factory
.AddSocketDataProvider(&test_data
);
209 NetworkStats
* udp_stats_client
= new NetworkStats(&mock_socket_factory
);
210 udp_stats_client
->maximum_tests_
= 1; // Only do one probe at a time.
211 udp_stats_client
->maximum_sequential_packets_
= max_probe_packets
;
212 udp_stats_client
->maximum_NAT_packets_
= max_probe_packets
;
213 // For NAT_BIND_TEST, we always set this to 1 (second) to avoid the
214 // randomness in NetworkStats::SendProbeRequest().
215 udp_stats_client
->maximum_NAT_idle_seconds_
= 1;
216 udp_stats_client
->start_test_after_connect_
= false;
217 udp_stats_client
->inter_arrival_time_
=
218 base::TimeDelta::FromMicroseconds(interval_micros
);
219 CreateToken(2L, "2a2b", &udp_stats_client
->token_
);
221 net::TestCompletionCallback cb
;
222 scoped_ptr
<net::MockHostResolver
> host_resolver(
223 new net::MockHostResolver());
224 net::HostPortPair host_port_pair
;
225 EXPECT_TRUE(udp_stats_client
->Start(host_resolver
.get(),
232 // Test need to be added after Start() because Start() will reset
234 udp_stats_client
->test_sequence_
.push_back(test_type
);
235 udp_stats_client
->current_test_index_
= 1;
236 // Wait for host resolving and check if there were no errors during
237 // connect/write/read to UDP server.
238 int rv
= cb
.WaitForResult();
240 udp_stats_client
->ReadData();
241 udp_stats_client
->StartOneTest();
242 rv
= cb
.WaitForResult();
246 base::MessageLoopForIO message_loop_
;
247 std::vector
<std::string
> inputs_
;
248 std::vector
<std::string
> outputs_
;
249 std::vector
<net::MockRead
> mock_reads_
;
250 std::vector
<net::MockWrite
> mock_writes_
;
253 TEST_F(NetworkStatsTest
, ProbeTest100BHasProxyGetToken
) {
254 TestStart(true, 0, 1, 100, net::ASYNC
);
257 TEST_F(NetworkStatsTest
, ProbeTest500BHasNoProxyGetTokenSync
) {
258 TestStart(false, 0, 1, 500, net::SYNCHRONOUS
);
261 TEST_F(NetworkStatsTest
, ProbeTest100BHasNoProxyOneTest
) {
262 TestStart(false, 1, 1, 100, net::ASYNC
);
265 TEST_F(NetworkStatsTest
, ProbeTest100BHasNoProxyOneTestSync
) {
266 TestStart(false, 1, 1, 100, net::SYNCHRONOUS
);
269 TEST_F(NetworkStatsTest
, ProbeTest100BHasProxyOneTest
) {
270 TestStart(true, 1, 1, 100, net::ASYNC
);
273 TEST_F(NetworkStatsTest
, ProbeTest100BHasProxyOneTestSync
) {
274 TestStart(true, 1, 1, 100, net::SYNCHRONOUS
);
277 TEST_F(NetworkStatsTest
, ProbeTest500BHasProxyOneTest
) {
278 TestStart(true, 1, 1, 500, net::ASYNC
);
281 TEST_F(NetworkStatsTest
, ProbeTest500BHasNoProxyOneTestSync
) {
282 TestStart(false, 1, 1, 500, net::SYNCHRONOUS
);
285 TEST_F(NetworkStatsTest
, ProbeTest500BHasNoProxyOneTest
) {
286 TestStart(false, 1, 1, 500, net::ASYNC
);
289 TEST_F(NetworkStatsTest
, ProbeTest500BHasProxyOneTestSync
) {
290 TestStart(true, 1, 1, 500, net::SYNCHRONOUS
);
293 TEST_F(NetworkStatsTest
, ProbeTest1200BHasProxyOneTest
) {
294 TestStart(true, 1, 1, 1200, net::ASYNC
);
297 TEST_F(NetworkStatsTest
, ProbeTest1200BHasNoProxyOneTestSync
) {
298 TestStart(false, 1, 1, 1200, net::SYNCHRONOUS
);
301 TEST_F(NetworkStatsTest
, ProbeTest1200BHasNoProxyOneTest
) {
302 TestStart(false, 1, 1, 1200, net::ASYNC
);
305 TEST_F(NetworkStatsTest
, ProbeTest1200BHasProxyOneTestSync
) {
306 TestStart(true, 1, 1, 1200, net::SYNCHRONOUS
);
309 TEST_F(NetworkStatsTest
, ProbeTest100BHasNoProxyOneTestMultiPackets
) {
310 TestStart(false, 1, 4, 100, net::ASYNC
);
313 TEST_F(NetworkStatsTest
, ProbeTest1200BHasProxyOneTestMultiPacketsSync
) {
314 TestStart(true, 1, 4, 1200, net::SYNCHRONOUS
);
317 TEST_F(NetworkStatsTest
, StartNonPacedTest100BHasProxy
) {
319 true, NetworkStats::NON_PACED_PACKET_TEST
, 100, 0, 1, net::ASYNC
);
322 TEST_F(NetworkStatsTest
, StartNonPacedTest100BHasNoProxySync
) {
324 false, NetworkStats::NON_PACED_PACKET_TEST
, 100, 0, 1, net::SYNCHRONOUS
);
327 TEST_F(NetworkStatsTest
, StartNonPacedTest500BHasNoProxy
) {
329 false, NetworkStats::NON_PACED_PACKET_TEST
, 500, 3, 1, net::ASYNC
);
332 TEST_F(NetworkStatsTest
, StartNonPacedTest1200BHasProxySync
) {
334 true, NetworkStats::NON_PACED_PACKET_TEST
, 1200, 1, 1, net::SYNCHRONOUS
);
337 TEST_F(NetworkStatsTest
, StartNonPacedTest500BHasNoProxyMulti
) {
339 false, NetworkStats::NON_PACED_PACKET_TEST
, 500, 2, 3, net::ASYNC
);
342 TEST_F(NetworkStatsTest
, StartNonPacedTest1200BHasProxySyncMulti
) {
344 true, NetworkStats::NON_PACED_PACKET_TEST
, 1200, 1, 4, net::SYNCHRONOUS
);
347 TEST_F(NetworkStatsTest
, StartPacedTest100BHasProxy
) {
349 true, NetworkStats::PACED_PACKET_TEST
, 100, 0, 1, net::ASYNC
);
352 TEST_F(NetworkStatsTest
, StartPacedTest100BHasNoProxySync
) {
354 false, NetworkStats::PACED_PACKET_TEST
, 100, 0, 1, net::SYNCHRONOUS
);
357 TEST_F(NetworkStatsTest
, StartPacedTest500BHasNoProxy
) {
359 false, NetworkStats::PACED_PACKET_TEST
, 500, 3, 1, net::ASYNC
);
362 TEST_F(NetworkStatsTest
, StartPacedTest1200BHasProxySync
) {
364 true, NetworkStats::PACED_PACKET_TEST
, 1200, 1, 1, net::SYNCHRONOUS
);
367 TEST_F(NetworkStatsTest
, StartPacedTest500BHasNoProxyMulti
) {
369 false, NetworkStats::PACED_PACKET_TEST
, 500, 2, 3, net::ASYNC
);
372 TEST_F(NetworkStatsTest
, StartPacedTest1200BHasProxySyncMulti
) {
374 true, NetworkStats::PACED_PACKET_TEST
, 1200, 1, 4, net::SYNCHRONOUS
);
377 TEST_F(NetworkStatsTest
, StartNATBindTest100BHasProxy
) {
378 TestStartOneTest(true, NetworkStats::NAT_BIND_TEST
, 100, 0, 1, net::ASYNC
);
381 TEST_F(NetworkStatsTest
, StartNATBindTest100BHasNoProxySync
) {
383 false, NetworkStats::NAT_BIND_TEST
, 100, 3, 1, net::SYNCHRONOUS
);
386 TEST_F(NetworkStatsTest
, StartNATBindTest500BHasNoProxy
) {
387 TestStartOneTest(false, NetworkStats::NAT_BIND_TEST
, 500, 0, 2, net::ASYNC
);
390 TEST_F(NetworkStatsTest
, StartNATBindTest1200BHasProxySync
) {
392 true, NetworkStats::NAT_BIND_TEST
, 1200, 3, 2, net::SYNCHRONOUS
);
395 TEST_F(NetworkStatsTest
, StartPacketSizeTest1500BHasProxy
) {
397 true, NetworkStats::PACKET_SIZE_TEST
, 1500, 0, 1, net::ASYNC
);
400 TEST_F(NetworkStatsTest
, StartPacketSizeTest1500HasNoProxySync
) {
402 false, NetworkStats::PACKET_SIZE_TEST
, 1500, 0, 1, net::SYNCHRONOUS
);
405 TEST_F(NetworkStatsTest
, StartPacketSizeTest1500BHasNoProxy
) {
407 false, NetworkStats::PACKET_SIZE_TEST
, 1500, 0, 1, net::ASYNC
);
410 } // namespace chrome_browser_net