blob: 5d9c1d44503826758266e563cc998b0e7f77c65a [file] [log] [blame]
Peter Qiuc0beca52015-09-03 11:25:46 -07001//
2// Copyright (C) 2015 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
Samuel Tan1b9546a2015-06-29 18:53:41 -070016
17#include "shill/connection_diagnostics.h"
18
19#include <net/if_arp.h>
20
21#include <gtest/gtest.h>
22
23#include "shill/arp_client.h"
24#include "shill/arp_client_test_helper.h"
25#include "shill/icmp_session.h"
26#include "shill/mock_arp_client.h"
27#include "shill/mock_connection.h"
28#include "shill/mock_control.h"
29#include "shill/mock_device_info.h"
30#include "shill/mock_dns_client.h"
31#include "shill/mock_dns_client_factory.h"
32#include "shill/mock_event_dispatcher.h"
33#include "shill/mock_icmp_session.h"
34#include "shill/mock_icmp_session_factory.h"
35#include "shill/mock_manager.h"
36#include "shill/mock_metrics.h"
37#include "shill/mock_portal_detector.h"
38#include "shill/mock_routing_table.h"
Samuel Tan56d3c662015-08-04 18:42:07 -070039#include "shill/net/mock_rtnl_handler.h"
Samuel Tan1b9546a2015-06-29 18:53:41 -070040
41using base::Bind;
42using base::Callback;
43using base::Unretained;
44using std::string;
45using std::vector;
46using testing::_;
47using testing::NiceMock;
48using testing::Return;
49using testing::ReturnRef;
50using testing::SetArgumentPointee;
51using testing::Test;
52
53namespace {
54const char kInterfaceName[] = "int0";
55const char kDNSServer0[] = "8.8.8.8";
56const char kDNSServer1[] = "8.8.4.4";
57const char kURL[] = "http://www.gstatic.com/generate_204";
58const char kLocalMacAddressASCIIString[] = "123456";
59const char kArpReplySenderMacAddressASCIIString[] = "345678";
60const char* kDNSServers[] = {kDNSServer0, kDNSServer1};
61const shill::IPAddress kIPv4LocalAddress("100.200.43.22");
Samuel Tand6c9ef62015-08-11 18:15:17 -070062const shill::IPAddress kIPv4ServerAddress("8.8.8.8");
63const shill::IPAddress kIPv6ServerAddress("fe80::1aa9:5ff:7ebf:14c5");
Samuel Tan1b9546a2015-06-29 18:53:41 -070064const shill::IPAddress kIPv4GatewayAddress("192.168.1.1");
65const shill::IPAddress kIPv6GatewayAddress("fee2::11b2:53f:13be:125e");
66const vector<base::TimeDelta> kEmptyResult;
67const vector<base::TimeDelta> kNonEmptyResult{
68 base::TimeDelta::FromMilliseconds(10)};
69} // namespace
70
71namespace shill {
72
73MATCHER_P(IsSameIPAddress, ip_addr, "") {
74 return arg.Equals(ip_addr);
75}
76
77MATCHER_P(IsEventList, expected_events, "") {
78 // Match on type, phase, and result, but not message.
79 if (arg.size() != expected_events.size()) {
80 return false;
81 }
82 for (size_t i = 0; i < expected_events.size(); ++i) {
83 if (expected_events[i].type != arg[i].type ||
84 expected_events[i].phase != arg[i].phase ||
85 expected_events[i].result != arg[i].result) {
86 *result_listener << "\n=== Mismatch found on expected event index " << i
87 << " ===";
88 *result_listener << "\nExpected: "
89 << ConnectionDiagnostics::EventToString(
90 expected_events[i]);
91 *result_listener << "\n Actual: "
92 << ConnectionDiagnostics::EventToString(arg[i]);
Samuel Tanf809b862015-09-01 17:24:16 -070093 *result_listener << "\nExpected connection diagnostics events:";
94 for (const auto& expected_event : expected_events) {
95 *result_listener << "\n" << ConnectionDiagnostics::EventToString(
96 expected_event);
97 }
98 *result_listener << "\nActual connection diagnostics events:";
99 for (const auto& actual_event : expected_events) {
100 *result_listener << "\n"
101 << ConnectionDiagnostics::EventToString(actual_event);
102 }
Samuel Tan1b9546a2015-06-29 18:53:41 -0700103 return false;
104 }
105 }
106 return true;
107}
108
109MATCHER_P4(IsArpRequest, local_ip, remote_ip, local_mac, remote_mac, "") {
110 if (local_ip.Equals(arg.local_ip_address()) &&
111 remote_ip.Equals(arg.remote_ip_address()) &&
112 local_mac.Equals(arg.local_mac_address()) &&
113 remote_mac.Equals(arg.remote_mac_address())) {
114 return true;
115 }
116
117 if (!local_ip.Equals(arg.local_ip_address())) {
118 *result_listener << "Local IP '" << arg.local_ip_address().ToString()
119 << "' (expected '" << local_ip.ToString() << "').";
120 }
121
122 if (!remote_ip.Equals(arg.remote_ip_address())) {
123 *result_listener << "Remote IP '" << arg.remote_ip_address().ToString()
124 << "' (expected '" << remote_ip.ToString() << "').";
125 }
126
127 if (!local_mac.Equals(arg.local_mac_address())) {
128 *result_listener << "Local MAC '" << arg.local_mac_address().HexEncode()
129 << "' (expected " << local_mac.HexEncode() << ")'.";
130 }
131
132 if (!remote_mac.Equals(arg.remote_mac_address())) {
133 *result_listener << "Remote MAC '" << arg.remote_mac_address().HexEncode()
134 << "' (expected " << remote_mac.HexEncode() << ")'.";
135 }
136
137 return false;
138}
139
140class ConnectionDiagnosticsTest : public Test {
141 public:
142 ConnectionDiagnosticsTest()
143 : interface_name_(kInterfaceName),
144 dns_servers_(kDNSServers, kDNSServers + 2),
145 local_ip_address_(kIPv4LocalAddress),
146 gateway_ipv4_address_(kIPv4GatewayAddress),
147 gateway_ipv6_address_(kIPv6GatewayAddress),
148 local_mac_address_(string(kLocalMacAddressASCIIString), false),
149 metrics_(&dispatcher_),
mukesh agrawalbad1c102015-09-18 16:15:08 -0700150 manager_(&control_, &dispatcher_, &metrics_),
Samuel Tan1b9546a2015-06-29 18:53:41 -0700151 device_info_(&control_, &dispatcher_, &metrics_, &manager_),
152 connection_(new NiceMock<MockConnection>(&device_info_)),
Samuel Tand1c71662015-08-14 15:11:38 -0700153 connection_diagnostics_(connection_, &dispatcher_, &metrics_,
154 &device_info_,
Samuel Tan1b9546a2015-06-29 18:53:41 -0700155 callback_target_.result_callback()),
156 portal_detector_(new NiceMock<MockPortalDetector>(connection_)) {}
157 virtual ~ConnectionDiagnosticsTest() {}
158
159 virtual void SetUp() {
160 ASSERT_EQ(IPAddress::kFamilyIPv4, kIPv4LocalAddress.family());
Samuel Tand6c9ef62015-08-11 18:15:17 -0700161 ASSERT_EQ(IPAddress::kFamilyIPv4, kIPv4ServerAddress.family());
Samuel Tan1b9546a2015-06-29 18:53:41 -0700162 ASSERT_EQ(IPAddress::kFamilyIPv4, kIPv4GatewayAddress.family());
Samuel Tand6c9ef62015-08-11 18:15:17 -0700163 ASSERT_EQ(IPAddress::kFamilyIPv6, kIPv6ServerAddress.family());
Samuel Tan1b9546a2015-06-29 18:53:41 -0700164 ASSERT_EQ(IPAddress::kFamilyIPv6, kIPv6GatewayAddress.family());
165
166 arp_client_ = new NiceMock<MockArpClient>();
167 client_test_helper_.reset(new ArpClientTestHelper(arp_client_));
168 icmp_session_ = new NiceMock<MockIcmpSession>(&dispatcher_);
169 connection_diagnostics_.arp_client_.reset(arp_client_); // Passes ownership
170 connection_diagnostics_.icmp_session_.reset(
171 icmp_session_); // Passes ownership
172 connection_diagnostics_.portal_detector_.reset(
173 portal_detector_); // Passes ownership
174 connection_diagnostics_.routing_table_ = &routing_table_;
Samuel Tan56d3c662015-08-04 18:42:07 -0700175 connection_diagnostics_.rtnl_handler_ = &rtnl_handler_;
Samuel Tan1b9546a2015-06-29 18:53:41 -0700176 ON_CALL(*connection_.get(), interface_name())
177 .WillByDefault(ReturnRef(interface_name_));
178 ON_CALL(*connection_.get(), dns_servers())
179 .WillByDefault(ReturnRef(dns_servers_));
180 ON_CALL(*connection_.get(), gateway())
181 .WillByDefault(ReturnRef(gateway_ipv4_address_));
182 ON_CALL(*connection_.get(), local())
183 .WillByDefault(ReturnRef(local_ip_address_));
184 connection_diagnostics_.dns_client_factory_ =
185 MockDNSClientFactory::GetInstance();
186 connection_diagnostics_.icmp_session_factory_ =
187 MockIcmpSessionFactory::GetInstance();
188 }
189
190 virtual void TearDown() {}
191
192 protected:
193 class CallbackTarget {
194 public:
195 CallbackTarget()
196 : result_callback_(
197 Bind(&CallbackTarget::ResultCallback, Unretained(this))) {}
198
199 MOCK_METHOD2(ResultCallback,
200 void(const string&,
201 const vector<ConnectionDiagnostics::Event>&));
202
203 Callback<void(const string&, const vector<ConnectionDiagnostics::Event>&)>&
204 result_callback() {
205 return result_callback_;
206 }
207
208 private:
209 Callback<void(const string&, const vector<ConnectionDiagnostics::Event>&)>
210 result_callback_;
211 };
212
213 CallbackTarget& callback_target() {
214 return callback_target_;
215 }
216
217 void UseIPv6Gateway() {
218 EXPECT_CALL(*connection_.get(), gateway())
219 .WillRepeatedly(ReturnRef(gateway_ipv6_address_));
220 }
221
222 void AddExpectedEvent(ConnectionDiagnostics::Type type,
223 ConnectionDiagnostics::Phase phase,
224 ConnectionDiagnostics::Result result) {
225 expected_events_.push_back(
226 ConnectionDiagnostics::Event(type, phase, result, ""));
227 }
228
229 void AddActualEvent(ConnectionDiagnostics::Type type,
230 ConnectionDiagnostics::Phase phase,
231 ConnectionDiagnostics::Result result) {
232 connection_diagnostics_.diagnostic_events_.push_back(
233 ConnectionDiagnostics::Event(type, phase, result, ""));
234 }
235
236 bool DoesPreviousEventMatch(ConnectionDiagnostics::Type type,
237 ConnectionDiagnostics::Phase phase,
238 ConnectionDiagnostics::Result result,
239 size_t num_events_ago) {
240 return connection_diagnostics_.DoesPreviousEventMatch(type, phase, result,
241 num_events_ago);
242 }
243
244 // This direct call to ConnectionDiagnostics::Start does not mock the
245 // return
246 // value of MockPortalDetector::CreatePortalDetector, so this will crash
247 // the
248 // test if PortalDetector::Start is actually called. Use only for testing
249 // bad input to ConnectionDiagnostics::Start.
250 bool Start(const string& url_string) {
251 return connection_diagnostics_.Start(url_string);
252 }
253
254 void VerifyStopped() {
255 EXPECT_FALSE(connection_diagnostics_.running());
256 EXPECT_EQ(0, connection_diagnostics_.num_dns_attempts_);
257 EXPECT_TRUE(connection_diagnostics_.diagnostic_events_.empty());
258 EXPECT_FALSE(connection_diagnostics_.dns_client_.get());
259 EXPECT_FALSE(connection_diagnostics_.arp_client_->IsStarted());
260 EXPECT_FALSE(connection_diagnostics_.icmp_session_->IsStarted());
261 EXPECT_FALSE(connection_diagnostics_.portal_detector_.get());
262 EXPECT_FALSE(connection_diagnostics_.receive_response_handler_.get());
Samuel Tan56d3c662015-08-04 18:42:07 -0700263 EXPECT_FALSE(connection_diagnostics_.neighbor_msg_listener_.get());
Samuel Tan1b9546a2015-06-29 18:53:41 -0700264 EXPECT_TRUE(
265 connection_diagnostics_.id_to_pending_dns_server_icmp_session_.empty());
266 EXPECT_FALSE(connection_diagnostics_.target_url_.get());
267 EXPECT_TRUE(connection_diagnostics_.route_query_callback_.IsCancelled());
268 EXPECT_TRUE(
269 connection_diagnostics_.route_query_timeout_callback_.IsCancelled());
270 EXPECT_TRUE(
271 connection_diagnostics_.arp_reply_timeout_callback_.IsCancelled());
Samuel Tan56d3c662015-08-04 18:42:07 -0700272 EXPECT_TRUE(connection_diagnostics_.neighbor_request_timeout_callback_
273 .IsCancelled());
Samuel Tan1b9546a2015-06-29 18:53:41 -0700274 }
275
276 void ExpectIcmpSessionStop() {
277 EXPECT_CALL(*icmp_session_, Stop());
278 }
279
280 void ExpectPortalDetectionStartSuccess(const string& url_string) {
281 AddExpectedEvent(ConnectionDiagnostics::kTypePortalDetection,
282 ConnectionDiagnostics::kPhaseStart,
283 ConnectionDiagnostics::kResultSuccess);
284 EXPECT_CALL(*portal_detector_, Start(url_string)).WillOnce(Return(true));
285 EXPECT_FALSE(connection_diagnostics_.running());
286 EXPECT_TRUE(connection_diagnostics_.diagnostic_events_.empty());
287 EXPECT_TRUE(Start(url_string));
288 EXPECT_TRUE(connection_diagnostics_.running());
289 }
290
291 void ExpectPortalDetectionEndContentPhaseSuccess() {
292 ExpectPortalDetectionEnd(
293 ConnectionDiagnostics::kPhasePortalDetectionEndContent,
294 ConnectionDiagnostics::kResultSuccess,
295 ConnectivityTrial::kPhaseContent,
296 ConnectivityTrial::kStatusSuccess);
297 }
298
299 void ExpectPortalDetectionEndContentPhaseFailure() {
300 ExpectPortalDetectionEnd(
301 ConnectionDiagnostics::kPhasePortalDetectionEndContent,
302 ConnectionDiagnostics::kResultFailure,
303 ConnectivityTrial::kPhaseContent,
304 ConnectivityTrial::kStatusFailure);
305 }
306
307 void ExpectPortalDetectionEndDNSPhaseFailure() {
308 ExpectPortalDetectionEnd(ConnectionDiagnostics::kPhasePortalDetectionEndDNS,
309 ConnectionDiagnostics::kResultFailure,
310 ConnectivityTrial::kPhaseDNS,
311 ConnectivityTrial::kStatusFailure);
312 }
313
314 void ExpectPortalDetectionEndDNSPhaseTimeout() {
315 ExpectPortalDetectionEnd(ConnectionDiagnostics::kPhasePortalDetectionEndDNS,
316 ConnectionDiagnostics::kResultTimeout,
317 ConnectivityTrial::kPhaseDNS,
318 ConnectivityTrial::kStatusTimeout);
319 }
320
321 void ExpectPortalDetectionEndHTTPPhaseFailure() {
322 ExpectPortalDetectionEnd(
323 ConnectionDiagnostics::kPhasePortalDetectionEndOther,
324 ConnectionDiagnostics::kResultFailure,
325 ConnectivityTrial::kPhaseHTTP,
326 ConnectivityTrial::kStatusFailure);
327 }
328
329 void ExpectPingDNSServersStartSuccess() {
330 ExpectPingDNSSeversStart(true, "");
331 }
332
333 void ExpectPingDNSSeversStartFailureAllAddressesInvalid() {
334 ExpectPingDNSSeversStart(false,
335 ConnectionDiagnostics::kIssueDNSServersInvalid);
336 }
337
338 void ExpectPingDNSSeversStartFailureAllIcmpSessionsFailed() {
339 ExpectPingDNSSeversStart(false, ConnectionDiagnostics::kIssueInternalError);
340 }
341
342 void ExpectPingDNSServersEndSuccessRetriesLeft() {
343 ExpectPingDNSServersEndSuccess(true);
344 }
345
346 void ExpectPingDNSServersEndSuccessNoRetriesLeft() {
347 ExpectPingDNSServersEndSuccess(false);
348 }
349
350 void ExpectPingDNSServersEndFailure() {
351 AddExpectedEvent(ConnectionDiagnostics::kTypePingDNSServers,
352 ConnectionDiagnostics::kPhaseEnd,
353 ConnectionDiagnostics::kResultFailure);
354 // Post task to find DNS server route only after all (i.e. 2) pings are
355 // done.
356 connection_diagnostics_.OnPingDNSServerComplete(0, kEmptyResult);
357 EXPECT_CALL(dispatcher_, PostTask(_));
358 connection_diagnostics_.OnPingDNSServerComplete(1, kEmptyResult);
359 }
360
361 void ExpectResolveTargetServerIPAddressStartSuccess(
362 IPAddress::Family family) {
363 AddExpectedEvent(ConnectionDiagnostics::kTypeResolveTargetServerIP,
364 ConnectionDiagnostics::kPhaseStart,
365 ConnectionDiagnostics::kResultSuccess);
366 ASSERT_FALSE(family == IPAddress::kFamilyUnknown);
367
368 dns_client_ = new NiceMock<MockDNSClient>();
369 EXPECT_CALL(*connection_.get(), IsIPv6())
370 .WillOnce(Return(family == IPAddress::kFamilyIPv6));
371 EXPECT_CALL(
372 *MockDNSClientFactory::GetInstance(),
373 CreateDNSClient(family, kInterfaceName, dns_servers_,
374 ConnectionDiagnostics::kDNSTimeoutSeconds * 1000,
375 &dispatcher_, _))
376 .WillOnce(Return(dns_client_)); // Passes ownership
377 EXPECT_CALL(*dns_client_,
378 Start(connection_diagnostics_.target_url_->host(), _))
379 .WillOnce(Return(true));
380 connection_diagnostics_.ResolveTargetServerIPAddress(dns_servers_);
381 }
382
383 void ExpectResolveTargetServerIPAddressEndSuccess(
384 const IPAddress& resolved_address) {
385 ExpectResolveTargetServerIPAddressEnd(ConnectionDiagnostics::kResultSuccess,
386 resolved_address);
387 }
388
389 void ExpectResolveTargetServerIPAddressEndTimeout() {
390 ExpectResolveTargetServerIPAddressEnd(ConnectionDiagnostics::kResultTimeout,
391 IPAddress(IPAddress::kFamilyIPv4));
392 }
393
394 void ExpectResolveTargetServerIPAddressEndFailure() {
395 ExpectResolveTargetServerIPAddressEnd(ConnectionDiagnostics::kResultFailure,
396 IPAddress(IPAddress::kFamilyIPv4));
397 }
398
399 void ExpectPingHostStartSuccess(ConnectionDiagnostics::Type ping_event_type,
400 const IPAddress& address) {
401 AddExpectedEvent(ping_event_type, ConnectionDiagnostics::kPhaseStart,
402 ConnectionDiagnostics::kResultSuccess);
403 EXPECT_CALL(*icmp_session_, Start(IsSameIPAddress(address), _))
404 .WillOnce(Return(true));
405 connection_diagnostics_.PingHost(address);
406 }
407
408 void ExpectPingHostStartFailure(ConnectionDiagnostics::Type ping_event_type,
409 const IPAddress& address) {
410 AddExpectedEvent(ping_event_type, ConnectionDiagnostics::kPhaseStart,
411 ConnectionDiagnostics::kResultFailure);
412 EXPECT_CALL(*icmp_session_, Start(IsSameIPAddress(address), _))
413 .WillOnce(Return(false));
Samuel Tand1c71662015-08-14 15:11:38 -0700414 EXPECT_CALL(metrics_, NotifyConnectionDiagnosticsIssue(
415 ConnectionDiagnostics::kIssueInternalError));
Samuel Tan1b9546a2015-06-29 18:53:41 -0700416 EXPECT_CALL(callback_target(),
417 ResultCallback(ConnectionDiagnostics::kIssueInternalError,
418 IsEventList(expected_events_)));
419 connection_diagnostics_.PingHost(address);
420 }
421
422 void ExpectPingHostEndSuccess(ConnectionDiagnostics::Type ping_event_type,
423 const IPAddress& address) {
424 AddExpectedEvent(ping_event_type, ConnectionDiagnostics::kPhaseEnd,
425 ConnectionDiagnostics::kResultSuccess);
Samuel Tand1c71662015-08-14 15:11:38 -0700426 const string& issue =
427 ping_event_type == ConnectionDiagnostics::kTypePingGateway
428 ? ConnectionDiagnostics::kIssueGatewayUpstream
429 : ConnectionDiagnostics::kIssueHTTPBrokenPortal;
430 EXPECT_CALL(metrics_, NotifyConnectionDiagnosticsIssue(issue));
Samuel Tan1b9546a2015-06-29 18:53:41 -0700431 EXPECT_CALL(callback_target(),
Samuel Tand1c71662015-08-14 15:11:38 -0700432 ResultCallback(issue, IsEventList(expected_events_)));
Samuel Tan1b9546a2015-06-29 18:53:41 -0700433 connection_diagnostics_.OnPingHostComplete(ping_event_type, address,
434 kNonEmptyResult);
435 }
436
437 void ExpectPingHostEndFailure(ConnectionDiagnostics::Type ping_event_type,
438 const IPAddress& address) {
439 AddExpectedEvent(ping_event_type, ConnectionDiagnostics::kPhaseEnd,
440 ConnectionDiagnostics::kResultFailure);
Samuel Tan56d3c662015-08-04 18:42:07 -0700441 // Next action is either to find a route to the target web server, find an
442 // ARP entry for the IPv4 gateway, or find a neighbor table entry for the
443 // IPv6 gateway.
444 EXPECT_CALL(dispatcher_, PostTask(_));
Samuel Tan1b9546a2015-06-29 18:53:41 -0700445 connection_diagnostics_.OnPingHostComplete(ping_event_type, address,
446 kEmptyResult);
447 }
448
449 void ExpectFindRouteToHostStartSuccess(const IPAddress& address) {
450 AddExpectedEvent(ConnectionDiagnostics::kTypeFindRoute,
451 ConnectionDiagnostics::kPhaseStart,
452 ConnectionDiagnostics::kResultSuccess);
453 EXPECT_CALL(routing_table_,
454 RequestRouteToHost(IsSameIPAddress(address),
455 connection_->interface_index(), _, _,
456 connection_->table_id()))
457 .WillOnce(Return(true));
458 EXPECT_CALL(
459 dispatcher_,
460 PostDelayedTask(
461 _, ConnectionDiagnostics::kRouteQueryTimeoutSeconds * 1000));
462 connection_diagnostics_.FindRouteToHost(address);
463 EXPECT_FALSE(
464 connection_diagnostics_.route_query_timeout_callback_.IsCancelled());
465 }
466
467 void ExpectFindRouteToHostEndSuccess(const IPAddress& address_queried,
468 bool is_local_address) {
469 AddExpectedEvent(ConnectionDiagnostics::kTypeFindRoute,
470 ConnectionDiagnostics::kPhaseEnd,
471 ConnectionDiagnostics::kResultSuccess);
472
473 IPAddress gateway(IPAddress::kFamilyIPv4);
474 if (is_local_address) {
475 gateway.SetAddressToDefault();
476 } else {
477 // Could be an IPv6 address, but we instrument this later with the
478 // argument passed to ExpectPingHostStartSuccess.
479 gateway = gateway_ipv4_address_;
480 }
481
Samuel Tan56d3c662015-08-04 18:42:07 -0700482 // Next action is either to ping the gateway, find an ARP table entry for
483 // the local IPv4 web server, or find a neighbor table entry for the local
484 // IPv6 web server.
485 EXPECT_CALL(dispatcher_, PostTask(_));
Samuel Tan1b9546a2015-06-29 18:53:41 -0700486 RoutingTableEntry entry(
487 address_queried, IPAddress(address_queried.family()), gateway, 0,
488 RT_SCOPE_UNIVERSE, true, connection_->table_id(), -1);
489 connection_diagnostics_.OnRouteQueryResponse(connection_->interface_index(),
490 entry);
491 }
492
493 void ExpectFindRouteToHostEndFailure() {
494 AddExpectedEvent(ConnectionDiagnostics::kTypeFindRoute,
495 ConnectionDiagnostics::kPhaseEnd,
496 ConnectionDiagnostics::kResultFailure);
Samuel Tand1c71662015-08-14 15:11:38 -0700497 EXPECT_CALL(metrics_, NotifyConnectionDiagnosticsIssue(
498 ConnectionDiagnostics::kIssueRouting));
Samuel Tan1b9546a2015-06-29 18:53:41 -0700499 EXPECT_CALL(callback_target(),
500 ResultCallback(ConnectionDiagnostics::kIssueRouting,
501 IsEventList(expected_events_)));
502 connection_diagnostics_.OnRouteQueryTimeout();
503 }
504
505 void ExpectArpTableLookupStartSuccessEndSuccess(const IPAddress& address,
506 bool is_gateway) {
507 ExpectArpTableLookup(address, true, is_gateway);
508 }
509
510 void ExpectArpTableLookupStartSuccessEndFailure(const IPAddress& address) {
511 ExpectArpTableLookup(address, false, false);
512 }
513
Samuel Tan56d3c662015-08-04 18:42:07 -0700514 void ExpectNeighborTableLookupStartSuccess(const IPAddress& address) {
515 AddExpectedEvent(ConnectionDiagnostics::kTypeNeighborTableLookup,
516 ConnectionDiagnostics::kPhaseStart,
517 ConnectionDiagnostics::kResultSuccess);
518 EXPECT_CALL(rtnl_handler_, RequestDump(RTNLHandler::kRequestNeighbor));
519 EXPECT_CALL(
520 dispatcher_,
521 PostDelayedTask(
522 _,
523 ConnectionDiagnostics::kNeighborTableRequestTimeoutSeconds * 1000));
524 connection_diagnostics_.FindNeighborTableEntry(address);
525 }
526
527 void ExpectNeighborTableLookupEndSuccess(const IPAddress& address_queried,
528 bool is_gateway) {
529 AddExpectedEvent(ConnectionDiagnostics::kTypeNeighborTableLookup,
530 ConnectionDiagnostics::kPhaseEnd,
531 ConnectionDiagnostics::kResultSuccess);
532 RTNLMessage msg(RTNLMessage::kTypeNeighbor, RTNLMessage::kModeAdd, 0, 0, 0,
533 connection_->interface_index(), IPAddress::kFamilyIPv6);
534 msg.set_neighbor_status(
535 RTNLMessage::NeighborStatus(NUD_REACHABLE, 0, NDA_DST));
536 msg.SetAttribute(NDA_DST, address_queried.address());
Samuel Tand1c71662015-08-14 15:11:38 -0700537 const string& issue =
538 is_gateway ? ConnectionDiagnostics::kIssueGatewayNotResponding
539 : ConnectionDiagnostics::kIssueServerNotResponding;
540 EXPECT_CALL(metrics_, NotifyConnectionDiagnosticsIssue(issue));
541 EXPECT_CALL(callback_target(),
542 ResultCallback(issue, IsEventList(expected_events_)));
Samuel Tan56d3c662015-08-04 18:42:07 -0700543 connection_diagnostics_.OnNeighborMsgReceived(address_queried, msg);
544 }
545
546 void ExpectNeighborTableLookupEndFailureNotReachable(
547 const IPAddress& address_queried, bool is_gateway) {
548 ExpectNeighborTableLookupEndFailure(address_queried, is_gateway, false);
549 }
550
551 void ExpectNeighborTableLookupEndFailureNoEntry(
552 const IPAddress& address_queried, bool is_gateway) {
553 ExpectNeighborTableLookupEndFailure(address_queried, is_gateway, true);
554 }
555
Samuel Tan1b9546a2015-06-29 18:53:41 -0700556 void ExpectCheckIPCollisionStartSuccess() {
557 AddExpectedEvent(ConnectionDiagnostics::kTypeIPCollisionCheck,
558 ConnectionDiagnostics::kPhaseStart,
559 ConnectionDiagnostics::kResultSuccess);
560 EXPECT_CALL(device_info_, GetMACAddress(connection_->interface_index(), _))
561 .WillOnce(
562 DoAll(SetArgumentPointee<1>(local_mac_address_), Return(true)));
563 EXPECT_CALL(*arp_client_, StartReplyListener()).WillOnce(Return(true));
564 // We should send an ARP request for our own local IP address.
565 EXPECT_CALL(*arp_client_, TransmitRequest(IsArpRequest(
566 local_ip_address_, local_ip_address_,
567 local_mac_address_, ByteString())))
568 .WillOnce(Return(true));
569 EXPECT_CALL(dispatcher_,
570 PostDelayedTask(
571 _, ConnectionDiagnostics::kArpReplyTimeoutSeconds * 1000));
572 connection_diagnostics_.CheckIpCollision();
573 }
574
575 void ExpectCheckIPCollisionEndSuccess() {
576 AddExpectedEvent(ConnectionDiagnostics::kTypeIPCollisionCheck,
577 ConnectionDiagnostics::kPhaseEnd,
578 ConnectionDiagnostics::kResultSuccess);
579 // Simulate ARP response from a sender with the same IP address as our
580 // connection, directed at our local IP address and local MAC address.
581 client_test_helper_->GeneratePacket(
582 ARPOP_REPLY, local_ip_address_,
583 ByteString(string(kArpReplySenderMacAddressASCIIString), false),
584 local_ip_address_, local_mac_address_);
Samuel Tand1c71662015-08-14 15:11:38 -0700585 EXPECT_CALL(metrics_, NotifyConnectionDiagnosticsIssue(
586 ConnectionDiagnostics::kIssueIPCollision));
Samuel Tan1b9546a2015-06-29 18:53:41 -0700587 EXPECT_CALL(callback_target(),
588 ResultCallback(ConnectionDiagnostics::kIssueIPCollision,
589 IsEventList(expected_events_)));
590 connection_diagnostics_.OnArpReplyReceived(1);
591 }
592
593 void ExpectCheckIPCollisionEndFailureGatewayArpFailed() {
594 ExpectCheckIPCollisionEndFailure(
595 ConnectionDiagnostics::kIssueGatewayArpFailed);
596 }
597
598 void ExpectCheckIPCollisionEndFailureServerArpFailed() {
599 ExpectCheckIPCollisionEndFailure(
600 ConnectionDiagnostics::kIssueServerArpFailed);
601 }
602
603 private:
604 void ExpectPortalDetectionEnd(ConnectionDiagnostics::Phase diag_phase,
605 ConnectionDiagnostics::Result diag_result,
606 ConnectivityTrial::Phase trial_phase,
607 ConnectivityTrial::Status trial_status) {
608 AddExpectedEvent(ConnectionDiagnostics::kTypePortalDetection, diag_phase,
609 diag_result);
610 if (diag_phase == ConnectionDiagnostics::kPhasePortalDetectionEndContent) {
Samuel Tand1c71662015-08-14 15:11:38 -0700611 const string& issue = diag_result == ConnectionDiagnostics::kResultSuccess
612 ? ConnectionDiagnostics::kIssueNone
613 : ConnectionDiagnostics::kIssueCaptivePortal;
614 EXPECT_CALL(metrics_, NotifyConnectionDiagnosticsIssue(issue));
615 EXPECT_CALL(callback_target(),
616 ResultCallback(issue, IsEventList(expected_events_)));
Samuel Tan1b9546a2015-06-29 18:53:41 -0700617
618 } else if (diag_phase ==
619 ConnectionDiagnostics::kPhasePortalDetectionEndDNS &&
620 diag_result == ConnectionDiagnostics::kResultFailure) {
Samuel Tand1c71662015-08-14 15:11:38 -0700621 EXPECT_CALL(metrics_,
622 NotifyConnectionDiagnosticsIssue(
623 ConnectionDiagnostics::kIssueDNSServerMisconfig));
Samuel Tan1b9546a2015-06-29 18:53:41 -0700624 EXPECT_CALL(
625 callback_target(),
626 ResultCallback(ConnectionDiagnostics::kIssueDNSServerMisconfig,
627 IsEventList(expected_events_)));
628 } else {
629 // Otherwise, we end in DNS phase with a timeout, or a HTTP phase failure.
630 // Either of these cases warrant further diagnostic actions.
631 EXPECT_CALL(dispatcher_, PostTask(_));
632 }
633 connection_diagnostics_.StartAfterPortalDetectionInternal(
634 PortalDetector::Result(
635 ConnectivityTrial::Result(trial_phase, trial_status)));
636 }
637
638 // |expected_issue| only used if |is_success| is false.
639 void ExpectPingDNSSeversStart(bool is_success, const string& expected_issue) {
640 AddExpectedEvent(ConnectionDiagnostics::kTypePingDNSServers,
641 ConnectionDiagnostics::kPhaseStart,
642 is_success ? ConnectionDiagnostics::kResultSuccess
643 : ConnectionDiagnostics::kResultFailure);
644 const char* bad_addresses[] = {"110.2.3", "1.5"};
645 const vector<string> bad_dns_servers(bad_addresses, bad_addresses + 2);
646 if (!is_success &&
647 expected_issue == ConnectionDiagnostics::kIssueDNSServersInvalid) {
648 // If the DNS server addresses are invalid, we will not even attempt to
649 // start any ICMP sessions.
650 EXPECT_CALL(*connection_.get(), dns_servers())
651 .WillRepeatedly(ReturnRef(bad_dns_servers));
652 } else {
653 // We are either instrumenting the success case (started pinging all
654 // DNS servers successfully) or the failure case where we fail to start
655 // any pings.
656 ASSERT_TRUE(is_success ||
657 expected_issue == ConnectionDiagnostics::kIssueInternalError);
658 dns_server_icmp_session_0_ = new NiceMock<MockIcmpSession>(&dispatcher_);
659 dns_server_icmp_session_1_ = new NiceMock<MockIcmpSession>(&dispatcher_);
660 EXPECT_CALL(*MockIcmpSessionFactory::GetInstance(),
661 CreateIcmpSession(&dispatcher_))
662 .WillOnce(Return(dns_server_icmp_session_0_))
663 .WillOnce(Return(dns_server_icmp_session_1_));
664 EXPECT_CALL(*dns_server_icmp_session_0_,
665 Start(IsSameIPAddress(IPAddress(kDNSServer0)), _))
666 .WillOnce(Return(is_success));
667 EXPECT_CALL(*dns_server_icmp_session_1_,
668 Start(IsSameIPAddress(IPAddress(kDNSServer1)), _))
669 .WillOnce(Return(is_success));
670 }
671
672 if (is_success) {
Samuel Tand1c71662015-08-14 15:11:38 -0700673 EXPECT_CALL(metrics_, NotifyConnectionDiagnosticsIssue(_)).Times(0);
Samuel Tan1b9546a2015-06-29 18:53:41 -0700674 EXPECT_CALL(callback_target(), ResultCallback(_, _)).Times(0);
675 } else {
Samuel Tand1c71662015-08-14 15:11:38 -0700676 EXPECT_CALL(metrics_, NotifyConnectionDiagnosticsIssue(expected_issue));
Samuel Tan1b9546a2015-06-29 18:53:41 -0700677 EXPECT_CALL(
678 callback_target(),
679 ResultCallback(expected_issue, IsEventList(expected_events_)));
680 }
681 connection_diagnostics_.PingDNSServers();
682 if (is_success) {
683 EXPECT_EQ(2, connection_diagnostics_
684 .id_to_pending_dns_server_icmp_session_.size());
685 } else {
686 EXPECT_TRUE(connection_diagnostics_.id_to_pending_dns_server_icmp_session_
687 .empty());
688 }
689 }
690
691 void ExpectResolveTargetServerIPAddressEnd(
692 ConnectionDiagnostics::Result result, const IPAddress& resolved_address) {
693 AddExpectedEvent(ConnectionDiagnostics::kTypeResolveTargetServerIP,
694 ConnectionDiagnostics::kPhaseEnd, result);
695 Error error;
696 if (result == ConnectionDiagnostics::kResultSuccess) {
697 error.Populate(Error::kSuccess);
698 EXPECT_CALL(dispatcher_, PostTask(_));
699 } else if (result == ConnectionDiagnostics::kResultTimeout) {
700 error.Populate(Error::kOperationTimeout);
701 EXPECT_CALL(dispatcher_, PostTask(_));
702 } else {
703 error.Populate(Error::kOperationFailed);
Samuel Tand1c71662015-08-14 15:11:38 -0700704 EXPECT_CALL(metrics_,
705 NotifyConnectionDiagnosticsIssue(
706 ConnectionDiagnostics::kIssueDNSServerMisconfig));
Samuel Tan1b9546a2015-06-29 18:53:41 -0700707 EXPECT_CALL(
708 callback_target(),
709 ResultCallback(ConnectionDiagnostics::kIssueDNSServerMisconfig,
710 IsEventList(expected_events_)));
711 }
712 connection_diagnostics_.OnDNSResolutionComplete(error, resolved_address);
713 }
714
715 void ExpectPingDNSServersEndSuccess(bool retries_left) {
716 AddExpectedEvent(ConnectionDiagnostics::kTypePingDNSServers,
717 ConnectionDiagnostics::kPhaseEnd,
718 ConnectionDiagnostics::kResultSuccess);
719 if (retries_left) {
720 EXPECT_LT(connection_diagnostics_.num_dns_attempts_,
721 ConnectionDiagnostics::kMaxDNSRetries);
722 } else {
723 EXPECT_GE(connection_diagnostics_.num_dns_attempts_,
724 ConnectionDiagnostics::kMaxDNSRetries);
725 }
726 // Post retry task or report done only after all (i.e. 2) pings are done.
727 connection_diagnostics_.OnPingDNSServerComplete(0, kNonEmptyResult);
728 if (retries_left) {
729 EXPECT_CALL(dispatcher_, PostTask(_));
Samuel Tand1c71662015-08-14 15:11:38 -0700730 EXPECT_CALL(metrics_, NotifyConnectionDiagnosticsIssue(_)).Times(0);
Samuel Tan1b9546a2015-06-29 18:53:41 -0700731 EXPECT_CALL(callback_target(), ResultCallback(_, _)).Times(0);
732 } else {
733 EXPECT_CALL(dispatcher_, PostTask(_)).Times(0);
Samuel Tand1c71662015-08-14 15:11:38 -0700734 EXPECT_CALL(metrics_,
735 NotifyConnectionDiagnosticsIssue(
736 ConnectionDiagnostics::kIssueDNSServerNoResponse));
Samuel Tan1b9546a2015-06-29 18:53:41 -0700737 EXPECT_CALL(
738 callback_target(),
739 ResultCallback(ConnectionDiagnostics::kIssueDNSServerNoResponse,
740 IsEventList(expected_events_)));
741 }
742 connection_diagnostics_.OnPingDNSServerComplete(1, kNonEmptyResult);
743 }
744
745 void ExpectArpTableLookup(const IPAddress& address, bool success,
746 bool is_gateway) {
747 AddExpectedEvent(ConnectionDiagnostics::kTypeArpTableLookup,
748 ConnectionDiagnostics::kPhaseStart,
749 ConnectionDiagnostics::kResultSuccess);
750 AddExpectedEvent(ConnectionDiagnostics::kTypeArpTableLookup,
751 ConnectionDiagnostics::kPhaseEnd,
752 success ? ConnectionDiagnostics::kResultSuccess
753 : ConnectionDiagnostics::kResultFailure);
754 EXPECT_CALL(device_info_,
755 GetMACAddressOfPeer(connection_->interface_index(),
756 IsSameIPAddress(address), _))
757 .WillOnce(Return(success));
758 if (success) {
Samuel Tand1c71662015-08-14 15:11:38 -0700759 const string& issue =
760 is_gateway ? ConnectionDiagnostics::kIssueGatewayNotResponding
761 : ConnectionDiagnostics::kIssueServerNotResponding;
762 EXPECT_CALL(metrics_, NotifyConnectionDiagnosticsIssue(issue));
763 EXPECT_CALL(callback_target(),
764 ResultCallback(issue, IsEventList(expected_events_)));
Samuel Tan1b9546a2015-06-29 18:53:41 -0700765 } else {
766 // Checking for IP collision.
767 EXPECT_CALL(dispatcher_, PostTask(_));
768 }
769 connection_diagnostics_.FindArpTableEntry(address);
770 }
771
772 void ExpectCheckIPCollisionEndFailure(const string& expected_issue) {
773 AddExpectedEvent(ConnectionDiagnostics::kTypeIPCollisionCheck,
774 ConnectionDiagnostics::kPhaseEnd,
775 ConnectionDiagnostics::kResultFailure);
Samuel Tand1c71662015-08-14 15:11:38 -0700776 EXPECT_CALL(metrics_, NotifyConnectionDiagnosticsIssue(expected_issue));
Samuel Tan1b9546a2015-06-29 18:53:41 -0700777 EXPECT_CALL(callback_target(),
778 ResultCallback(expected_issue, IsEventList(expected_events_)));
779 connection_diagnostics_.OnArpRequestTimeout();
780 }
781
Samuel Tan56d3c662015-08-04 18:42:07 -0700782 void ExpectNeighborTableLookupEndFailure(const IPAddress& address_queried,
783 bool is_gateway, bool is_timeout) {
784 AddExpectedEvent(ConnectionDiagnostics::kTypeNeighborTableLookup,
785 ConnectionDiagnostics::kPhaseEnd,
786 ConnectionDiagnostics::kResultFailure);
Samuel Tand1c71662015-08-14 15:11:38 -0700787 string issue;
Samuel Tan56d3c662015-08-04 18:42:07 -0700788 if (is_timeout) {
Samuel Tand1c71662015-08-14 15:11:38 -0700789 issue = is_gateway ? ConnectionDiagnostics::kIssueGatewayNoNeighborEntry
790 : ConnectionDiagnostics::kIssueServerNoNeighborEntry;
791 EXPECT_CALL(metrics_, NotifyConnectionDiagnosticsIssue(issue));
792 EXPECT_CALL(callback_target(),
793 ResultCallback(issue, IsEventList(expected_events_)));
Samuel Tan56d3c662015-08-04 18:42:07 -0700794 connection_diagnostics_.OnNeighborTableRequestTimeout(address_queried);
795 } else {
Samuel Tand1c71662015-08-14 15:11:38 -0700796 issue =
797 is_gateway
798 ? ConnectionDiagnostics::kIssueGatewayNeighborEntryNotConnected
799 : ConnectionDiagnostics::kIssueServerNeighborEntryNotConnected;
800 EXPECT_CALL(metrics_, NotifyConnectionDiagnosticsIssue(issue));
Samuel Tan56d3c662015-08-04 18:42:07 -0700801 EXPECT_CALL(
802 callback_target(),
Samuel Tand1c71662015-08-14 15:11:38 -0700803 ResultCallback(issue,
Samuel Tan56d3c662015-08-04 18:42:07 -0700804 IsEventList(expected_events_)));
805 RTNLMessage msg(RTNLMessage::kTypeNeighbor, RTNLMessage::kModeAdd, 0, 0,
806 0, connection_->interface_index(),
807 IPAddress::kFamilyIPv6);
808 msg.set_neighbor_status(
809 RTNLMessage::NeighborStatus(NUD_FAILED, 0, NDA_DST));
810 msg.SetAttribute(NDA_DST, address_queried.address());
811 connection_diagnostics_.OnNeighborMsgReceived(address_queried, msg);
812 }
813 }
814
Samuel Tan1b9546a2015-06-29 18:53:41 -0700815 const string interface_name_;
816 const vector<string> dns_servers_;
817 const IPAddress local_ip_address_;
818 const IPAddress gateway_ipv4_address_;
819 const IPAddress gateway_ipv6_address_;
820 ByteString local_mac_address_;
821 CallbackTarget callback_target_;
822 MockControl control_;
Samuel Tand1c71662015-08-14 15:11:38 -0700823 NiceMock<MockMetrics> metrics_;
Samuel Tan1b9546a2015-06-29 18:53:41 -0700824 MockManager manager_;
825 NiceMock<MockDeviceInfo> device_info_;
826 scoped_refptr<NiceMock<MockConnection>> connection_;
827 ConnectionDiagnostics connection_diagnostics_;
828 NiceMock<MockEventDispatcher> dispatcher_;
829 NiceMock<MockRoutingTable> routing_table_;
Samuel Tan56d3c662015-08-04 18:42:07 -0700830 NiceMock<MockRTNLHandler> rtnl_handler_;
Samuel Tan1b9546a2015-06-29 18:53:41 -0700831 std::unique_ptr<ArpClientTestHelper> client_test_helper_;
832
833 // Used only for EXPECT_CALL(). Objects are owned by
834 // |connection_diagnostics_|.
835 NiceMock<MockArpClient>* arp_client_;
836 NiceMock<MockDNSClient>* dns_client_;
837 NiceMock<MockIcmpSession>* icmp_session_;
838 NiceMock<MockIcmpSession>* dns_server_icmp_session_0_;
839 NiceMock<MockIcmpSession>* dns_server_icmp_session_1_;
840 NiceMock<MockPortalDetector>* portal_detector_;
841
842 // For each test, all events we expect to appear in the final result are
843 // accumulated in this vector.
844 vector<ConnectionDiagnostics::Event> expected_events_;
845};
846
847TEST_F(ConnectionDiagnosticsTest, DoesPreviousEventMatch) {
848 // If |diagnostic_events| is empty, we should always fail to match an event.
849 EXPECT_FALSE(
850 DoesPreviousEventMatch(ConnectionDiagnostics::kTypePortalDetection,
851 ConnectionDiagnostics::kPhaseStart,
852 ConnectionDiagnostics::kResultSuccess, 0));
853 EXPECT_FALSE(
854 DoesPreviousEventMatch(ConnectionDiagnostics::kTypePortalDetection,
855 ConnectionDiagnostics::kPhaseStart,
856 ConnectionDiagnostics::kResultSuccess, 2));
857
858 AddActualEvent(ConnectionDiagnostics::kTypePortalDetection,
859 ConnectionDiagnostics::kPhaseStart,
860 ConnectionDiagnostics::kResultSuccess);
861 AddActualEvent(ConnectionDiagnostics::kTypePortalDetection,
862 ConnectionDiagnostics::kPhasePortalDetectionEndOther,
863 ConnectionDiagnostics::kResultFailure);
864 AddActualEvent(ConnectionDiagnostics::kTypeResolveTargetServerIP,
865 ConnectionDiagnostics::kPhaseStart,
866 ConnectionDiagnostics::kResultSuccess);
867 AddActualEvent(ConnectionDiagnostics::kTypeResolveTargetServerIP,
868 ConnectionDiagnostics::kPhaseEnd,
869 ConnectionDiagnostics::kResultSuccess);
870
871 // Matching out of bounds should fail. (4 events total, so 4 events before the
872 // last event is out of bounds).
873 EXPECT_FALSE(
874 DoesPreviousEventMatch(ConnectionDiagnostics::kTypePortalDetection,
875 ConnectionDiagnostics::kPhaseStart,
876 ConnectionDiagnostics::kResultSuccess, 4));
877
878 // Valid matches.
879 EXPECT_TRUE(
880 DoesPreviousEventMatch(ConnectionDiagnostics::kTypePortalDetection,
881 ConnectionDiagnostics::kPhaseStart,
882 ConnectionDiagnostics::kResultSuccess, 3));
883 EXPECT_TRUE(
884 DoesPreviousEventMatch(ConnectionDiagnostics::kTypeResolveTargetServerIP,
885 ConnectionDiagnostics::kPhaseStart,
886 ConnectionDiagnostics::kResultSuccess, 1));
887 EXPECT_TRUE(
888 DoesPreviousEventMatch(ConnectionDiagnostics::kTypeResolveTargetServerIP,
889 ConnectionDiagnostics::kPhaseEnd,
890 ConnectionDiagnostics::kResultSuccess, 0));
891}
892
893TEST_F(ConnectionDiagnosticsTest, StartWhileRunning) {
894 ExpectPortalDetectionStartSuccess(kURL); // Start diagnostics;
895 EXPECT_FALSE(Start(kURL));
896}
897
898TEST_F(ConnectionDiagnosticsTest, StartWithBadURL) {
899 const string kBadURL("http://www.foo.com:x"); // Colon but no port
900 // IcmpSession::Stop will be called once when the bad URL is rejected.
901 ExpectIcmpSessionStop();
902 EXPECT_FALSE(Start(kBadURL));
903 // IcmpSession::Stop will be called a second time when
904 // |connection_diagnostics_| is destructed.
905 ExpectIcmpSessionStop();
906}
907
908TEST_F(ConnectionDiagnosticsTest, EndWith_InternalError) {
909 // Portal detection ends in HTTP phase, DNS resolution succeeds, and we
910 // attempt to ping the target web server but fail because of an internal
911 // error.
912 ExpectPortalDetectionStartSuccess(kURL);
913 ExpectPortalDetectionEndHTTPPhaseFailure();
914 ExpectResolveTargetServerIPAddressStartSuccess(IPAddress::kFamilyIPv4);
Samuel Tand6c9ef62015-08-11 18:15:17 -0700915 ExpectResolveTargetServerIPAddressEndSuccess(kIPv4ServerAddress);
Samuel Tan1b9546a2015-06-29 18:53:41 -0700916 ExpectPingHostStartFailure(ConnectionDiagnostics::kTypePingTargetServer,
Samuel Tand6c9ef62015-08-11 18:15:17 -0700917 kIPv4ServerAddress);
Samuel Tan1b9546a2015-06-29 18:53:41 -0700918 VerifyStopped();
919}
920
921TEST_F(ConnectionDiagnosticsTest, EndWith_PortalDetectionContentPhase_Success) {
922 // Portal detection ends successfully in content phase, so we end diagnostics.
923 ExpectPortalDetectionStartSuccess(kURL);
924 ExpectPortalDetectionEndContentPhaseSuccess();
925 VerifyStopped();
926}
927
928TEST_F(ConnectionDiagnosticsTest, EndWith_PortalDetectionContentPhase_Failure) {
929 // Portal detection ends unsuccessfully in content phase, so we end
930 // diagnostics.
931 ExpectPortalDetectionStartSuccess(kURL);
932 ExpectPortalDetectionEndContentPhaseFailure();
933 VerifyStopped();
934}
935
936TEST_F(ConnectionDiagnosticsTest, EndWith_DNSFailure_1) {
937 // Portal detection ends with a DNS failure (not timeout), so we end
938 // diagnostics.
939 ExpectPortalDetectionStartSuccess(kURL);
940 ExpectPortalDetectionEndDNSPhaseFailure();
941 VerifyStopped();
942}
943
944TEST_F(ConnectionDiagnosticsTest, EndWith_DNSFailure_2) {
945 // Portal detection ends in HTTP phase, DNS resolution fails (not timeout), so
946 // we end diagnostics.
947 ExpectPortalDetectionStartSuccess(kURL);
948 ExpectPortalDetectionEndHTTPPhaseFailure();
949 ExpectResolveTargetServerIPAddressStartSuccess(IPAddress::kFamilyIPv4);
950 ExpectResolveTargetServerIPAddressEndFailure();
951 VerifyStopped();
952}
953
954TEST_F(ConnectionDiagnosticsTest, EndWith_PingDNSServerStartFailure_1) {
955 // Portal detection ends with a DNS timeout, and we attempt to pinging DNS
956 // servers, but fail to start any IcmpSessions, so end diagnostics.
957 ExpectPortalDetectionStartSuccess(kURL);
958 ExpectPortalDetectionEndDNSPhaseTimeout();
959 ExpectPingDNSSeversStartFailureAllIcmpSessionsFailed();
960 VerifyStopped();
961}
962
963TEST_F(ConnectionDiagnosticsTest, EndWith_PingDNSServerStartFailure_2) {
964 // Portal detection ends with a DNS timeout, and we attempt to pinging DNS
965 // servers, but all DNS servers configured for this connection have invalid IP
966 // addresses, so we fail to start ping DNs servers, andend diagnostics.
967 ExpectPortalDetectionStartSuccess(kURL);
968 ExpectPortalDetectionEndDNSPhaseTimeout();
969 ExpectPingDNSSeversStartFailureAllAddressesInvalid();
970 VerifyStopped();
971}
972
973TEST_F(ConnectionDiagnosticsTest, EndWith_PingDNSServerEndSuccess_NoRetries_1) {
974 // Portal detection ends with a DNS timeout, pinging DNS servers succeeds, DNS
975 // resolution times out, pinging DNS servers succeeds again, and DNS
976 // resolution times out again. End diagnostics because we have no more DNS
977 // retries left.
978 ExpectPortalDetectionStartSuccess(kURL);
979 ExpectPortalDetectionEndDNSPhaseTimeout();
980 ExpectPingDNSServersStartSuccess();
981 ExpectPingDNSServersEndSuccessRetriesLeft();
982 ExpectResolveTargetServerIPAddressStartSuccess(IPAddress::kFamilyIPv4);
983 ExpectResolveTargetServerIPAddressEndTimeout();
984 ExpectPingDNSServersStartSuccess();
985 ExpectPingDNSServersEndSuccessRetriesLeft();
986 ExpectResolveTargetServerIPAddressStartSuccess(IPAddress::kFamilyIPv4);
987 ExpectResolveTargetServerIPAddressEndTimeout();
988 ExpectPingDNSServersStartSuccess();
989 ExpectPingDNSServersEndSuccessNoRetriesLeft();
990 VerifyStopped();
991}
992
993TEST_F(ConnectionDiagnosticsTest, EndWith_PingDNSServerEndSuccess_NoRetries_2) {
994 // Portal detection ends in HTTP phase, DNS resolution times out, pinging DNS
995 // servers succeeds, DNS resolution times out again, pinging DNS servers
996 // succeeds. End diagnostics because we have no more DNS retries left.
997 ExpectPortalDetectionStartSuccess(kURL);
998 ExpectPortalDetectionEndHTTPPhaseFailure();
999 ExpectResolveTargetServerIPAddressStartSuccess(IPAddress::kFamilyIPv4);
1000 ExpectResolveTargetServerIPAddressEndTimeout();
1001 ExpectPingDNSServersStartSuccess();
1002 ExpectPingDNSServersEndSuccessRetriesLeft();
1003 ExpectResolveTargetServerIPAddressStartSuccess(IPAddress::kFamilyIPv4);
1004 ExpectResolveTargetServerIPAddressEndTimeout();
1005 ExpectPingDNSServersStartSuccess();
1006 ExpectPingDNSServersEndSuccessNoRetriesLeft();
1007 VerifyStopped();
1008}
1009
1010TEST_F(ConnectionDiagnosticsTest, EndWith_PingTargetIPSuccess_1) {
1011 // Portal detection ends in HTTP phase, DNS resolution succeeds, and pinging
1012 // the resolved IP address succeeds, so we end diagnostics.
1013 ExpectPortalDetectionStartSuccess(kURL);
1014 ExpectPortalDetectionEndHTTPPhaseFailure();
1015 ExpectResolveTargetServerIPAddressStartSuccess(IPAddress::kFamilyIPv4);
Samuel Tand6c9ef62015-08-11 18:15:17 -07001016 ExpectResolveTargetServerIPAddressEndSuccess(kIPv4ServerAddress);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001017 ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingTargetServer,
Samuel Tand6c9ef62015-08-11 18:15:17 -07001018 kIPv4ServerAddress);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001019 ExpectPingHostEndSuccess(ConnectionDiagnostics::kTypePingTargetServer,
Samuel Tand6c9ef62015-08-11 18:15:17 -07001020 kIPv4ServerAddress);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001021 VerifyStopped();
1022}
1023
1024TEST_F(ConnectionDiagnosticsTest, EndWith_PingTargetIPSuccess_2) {
1025 // Portal detection ends with a DNS timeout, pinging DNS servers succeeds, DNS
1026 // resolution succeeds, and pinging the resolved IP address succeeds, so we
1027 // end diagnostics.
1028 ExpectPortalDetectionStartSuccess(kURL);
1029 ExpectPortalDetectionEndDNSPhaseTimeout();
1030 ExpectPingDNSServersStartSuccess();
1031 ExpectPingDNSServersEndSuccessRetriesLeft();
1032 ExpectResolveTargetServerIPAddressStartSuccess(IPAddress::kFamilyIPv4);
Samuel Tand6c9ef62015-08-11 18:15:17 -07001033 ExpectResolveTargetServerIPAddressEndSuccess(kIPv4ServerAddress);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001034 ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingTargetServer,
Samuel Tand6c9ef62015-08-11 18:15:17 -07001035 kIPv4ServerAddress);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001036 ExpectPingHostEndSuccess(ConnectionDiagnostics::kTypePingTargetServer,
Samuel Tand6c9ef62015-08-11 18:15:17 -07001037 kIPv4ServerAddress);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001038 VerifyStopped();
1039}
1040
1041TEST_F(ConnectionDiagnosticsTest, EndWith_PingTargetIPSuccess_3) {
1042 // Portal detection ends in HTTP phase, DNS resolution times out, pinging DNS
1043 // servers succeeds, DNS resolution succeeds, and pinging the resolved IP
1044 // address succeeds, so we end diagnostics.
1045 ExpectPortalDetectionStartSuccess(kURL);
1046 ExpectPortalDetectionEndHTTPPhaseFailure();
1047 ExpectResolveTargetServerIPAddressStartSuccess(IPAddress::kFamilyIPv4);
1048 ExpectResolveTargetServerIPAddressEndTimeout();
1049 ExpectPingDNSServersStartSuccess();
1050 ExpectPingDNSServersEndSuccessRetriesLeft();
1051 ExpectResolveTargetServerIPAddressStartSuccess(IPAddress::kFamilyIPv4);
Samuel Tand6c9ef62015-08-11 18:15:17 -07001052 ExpectResolveTargetServerIPAddressEndSuccess(kIPv4ServerAddress);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001053 ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingTargetServer,
Samuel Tand6c9ef62015-08-11 18:15:17 -07001054 kIPv4ServerAddress);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001055 ExpectPingHostEndSuccess(ConnectionDiagnostics::kTypePingTargetServer,
Samuel Tand6c9ef62015-08-11 18:15:17 -07001056 kIPv4ServerAddress);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001057 VerifyStopped();
1058}
1059
Samuel Tan1b9546a2015-06-29 18:53:41 -07001060TEST_F(ConnectionDiagnosticsTest, EndWith_FindRouteFailure_1) {
1061 // Portal detection ends in HTTP phase, DNS resolution succeeds, pinging the
1062 // resolved IP address fails, and we fail to get a route for the IP address,
1063 // so we end diagnostics.
1064 ExpectPortalDetectionStartSuccess(kURL);
1065 ExpectPortalDetectionEndHTTPPhaseFailure();
1066 ExpectResolveTargetServerIPAddressStartSuccess(IPAddress::kFamilyIPv4);
Samuel Tand6c9ef62015-08-11 18:15:17 -07001067 ExpectResolveTargetServerIPAddressEndSuccess(kIPv4ServerAddress);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001068 ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingTargetServer,
Samuel Tand6c9ef62015-08-11 18:15:17 -07001069 kIPv4ServerAddress);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001070 ExpectPingHostEndFailure(ConnectionDiagnostics::kTypePingTargetServer,
Samuel Tand6c9ef62015-08-11 18:15:17 -07001071 kIPv4ServerAddress);
1072 ExpectFindRouteToHostStartSuccess(kIPv4ServerAddress);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001073 ExpectFindRouteToHostEndFailure();
1074 VerifyStopped();
1075}
1076
1077TEST_F(ConnectionDiagnosticsTest, EndWith_FindRoute_Failure_2) {
1078 // Portal detection ends with a DNS timeout, pinging DNS servers succeeds, DNS
1079 // resolution succeeds, pinging the resolved IP address fails, and we fail to
1080 // get a route for the IP address, so we end diagnostics.
1081 ExpectPortalDetectionStartSuccess(kURL);
1082 ExpectPortalDetectionEndDNSPhaseTimeout();
1083 ExpectPingDNSServersStartSuccess();
1084 ExpectPingDNSServersEndSuccessRetriesLeft();
1085 ExpectResolveTargetServerIPAddressStartSuccess(IPAddress::kFamilyIPv4);
Samuel Tand6c9ef62015-08-11 18:15:17 -07001086 ExpectResolveTargetServerIPAddressEndSuccess(kIPv4ServerAddress);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001087 ExpectPingHostEndFailure(ConnectionDiagnostics::kTypePingTargetServer,
Samuel Tand6c9ef62015-08-11 18:15:17 -07001088 kIPv4ServerAddress);
1089 ExpectFindRouteToHostStartSuccess(kIPv4ServerAddress);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001090 ExpectFindRouteToHostEndFailure();
1091 VerifyStopped();
1092}
1093
1094TEST_F(ConnectionDiagnosticsTest, EndWith_FindRouteFailure_3) {
1095 // Portal detection ends in HTTP phase, DNS resolution times out, pinging DNS
1096 // servers succeeds, DNS resolution succeeds, pinging the resolved IP address
1097 // fails, and we fail to get a route for the IP address, so we end
1098 // diagnostics.
1099 ExpectPortalDetectionStartSuccess(kURL);
1100 ExpectPortalDetectionEndHTTPPhaseFailure();
1101 ExpectResolveTargetServerIPAddressStartSuccess(IPAddress::kFamilyIPv4);
1102 ExpectResolveTargetServerIPAddressEndTimeout();
1103 ExpectPingDNSServersStartSuccess();
1104 ExpectPingDNSServersEndSuccessRetriesLeft();
1105 ExpectResolveTargetServerIPAddressStartSuccess(IPAddress::kFamilyIPv4);
Samuel Tand6c9ef62015-08-11 18:15:17 -07001106 ExpectResolveTargetServerIPAddressEndSuccess(kIPv4ServerAddress);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001107 ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingTargetServer,
Samuel Tand6c9ef62015-08-11 18:15:17 -07001108 kIPv4ServerAddress);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001109 ExpectPingHostEndFailure(ConnectionDiagnostics::kTypePingTargetServer,
Samuel Tand6c9ef62015-08-11 18:15:17 -07001110 kIPv4ServerAddress);
1111 ExpectFindRouteToHostStartSuccess(kIPv4ServerAddress);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001112 ExpectFindRouteToHostEndFailure();
1113 VerifyStopped();
1114}
1115
1116TEST_F(ConnectionDiagnosticsTest, EndWith_FindRouteFailure_4) {
1117 // Portal detection ends with a DNS timeout, pinging DNS servers fails, get a
1118 // route for the first DNS server, so we end diagnostics.
1119 ExpectPortalDetectionStartSuccess(kURL);
1120 ExpectPortalDetectionEndDNSPhaseTimeout();
1121 ExpectPingDNSServersStartSuccess();
1122 ExpectPingDNSServersEndFailure();
1123 ExpectFindRouteToHostStartSuccess(kIPv4GatewayAddress);
1124 ExpectFindRouteToHostEndFailure();
1125 VerifyStopped();
1126}
1127
1128TEST_F(ConnectionDiagnosticsTest, EndWith_PingGatewaySuccess_1_IPv4) {
1129 // Portal detection ends in HTTP phase, DNS resolution succeeds, pinging the
1130 // resolved IP address fails, and we successfully get route for the IP
1131 // address. This address is remote, so ping the local gateway and succeed, so
1132 // we end diagnostics.
1133 ExpectPortalDetectionStartSuccess(kURL);
1134 ExpectPortalDetectionEndHTTPPhaseFailure();
1135 ExpectResolveTargetServerIPAddressStartSuccess(IPAddress::kFamilyIPv4);
Samuel Tand6c9ef62015-08-11 18:15:17 -07001136 ExpectResolveTargetServerIPAddressEndSuccess(kIPv4ServerAddress);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001137 ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingTargetServer,
Samuel Tand6c9ef62015-08-11 18:15:17 -07001138 kIPv4ServerAddress);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001139 ExpectPingHostEndFailure(ConnectionDiagnostics::kTypePingTargetServer,
Samuel Tand6c9ef62015-08-11 18:15:17 -07001140 kIPv4ServerAddress);
1141 ExpectFindRouteToHostStartSuccess(kIPv4ServerAddress);
1142 ExpectFindRouteToHostEndSuccess(kIPv4ServerAddress, false);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001143 ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingGateway,
1144 kIPv4GatewayAddress);
1145 ExpectPingHostEndSuccess(ConnectionDiagnostics::kTypePingGateway,
1146 kIPv4GatewayAddress);
1147 VerifyStopped();
1148}
1149
1150TEST_F(ConnectionDiagnosticsTest, EndWith_PingGatewaySuccess_1_IPv6) {
1151 // Same as above, but this time the resolved IP address of the target URL
1152 // is IPv6.
1153 UseIPv6Gateway();
1154
1155 ExpectPortalDetectionStartSuccess(kURL);
1156 ExpectPortalDetectionEndHTTPPhaseFailure();
1157 ExpectResolveTargetServerIPAddressStartSuccess(IPAddress::kFamilyIPv6);
Samuel Tand6c9ef62015-08-11 18:15:17 -07001158 ExpectResolveTargetServerIPAddressEndSuccess(kIPv6ServerAddress);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001159 ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingTargetServer,
Samuel Tand6c9ef62015-08-11 18:15:17 -07001160 kIPv6ServerAddress);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001161 ExpectPingHostEndFailure(ConnectionDiagnostics::kTypePingTargetServer,
Samuel Tand6c9ef62015-08-11 18:15:17 -07001162 kIPv6ServerAddress);
1163 ExpectFindRouteToHostStartSuccess(kIPv6ServerAddress);
1164 ExpectFindRouteToHostEndSuccess(kIPv6ServerAddress, false);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001165 ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingGateway,
1166 kIPv6GatewayAddress);
1167 ExpectPingHostEndSuccess(ConnectionDiagnostics::kTypePingGateway,
1168 kIPv6GatewayAddress);
1169 VerifyStopped();
1170}
1171
1172TEST_F(ConnectionDiagnosticsTest, EndWith_PingGatewaySuccess_2) {
1173 // Portal detection ends with a DNS timeout, pinging DNS servers succeeds, DNS
1174 // resolution succeeds, pinging the resolved IP address fails, and we
1175 // successfully get route for the IP address. This address is remote, so ping
1176 // the local gateway and succeed, so we end diagnostics.
1177 ExpectPortalDetectionStartSuccess(kURL);
1178 ExpectPortalDetectionEndDNSPhaseTimeout();
1179 ExpectPingDNSServersStartSuccess();
1180 ExpectPingDNSServersEndSuccessRetriesLeft();
1181 ExpectResolveTargetServerIPAddressStartSuccess(IPAddress::kFamilyIPv4);
Samuel Tand6c9ef62015-08-11 18:15:17 -07001182 ExpectResolveTargetServerIPAddressEndSuccess(kIPv4ServerAddress);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001183 ExpectPingHostEndFailure(ConnectionDiagnostics::kTypePingTargetServer,
Samuel Tand6c9ef62015-08-11 18:15:17 -07001184 kIPv4ServerAddress);
1185 ExpectFindRouteToHostStartSuccess(kIPv4ServerAddress);
1186 ExpectFindRouteToHostEndSuccess(kIPv4ServerAddress, false);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001187 ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingGateway,
1188 kIPv4GatewayAddress);
1189 ExpectPingHostEndSuccess(ConnectionDiagnostics::kTypePingGateway,
1190 kIPv4GatewayAddress);
1191 VerifyStopped();
1192}
1193
1194TEST_F(ConnectionDiagnosticsTest, EndWith_PingGatewaySuccess_3) {
1195 // Portal detection ends in HTTP phase, DNS resolution times out, pinging DNS
1196 // servers succeeds, DNS resolution succeeds, pinging the resolved IP address
1197 // fails, and we successfully get route for the IP address. This address is
1198 // remote, so ping the local gateway. The ping succeeds, so we end
1199 // diagnostics.
1200 ExpectPortalDetectionStartSuccess(kURL);
1201 ExpectPortalDetectionEndHTTPPhaseFailure();
1202 ExpectResolveTargetServerIPAddressStartSuccess(IPAddress::kFamilyIPv4);
1203 ExpectResolveTargetServerIPAddressEndTimeout();
1204 ExpectPingDNSServersStartSuccess();
1205 ExpectPingDNSServersEndSuccessRetriesLeft();
1206 ExpectResolveTargetServerIPAddressStartSuccess(IPAddress::kFamilyIPv4);
Samuel Tand6c9ef62015-08-11 18:15:17 -07001207 ExpectResolveTargetServerIPAddressEndSuccess(kIPv4ServerAddress);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001208 ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingTargetServer,
Samuel Tand6c9ef62015-08-11 18:15:17 -07001209 kIPv4ServerAddress);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001210 ExpectPingHostEndFailure(ConnectionDiagnostics::kTypePingTargetServer,
Samuel Tand6c9ef62015-08-11 18:15:17 -07001211 kIPv4ServerAddress);
1212 ExpectFindRouteToHostStartSuccess(kIPv4ServerAddress);
1213 ExpectFindRouteToHostEndSuccess(kIPv4ServerAddress, false);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001214 ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingGateway,
1215 kIPv4GatewayAddress);
1216 ExpectPingHostEndSuccess(ConnectionDiagnostics::kTypePingGateway,
1217 kIPv4GatewayAddress);
1218 VerifyStopped();
1219}
1220
Samuel Tan1b9546a2015-06-29 18:53:41 -07001221// Note: for the test below, several other possible paths through the diagnostic
1222// state machine that will lead us to end diagnostics at ARP table lookup or IP
1223// collision check are not explicitly tested. We do this to avoid redundancy
1224// since the above tests have already exercised these sub-paths extensively,
1225
1226TEST_F(ConnectionDiagnosticsTest, EndWith_FindArpTableEntrySuccess_1) {
1227 // Portal detection ends in HTTP phase, DNS resolution succeeds, pinging the
1228 // resolved IP address fails, and we successfully get route for the IP
1229 // address. This address is remote, pinging the local gateway fails, and we
1230 // find an ARP table entry for the gateway address, so we end diagnostics.
1231 ExpectPortalDetectionStartSuccess(kURL);
1232 ExpectPortalDetectionEndHTTPPhaseFailure();
1233 ExpectResolveTargetServerIPAddressStartSuccess(IPAddress::kFamilyIPv4);
Samuel Tand6c9ef62015-08-11 18:15:17 -07001234 ExpectResolveTargetServerIPAddressEndSuccess(kIPv4ServerAddress);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001235 ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingTargetServer,
Samuel Tand6c9ef62015-08-11 18:15:17 -07001236 kIPv4ServerAddress);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001237 ExpectPingHostEndFailure(ConnectionDiagnostics::kTypePingTargetServer,
Samuel Tand6c9ef62015-08-11 18:15:17 -07001238 kIPv4ServerAddress);
1239 ExpectFindRouteToHostStartSuccess(kIPv4ServerAddress);
1240 ExpectFindRouteToHostEndSuccess(kIPv4ServerAddress, false);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001241 ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingGateway,
1242 kIPv4GatewayAddress);
1243 ExpectPingHostEndFailure(ConnectionDiagnostics::kTypePingGateway,
1244 kIPv4GatewayAddress);
1245 ExpectArpTableLookupStartSuccessEndSuccess(kIPv4GatewayAddress, true);
1246 VerifyStopped();
1247}
1248
1249TEST_F(ConnectionDiagnosticsTest, EndWith_FindArpTableEntrySuccess_2) {
1250 // Portal detection ends in HTTP phase, DNS resolution succeeds, pinging the
1251 // resolved IP address fails, and we successfully get route for the IP
1252 // address. This address is local, and we find an ARP table entry for this
1253 // address, so we end diagnostics.
1254 ExpectPortalDetectionStartSuccess(kURL);
1255 ExpectPortalDetectionEndHTTPPhaseFailure();
1256 ExpectResolveTargetServerIPAddressStartSuccess(IPAddress::kFamilyIPv4);
Samuel Tand6c9ef62015-08-11 18:15:17 -07001257 ExpectResolveTargetServerIPAddressEndSuccess(kIPv4ServerAddress);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001258 ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingTargetServer,
Samuel Tand6c9ef62015-08-11 18:15:17 -07001259 kIPv4ServerAddress);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001260 ExpectPingHostEndFailure(ConnectionDiagnostics::kTypePingTargetServer,
Samuel Tand6c9ef62015-08-11 18:15:17 -07001261 kIPv4ServerAddress);
1262 ExpectFindRouteToHostStartSuccess(kIPv4ServerAddress);
1263 ExpectFindRouteToHostEndSuccess(kIPv4ServerAddress, true);
1264 ExpectArpTableLookupStartSuccessEndSuccess(kIPv4ServerAddress, false);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001265 VerifyStopped();
1266}
1267
1268TEST_F(ConnectionDiagnosticsTest, EndWith_IPCollisionSuccess_1) {
1269 // Portal detection ends in HTTP phase, DNS resolution succeeds, pinging the
1270 // resolved IP address fails, and we successfully get route for the IP
1271 // address. This address is remote, pinging the local gateway fails, ARP table
1272 // lookup fails, we check for IP collision and find one, so we end
1273 // diagnostics.
1274 ExpectPortalDetectionStartSuccess(kURL);
1275 ExpectPortalDetectionEndHTTPPhaseFailure();
1276 ExpectResolveTargetServerIPAddressStartSuccess(IPAddress::kFamilyIPv4);
Samuel Tand6c9ef62015-08-11 18:15:17 -07001277 ExpectResolveTargetServerIPAddressEndSuccess(kIPv4ServerAddress);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001278 ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingTargetServer,
Samuel Tand6c9ef62015-08-11 18:15:17 -07001279 kIPv4ServerAddress);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001280 ExpectPingHostEndFailure(ConnectionDiagnostics::kTypePingTargetServer,
Samuel Tand6c9ef62015-08-11 18:15:17 -07001281 kIPv4ServerAddress);
1282 ExpectFindRouteToHostStartSuccess(kIPv4ServerAddress);
1283 ExpectFindRouteToHostEndSuccess(kIPv4ServerAddress, false);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001284 ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingGateway,
1285 kIPv4GatewayAddress);
1286 ExpectPingHostEndFailure(ConnectionDiagnostics::kTypePingGateway,
1287 kIPv4GatewayAddress);
1288 ExpectArpTableLookupStartSuccessEndFailure(kIPv4GatewayAddress);
1289 ExpectCheckIPCollisionStartSuccess();
1290 ExpectCheckIPCollisionEndSuccess();
1291 VerifyStopped();
1292}
1293
1294TEST_F(ConnectionDiagnosticsTest, EndWith_IPCollisionSuccess_2) {
1295 // Portal detection ends in HTTP phase, DNS resolution succeeds, pinging the
1296 // resolved IP address fails, and we successfully get route for the IP
1297 // address. This address is local, ARP table lookup fails, we check for IP
1298 // collision and find one, so we end diagnostics.
1299 ExpectPortalDetectionStartSuccess(kURL);
1300 ExpectPortalDetectionEndHTTPPhaseFailure();
1301 ExpectResolveTargetServerIPAddressStartSuccess(IPAddress::kFamilyIPv4);
Samuel Tand6c9ef62015-08-11 18:15:17 -07001302 ExpectResolveTargetServerIPAddressEndSuccess(kIPv4ServerAddress);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001303 ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingTargetServer,
Samuel Tand6c9ef62015-08-11 18:15:17 -07001304 kIPv4ServerAddress);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001305 ExpectPingHostEndFailure(ConnectionDiagnostics::kTypePingTargetServer,
Samuel Tand6c9ef62015-08-11 18:15:17 -07001306 kIPv4ServerAddress);
1307 ExpectFindRouteToHostStartSuccess(kIPv4ServerAddress);
1308 ExpectFindRouteToHostEndSuccess(kIPv4ServerAddress, true);
1309 ExpectArpTableLookupStartSuccessEndSuccess(kIPv4ServerAddress, false);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001310 VerifyStopped();
1311}
1312
1313TEST_F(ConnectionDiagnosticsTest, EndWith_IPCollisionFailure_1) {
1314 // Portal detection ends in HTTP phase, DNS resolution succeeds, pinging the
1315 // resolved IP address fails, and we successfully get route for the IP
1316 // address. This address is remote, pinging the local gateway fails, ARP table
1317 // lookup fails, we check for IP collision and do not find one, so we end
1318 // diagnostics.
1319 ExpectPortalDetectionStartSuccess(kURL);
1320 ExpectPortalDetectionEndHTTPPhaseFailure();
1321 ExpectResolveTargetServerIPAddressStartSuccess(IPAddress::kFamilyIPv4);
Samuel Tand6c9ef62015-08-11 18:15:17 -07001322 ExpectResolveTargetServerIPAddressEndSuccess(kIPv4ServerAddress);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001323 ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingTargetServer,
Samuel Tand6c9ef62015-08-11 18:15:17 -07001324 kIPv4ServerAddress);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001325 ExpectPingHostEndFailure(ConnectionDiagnostics::kTypePingTargetServer,
Samuel Tand6c9ef62015-08-11 18:15:17 -07001326 kIPv4ServerAddress);
1327 ExpectFindRouteToHostStartSuccess(kIPv4ServerAddress);
1328 ExpectFindRouteToHostEndSuccess(kIPv4ServerAddress, false);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001329 ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingGateway,
1330 kIPv4GatewayAddress);
1331 ExpectPingHostEndFailure(ConnectionDiagnostics::kTypePingGateway,
1332 kIPv4GatewayAddress);
1333 ExpectArpTableLookupStartSuccessEndFailure(kIPv4GatewayAddress);
1334 ExpectCheckIPCollisionStartSuccess();
1335 ExpectCheckIPCollisionEndFailureGatewayArpFailed();
1336 VerifyStopped();
1337}
1338
1339TEST_F(ConnectionDiagnosticsTest, EndWith_IPCollisionFailure_2) {
1340 // Portal detection ends in HTTP phase, DNS resolution succeeds, pinging the
1341 // resolved IP address fails, and we successfully get route for the IP
1342 // address. This address is local, ARP table lookup fails, we check for IP
1343 // collision and do not find one, so we end diagnostics.
1344 ExpectPortalDetectionStartSuccess(kURL);
1345 ExpectPortalDetectionEndHTTPPhaseFailure();
1346 ExpectResolveTargetServerIPAddressStartSuccess(IPAddress::kFamilyIPv4);
Samuel Tand6c9ef62015-08-11 18:15:17 -07001347 ExpectResolveTargetServerIPAddressEndSuccess(kIPv4ServerAddress);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001348 ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingTargetServer,
Samuel Tand6c9ef62015-08-11 18:15:17 -07001349 kIPv4ServerAddress);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001350 ExpectPingHostEndFailure(ConnectionDiagnostics::kTypePingTargetServer,
Samuel Tand6c9ef62015-08-11 18:15:17 -07001351 kIPv4ServerAddress);
1352 ExpectFindRouteToHostStartSuccess(kIPv4ServerAddress);
1353 ExpectFindRouteToHostEndSuccess(kIPv4ServerAddress, true);
1354 ExpectArpTableLookupStartSuccessEndFailure(kIPv4ServerAddress);
Samuel Tan1b9546a2015-06-29 18:53:41 -07001355 ExpectCheckIPCollisionStartSuccess();
1356 ExpectCheckIPCollisionEndFailureServerArpFailed();
1357 VerifyStopped();
1358}
1359
Samuel Tan56d3c662015-08-04 18:42:07 -07001360TEST_F(ConnectionDiagnosticsTest, EndWith_kTypeNeighborTableLookupSuccess_1) {
1361 // Portal detection ends in HTTP phase, DNS resolution succeeds, pinging the
1362 // resolved IP address fails, and we successfully get route for the IP
1363 // address. This address is remote, pinging the local IPv6 gateway fails,
1364 // and we find a neighbor table entry for the gateway. End diagnostics.
1365 UseIPv6Gateway();
1366
1367 ExpectPortalDetectionStartSuccess(kURL);
1368 ExpectPortalDetectionEndHTTPPhaseFailure();
1369 ExpectResolveTargetServerIPAddressStartSuccess(IPAddress::kFamilyIPv6);
Samuel Tand6c9ef62015-08-11 18:15:17 -07001370 ExpectResolveTargetServerIPAddressEndSuccess(kIPv6ServerAddress);
Samuel Tan56d3c662015-08-04 18:42:07 -07001371 ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingTargetServer,
Samuel Tand6c9ef62015-08-11 18:15:17 -07001372 kIPv6ServerAddress);
Samuel Tan56d3c662015-08-04 18:42:07 -07001373 ExpectPingHostEndFailure(ConnectionDiagnostics::kTypePingTargetServer,
Samuel Tand6c9ef62015-08-11 18:15:17 -07001374 kIPv6ServerAddress);
1375 ExpectFindRouteToHostStartSuccess(kIPv6ServerAddress);
1376 ExpectFindRouteToHostEndSuccess(kIPv6ServerAddress, false);
Samuel Tan56d3c662015-08-04 18:42:07 -07001377 ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingGateway,
1378 kIPv6GatewayAddress);
1379 ExpectPingHostEndFailure(ConnectionDiagnostics::kTypePingGateway,
1380 kIPv6GatewayAddress);
1381 ExpectNeighborTableLookupStartSuccess(kIPv6GatewayAddress);
1382 ExpectNeighborTableLookupEndSuccess(kIPv6GatewayAddress, true);
1383 VerifyStopped();
1384}
1385
1386TEST_F(ConnectionDiagnosticsTest, EndWith_kTypeNeighborTableLookupSuccess_2) {
1387 // Portal detection ends in HTTP phase, DNS resolution succeeds, pinging the
1388 // resolved IP address fails, we succeed in getting a route for the IP
1389 // address. This address is a local IPv6 address, and we find a neighbor table
1390 // entry for it. End diagnostics.
1391 UseIPv6Gateway();
1392
1393 ExpectPortalDetectionStartSuccess(kURL);
1394 ExpectPortalDetectionEndHTTPPhaseFailure();
1395 ExpectResolveTargetServerIPAddressStartSuccess(IPAddress::kFamilyIPv6);
Samuel Tand6c9ef62015-08-11 18:15:17 -07001396 ExpectResolveTargetServerIPAddressEndSuccess(kIPv6ServerAddress);
Samuel Tan56d3c662015-08-04 18:42:07 -07001397 ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingTargetServer,
Samuel Tand6c9ef62015-08-11 18:15:17 -07001398 kIPv6ServerAddress);
Samuel Tan56d3c662015-08-04 18:42:07 -07001399 ExpectPingHostEndFailure(ConnectionDiagnostics::kTypePingTargetServer,
Samuel Tand6c9ef62015-08-11 18:15:17 -07001400 kIPv6ServerAddress);
1401 ExpectFindRouteToHostStartSuccess(kIPv6ServerAddress);
1402 ExpectFindRouteToHostEndSuccess(kIPv6ServerAddress, true);
1403 ExpectNeighborTableLookupStartSuccess(kIPv6ServerAddress);
1404 ExpectNeighborTableLookupEndSuccess(kIPv6ServerAddress, false);
Samuel Tan56d3c662015-08-04 18:42:07 -07001405 VerifyStopped();
1406}
1407
1408TEST_F(ConnectionDiagnosticsTest, EndWith_kTypeNeighborTableLookupFailure_1) {
1409 // Portal detection ends in HTTP phase, DNS resolution succeeds, pinging the
1410 // resolved IP address fails, and we successfully get route for the IP
1411 // address. This address is remote, pinging the local IPv6 gateway fails, and
1412 // we find a neighbor table entry for the gateway, but it is not marked as
1413 // reachable. End diagnostics.
1414 UseIPv6Gateway();
1415
1416 ExpectPortalDetectionStartSuccess(kURL);
1417 ExpectPortalDetectionEndHTTPPhaseFailure();
1418 ExpectResolveTargetServerIPAddressStartSuccess(IPAddress::kFamilyIPv6);
Samuel Tand6c9ef62015-08-11 18:15:17 -07001419 ExpectResolveTargetServerIPAddressEndSuccess(kIPv6ServerAddress);
Samuel Tan56d3c662015-08-04 18:42:07 -07001420 ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingTargetServer,
Samuel Tand6c9ef62015-08-11 18:15:17 -07001421 kIPv6ServerAddress);
Samuel Tan56d3c662015-08-04 18:42:07 -07001422 ExpectPingHostEndFailure(ConnectionDiagnostics::kTypePingTargetServer,
Samuel Tand6c9ef62015-08-11 18:15:17 -07001423 kIPv6ServerAddress);
1424 ExpectFindRouteToHostStartSuccess(kIPv6ServerAddress);
1425 ExpectFindRouteToHostEndSuccess(kIPv6ServerAddress, false);
Samuel Tan56d3c662015-08-04 18:42:07 -07001426 ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingGateway,
1427 kIPv6GatewayAddress);
1428 ExpectPingHostEndFailure(ConnectionDiagnostics::kTypePingGateway,
1429 kIPv6GatewayAddress);
1430 ExpectNeighborTableLookupStartSuccess(kIPv6GatewayAddress);
1431 ExpectNeighborTableLookupEndFailureNotReachable(kIPv6GatewayAddress, true);
1432 VerifyStopped();
1433}
1434
1435TEST_F(ConnectionDiagnosticsTest, EndWith_kTypeNeighborTableLookupFailure_2) {
1436 // Portal detection ends in HTTP phase, DNS resolution succeeds, pinging the
1437 // resolved IP address fails, we succeed in getting a route for the IP
1438 // address. This address is a local IPv6 address, and we do not find a
1439 // neighbor table entry for it. End diagnostics.
1440 UseIPv6Gateway();
1441
1442 ExpectPortalDetectionStartSuccess(kURL);
1443 ExpectPortalDetectionEndHTTPPhaseFailure();
1444 ExpectResolveTargetServerIPAddressStartSuccess(IPAddress::kFamilyIPv6);
Samuel Tand6c9ef62015-08-11 18:15:17 -07001445 ExpectResolveTargetServerIPAddressEndSuccess(kIPv6ServerAddress);
Samuel Tan56d3c662015-08-04 18:42:07 -07001446 ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingTargetServer,
Samuel Tand6c9ef62015-08-11 18:15:17 -07001447 kIPv6ServerAddress);
Samuel Tan56d3c662015-08-04 18:42:07 -07001448 ExpectPingHostEndFailure(ConnectionDiagnostics::kTypePingTargetServer,
Samuel Tand6c9ef62015-08-11 18:15:17 -07001449 kIPv6ServerAddress);
1450 ExpectFindRouteToHostStartSuccess(kIPv6ServerAddress);
1451 ExpectFindRouteToHostEndSuccess(kIPv6ServerAddress, true);
1452 ExpectNeighborTableLookupStartSuccess(kIPv6ServerAddress);
1453 ExpectNeighborTableLookupEndFailureNoEntry(kIPv6ServerAddress, false);
Samuel Tan56d3c662015-08-04 18:42:07 -07001454 VerifyStopped();
1455}
1456
Samuel Tan1b9546a2015-06-29 18:53:41 -07001457} // namespace shill