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