network_stats_unittest.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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.h"
7#include "base/stringprintf.h"
8#include "chrome/browser/net/network_stats.h"
9#include "net/base/net_errors.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/test/test_server.h"
14#include "testing/gtest/include/gtest/gtest.h"
15#include "testing/platform_test.h"
16
17namespace chrome_browser_net {
18
19class NetworkStatsTest : public PlatformTest {
20 public:
21  NetworkStatsTest() {}
22 protected:
23  virtual void TearDown() {
24    // Flush the message loop to make application verifiers happy.
25    message_loop_.RunUntilIdle();
26  }
27  MessageLoopForIO message_loop_;
28};
29
30class NetworkStatsTestUDP : public NetworkStatsTest {
31 public:
32  NetworkStatsTestUDP()
33      : test_server_(net::TestServer::TYPE_UDP_ECHO,
34                     net::TestServer::kLocalhost,
35                     base::FilePath(FILE_PATH_LITERAL("net/data"))) {
36  }
37
38 protected:
39  void RunUDPEchoTest(int bytes, int packets, bool has_proxy) {
40    net::TestCompletionCallback cb;
41
42    scoped_ptr<net::MockHostResolver> host_resolver(
43        new net::MockHostResolver());
44
45    // We will use HISTOGRAM_PORT_MAX as the PortIndex enum for testing
46    // purposes.
47    NetworkStats* udp_stats_client = new NetworkStats();
48    EXPECT_TRUE(udp_stats_client->Start(host_resolver.get(),
49                                        test_server_.host_port_pair(),
50                                        NetworkStats::HISTOGRAM_PORT_MAX,
51                                        has_proxy,
52                                        bytes,
53                                        packets,
54                                        cb.callback()));
55    int rv = cb.WaitForResult();
56    // Check there were no errors during connect/write/read to echo UDP server.
57    EXPECT_EQ(0, rv);
58  }
59
60  net::TestServer test_server_;
61};
62
63TEST_F(NetworkStatsTestUDP, UDPEcho100BytesHasProxy) {
64  ASSERT_TRUE(test_server_.Start());
65  RunUDPEchoTest(100, 1, true);
66}
67
68TEST_F(NetworkStatsTestUDP, UDPEcho100BytesNoProxy) {
69  ASSERT_TRUE(test_server_.Start());
70  RunUDPEchoTest(100, 1, false);
71}
72
73TEST_F(NetworkStatsTestUDP, UDPEcho500BytesHasProxy) {
74  ASSERT_TRUE(test_server_.Start());
75  RunUDPEchoTest(500, 1, true);
76}
77
78TEST_F(NetworkStatsTestUDP, UDPEcho500BytesNoProxy) {
79  ASSERT_TRUE(test_server_.Start());
80  RunUDPEchoTest(500, 1, false);
81}
82
83TEST_F(NetworkStatsTestUDP, UDPEcho1KBytesHasProxy) {
84  ASSERT_TRUE(test_server_.Start());
85  RunUDPEchoTest(1024, 1, true);
86}
87
88TEST_F(NetworkStatsTestUDP, UDPEcho1KBytesNoProxy) {
89  ASSERT_TRUE(test_server_.Start());
90  RunUDPEchoTest(1024, 1, false);
91}
92
93TEST_F(NetworkStatsTestUDP, UDPEchoMultiplePacketsHasProxy) {
94  ASSERT_TRUE(test_server_.Start());
95  RunUDPEchoTest(1024, 4, true);
96}
97
98TEST_F(NetworkStatsTestUDP, UDPEchoMultiplePacketsNoProxy) {
99  ASSERT_TRUE(test_server_.Start());
100  RunUDPEchoTest(1024, 4, false);
101}
102
103TEST_F(NetworkStatsTestUDP, VerifyBytesInvalidHeaders) {
104  const uint32 KBytesToSend = 100;
105  const uint32 packets_to_send = 1;
106  NetworkStats network_stats;
107  net::TestCompletionCallback cb;
108  network_stats.Initialize(KBytesToSend,
109                           NetworkStats::HISTOGRAM_PORT_MAX,
110                           true,
111                           packets_to_send,
112                           cb.callback());
113  uint32 packet_number = network_stats.packet_number();
114  network_stats.set_base_packet_number(packet_number);
115
116  std::string message;
117  EXPECT_EQ(NetworkStats::ZERO_LENGTH_ERROR,
118            network_stats.VerifyBytes(message));
119
120  std::string version = base::StringPrintf("%02d", 1);
121  std::string invalid_checksum = base::StringPrintf("%010d", 0);
122  std::string payload_size = base::StringPrintf("%07d", KBytesToSend);
123  std::string invalid_key = base::StringPrintf("%06d", -1);
124  std::string key_string = base::StringPrintf("%06d", 899999);
125  std::string packet_number_string = base::StringPrintf("%010d", packet_number);
126  std::string short_payload(packet_number_string +
127      "1234567890123456789012345678901234567890123456789012345678901234567890");
128  std::string long_payload(packet_number_string +
129      "1234567890123456789012345678901234567890123456789012345678901234567890"
130      "1234567890123456789012345678901234567890123456789012345678901234567890");
131
132  message = version;
133  EXPECT_EQ(NetworkStats::NO_CHECKSUM_ERROR,
134            network_stats.VerifyBytes(message));
135
136  message = version + invalid_checksum;
137  EXPECT_EQ(NetworkStats::NO_PAYLOAD_SIZE_ERROR,
138            network_stats.VerifyBytes(message));
139
140  message = version + invalid_checksum + payload_size;
141  EXPECT_EQ(NetworkStats::NO_KEY_ERROR, network_stats.VerifyBytes(message));
142
143  message = version + invalid_checksum + payload_size + invalid_key;
144  EXPECT_EQ(NetworkStats::NO_PAYLOAD_ERROR, network_stats.VerifyBytes(message));
145
146  message = version + invalid_checksum + payload_size + invalid_key +
147      short_payload;
148  EXPECT_EQ(NetworkStats::INVALID_KEY_ERROR,
149            network_stats.VerifyBytes(message));
150
151  message = version + invalid_checksum + payload_size + key_string +
152      short_payload;
153  EXPECT_EQ(NetworkStats::TOO_SHORT_PAYLOAD,
154            network_stats.VerifyBytes(message));
155
156  message = version + invalid_checksum + payload_size + key_string +
157      long_payload;
158  EXPECT_EQ(NetworkStats::TOO_LONG_PAYLOAD, network_stats.VerifyBytes(message));
159}
160
161TEST_F(NetworkStatsTestUDP, VerifyBytesInvalidChecksum) {
162  const uint32 KBytesToSend = 100;
163  const uint32 packets_to_send = 1;
164  NetworkStats network_stats;
165  net::TestCompletionCallback cb;
166
167  network_stats.Initialize(KBytesToSend,
168                           NetworkStats::HISTOGRAM_PORT_MAX,
169                           true,
170                           packets_to_send,
171                           cb.callback());
172  uint32 packet_number = network_stats.packet_number();
173  network_stats.set_base_packet_number(packet_number);
174
175  std::string message;
176  EXPECT_EQ(NetworkStats::ZERO_LENGTH_ERROR,
177            network_stats.VerifyBytes(message));
178
179  std::string version = base::StringPrintf("%02d", 1);
180  std::string invalid_checksum = base::StringPrintf("%010d", 0);
181  std::string payload_size = base::StringPrintf("%07d", KBytesToSend);
182  std::string key_string = base::StringPrintf("%06d", 899999);
183  std::string packet_number_string = base::StringPrintf("%010d", packet_number);
184
185  scoped_refptr<net::IOBuffer> payload(new net::IOBuffer(KBytesToSend));
186
187  // Copy the Packet number into the payload.
188  size_t packet_number_size = packet_number_string.size();
189  memcpy(payload->data(), packet_number_string.c_str(), packet_number_size);
190
191  // Get random bytes to fill rest of the payload.
192  network_stats.stream_.GetBytes(payload->data() + packet_number_size,
193                                 KBytesToSend - packet_number_size);
194
195  // Calculate checksum for the payload.
196  char* payload_data = payload->data();
197  uint32 sum = network_stats.GetChecksum(payload_data, KBytesToSend);
198  std::string checksum = base::StringPrintf("%010d", sum);
199
200  char encoded_data[KBytesToSend];
201  memset(encoded_data, 0, KBytesToSend);
202  const char* key = key_string.c_str();
203  network_stats.Crypt(
204      key, key_string.length(), payload_data, KBytesToSend, encoded_data);
205  std::string encoded_payload(encoded_data, KBytesToSend);
206
207  // Test invalid checksum error by sending wrong checksum.
208  message = version + invalid_checksum + payload_size + key_string +
209      encoded_payload;
210  EXPECT_EQ(NetworkStats::INVALID_CHECKSUM, network_stats.VerifyBytes(message));
211}
212
213TEST_F(NetworkStatsTestUDP, VerifyBytesPreviousPacket) {
214  const uint32 KBytesToSend = 100;
215  const uint32 packets_to_send = 1;
216  NetworkStats network_stats;
217  net::TestCompletionCallback cb;
218
219  network_stats.Initialize(KBytesToSend,
220                           NetworkStats::HISTOGRAM_PORT_MAX,
221                           true,
222                           packets_to_send,
223                           cb.callback());
224  uint32 packet_number = network_stats.packet_number();
225  network_stats.set_base_packet_number(packet_number);
226  uint32 prev_packet_number = packet_number - 1;
227
228  std::string message;
229  std::string version = base::StringPrintf("%02d", 1);
230  std::string payload_size = base::StringPrintf("%07d", KBytesToSend);
231  std::string key_string = base::StringPrintf("%06d", 899999);
232  std::string prev_packet_number_string =
233      base::StringPrintf("%010d", prev_packet_number);
234
235  // Copy the previous packet number into the payload.
236  scoped_refptr<net::IOBuffer> payload(new net::IOBuffer(KBytesToSend));
237  size_t packet_number_size = prev_packet_number_string.size();
238  memcpy(payload->data(), prev_packet_number_string.c_str(),
239         packet_number_size);
240
241  // Get random bytes to fill rest of the payload.
242  network_stats.stream_.GetBytes(payload->data() + packet_number_size,
243                                 KBytesToSend - packet_number_size);
244
245  // Calculate checksum for the previous packet number payload.
246  char* payload_data = payload->data();
247  uint32 sum = network_stats.GetChecksum(payload_data, KBytesToSend);
248  std::string checksum = base::StringPrintf("%010d", sum);
249
250  char encoded_data[KBytesToSend];
251  memset(encoded_data, 0, KBytesToSend);
252  const char* key = key_string.c_str();
253  network_stats.Crypt(
254      key, key_string.length(), payload_data, KBytesToSend, encoded_data);
255  std::string encoded_payload(encoded_data, KBytesToSend);
256
257  message = version + checksum + payload_size + key_string +  encoded_payload;
258  EXPECT_EQ(NetworkStats::PREVIOUS_PACKET_NUMBER,
259            network_stats.VerifyBytes(message));
260  EXPECT_EQ(0u, network_stats.packets_received_mask());
261}
262
263TEST_F(NetworkStatsTestUDP, VerifyBytesInvalidPacketNumber) {
264  const uint32 KBytesToSend = 100;
265  const uint32 packets_to_send = 1;
266  NetworkStats network_stats;
267  net::TestCompletionCallback cb;
268
269  network_stats.Initialize(KBytesToSend,
270                           NetworkStats::HISTOGRAM_PORT_MAX,
271                           true,
272                           packets_to_send,
273                           cb.callback());
274  uint32 packet_number = network_stats.packet_number();
275  network_stats.set_base_packet_number(packet_number);
276  uint32 corrupt_packet_number = packet_number + 1;
277
278  std::string message;
279  std::string version = base::StringPrintf("%02d", 1);
280  std::string payload_size = base::StringPrintf("%07d", KBytesToSend);
281  std::string key_string = base::StringPrintf("%06d", 899999);
282  std::string corrupt_packet_number_string =
283      base::StringPrintf("%010d", corrupt_packet_number);
284
285  scoped_refptr<net::IOBuffer> payload(new net::IOBuffer(KBytesToSend));
286  size_t packet_number_size = corrupt_packet_number_string.size();
287  memcpy(payload->data(), corrupt_packet_number_string.c_str(),
288         packet_number_size);
289
290  // Get random bytes to fill rest of the payload.
291  network_stats.stream_.GetBytes(payload->data() + packet_number_size,
292                                 KBytesToSend - packet_number_size);
293
294  // Calculate checksum for the corrupt packet number payload.
295  char* payload_data = payload->data();
296  uint32 sum = network_stats.GetChecksum(payload_data, KBytesToSend);
297  std::string checksum = base::StringPrintf("%010d", sum);
298
299  char encoded_data[KBytesToSend];
300  memset(encoded_data, 0, KBytesToSend);
301  const char* key = key_string.c_str();
302  network_stats.Crypt(
303      key, key_string.length(), payload_data, KBytesToSend, encoded_data);
304  std::string encoded_payload(encoded_data, KBytesToSend);
305  message = version + checksum + payload_size + key_string + encoded_payload;
306  EXPECT_EQ(NetworkStats::INVALID_PACKET_NUMBER,
307            network_stats.VerifyBytes(message));
308  EXPECT_EQ(0u, network_stats.packets_received_mask());
309}
310
311TEST_F(NetworkStatsTestUDP, VerifyBytesPatternChanged) {
312  const uint32 KBytesToSend = 100;
313  const uint32 packets_to_send = 1;
314  NetworkStats network_stats;
315  net::TestCompletionCallback cb;
316
317  network_stats.Initialize(KBytesToSend,
318                           NetworkStats::HISTOGRAM_PORT_MAX,
319                           true,
320                           packets_to_send,
321                           cb.callback());
322  uint32 packet_number = network_stats.packet_number();
323  network_stats.set_base_packet_number(packet_number);
324
325  std::string message;
326  std::string version = base::StringPrintf("%02d", 1);
327  std::string payload_size = base::StringPrintf("%07d", KBytesToSend);
328  std::string key_string = base::StringPrintf("%06d", 899999);
329  std::string packet_number_string = base::StringPrintf("%010d", packet_number);
330
331  scoped_refptr<net::IOBuffer> payload(new net::IOBuffer(KBytesToSend));
332
333  // Copy the Packet number into the payload.
334  size_t packet_number_size = packet_number_string.size();
335  memcpy(payload->data(), packet_number_string.c_str(), packet_number_size);
336
337  // Get random bytes to fill rest of the payload.
338  network_stats.stream_.GetBytes(payload->data() + packet_number_size,
339                                 KBytesToSend - packet_number_size);
340
341  // Calculate checksum for the payload.
342  char* payload_data = payload->data();
343  uint32 sum = network_stats.GetChecksum(payload_data, KBytesToSend);
344  std::string checksum = base::StringPrintf("%010d", sum);
345
346  const char* key = key_string.c_str();
347
348  // Corrupt the randomly generated bytes in payload data.
349  char corrupted_data_2[KBytesToSend];
350  memcpy(corrupted_data_2, payload_data, KBytesToSend);
351  char temp_char_1 = corrupted_data_2[packet_number_size];
352  corrupted_data_2[packet_number_size] =
353      corrupted_data_2[packet_number_size + 1];
354  corrupted_data_2[packet_number_size + 1] = temp_char_1;
355  char encoded_corrupted_data_2[KBytesToSend];
356  memset(encoded_corrupted_data_2, 0, KBytesToSend);
357  network_stats.Crypt(key,
358                      key_string.length(),
359                      corrupted_data_2,
360                      KBytesToSend,
361                      encoded_corrupted_data_2);
362  std::string invalid_payload(encoded_corrupted_data_2, KBytesToSend);
363  message = version + checksum + payload_size + key_string + invalid_payload;
364  EXPECT_EQ(NetworkStats::PATTERN_CHANGED, network_stats.VerifyBytes(message));
365  EXPECT_EQ(0u, network_stats.packets_received_mask());
366}
367
368
369TEST_F(NetworkStatsTestUDP, VerifyBytes) {
370  const uint32 KBytesToSend = 100;
371  const uint32 packets_to_send = 1;
372  NetworkStats network_stats;
373  net::TestCompletionCallback cb;
374
375  network_stats.Initialize(KBytesToSend,
376                           NetworkStats::HISTOGRAM_PORT_MAX,
377                           true,
378                           packets_to_send,
379                           cb.callback());
380  uint32 packet_number = network_stats.packet_number();
381  network_stats.set_base_packet_number(packet_number);
382
383  std::string message;
384  std::string version = base::StringPrintf("%02d", 1);
385  std::string payload_size = base::StringPrintf("%07d", KBytesToSend);
386  std::string key_string = base::StringPrintf("%06d", 899999);
387  std::string packet_number_string = base::StringPrintf("%010d", packet_number);
388
389  scoped_refptr<net::IOBuffer> payload(new net::IOBuffer(KBytesToSend));
390
391  // Copy the Packet number into the payload.
392  size_t packet_number_size = packet_number_string.size();
393  memcpy(payload->data(), packet_number_string.c_str(), packet_number_size);
394
395  // Get random bytes to fill rest of the payload.
396  network_stats.stream_.GetBytes(payload->data() + packet_number_size,
397                                 KBytesToSend - packet_number_size);
398
399  // Calculate checksum for the payload.
400  char* payload_data = payload->data();
401  uint32 sum = network_stats.GetChecksum(payload_data, KBytesToSend);
402  std::string checksum = base::StringPrintf("%010d", sum);
403
404  char encoded_data[KBytesToSend];
405  memset(encoded_data, 0, KBytesToSend);
406  const char* key = key_string.c_str();
407  network_stats.Crypt(
408      key, key_string.length(), payload_data, KBytesToSend, encoded_data);
409  std::string encoded_payload(encoded_data, KBytesToSend);
410
411  message = version + checksum + payload_size + key_string + encoded_payload;
412  EXPECT_EQ(NetworkStats::SUCCESS, network_stats.VerifyBytes(message));
413  EXPECT_EQ(1u, network_stats.packets_received_mask());
414}
415
416}  // namespace chrome_browser_net
417