| OLD | NEW |
| (Empty) |
| 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 using std::string; | |
| 18 | |
| 19 namespace chrome_browser_net { | |
| 20 | |
| 21 class NetworkStatsTest : public PlatformTest { | |
| 22 public: | |
| 23 NetworkStatsTest() {} | |
| 24 | |
| 25 protected: | |
| 26 void SetUp() override { | |
| 27 net::NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); | |
| 28 base::MessageLoop::current()->RunUntilIdle(); | |
| 29 mock_writes_.clear(); | |
| 30 mock_reads_.clear(); | |
| 31 } | |
| 32 | |
| 33 void TearDown() override { | |
| 34 net::NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); | |
| 35 // Empty the current queue. | |
| 36 base::MessageLoop::current()->RunUntilIdle(); | |
| 37 PlatformTest::TearDown(); | |
| 38 } | |
| 39 | |
| 40 void CreateToken(uint64 timestamp_micros, | |
| 41 const string& hash, | |
| 42 ProbePacket_Token* token) { | |
| 43 token->set_timestamp_micros(timestamp_micros); | |
| 44 token->mutable_hash()->assign(hash); | |
| 45 } | |
| 46 | |
| 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, | |
| 52 uint32 probe_bytes, | |
| 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); | |
| 56 outputs_.resize(10); | |
| 57 ProbePacket probe_packet; | |
| 58 ProbeMessage probe_message; | |
| 59 probe_message.SetPacketHeader(ProbePacket_Type_HELLO_REQUEST, | |
| 60 &probe_packet); | |
| 61 probe_packet.set_group_id(0); | |
| 62 outputs_[0] = probe_message.MakeEncodedPacket(probe_packet); | |
| 63 mock_writes_.clear(); | |
| 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)); | |
| 75 | |
| 76 inputs_.resize(10); | |
| 77 mock_reads_.clear(); | |
| 78 // Add a hello reply. | |
| 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)); | |
| 86 | |
| 87 for (uint32 i = 0; i < max_probe_packets; ++i) { | |
| 88 // Add a probe reply. | |
| 89 probe_packet = ProbePacket(); // Clear all content. | |
| 90 probe_message.SetPacketHeader(ProbePacket_Type_PROBE_REPLY, | |
| 91 &probe_packet); | |
| 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)); | |
| 101 } | |
| 102 } | |
| 103 | |
| 104 // Test NetworkStats::Start(...) method. | |
| 105 void TestStart(bool has_proxy, | |
| 106 uint32 max_tests, | |
| 107 uint32 max_probe_packets, | |
| 108 uint32 bytes, | |
| 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; | |
| 119 | |
| 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(), | |
| 125 host_port_pair, | |
| 126 9999, | |
| 127 has_proxy, | |
| 128 bytes, | |
| 129 bytes, | |
| 130 cb.callback())); | |
| 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. | |
| 135 EXPECT_EQ(0, rv); | |
| 136 } | |
| 137 | |
| 138 // Make one write and then |max_probe_packets| reads. | |
| 139 void MakeDelayedMockData(NetworkStats::TestType test_type, | |
| 140 uint32 probe_bytes, | |
| 141 uint32 pacing_interval_micros, | |
| 142 uint32 max_probe_packets, | |
| 143 net::IoMode io_mode) { | |
| 144 outputs_.resize(1); | |
| 145 ProbePacket probe_packet; | |
| 146 ProbeMessage probe_message; | |
| 147 mock_writes_.clear(); | |
| 148 ProbePacket_Token token; | |
| 149 CreateToken(2L, "2a2b", &token); | |
| 150 switch (test_type) { | |
| 151 case NetworkStats::PACKET_SIZE_TEST: | |
| 152 case NetworkStats::NON_PACED_PACKET_TEST: | |
| 153 pacing_interval_micros = 0; | |
| 154 break; | |
| 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; | |
| 160 break; | |
| 161 default: {} // Do nothing here. | |
| 162 } | |
| 163 probe_message.GenerateProbeRequest(token, | |
| 164 1, // current_test_index_ = 1. | |
| 165 probe_bytes, | |
| 166 pacing_interval_micros, | |
| 167 max_probe_packets, | |
| 168 &probe_packet); | |
| 169 outputs_[0] = probe_message.MakeEncodedPacket(probe_packet); | |
| 170 mock_writes_.push_back( | |
| 171 net::MockWrite(io_mode, &outputs_[0][0], outputs_[0].size())); | |
| 172 | |
| 173 inputs_.resize(max_probe_packets); | |
| 174 mock_reads_.clear(); | |
| 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, | |
| 179 &probe_packet); | |
| 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())); | |
| 189 } | |
| 190 } | |
| 191 | |
| 192 // Test NetworkStats::StartOneTest(...) method. | |
| 193 void TestStartOneTest(bool has_proxy, | |
| 194 NetworkStats::TestType test_type, | |
| 195 uint32 bytes, | |
| 196 uint32 interval_micros, | |
| 197 uint32 max_probe_packets, | |
| 198 net::IoMode io_mode) { | |
| 199 | |
| 200 net::MockClientSocketFactory mock_socket_factory; | |
| 201 MakeDelayedMockData( | |
| 202 test_type, bytes, interval_micros, max_probe_packets, io_mode); | |
| 203 net::DelayedSocketData test_data(1, | |
| 204 &mock_reads_[0], | |
| 205 mock_reads_.size(), | |
| 206 &mock_writes_[0], | |
| 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_); | |
| 220 | |
| 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(), | |
| 226 host_port_pair, | |
| 227 9999, | |
| 228 has_proxy, | |
| 229 bytes, | |
| 230 bytes, | |
| 231 cb.callback())); | |
| 232 // Test need to be added after Start() because Start() will reset | |
| 233 // test_sequence_ | |
| 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(); | |
| 239 EXPECT_EQ(0, rv); | |
| 240 udp_stats_client->ReadData(); | |
| 241 udp_stats_client->StartOneTest(); | |
| 242 rv = cb.WaitForResult(); | |
| 243 EXPECT_EQ(0, rv); | |
| 244 } | |
| 245 | |
| 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_; | |
| 251 }; | |
| 252 | |
| 253 TEST_F(NetworkStatsTest, ProbeTest100BHasProxyGetToken) { | |
| 254 TestStart(true, 0, 1, 100, net::ASYNC); | |
| 255 } | |
| 256 | |
| 257 TEST_F(NetworkStatsTest, ProbeTest500BHasNoProxyGetTokenSync) { | |
| 258 TestStart(false, 0, 1, 500, net::SYNCHRONOUS); | |
| 259 } | |
| 260 | |
| 261 TEST_F(NetworkStatsTest, ProbeTest100BHasNoProxyOneTest) { | |
| 262 TestStart(false, 1, 1, 100, net::ASYNC); | |
| 263 } | |
| 264 | |
| 265 TEST_F(NetworkStatsTest, ProbeTest100BHasNoProxyOneTestSync) { | |
| 266 TestStart(false, 1, 1, 100, net::SYNCHRONOUS); | |
| 267 } | |
| 268 | |
| 269 TEST_F(NetworkStatsTest, ProbeTest100BHasProxyOneTest) { | |
| 270 TestStart(true, 1, 1, 100, net::ASYNC); | |
| 271 } | |
| 272 | |
| 273 TEST_F(NetworkStatsTest, ProbeTest100BHasProxyOneTestSync) { | |
| 274 TestStart(true, 1, 1, 100, net::SYNCHRONOUS); | |
| 275 } | |
| 276 | |
| 277 TEST_F(NetworkStatsTest, ProbeTest500BHasProxyOneTest) { | |
| 278 TestStart(true, 1, 1, 500, net::ASYNC); | |
| 279 } | |
| 280 | |
| 281 TEST_F(NetworkStatsTest, ProbeTest500BHasNoProxyOneTestSync) { | |
| 282 TestStart(false, 1, 1, 500, net::SYNCHRONOUS); | |
| 283 } | |
| 284 | |
| 285 TEST_F(NetworkStatsTest, ProbeTest500BHasNoProxyOneTest) { | |
| 286 TestStart(false, 1, 1, 500, net::ASYNC); | |
| 287 } | |
| 288 | |
| 289 TEST_F(NetworkStatsTest, ProbeTest500BHasProxyOneTestSync) { | |
| 290 TestStart(true, 1, 1, 500, net::SYNCHRONOUS); | |
| 291 } | |
| 292 | |
| 293 TEST_F(NetworkStatsTest, ProbeTest1200BHasProxyOneTest) { | |
| 294 TestStart(true, 1, 1, 1200, net::ASYNC); | |
| 295 } | |
| 296 | |
| 297 TEST_F(NetworkStatsTest, ProbeTest1200BHasNoProxyOneTestSync) { | |
| 298 TestStart(false, 1, 1, 1200, net::SYNCHRONOUS); | |
| 299 } | |
| 300 | |
| 301 TEST_F(NetworkStatsTest, ProbeTest1200BHasNoProxyOneTest) { | |
| 302 TestStart(false, 1, 1, 1200, net::ASYNC); | |
| 303 } | |
| 304 | |
| 305 TEST_F(NetworkStatsTest, ProbeTest1200BHasProxyOneTestSync) { | |
| 306 TestStart(true, 1, 1, 1200, net::SYNCHRONOUS); | |
| 307 } | |
| 308 | |
| 309 TEST_F(NetworkStatsTest, ProbeTest100BHasNoProxyOneTestMultiPackets) { | |
| 310 TestStart(false, 1, 4, 100, net::ASYNC); | |
| 311 } | |
| 312 | |
| 313 TEST_F(NetworkStatsTest, ProbeTest1200BHasProxyOneTestMultiPacketsSync) { | |
| 314 TestStart(true, 1, 4, 1200, net::SYNCHRONOUS); | |
| 315 } | |
| 316 | |
| 317 TEST_F(NetworkStatsTest, StartNonPacedTest100BHasProxy) { | |
| 318 TestStartOneTest( | |
| 319 true, NetworkStats::NON_PACED_PACKET_TEST, 100, 0, 1, net::ASYNC); | |
| 320 } | |
| 321 | |
| 322 TEST_F(NetworkStatsTest, StartNonPacedTest100BHasNoProxySync) { | |
| 323 TestStartOneTest( | |
| 324 false, NetworkStats::NON_PACED_PACKET_TEST, 100, 0, 1, net::SYNCHRONOUS); | |
| 325 } | |
| 326 | |
| 327 TEST_F(NetworkStatsTest, StartNonPacedTest500BHasNoProxy) { | |
| 328 TestStartOneTest( | |
| 329 false, NetworkStats::NON_PACED_PACKET_TEST, 500, 3, 1, net::ASYNC); | |
| 330 } | |
| 331 | |
| 332 TEST_F(NetworkStatsTest, StartNonPacedTest1200BHasProxySync) { | |
| 333 TestStartOneTest( | |
| 334 true, NetworkStats::NON_PACED_PACKET_TEST, 1200, 1, 1, net::SYNCHRONOUS); | |
| 335 } | |
| 336 | |
| 337 TEST_F(NetworkStatsTest, StartNonPacedTest500BHasNoProxyMulti) { | |
| 338 TestStartOneTest( | |
| 339 false, NetworkStats::NON_PACED_PACKET_TEST, 500, 2, 3, net::ASYNC); | |
| 340 } | |
| 341 | |
| 342 TEST_F(NetworkStatsTest, StartNonPacedTest1200BHasProxySyncMulti) { | |
| 343 TestStartOneTest( | |
| 344 true, NetworkStats::NON_PACED_PACKET_TEST, 1200, 1, 4, net::SYNCHRONOUS); | |
| 345 } | |
| 346 | |
| 347 TEST_F(NetworkStatsTest, StartPacedTest100BHasProxy) { | |
| 348 TestStartOneTest( | |
| 349 true, NetworkStats::PACED_PACKET_TEST, 100, 0, 1, net::ASYNC); | |
| 350 } | |
| 351 | |
| 352 TEST_F(NetworkStatsTest, StartPacedTest100BHasNoProxySync) { | |
| 353 TestStartOneTest( | |
| 354 false, NetworkStats::PACED_PACKET_TEST, 100, 0, 1, net::SYNCHRONOUS); | |
| 355 } | |
| 356 | |
| 357 TEST_F(NetworkStatsTest, StartPacedTest500BHasNoProxy) { | |
| 358 TestStartOneTest( | |
| 359 false, NetworkStats::PACED_PACKET_TEST, 500, 3, 1, net::ASYNC); | |
| 360 } | |
| 361 | |
| 362 TEST_F(NetworkStatsTest, StartPacedTest1200BHasProxySync) { | |
| 363 TestStartOneTest( | |
| 364 true, NetworkStats::PACED_PACKET_TEST, 1200, 1, 1, net::SYNCHRONOUS); | |
| 365 } | |
| 366 | |
| 367 TEST_F(NetworkStatsTest, StartPacedTest500BHasNoProxyMulti) { | |
| 368 TestStartOneTest( | |
| 369 false, NetworkStats::PACED_PACKET_TEST, 500, 2, 3, net::ASYNC); | |
| 370 } | |
| 371 | |
| 372 TEST_F(NetworkStatsTest, StartPacedTest1200BHasProxySyncMulti) { | |
| 373 TestStartOneTest( | |
| 374 true, NetworkStats::PACED_PACKET_TEST, 1200, 1, 4, net::SYNCHRONOUS); | |
| 375 } | |
| 376 | |
| 377 TEST_F(NetworkStatsTest, StartNATBindTest100BHasProxy) { | |
| 378 TestStartOneTest(true, NetworkStats::NAT_BIND_TEST, 100, 0, 1, net::ASYNC); | |
| 379 } | |
| 380 | |
| 381 TEST_F(NetworkStatsTest, StartNATBindTest100BHasNoProxySync) { | |
| 382 TestStartOneTest( | |
| 383 false, NetworkStats::NAT_BIND_TEST, 100, 3, 1, net::SYNCHRONOUS); | |
| 384 } | |
| 385 | |
| 386 TEST_F(NetworkStatsTest, StartNATBindTest500BHasNoProxy) { | |
| 387 TestStartOneTest(false, NetworkStats::NAT_BIND_TEST, 500, 0, 2, net::ASYNC); | |
| 388 } | |
| 389 | |
| 390 TEST_F(NetworkStatsTest, StartNATBindTest1200BHasProxySync) { | |
| 391 TestStartOneTest( | |
| 392 true, NetworkStats::NAT_BIND_TEST, 1200, 3, 2, net::SYNCHRONOUS); | |
| 393 } | |
| 394 | |
| 395 TEST_F(NetworkStatsTest, StartPacketSizeTest1500BHasProxy) { | |
| 396 TestStartOneTest( | |
| 397 true, NetworkStats::PACKET_SIZE_TEST, 1500, 0, 1, net::ASYNC); | |
| 398 } | |
| 399 | |
| 400 TEST_F(NetworkStatsTest, StartPacketSizeTest1500HasNoProxySync) { | |
| 401 TestStartOneTest( | |
| 402 false, NetworkStats::PACKET_SIZE_TEST, 1500, 0, 1, net::SYNCHRONOUS); | |
| 403 } | |
| 404 | |
| 405 TEST_F(NetworkStatsTest, StartPacketSizeTest1500BHasNoProxy) { | |
| 406 TestStartOneTest( | |
| 407 false, NetworkStats::PACKET_SIZE_TEST, 1500, 0, 1, net::ASYNC); | |
| 408 } | |
| 409 | |
| 410 } // namespace chrome_browser_net | |
| OLD | NEW |