Home | History | Annotate | Download | only in net
      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                                         bytes,
    129                                         cb.callback()));
    130     int num_packets_run = (max_tests + 1) * 2 + max_probe_packets - 1;
    131     test_data.RunFor(num_packets_run);
    132     int rv = cb.WaitForResult();
    133     // Check there were no errors during connect/write/read to echo UDP server.
    134     EXPECT_EQ(0, rv);
    135   }
    136 
    137   // Make one write and then |max_probe_packets| reads.
    138   void MakeDelayedMockData(NetworkStats::TestType test_type,
    139                            uint32 probe_bytes,
    140                            uint32 pacing_interval_micros,
    141                            uint32 max_probe_packets,
    142                            net::IoMode io_mode) {
    143     outputs_.resize(1);
    144     ProbePacket probe_packet;
    145     ProbeMessage probe_message;
    146     mock_writes_.clear();
    147     ProbePacket_Token token;
    148     CreateToken(2L, "2a2b", &token);
    149     switch (test_type) {
    150       case NetworkStats::PACKET_SIZE_TEST:
    151       case NetworkStats::NON_PACED_PACKET_TEST:
    152         pacing_interval_micros = 0;
    153         break;
    154       case NetworkStats::NAT_BIND_TEST:
    155         // For NAT_BIND_TEST, we always set this to 1000000 to avoid the
    156         // randomness in NetworkStats::SendProbeRequest() and to match
    157         // the value chosen in TestStartOneTest() below.
    158         pacing_interval_micros = 1000000;
    159         break;
    160       default: {}  // Do nothing here.
    161     }
    162     probe_message.GenerateProbeRequest(token,
    163                                        1,  // current_test_index_ = 1.
    164                                        probe_bytes,
    165                                        pacing_interval_micros,
    166                                        max_probe_packets,
    167                                        &probe_packet);
    168     outputs_[0] = probe_message.MakeEncodedPacket(probe_packet);
    169     mock_writes_.push_back(
    170         net::MockWrite(io_mode, &outputs_[0][0], outputs_[0].size()));
    171 
    172     inputs_.resize(max_probe_packets);
    173     mock_reads_.clear();
    174     for (uint32 i = 0; i < max_probe_packets; ++i) {
    175       // Add a probe reply.
    176       probe_packet = ProbePacket();  // Clear all content.
    177       probe_message.SetPacketHeader(ProbePacket_Type_PROBE_REPLY,
    178                                     &probe_packet);
    179       int padding_size = probe_bytes - probe_packet.ByteSize() - 8;
    180       probe_packet.mutable_padding()->append(
    181           std::string(std::max(0, padding_size), 0));
    182       probe_packet.mutable_header()->set_checksum(0);
    183       probe_packet.set_group_id(1);
    184       probe_packet.set_packet_index(i);
    185       inputs_[i] = probe_message.MakeEncodedPacket(probe_packet);
    186       mock_reads_.push_back(
    187           net::MockRead(io_mode, &inputs_[i][0], inputs_[i].size()));
    188     }
    189   }
    190 
    191   // Test NetworkStats::StartOneTest(...) method.
    192   void TestStartOneTest(bool has_proxy,
    193                         NetworkStats::TestType test_type,
    194                         uint32 bytes,
    195                         uint32 interval_micros,
    196                         uint32 max_probe_packets,
    197                         net::IoMode io_mode) {
    198 
    199     net::MockClientSocketFactory mock_socket_factory;
    200     MakeDelayedMockData(
    201         test_type, bytes, interval_micros, max_probe_packets, io_mode);
    202     net::DelayedSocketData test_data(1,
    203                                      &mock_reads_[0],
    204                                      mock_reads_.size(),
    205                                      &mock_writes_[0],
    206                                      mock_writes_.size());
    207     mock_socket_factory.AddSocketDataProvider(&test_data);
    208     NetworkStats* udp_stats_client = new NetworkStats(&mock_socket_factory);
    209     udp_stats_client->maximum_tests_ = 1;  // Only do one probe at a time.
    210     udp_stats_client->maximum_sequential_packets_ = max_probe_packets;
    211     udp_stats_client->maximum_NAT_packets_ = max_probe_packets;
    212     // For NAT_BIND_TEST, we always set this to 1 (second) to avoid the
    213     // randomness in NetworkStats::SendProbeRequest().
    214     udp_stats_client->maximum_NAT_idle_seconds_ = 1;
    215     udp_stats_client->start_test_after_connect_ = false;
    216     udp_stats_client->inter_arrival_time_ =
    217         base::TimeDelta::FromMicroseconds(interval_micros);
    218     CreateToken(2L, "2a2b", &udp_stats_client->token_);
    219 
    220     net::TestCompletionCallback cb;
    221     scoped_ptr<net::MockHostResolver> host_resolver(
    222         new net::MockHostResolver());
    223     net::HostPortPair host_port_pair;
    224     EXPECT_TRUE(udp_stats_client->Start(host_resolver.get(),
    225                                         host_port_pair,
    226                                         9999,
    227                                         has_proxy,
    228                                         bytes,
    229                                         bytes,
    230                                         cb.callback()));
    231     // Test need to be added after Start() because Start() will reset
    232     // test_sequence_
    233     udp_stats_client->test_sequence_.push_back(test_type);
    234     udp_stats_client->current_test_index_ = 1;
    235     // Wait for host resolving and check if there were no errors during
    236     // connect/write/read to UDP server.
    237     int rv = cb.WaitForResult();
    238     EXPECT_EQ(0, rv);
    239     udp_stats_client->ReadData();
    240     udp_stats_client->StartOneTest();
    241     rv = cb.WaitForResult();
    242     EXPECT_EQ(0, rv);
    243   }
    244 
    245   base::MessageLoopForIO message_loop_;
    246   std::vector<std::string> inputs_;
    247   std::vector<std::string> outputs_;
    248   std::vector<net::MockRead> mock_reads_;
    249   std::vector<net::MockWrite> mock_writes_;
    250 };
    251 
    252 TEST_F(NetworkStatsTest, ProbeTest100BHasProxyGetToken) {
    253   TestStart(true, 0, 1, 100, net::ASYNC);
    254 }
    255 
    256 TEST_F(NetworkStatsTest, ProbeTest500BHasNoProxyGetTokenSync) {
    257   TestStart(false, 0, 1, 500, net::SYNCHRONOUS);
    258 }
    259 
    260 TEST_F(NetworkStatsTest, ProbeTest100BHasNoProxyOneTest) {
    261   TestStart(false, 1, 1, 100, net::ASYNC);
    262 }
    263 
    264 TEST_F(NetworkStatsTest, ProbeTest100BHasNoProxyOneTestSync) {
    265   TestStart(false, 1, 1, 100, net::SYNCHRONOUS);
    266 }
    267 
    268 TEST_F(NetworkStatsTest, ProbeTest100BHasProxyOneTest) {
    269   TestStart(true, 1, 1, 100, net::ASYNC);
    270 }
    271 
    272 TEST_F(NetworkStatsTest, ProbeTest100BHasProxyOneTestSync) {
    273   TestStart(true, 1, 1, 100, net::SYNCHRONOUS);
    274 }
    275 
    276 TEST_F(NetworkStatsTest, ProbeTest500BHasProxyOneTest) {
    277   TestStart(true, 1, 1, 500, net::ASYNC);
    278 }
    279 
    280 TEST_F(NetworkStatsTest, ProbeTest500BHasNoProxyOneTestSync) {
    281   TestStart(false, 1, 1, 500, net::SYNCHRONOUS);
    282 }
    283 
    284 TEST_F(NetworkStatsTest, ProbeTest500BHasNoProxyOneTest) {
    285   TestStart(false, 1, 1, 500, net::ASYNC);
    286 }
    287 
    288 TEST_F(NetworkStatsTest, ProbeTest500BHasProxyOneTestSync) {
    289   TestStart(true, 1, 1, 500, net::SYNCHRONOUS);
    290 }
    291 
    292 TEST_F(NetworkStatsTest, ProbeTest1200BHasProxyOneTest) {
    293   TestStart(true, 1, 1, 1200, net::ASYNC);
    294 }
    295 
    296 TEST_F(NetworkStatsTest, ProbeTest1200BHasNoProxyOneTestSync) {
    297   TestStart(false, 1, 1, 1200, net::SYNCHRONOUS);
    298 }
    299 
    300 TEST_F(NetworkStatsTest, ProbeTest1200BHasNoProxyOneTest) {
    301   TestStart(false, 1, 1, 1200, net::ASYNC);
    302 }
    303 
    304 TEST_F(NetworkStatsTest, ProbeTest1200BHasProxyOneTestSync) {
    305   TestStart(true, 1, 1, 1200, net::SYNCHRONOUS);
    306 }
    307 
    308 TEST_F(NetworkStatsTest, ProbeTest100BHasNoProxyOneTestMultiPackets) {
    309   TestStart(false, 1, 4, 100, net::ASYNC);
    310 }
    311 
    312 TEST_F(NetworkStatsTest, ProbeTest1200BHasProxyOneTestMultiPacketsSync) {
    313   TestStart(true, 1, 4, 1200, net::SYNCHRONOUS);
    314 }
    315 
    316 TEST_F(NetworkStatsTest, StartNonPacedTest100BHasProxy) {
    317   TestStartOneTest(
    318       true, NetworkStats::NON_PACED_PACKET_TEST, 100, 0, 1, net::ASYNC);
    319 }
    320 
    321 TEST_F(NetworkStatsTest, StartNonPacedTest100BHasNoProxySync) {
    322   TestStartOneTest(
    323       false, NetworkStats::NON_PACED_PACKET_TEST, 100, 0, 1, net::SYNCHRONOUS);
    324 }
    325 
    326 TEST_F(NetworkStatsTest, StartNonPacedTest500BHasNoProxy) {
    327   TestStartOneTest(
    328       false, NetworkStats::NON_PACED_PACKET_TEST, 500, 3, 1, net::ASYNC);
    329 }
    330 
    331 TEST_F(NetworkStatsTest, StartNonPacedTest1200BHasProxySync) {
    332   TestStartOneTest(
    333       true, NetworkStats::NON_PACED_PACKET_TEST, 1200, 1, 1, net::SYNCHRONOUS);
    334 }
    335 
    336 TEST_F(NetworkStatsTest, StartNonPacedTest500BHasNoProxyMulti) {
    337   TestStartOneTest(
    338       false, NetworkStats::NON_PACED_PACKET_TEST, 500, 2, 3, net::ASYNC);
    339 }
    340 
    341 TEST_F(NetworkStatsTest, StartNonPacedTest1200BHasProxySyncMulti) {
    342   TestStartOneTest(
    343       true, NetworkStats::NON_PACED_PACKET_TEST, 1200, 1, 4, net::SYNCHRONOUS);
    344 }
    345 
    346 TEST_F(NetworkStatsTest, StartPacedTest100BHasProxy) {
    347   TestStartOneTest(
    348       true, NetworkStats::PACED_PACKET_TEST, 100, 0, 1, net::ASYNC);
    349 }
    350 
    351 TEST_F(NetworkStatsTest, StartPacedTest100BHasNoProxySync) {
    352   TestStartOneTest(
    353       false, NetworkStats::PACED_PACKET_TEST, 100, 0, 1, net::SYNCHRONOUS);
    354 }
    355 
    356 TEST_F(NetworkStatsTest, StartPacedTest500BHasNoProxy) {
    357   TestStartOneTest(
    358       false, NetworkStats::PACED_PACKET_TEST, 500, 3, 1, net::ASYNC);
    359 }
    360 
    361 TEST_F(NetworkStatsTest, StartPacedTest1200BHasProxySync) {
    362   TestStartOneTest(
    363       true, NetworkStats::PACED_PACKET_TEST, 1200, 1, 1, net::SYNCHRONOUS);
    364 }
    365 
    366 TEST_F(NetworkStatsTest, StartPacedTest500BHasNoProxyMulti) {
    367   TestStartOneTest(
    368       false, NetworkStats::PACED_PACKET_TEST, 500, 2, 3, net::ASYNC);
    369 }
    370 
    371 TEST_F(NetworkStatsTest, StartPacedTest1200BHasProxySyncMulti) {
    372   TestStartOneTest(
    373       true, NetworkStats::PACED_PACKET_TEST, 1200, 1, 4, net::SYNCHRONOUS);
    374 }
    375 
    376 TEST_F(NetworkStatsTest, StartNATBindTest100BHasProxy) {
    377   TestStartOneTest(true, NetworkStats::NAT_BIND_TEST, 100, 0, 1, net::ASYNC);
    378 }
    379 
    380 TEST_F(NetworkStatsTest, StartNATBindTest100BHasNoProxySync) {
    381   TestStartOneTest(
    382       false, NetworkStats::NAT_BIND_TEST, 100, 3, 1, net::SYNCHRONOUS);
    383 }
    384 
    385 TEST_F(NetworkStatsTest, StartNATBindTest500BHasNoProxy) {
    386   TestStartOneTest(false, NetworkStats::NAT_BIND_TEST, 500, 0, 2, net::ASYNC);
    387 }
    388 
    389 TEST_F(NetworkStatsTest, StartNATBindTest1200BHasProxySync) {
    390   TestStartOneTest(
    391       true, NetworkStats::NAT_BIND_TEST, 1200, 3, 2, net::SYNCHRONOUS);
    392 }
    393 
    394 TEST_F(NetworkStatsTest, StartPacketSizeTest1500BHasProxy) {
    395   TestStartOneTest(
    396       true, NetworkStats::PACKET_SIZE_TEST, 1500, 0, 1, net::ASYNC);
    397 }
    398 
    399 TEST_F(NetworkStatsTest, StartPacketSizeTest1500HasNoProxySync) {
    400   TestStartOneTest(
    401       false, NetworkStats::PACKET_SIZE_TEST, 1500, 0, 1, net::SYNCHRONOUS);
    402 }
    403 
    404 TEST_F(NetworkStatsTest, StartPacketSizeTest1500BHasNoProxy) {
    405   TestStartOneTest(
    406       false, NetworkStats::PACKET_SIZE_TEST, 1500, 0, 1, net::ASYNC);
    407 }
    408 
    409 }  // namespace chrome_browser_net
    410