- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / net / network_stats_unittest.cc
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.
4
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"
16
17 namespace chrome_browser_net {
18
19 class NetworkStatsTest : public PlatformTest {
20  public:
21   NetworkStatsTest() {}
22
23  protected:
24
25   virtual void SetUp() {
26     net::NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
27     base::MessageLoop::current()->RunUntilIdle();
28     mock_writes_.clear();
29     mock_reads_.clear();
30   }
31
32   virtual void TearDown() {
33     net::NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
34     // Empty the current queue.
35     base::MessageLoop::current()->RunUntilIdle();
36     PlatformTest::TearDown();
37   }
38
39   void CreateToken(uint64 timestamp_micros,
40                    const string& hash,
41                    ProbePacket_Token* token) {
42     token->set_timestamp_micros(timestamp_micros);
43     token->mutable_hash()->assign(hash);
44   }
45
46   // DeterministicMockData defines the exact sequence of the read/write
47   // operations (specified by the last parameter of MockRead/MockWrite).
48   // |io_mode_write| is the IO mode for writing only. Reading is always async.
49   void MakeDeterministicMockData(uint32 max_tests,
50                                  uint32 max_probe_packets,
51                                  uint32 probe_bytes,
52                                  net::IoMode io_mode_write) {
53     // Only allow 0 or 1 test because the test 2 in NetworkStats is random.
54     DCHECK_LT(max_tests, 2U);
55     outputs_.resize(10);
56     ProbePacket probe_packet;
57     ProbeMessage probe_message;
58     probe_message.SetPacketHeader(ProbePacket_Type_HELLO_REQUEST,
59                                   &probe_packet);
60     probe_packet.set_group_id(0);
61     outputs_[0] = probe_message.MakeEncodedPacket(probe_packet);
62     mock_writes_.clear();
63     mock_writes_.push_back(net::MockWrite(
64         io_mode_write, &outputs_[0][0], outputs_[0].size(), 0));
65     // Add one probe_request.
66     probe_packet = ProbePacket();  // Clear all content.
67     ProbePacket_Token token;
68     CreateToken(1L, "1010", &token);
69     probe_message.GenerateProbeRequest(
70         token, 1, probe_bytes, 0, max_probe_packets, &probe_packet);
71     outputs_[1] = probe_message.MakeEncodedPacket(probe_packet);
72     mock_writes_.push_back(net::MockWrite(
73         io_mode_write, &outputs_[1][0], outputs_[1].size(), 2));
74
75     inputs_.resize(10);
76     mock_reads_.clear();
77     // Add a hello reply.
78     probe_packet = ProbePacket();  // Clear all content.
79     probe_message.SetPacketHeader(ProbePacket_Type_HELLO_REPLY, &probe_packet);
80     probe_packet.set_group_id(0);
81     CreateToken(1L, "1010", probe_packet.mutable_token());
82     inputs_[0] = probe_message.MakeEncodedPacket(probe_packet);
83     mock_reads_.push_back(
84         net::MockRead(net::ASYNC, &inputs_[0][0], inputs_[0].size(), 1));
85
86     for (uint32 i = 0; i < max_probe_packets; ++i) {
87       // Add a probe reply.
88       probe_packet = ProbePacket();  // Clear all content.
89       probe_message.SetPacketHeader(ProbePacket_Type_PROBE_REPLY,
90                                     &probe_packet);
91       int padding_size = probe_bytes - probe_packet.ByteSize() - 8;
92       probe_packet.mutable_padding()->append(
93           std::string(std::max(0, padding_size), 0));
94       probe_packet.mutable_header()->set_checksum(0);
95       probe_packet.set_group_id(1);
96       probe_packet.set_packet_index(i);
97       inputs_[1 + i] = probe_message.MakeEncodedPacket(probe_packet);
98       mock_reads_.push_back(net::MockRead(
99           net::ASYNC, &inputs_[1 + i][0], inputs_[1 + i].size(), 3 + i));
100     }
101   }
102
103   // Test NetworkStats::Start(...) method.
104   void TestStart(bool has_proxy,
105                  uint32 max_tests,
106                  uint32 max_probe_packets,
107                  uint32 bytes,
108                  net::IoMode io_mode) {
109     net::DeterministicMockClientSocketFactory mock_socket_factory;
110     MakeDeterministicMockData(max_tests, max_probe_packets, bytes, io_mode);
111     net::DeterministicSocketData test_data(
112         &mock_reads_[0], mock_reads_.size(),
113         &mock_writes_[0], mock_writes_.size());
114     mock_socket_factory.AddSocketDataProvider(&test_data);
115     NetworkStats* udp_stats_client = new NetworkStats(&mock_socket_factory);
116     udp_stats_client->maximum_tests_ = max_tests;
117     udp_stats_client->maximum_sequential_packets_ = max_probe_packets;
118
119     net::TestCompletionCallback cb;
120     scoped_ptr<net::MockHostResolver> host_resolver(
121         new net::MockHostResolver());
122     net::HostPortPair host_port_pair;
123     EXPECT_TRUE(udp_stats_client->Start(host_resolver.get(),
124                                         host_port_pair,
125                                         9999,
126                                         has_proxy,
127                                         bytes,
128                                         cb.callback()));
129     int num_packets_run = (max_tests + 1) * 2 + max_probe_packets - 1;
130     test_data.RunFor(num_packets_run);
131     int rv = cb.WaitForResult();
132     // Check there were no errors during connect/write/read to echo UDP server.
133     EXPECT_EQ(0, rv);
134   }
135
136   // Make one write and then |max_probe_packets| reads.
137   void MakeDelayedMockData(NetworkStats::TestType test_type,
138                            uint32 probe_bytes,
139                            uint32 pacing_interval_micros,
140                            uint32 max_probe_packets,
141                            net::IoMode io_mode) {
142     outputs_.resize(1);
143     ProbePacket probe_packet;
144     ProbeMessage probe_message;
145     mock_writes_.clear();
146     ProbePacket_Token token;
147     CreateToken(2L, "2a2b", &token);
148     switch (test_type) {
149       case NetworkStats::NON_PACED_PACKET_TEST:
150         pacing_interval_micros = 0;
151         break;
152       case NetworkStats::NAT_BIND_TEST:
153         // For NAT_BIND_TEST, we always set this to 1000000 to avoid the
154         // randomness in NetworkStats::SendProbeRequest() and to match
155         // the value chosen in TestStartOneTest() below.
156         pacing_interval_micros = 1000000;
157         break;
158       default: {}  // Do nothing here.
159     }
160     probe_message.GenerateProbeRequest(token,
161                                        1,  // current_test_index_ = 1.
162                                        probe_bytes,
163                                        pacing_interval_micros,
164                                        max_probe_packets,
165                                        &probe_packet);
166     outputs_[0] = probe_message.MakeEncodedPacket(probe_packet);
167     mock_writes_.push_back(
168         net::MockWrite(io_mode, &outputs_[0][0], outputs_[0].size()));
169
170     inputs_.resize(max_probe_packets);
171     mock_reads_.clear();
172     for (uint32 i = 0; i < max_probe_packets; ++i) {
173       // Add a probe reply.
174       probe_packet = ProbePacket();  // Clear all content.
175       probe_message.SetPacketHeader(ProbePacket_Type_PROBE_REPLY,
176                                     &probe_packet);
177       int padding_size = probe_bytes - probe_packet.ByteSize() - 8;
178       probe_packet.mutable_padding()->append(
179           std::string(std::max(0, padding_size), 0));
180       probe_packet.mutable_header()->set_checksum(0);
181       probe_packet.set_group_id(1);
182       probe_packet.set_packet_index(i);
183       inputs_[i] = probe_message.MakeEncodedPacket(probe_packet);
184       mock_reads_.push_back(
185           net::MockRead(io_mode, &inputs_[i][0], inputs_[i].size()));
186     }
187   }
188
189   // Test NetworkStats::StartOneTest(...) method.
190   void TestStartOneTest(bool has_proxy,
191                         NetworkStats::TestType test_type,
192                         uint32 bytes,
193                         uint32 interval_micros,
194                         uint32 max_probe_packets,
195                         net::IoMode io_mode) {
196
197     net::MockClientSocketFactory mock_socket_factory;
198     MakeDelayedMockData(
199         test_type, bytes, interval_micros, max_probe_packets, io_mode);
200     net::DelayedSocketData test_data(1,
201                                      &mock_reads_[0],
202                                      mock_reads_.size(),
203                                      &mock_writes_[0],
204                                      mock_writes_.size());
205     mock_socket_factory.AddSocketDataProvider(&test_data);
206     NetworkStats* udp_stats_client = new NetworkStats(&mock_socket_factory);
207     udp_stats_client->maximum_tests_ = 1;  // Only do one probe at a time.
208     udp_stats_client->maximum_sequential_packets_ = max_probe_packets;
209     udp_stats_client->maximum_NAT_packets_ = max_probe_packets;
210     // For NAT_BIND_TEST, we always set this to 1 (second) to avoid the
211     // randomness in NetworkStats::SendProbeRequest().
212     udp_stats_client->maximum_NAT_idle_seconds_ = 1;
213     udp_stats_client->start_test_after_connect_ = false;
214     udp_stats_client->inter_arrival_time_ =
215         base::TimeDelta::FromMicroseconds(interval_micros);
216     CreateToken(2L, "2a2b", &udp_stats_client->token_);
217
218     net::TestCompletionCallback cb;
219     scoped_ptr<net::MockHostResolver> host_resolver(
220         new net::MockHostResolver());
221     net::HostPortPair host_port_pair;
222     EXPECT_TRUE(udp_stats_client->Start(host_resolver.get(),
223                                         host_port_pair,
224                                         9999,
225                                         has_proxy,
226                                         bytes,
227                                         cb.callback()));
228     // Test need to be added after Start() because Start() will reset
229     // test_sequence_
230     udp_stats_client->test_sequence_.push_back(test_type);
231     udp_stats_client->current_test_index_ = 1;
232     // Wait for host resolving and check if there were no errors during
233     // connect/write/read to UDP server.
234     int rv = cb.WaitForResult();
235     EXPECT_EQ(0, rv);
236     udp_stats_client->ReadData();
237     udp_stats_client->StartOneTest();
238     rv = cb.WaitForResult();
239     EXPECT_EQ(0, rv);
240   }
241
242   base::MessageLoopForIO message_loop_;
243   std::vector<std::string> inputs_;
244   std::vector<std::string> outputs_;
245   std::vector<net::MockRead> mock_reads_;
246   std::vector<net::MockWrite> mock_writes_;
247 };
248
249 TEST_F(NetworkStatsTest, ProbeTest100BHasProxyGetToken) {
250   TestStart(true, 0, 1, 100, net::ASYNC);
251 }
252
253 TEST_F(NetworkStatsTest, ProbeTest500BHasNoProxyGetTokenSync) {
254   TestStart(false, 0, 1, 500, net::SYNCHRONOUS);
255 }
256
257 TEST_F(NetworkStatsTest, ProbeTest100BHasNoProxyOneTest) {
258   TestStart(false, 1, 1, 100, net::ASYNC);
259 }
260
261 TEST_F(NetworkStatsTest, ProbeTest100BHasNoProxyOneTestSync) {
262   TestStart(false, 1, 1, 100, net::SYNCHRONOUS);
263 }
264
265 TEST_F(NetworkStatsTest, ProbeTest100BHasProxyOneTest) {
266   TestStart(true, 1, 1, 100, net::ASYNC);
267 }
268
269 TEST_F(NetworkStatsTest, ProbeTest100BHasProxyOneTestSync) {
270   TestStart(true, 1, 1, 100, net::SYNCHRONOUS);
271 }
272
273 TEST_F(NetworkStatsTest, ProbeTest500BHasProxyOneTest) {
274   TestStart(true, 1, 1, 500, net::ASYNC);
275 }
276
277 TEST_F(NetworkStatsTest, ProbeTest500BHasNoProxyOneTestSync) {
278   TestStart(false, 1, 1, 500, net::SYNCHRONOUS);
279 }
280
281 TEST_F(NetworkStatsTest, ProbeTest500BHasNoProxyOneTest) {
282   TestStart(false, 1, 1, 500, net::ASYNC);
283 }
284
285 TEST_F(NetworkStatsTest, ProbeTest500BHasProxyOneTestSync) {
286   TestStart(true, 1, 1, 500, net::SYNCHRONOUS);
287 }
288
289 TEST_F(NetworkStatsTest, ProbeTest1200BHasProxyOneTest) {
290   TestStart(true, 1, 1, 1200, net::ASYNC);
291 }
292
293 TEST_F(NetworkStatsTest, ProbeTest1200BHasNoProxyOneTestSync) {
294   TestStart(false, 1, 1, 1200, net::SYNCHRONOUS);
295 }
296
297 TEST_F(NetworkStatsTest, ProbeTest1200BHasNoProxyOneTest) {
298   TestStart(false, 1, 1, 1200, net::ASYNC);
299 }
300
301 TEST_F(NetworkStatsTest, ProbeTest1200BHasProxyOneTestSync) {
302   TestStart(true, 1, 1, 1200, net::SYNCHRONOUS);
303 }
304
305 TEST_F(NetworkStatsTest, ProbeTest100BHasNoProxyOneTestMultiPackets) {
306   TestStart(false, 1, 4, 100, net::ASYNC);
307 }
308
309 TEST_F(NetworkStatsTest, ProbeTest1200BHasProxyOneTestMultiPacketsSync) {
310   TestStart(true, 1, 4, 1200, net::SYNCHRONOUS);
311 }
312
313 TEST_F(NetworkStatsTest, StartNonPacedTest100BHasProxy) {
314   TestStartOneTest(
315       true, NetworkStats::NON_PACED_PACKET_TEST, 100, 0, 1, net::ASYNC);
316 }
317
318 TEST_F(NetworkStatsTest, StartNonPacedTest100BHasNoProxySync) {
319   TestStartOneTest(
320       false, NetworkStats::NON_PACED_PACKET_TEST, 100, 0, 1, net::SYNCHRONOUS);
321 }
322
323 TEST_F(NetworkStatsTest, StartNonPacedTest500BHasNoProxy) {
324   TestStartOneTest(
325       false, NetworkStats::NON_PACED_PACKET_TEST, 500, 3, 1, net::ASYNC);
326 }
327
328 TEST_F(NetworkStatsTest, StartNonPacedTest1200BHasProxySync) {
329   TestStartOneTest(
330       true, NetworkStats::NON_PACED_PACKET_TEST, 1200, 1, 1, net::SYNCHRONOUS);
331 }
332
333 TEST_F(NetworkStatsTest, StartNonPacedTest500BHasNoProxyMulti) {
334   TestStartOneTest(
335       false, NetworkStats::NON_PACED_PACKET_TEST, 500, 2, 3, net::ASYNC);
336 }
337
338 TEST_F(NetworkStatsTest, StartNonPacedTest1200BHasProxySyncMulti) {
339   TestStartOneTest(
340       true, NetworkStats::NON_PACED_PACKET_TEST, 1200, 1, 4, net::SYNCHRONOUS);
341 }
342
343 TEST_F(NetworkStatsTest, StartPacedTest100BHasProxy) {
344   TestStartOneTest(
345       true, NetworkStats::PACED_PACKET_TEST, 100, 0, 1, net::ASYNC);
346 }
347
348 TEST_F(NetworkStatsTest, StartPacedTest100BHasNoProxySync) {
349   TestStartOneTest(
350       false, NetworkStats::PACED_PACKET_TEST, 100, 0, 1, net::SYNCHRONOUS);
351 }
352
353 TEST_F(NetworkStatsTest, StartPacedTest500BHasNoProxy) {
354   TestStartOneTest(
355       false, NetworkStats::PACED_PACKET_TEST, 500, 3, 1, net::ASYNC);
356 }
357
358 TEST_F(NetworkStatsTest, StartPacedTest1200BHasProxySync) {
359   TestStartOneTest(
360       true, NetworkStats::PACED_PACKET_TEST, 1200, 1, 1, net::SYNCHRONOUS);
361 }
362
363 TEST_F(NetworkStatsTest, StartPacedTest500BHasNoProxyMulti) {
364   TestStartOneTest(
365       false, NetworkStats::PACED_PACKET_TEST, 500, 2, 3, net::ASYNC);
366 }
367
368 TEST_F(NetworkStatsTest, StartPacedTest1200BHasProxySyncMulti) {
369   TestStartOneTest(
370       true, NetworkStats::PACED_PACKET_TEST, 1200, 1, 4, net::SYNCHRONOUS);
371 }
372
373 TEST_F(NetworkStatsTest, StartNATBindTest100BHasProxy) {
374   TestStartOneTest(true, NetworkStats::NAT_BIND_TEST, 100, 0, 1, net::ASYNC);
375 }
376
377 TEST_F(NetworkStatsTest, StartNATBindTest100BHasNoProxySync) {
378   TestStartOneTest(
379       false, NetworkStats::NAT_BIND_TEST, 100, 3, 1, net::SYNCHRONOUS);
380 }
381
382 TEST_F(NetworkStatsTest, StartNATBindTest500BHasNoProxy) {
383   TestStartOneTest(false, NetworkStats::NAT_BIND_TEST, 500, 0, 2, net::ASYNC);
384 }
385
386 TEST_F(NetworkStatsTest, StartNATBindTest1200BHasProxySync) {
387   TestStartOneTest(
388       true, NetworkStats::NAT_BIND_TEST, 1200, 3, 2, net::SYNCHRONOUS);
389 }
390
391 }  // namespace chrome_browser_net