• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
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 //
16 
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"
39 #include "shill/net/mock_rtnl_handler.h"
40 
41 using base::Bind;
42 using base::Callback;
43 using base::Unretained;
44 using std::string;
45 using std::vector;
46 using testing::_;
47 using testing::NiceMock;
48 using testing::Return;
49 using testing::ReturnRef;
50 using testing::SetArgumentPointee;
51 using testing::Test;
52 
53 namespace {
54 const char kInterfaceName[] = "int0";
55 const char kDNSServer0[] = "8.8.8.8";
56 const char kDNSServer1[] = "8.8.4.4";
57 const char kURL[] = "http://www.gstatic.com/generate_204";
58 const char kLocalMacAddressASCIIString[] = "123456";
59 const char kArpReplySenderMacAddressASCIIString[] = "345678";
60 const char* kDNSServers[] = {kDNSServer0, kDNSServer1};
61 const shill::IPAddress kIPv4LocalAddress("100.200.43.22");
62 const shill::IPAddress kIPv4ServerAddress("8.8.8.8");
63 const shill::IPAddress kIPv6ServerAddress("fe80::1aa9:5ff:7ebf:14c5");
64 const shill::IPAddress kIPv4GatewayAddress("192.168.1.1");
65 const shill::IPAddress kIPv6GatewayAddress("fee2::11b2:53f:13be:125e");
66 const vector<base::TimeDelta> kEmptyResult;
67 const vector<base::TimeDelta> kNonEmptyResult{
68     base::TimeDelta::FromMilliseconds(10)};
69 }  // namespace
70 
71 namespace shill {
72 
73 MATCHER_P(IsSameIPAddress, ip_addr, "") {
74   return arg.Equals(ip_addr);
75 }
76 
77 MATCHER_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]);
93       *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       }
103       return false;
104     }
105   }
106   return true;
107 }
108 
109 MATCHER_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 
140 class ConnectionDiagnosticsTest : public Test {
141  public:
ConnectionDiagnosticsTest()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_),
150         manager_(&control_, &dispatcher_, &metrics_),
151         device_info_(&control_, &dispatcher_, &metrics_, &manager_),
152         connection_(new NiceMock<MockConnection>(&device_info_)),
153         connection_diagnostics_(connection_, &dispatcher_, &metrics_,
154                                 &device_info_,
155                                 callback_target_.result_callback()),
156         portal_detector_(new NiceMock<MockPortalDetector>(connection_)) {}
~ConnectionDiagnosticsTest()157   virtual ~ConnectionDiagnosticsTest() {}
158 
SetUp()159   virtual void SetUp() {
160     ASSERT_EQ(IPAddress::kFamilyIPv4, kIPv4LocalAddress.family());
161     ASSERT_EQ(IPAddress::kFamilyIPv4, kIPv4ServerAddress.family());
162     ASSERT_EQ(IPAddress::kFamilyIPv4, kIPv4GatewayAddress.family());
163     ASSERT_EQ(IPAddress::kFamilyIPv6, kIPv6ServerAddress.family());
164     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_;
175     connection_diagnostics_.rtnl_handler_ = &rtnl_handler_;
176     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 
TearDown()190   virtual void TearDown() {}
191 
192  protected:
193   class CallbackTarget {
194    public:
CallbackTarget()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>&)>&
result_callback()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 
callback_target()213   CallbackTarget& callback_target() {
214     return callback_target_;
215   }
216 
UseIPv6Gateway()217   void UseIPv6Gateway() {
218     EXPECT_CALL(*connection_.get(), gateway())
219         .WillRepeatedly(ReturnRef(gateway_ipv6_address_));
220   }
221 
AddExpectedEvent(ConnectionDiagnostics::Type type,ConnectionDiagnostics::Phase phase,ConnectionDiagnostics::Result result)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 
AddActualEvent(ConnectionDiagnostics::Type type,ConnectionDiagnostics::Phase phase,ConnectionDiagnostics::Result result)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 
DoesPreviousEventMatch(ConnectionDiagnostics::Type type,ConnectionDiagnostics::Phase phase,ConnectionDiagnostics::Result result,size_t num_events_ago)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.
Start(const string & url_string)250       bool Start(const string& url_string) {
251     return connection_diagnostics_.Start(url_string);
252   }
253 
VerifyStopped()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());
263     EXPECT_FALSE(connection_diagnostics_.neighbor_msg_listener_.get());
264     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());
272     EXPECT_TRUE(connection_diagnostics_.neighbor_request_timeout_callback_
273                     .IsCancelled());
274   }
275 
ExpectIcmpSessionStop()276   void ExpectIcmpSessionStop() {
277     EXPECT_CALL(*icmp_session_, Stop());
278   }
279 
ExpectPortalDetectionStartSuccess(const string & url_string)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 
ExpectPortalDetectionEndContentPhaseSuccess()291   void ExpectPortalDetectionEndContentPhaseSuccess() {
292     ExpectPortalDetectionEnd(
293         ConnectionDiagnostics::kPhasePortalDetectionEndContent,
294         ConnectionDiagnostics::kResultSuccess,
295         ConnectivityTrial::kPhaseContent,
296         ConnectivityTrial::kStatusSuccess);
297   }
298 
ExpectPortalDetectionEndContentPhaseFailure()299   void ExpectPortalDetectionEndContentPhaseFailure() {
300     ExpectPortalDetectionEnd(
301         ConnectionDiagnostics::kPhasePortalDetectionEndContent,
302         ConnectionDiagnostics::kResultFailure,
303         ConnectivityTrial::kPhaseContent,
304         ConnectivityTrial::kStatusFailure);
305   }
306 
ExpectPortalDetectionEndDNSPhaseFailure()307   void ExpectPortalDetectionEndDNSPhaseFailure() {
308     ExpectPortalDetectionEnd(ConnectionDiagnostics::kPhasePortalDetectionEndDNS,
309                              ConnectionDiagnostics::kResultFailure,
310                              ConnectivityTrial::kPhaseDNS,
311                              ConnectivityTrial::kStatusFailure);
312   }
313 
ExpectPortalDetectionEndDNSPhaseTimeout()314   void ExpectPortalDetectionEndDNSPhaseTimeout() {
315     ExpectPortalDetectionEnd(ConnectionDiagnostics::kPhasePortalDetectionEndDNS,
316                              ConnectionDiagnostics::kResultTimeout,
317                              ConnectivityTrial::kPhaseDNS,
318                              ConnectivityTrial::kStatusTimeout);
319   }
320 
ExpectPortalDetectionEndHTTPPhaseFailure()321   void ExpectPortalDetectionEndHTTPPhaseFailure() {
322     ExpectPortalDetectionEnd(
323         ConnectionDiagnostics::kPhasePortalDetectionEndOther,
324         ConnectionDiagnostics::kResultFailure,
325         ConnectivityTrial::kPhaseHTTP,
326         ConnectivityTrial::kStatusFailure);
327   }
328 
ExpectPingDNSServersStartSuccess()329   void ExpectPingDNSServersStartSuccess() {
330     ExpectPingDNSSeversStart(true, "");
331   }
332 
ExpectPingDNSSeversStartFailureAllAddressesInvalid()333   void ExpectPingDNSSeversStartFailureAllAddressesInvalid() {
334     ExpectPingDNSSeversStart(false,
335                              ConnectionDiagnostics::kIssueDNSServersInvalid);
336   }
337 
ExpectPingDNSSeversStartFailureAllIcmpSessionsFailed()338   void ExpectPingDNSSeversStartFailureAllIcmpSessionsFailed() {
339     ExpectPingDNSSeversStart(false, ConnectionDiagnostics::kIssueInternalError);
340   }
341 
ExpectPingDNSServersEndSuccessRetriesLeft()342   void ExpectPingDNSServersEndSuccessRetriesLeft() {
343     ExpectPingDNSServersEndSuccess(true);
344   }
345 
ExpectPingDNSServersEndSuccessNoRetriesLeft()346   void ExpectPingDNSServersEndSuccessNoRetriesLeft() {
347     ExpectPingDNSServersEndSuccess(false);
348   }
349 
ExpectPingDNSServersEndFailure()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 
ExpectResolveTargetServerIPAddressStartSuccess(IPAddress::Family family)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 
ExpectResolveTargetServerIPAddressEndSuccess(const IPAddress & resolved_address)383   void ExpectResolveTargetServerIPAddressEndSuccess(
384       const IPAddress& resolved_address) {
385     ExpectResolveTargetServerIPAddressEnd(ConnectionDiagnostics::kResultSuccess,
386                                           resolved_address);
387   }
388 
ExpectResolveTargetServerIPAddressEndTimeout()389   void ExpectResolveTargetServerIPAddressEndTimeout() {
390     ExpectResolveTargetServerIPAddressEnd(ConnectionDiagnostics::kResultTimeout,
391                                           IPAddress(IPAddress::kFamilyIPv4));
392   }
393 
ExpectResolveTargetServerIPAddressEndFailure()394   void ExpectResolveTargetServerIPAddressEndFailure() {
395     ExpectResolveTargetServerIPAddressEnd(ConnectionDiagnostics::kResultFailure,
396                                           IPAddress(IPAddress::kFamilyIPv4));
397   }
398 
ExpectPingHostStartSuccess(ConnectionDiagnostics::Type ping_event_type,const IPAddress & address)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 
ExpectPingHostStartFailure(ConnectionDiagnostics::Type ping_event_type,const IPAddress & address)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));
414     EXPECT_CALL(metrics_, NotifyConnectionDiagnosticsIssue(
415                               ConnectionDiagnostics::kIssueInternalError));
416     EXPECT_CALL(callback_target(),
417                 ResultCallback(ConnectionDiagnostics::kIssueInternalError,
418                                IsEventList(expected_events_)));
419     connection_diagnostics_.PingHost(address);
420   }
421 
ExpectPingHostEndSuccess(ConnectionDiagnostics::Type ping_event_type,const IPAddress & address)422   void ExpectPingHostEndSuccess(ConnectionDiagnostics::Type ping_event_type,
423                                 const IPAddress& address) {
424     AddExpectedEvent(ping_event_type, ConnectionDiagnostics::kPhaseEnd,
425                      ConnectionDiagnostics::kResultSuccess);
426     const string& issue =
427         ping_event_type == ConnectionDiagnostics::kTypePingGateway
428             ? ConnectionDiagnostics::kIssueGatewayUpstream
429             : ConnectionDiagnostics::kIssueHTTPBrokenPortal;
430     EXPECT_CALL(metrics_, NotifyConnectionDiagnosticsIssue(issue));
431     EXPECT_CALL(callback_target(),
432                 ResultCallback(issue, IsEventList(expected_events_)));
433     connection_diagnostics_.OnPingHostComplete(ping_event_type, address,
434                                                kNonEmptyResult);
435   }
436 
ExpectPingHostEndFailure(ConnectionDiagnostics::Type ping_event_type,const IPAddress & address)437   void ExpectPingHostEndFailure(ConnectionDiagnostics::Type ping_event_type,
438                                 const IPAddress& address) {
439     AddExpectedEvent(ping_event_type, ConnectionDiagnostics::kPhaseEnd,
440                      ConnectionDiagnostics::kResultFailure);
441     // 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(_));
445     connection_diagnostics_.OnPingHostComplete(ping_event_type, address,
446                                                kEmptyResult);
447   }
448 
ExpectFindRouteToHostStartSuccess(const IPAddress & address)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 
ExpectFindRouteToHostEndSuccess(const IPAddress & address_queried,bool is_local_address)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 
482     // 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(_));
486     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 
ExpectFindRouteToHostEndFailure()493   void ExpectFindRouteToHostEndFailure() {
494     AddExpectedEvent(ConnectionDiagnostics::kTypeFindRoute,
495                      ConnectionDiagnostics::kPhaseEnd,
496                      ConnectionDiagnostics::kResultFailure);
497     EXPECT_CALL(metrics_, NotifyConnectionDiagnosticsIssue(
498                               ConnectionDiagnostics::kIssueRouting));
499     EXPECT_CALL(callback_target(),
500                 ResultCallback(ConnectionDiagnostics::kIssueRouting,
501                                IsEventList(expected_events_)));
502     connection_diagnostics_.OnRouteQueryTimeout();
503   }
504 
ExpectArpTableLookupStartSuccessEndSuccess(const IPAddress & address,bool is_gateway)505   void ExpectArpTableLookupStartSuccessEndSuccess(const IPAddress& address,
506                                                   bool is_gateway) {
507     ExpectArpTableLookup(address, true, is_gateway);
508   }
509 
ExpectArpTableLookupStartSuccessEndFailure(const IPAddress & address)510   void ExpectArpTableLookupStartSuccessEndFailure(const IPAddress& address) {
511     ExpectArpTableLookup(address, false, false);
512   }
513 
ExpectNeighborTableLookupStartSuccess(const IPAddress & address)514   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 
ExpectNeighborTableLookupEndSuccess(const IPAddress & address_queried,bool is_gateway)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());
537     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_)));
543     connection_diagnostics_.OnNeighborMsgReceived(address_queried, msg);
544   }
545 
ExpectNeighborTableLookupEndFailureNotReachable(const IPAddress & address_queried,bool is_gateway)546   void ExpectNeighborTableLookupEndFailureNotReachable(
547       const IPAddress& address_queried, bool is_gateway) {
548     ExpectNeighborTableLookupEndFailure(address_queried, is_gateway, false);
549   }
550 
ExpectNeighborTableLookupEndFailureNoEntry(const IPAddress & address_queried,bool is_gateway)551   void ExpectNeighborTableLookupEndFailureNoEntry(
552       const IPAddress& address_queried, bool is_gateway) {
553     ExpectNeighborTableLookupEndFailure(address_queried, is_gateway, true);
554   }
555 
ExpectCheckIPCollisionStartSuccess()556   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 
ExpectCheckIPCollisionEndSuccess()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_);
585     EXPECT_CALL(metrics_, NotifyConnectionDiagnosticsIssue(
586                               ConnectionDiagnostics::kIssueIPCollision));
587     EXPECT_CALL(callback_target(),
588                 ResultCallback(ConnectionDiagnostics::kIssueIPCollision,
589                                IsEventList(expected_events_)));
590     connection_diagnostics_.OnArpReplyReceived(1);
591   }
592 
ExpectCheckIPCollisionEndFailureGatewayArpFailed()593   void ExpectCheckIPCollisionEndFailureGatewayArpFailed() {
594     ExpectCheckIPCollisionEndFailure(
595         ConnectionDiagnostics::kIssueGatewayArpFailed);
596   }
597 
ExpectCheckIPCollisionEndFailureServerArpFailed()598   void ExpectCheckIPCollisionEndFailureServerArpFailed() {
599     ExpectCheckIPCollisionEndFailure(
600         ConnectionDiagnostics::kIssueServerArpFailed);
601   }
602 
603  private:
ExpectPortalDetectionEnd(ConnectionDiagnostics::Phase diag_phase,ConnectionDiagnostics::Result diag_result,ConnectivityTrial::Phase trial_phase,ConnectivityTrial::Status trial_status)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) {
611       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_)));
617 
618     } else if (diag_phase ==
619                    ConnectionDiagnostics::kPhasePortalDetectionEndDNS &&
620                diag_result == ConnectionDiagnostics::kResultFailure) {
621       EXPECT_CALL(metrics_,
622                   NotifyConnectionDiagnosticsIssue(
623                       ConnectionDiagnostics::kIssueDNSServerMisconfig));
624       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.
ExpectPingDNSSeversStart(bool is_success,const string & expected_issue)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) {
673       EXPECT_CALL(metrics_, NotifyConnectionDiagnosticsIssue(_)).Times(0);
674       EXPECT_CALL(callback_target(), ResultCallback(_, _)).Times(0);
675     } else {
676       EXPECT_CALL(metrics_, NotifyConnectionDiagnosticsIssue(expected_issue));
677       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 
ExpectResolveTargetServerIPAddressEnd(ConnectionDiagnostics::Result result,const IPAddress & resolved_address)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);
704       EXPECT_CALL(metrics_,
705                   NotifyConnectionDiagnosticsIssue(
706                       ConnectionDiagnostics::kIssueDNSServerMisconfig));
707       EXPECT_CALL(
708           callback_target(),
709           ResultCallback(ConnectionDiagnostics::kIssueDNSServerMisconfig,
710                          IsEventList(expected_events_)));
711     }
712     connection_diagnostics_.OnDNSResolutionComplete(error, resolved_address);
713   }
714 
ExpectPingDNSServersEndSuccess(bool retries_left)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(_));
730       EXPECT_CALL(metrics_, NotifyConnectionDiagnosticsIssue(_)).Times(0);
731       EXPECT_CALL(callback_target(), ResultCallback(_, _)).Times(0);
732     } else {
733       EXPECT_CALL(dispatcher_, PostTask(_)).Times(0);
734       EXPECT_CALL(metrics_,
735                   NotifyConnectionDiagnosticsIssue(
736                       ConnectionDiagnostics::kIssueDNSServerNoResponse));
737       EXPECT_CALL(
738           callback_target(),
739           ResultCallback(ConnectionDiagnostics::kIssueDNSServerNoResponse,
740                          IsEventList(expected_events_)));
741     }
742     connection_diagnostics_.OnPingDNSServerComplete(1, kNonEmptyResult);
743   }
744 
ExpectArpTableLookup(const IPAddress & address,bool success,bool is_gateway)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) {
759       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_)));
765     } else {
766       // Checking for IP collision.
767       EXPECT_CALL(dispatcher_, PostTask(_));
768     }
769     connection_diagnostics_.FindArpTableEntry(address);
770   }
771 
ExpectCheckIPCollisionEndFailure(const string & expected_issue)772   void ExpectCheckIPCollisionEndFailure(const string& expected_issue) {
773     AddExpectedEvent(ConnectionDiagnostics::kTypeIPCollisionCheck,
774                      ConnectionDiagnostics::kPhaseEnd,
775                      ConnectionDiagnostics::kResultFailure);
776     EXPECT_CALL(metrics_, NotifyConnectionDiagnosticsIssue(expected_issue));
777     EXPECT_CALL(callback_target(),
778                 ResultCallback(expected_issue, IsEventList(expected_events_)));
779     connection_diagnostics_.OnArpRequestTimeout();
780   }
781 
ExpectNeighborTableLookupEndFailure(const IPAddress & address_queried,bool is_gateway,bool is_timeout)782   void ExpectNeighborTableLookupEndFailure(const IPAddress& address_queried,
783                                            bool is_gateway, bool is_timeout) {
784     AddExpectedEvent(ConnectionDiagnostics::kTypeNeighborTableLookup,
785                      ConnectionDiagnostics::kPhaseEnd,
786                      ConnectionDiagnostics::kResultFailure);
787     string issue;
788     if (is_timeout) {
789       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_)));
794       connection_diagnostics_.OnNeighborTableRequestTimeout(address_queried);
795     } else {
796       issue =
797           is_gateway
798               ? ConnectionDiagnostics::kIssueGatewayNeighborEntryNotConnected
799               : ConnectionDiagnostics::kIssueServerNeighborEntryNotConnected;
800       EXPECT_CALL(metrics_, NotifyConnectionDiagnosticsIssue(issue));
801       EXPECT_CALL(
802           callback_target(),
803           ResultCallback(issue,
804                          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 
815   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_;
823   NiceMock<MockMetrics> metrics_;
824   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_;
830   NiceMock<MockRTNLHandler> rtnl_handler_;
831   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 
TEST_F(ConnectionDiagnosticsTest,DoesPreviousEventMatch)847 TEST_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 
TEST_F(ConnectionDiagnosticsTest,StartWhileRunning)893 TEST_F(ConnectionDiagnosticsTest, StartWhileRunning) {
894   ExpectPortalDetectionStartSuccess(kURL);  // Start diagnostics;
895   EXPECT_FALSE(Start(kURL));
896 }
897 
TEST_F(ConnectionDiagnosticsTest,StartWithBadURL)898 TEST_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 
TEST_F(ConnectionDiagnosticsTest,EndWith_InternalError)908 TEST_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);
915   ExpectResolveTargetServerIPAddressEndSuccess(kIPv4ServerAddress);
916   ExpectPingHostStartFailure(ConnectionDiagnostics::kTypePingTargetServer,
917                              kIPv4ServerAddress);
918   VerifyStopped();
919 }
920 
TEST_F(ConnectionDiagnosticsTest,EndWith_PortalDetectionContentPhase_Success)921 TEST_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 
TEST_F(ConnectionDiagnosticsTest,EndWith_PortalDetectionContentPhase_Failure)928 TEST_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 
TEST_F(ConnectionDiagnosticsTest,EndWith_DNSFailure_1)936 TEST_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 
TEST_F(ConnectionDiagnosticsTest,EndWith_DNSFailure_2)944 TEST_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 
TEST_F(ConnectionDiagnosticsTest,EndWith_PingDNSServerStartFailure_1)954 TEST_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 
TEST_F(ConnectionDiagnosticsTest,EndWith_PingDNSServerStartFailure_2)963 TEST_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 
TEST_F(ConnectionDiagnosticsTest,EndWith_PingDNSServerEndSuccess_NoRetries_1)973 TEST_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 
TEST_F(ConnectionDiagnosticsTest,EndWith_PingDNSServerEndSuccess_NoRetries_2)993 TEST_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 
TEST_F(ConnectionDiagnosticsTest,EndWith_PingTargetIPSuccess_1)1010 TEST_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);
1016   ExpectResolveTargetServerIPAddressEndSuccess(kIPv4ServerAddress);
1017   ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingTargetServer,
1018                              kIPv4ServerAddress);
1019   ExpectPingHostEndSuccess(ConnectionDiagnostics::kTypePingTargetServer,
1020                            kIPv4ServerAddress);
1021   VerifyStopped();
1022 }
1023 
TEST_F(ConnectionDiagnosticsTest,EndWith_PingTargetIPSuccess_2)1024 TEST_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);
1033   ExpectResolveTargetServerIPAddressEndSuccess(kIPv4ServerAddress);
1034   ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingTargetServer,
1035                              kIPv4ServerAddress);
1036   ExpectPingHostEndSuccess(ConnectionDiagnostics::kTypePingTargetServer,
1037                            kIPv4ServerAddress);
1038   VerifyStopped();
1039 }
1040 
TEST_F(ConnectionDiagnosticsTest,EndWith_PingTargetIPSuccess_3)1041 TEST_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);
1052   ExpectResolveTargetServerIPAddressEndSuccess(kIPv4ServerAddress);
1053   ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingTargetServer,
1054                              kIPv4ServerAddress);
1055   ExpectPingHostEndSuccess(ConnectionDiagnostics::kTypePingTargetServer,
1056                            kIPv4ServerAddress);
1057   VerifyStopped();
1058 }
1059 
TEST_F(ConnectionDiagnosticsTest,EndWith_FindRouteFailure_1)1060 TEST_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);
1067   ExpectResolveTargetServerIPAddressEndSuccess(kIPv4ServerAddress);
1068   ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingTargetServer,
1069                              kIPv4ServerAddress);
1070   ExpectPingHostEndFailure(ConnectionDiagnostics::kTypePingTargetServer,
1071                            kIPv4ServerAddress);
1072   ExpectFindRouteToHostStartSuccess(kIPv4ServerAddress);
1073   ExpectFindRouteToHostEndFailure();
1074   VerifyStopped();
1075 }
1076 
TEST_F(ConnectionDiagnosticsTest,EndWith_FindRoute_Failure_2)1077 TEST_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);
1086   ExpectResolveTargetServerIPAddressEndSuccess(kIPv4ServerAddress);
1087   ExpectPingHostEndFailure(ConnectionDiagnostics::kTypePingTargetServer,
1088                            kIPv4ServerAddress);
1089   ExpectFindRouteToHostStartSuccess(kIPv4ServerAddress);
1090   ExpectFindRouteToHostEndFailure();
1091   VerifyStopped();
1092 }
1093 
TEST_F(ConnectionDiagnosticsTest,EndWith_FindRouteFailure_3)1094 TEST_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);
1106   ExpectResolveTargetServerIPAddressEndSuccess(kIPv4ServerAddress);
1107   ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingTargetServer,
1108                              kIPv4ServerAddress);
1109   ExpectPingHostEndFailure(ConnectionDiagnostics::kTypePingTargetServer,
1110                            kIPv4ServerAddress);
1111   ExpectFindRouteToHostStartSuccess(kIPv4ServerAddress);
1112   ExpectFindRouteToHostEndFailure();
1113   VerifyStopped();
1114 }
1115 
TEST_F(ConnectionDiagnosticsTest,EndWith_FindRouteFailure_4)1116 TEST_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 
TEST_F(ConnectionDiagnosticsTest,EndWith_PingGatewaySuccess_1_IPv4)1128 TEST_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);
1136   ExpectResolveTargetServerIPAddressEndSuccess(kIPv4ServerAddress);
1137   ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingTargetServer,
1138                              kIPv4ServerAddress);
1139   ExpectPingHostEndFailure(ConnectionDiagnostics::kTypePingTargetServer,
1140                            kIPv4ServerAddress);
1141   ExpectFindRouteToHostStartSuccess(kIPv4ServerAddress);
1142   ExpectFindRouteToHostEndSuccess(kIPv4ServerAddress, false);
1143   ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingGateway,
1144                              kIPv4GatewayAddress);
1145   ExpectPingHostEndSuccess(ConnectionDiagnostics::kTypePingGateway,
1146                            kIPv4GatewayAddress);
1147   VerifyStopped();
1148 }
1149 
TEST_F(ConnectionDiagnosticsTest,EndWith_PingGatewaySuccess_1_IPv6)1150 TEST_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);
1158   ExpectResolveTargetServerIPAddressEndSuccess(kIPv6ServerAddress);
1159   ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingTargetServer,
1160                              kIPv6ServerAddress);
1161   ExpectPingHostEndFailure(ConnectionDiagnostics::kTypePingTargetServer,
1162                            kIPv6ServerAddress);
1163   ExpectFindRouteToHostStartSuccess(kIPv6ServerAddress);
1164   ExpectFindRouteToHostEndSuccess(kIPv6ServerAddress, false);
1165   ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingGateway,
1166                              kIPv6GatewayAddress);
1167   ExpectPingHostEndSuccess(ConnectionDiagnostics::kTypePingGateway,
1168                            kIPv6GatewayAddress);
1169   VerifyStopped();
1170 }
1171 
TEST_F(ConnectionDiagnosticsTest,EndWith_PingGatewaySuccess_2)1172 TEST_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);
1182   ExpectResolveTargetServerIPAddressEndSuccess(kIPv4ServerAddress);
1183   ExpectPingHostEndFailure(ConnectionDiagnostics::kTypePingTargetServer,
1184                            kIPv4ServerAddress);
1185   ExpectFindRouteToHostStartSuccess(kIPv4ServerAddress);
1186   ExpectFindRouteToHostEndSuccess(kIPv4ServerAddress, false);
1187   ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingGateway,
1188                              kIPv4GatewayAddress);
1189   ExpectPingHostEndSuccess(ConnectionDiagnostics::kTypePingGateway,
1190                            kIPv4GatewayAddress);
1191   VerifyStopped();
1192 }
1193 
TEST_F(ConnectionDiagnosticsTest,EndWith_PingGatewaySuccess_3)1194 TEST_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);
1207   ExpectResolveTargetServerIPAddressEndSuccess(kIPv4ServerAddress);
1208   ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingTargetServer,
1209                              kIPv4ServerAddress);
1210   ExpectPingHostEndFailure(ConnectionDiagnostics::kTypePingTargetServer,
1211                            kIPv4ServerAddress);
1212   ExpectFindRouteToHostStartSuccess(kIPv4ServerAddress);
1213   ExpectFindRouteToHostEndSuccess(kIPv4ServerAddress, false);
1214   ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingGateway,
1215                              kIPv4GatewayAddress);
1216   ExpectPingHostEndSuccess(ConnectionDiagnostics::kTypePingGateway,
1217                            kIPv4GatewayAddress);
1218   VerifyStopped();
1219 }
1220 
1221 // 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 
TEST_F(ConnectionDiagnosticsTest,EndWith_FindArpTableEntrySuccess_1)1226 TEST_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);
1234   ExpectResolveTargetServerIPAddressEndSuccess(kIPv4ServerAddress);
1235   ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingTargetServer,
1236                              kIPv4ServerAddress);
1237   ExpectPingHostEndFailure(ConnectionDiagnostics::kTypePingTargetServer,
1238                            kIPv4ServerAddress);
1239   ExpectFindRouteToHostStartSuccess(kIPv4ServerAddress);
1240   ExpectFindRouteToHostEndSuccess(kIPv4ServerAddress, false);
1241   ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingGateway,
1242                              kIPv4GatewayAddress);
1243   ExpectPingHostEndFailure(ConnectionDiagnostics::kTypePingGateway,
1244                            kIPv4GatewayAddress);
1245   ExpectArpTableLookupStartSuccessEndSuccess(kIPv4GatewayAddress, true);
1246   VerifyStopped();
1247 }
1248 
TEST_F(ConnectionDiagnosticsTest,EndWith_FindArpTableEntrySuccess_2)1249 TEST_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);
1257   ExpectResolveTargetServerIPAddressEndSuccess(kIPv4ServerAddress);
1258   ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingTargetServer,
1259                              kIPv4ServerAddress);
1260   ExpectPingHostEndFailure(ConnectionDiagnostics::kTypePingTargetServer,
1261                            kIPv4ServerAddress);
1262   ExpectFindRouteToHostStartSuccess(kIPv4ServerAddress);
1263   ExpectFindRouteToHostEndSuccess(kIPv4ServerAddress, true);
1264   ExpectArpTableLookupStartSuccessEndSuccess(kIPv4ServerAddress, false);
1265   VerifyStopped();
1266 }
1267 
TEST_F(ConnectionDiagnosticsTest,EndWith_IPCollisionSuccess_1)1268 TEST_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);
1277   ExpectResolveTargetServerIPAddressEndSuccess(kIPv4ServerAddress);
1278   ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingTargetServer,
1279                              kIPv4ServerAddress);
1280   ExpectPingHostEndFailure(ConnectionDiagnostics::kTypePingTargetServer,
1281                            kIPv4ServerAddress);
1282   ExpectFindRouteToHostStartSuccess(kIPv4ServerAddress);
1283   ExpectFindRouteToHostEndSuccess(kIPv4ServerAddress, false);
1284   ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingGateway,
1285                              kIPv4GatewayAddress);
1286   ExpectPingHostEndFailure(ConnectionDiagnostics::kTypePingGateway,
1287                            kIPv4GatewayAddress);
1288   ExpectArpTableLookupStartSuccessEndFailure(kIPv4GatewayAddress);
1289   ExpectCheckIPCollisionStartSuccess();
1290   ExpectCheckIPCollisionEndSuccess();
1291   VerifyStopped();
1292 }
1293 
TEST_F(ConnectionDiagnosticsTest,EndWith_IPCollisionSuccess_2)1294 TEST_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);
1302   ExpectResolveTargetServerIPAddressEndSuccess(kIPv4ServerAddress);
1303   ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingTargetServer,
1304                              kIPv4ServerAddress);
1305   ExpectPingHostEndFailure(ConnectionDiagnostics::kTypePingTargetServer,
1306                            kIPv4ServerAddress);
1307   ExpectFindRouteToHostStartSuccess(kIPv4ServerAddress);
1308   ExpectFindRouteToHostEndSuccess(kIPv4ServerAddress, true);
1309   ExpectArpTableLookupStartSuccessEndSuccess(kIPv4ServerAddress, false);
1310   VerifyStopped();
1311 }
1312 
TEST_F(ConnectionDiagnosticsTest,EndWith_IPCollisionFailure_1)1313 TEST_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);
1322   ExpectResolveTargetServerIPAddressEndSuccess(kIPv4ServerAddress);
1323   ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingTargetServer,
1324                              kIPv4ServerAddress);
1325   ExpectPingHostEndFailure(ConnectionDiagnostics::kTypePingTargetServer,
1326                            kIPv4ServerAddress);
1327   ExpectFindRouteToHostStartSuccess(kIPv4ServerAddress);
1328   ExpectFindRouteToHostEndSuccess(kIPv4ServerAddress, false);
1329   ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingGateway,
1330                              kIPv4GatewayAddress);
1331   ExpectPingHostEndFailure(ConnectionDiagnostics::kTypePingGateway,
1332                            kIPv4GatewayAddress);
1333   ExpectArpTableLookupStartSuccessEndFailure(kIPv4GatewayAddress);
1334   ExpectCheckIPCollisionStartSuccess();
1335   ExpectCheckIPCollisionEndFailureGatewayArpFailed();
1336   VerifyStopped();
1337 }
1338 
TEST_F(ConnectionDiagnosticsTest,EndWith_IPCollisionFailure_2)1339 TEST_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);
1347   ExpectResolveTargetServerIPAddressEndSuccess(kIPv4ServerAddress);
1348   ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingTargetServer,
1349                              kIPv4ServerAddress);
1350   ExpectPingHostEndFailure(ConnectionDiagnostics::kTypePingTargetServer,
1351                            kIPv4ServerAddress);
1352   ExpectFindRouteToHostStartSuccess(kIPv4ServerAddress);
1353   ExpectFindRouteToHostEndSuccess(kIPv4ServerAddress, true);
1354   ExpectArpTableLookupStartSuccessEndFailure(kIPv4ServerAddress);
1355   ExpectCheckIPCollisionStartSuccess();
1356   ExpectCheckIPCollisionEndFailureServerArpFailed();
1357   VerifyStopped();
1358 }
1359 
TEST_F(ConnectionDiagnosticsTest,EndWith_kTypeNeighborTableLookupSuccess_1)1360 TEST_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);
1370   ExpectResolveTargetServerIPAddressEndSuccess(kIPv6ServerAddress);
1371   ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingTargetServer,
1372                              kIPv6ServerAddress);
1373   ExpectPingHostEndFailure(ConnectionDiagnostics::kTypePingTargetServer,
1374                            kIPv6ServerAddress);
1375   ExpectFindRouteToHostStartSuccess(kIPv6ServerAddress);
1376   ExpectFindRouteToHostEndSuccess(kIPv6ServerAddress, false);
1377   ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingGateway,
1378                              kIPv6GatewayAddress);
1379   ExpectPingHostEndFailure(ConnectionDiagnostics::kTypePingGateway,
1380                            kIPv6GatewayAddress);
1381   ExpectNeighborTableLookupStartSuccess(kIPv6GatewayAddress);
1382   ExpectNeighborTableLookupEndSuccess(kIPv6GatewayAddress, true);
1383   VerifyStopped();
1384 }
1385 
TEST_F(ConnectionDiagnosticsTest,EndWith_kTypeNeighborTableLookupSuccess_2)1386 TEST_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);
1396   ExpectResolveTargetServerIPAddressEndSuccess(kIPv6ServerAddress);
1397   ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingTargetServer,
1398                              kIPv6ServerAddress);
1399   ExpectPingHostEndFailure(ConnectionDiagnostics::kTypePingTargetServer,
1400                            kIPv6ServerAddress);
1401   ExpectFindRouteToHostStartSuccess(kIPv6ServerAddress);
1402   ExpectFindRouteToHostEndSuccess(kIPv6ServerAddress, true);
1403   ExpectNeighborTableLookupStartSuccess(kIPv6ServerAddress);
1404   ExpectNeighborTableLookupEndSuccess(kIPv6ServerAddress, false);
1405   VerifyStopped();
1406 }
1407 
TEST_F(ConnectionDiagnosticsTest,EndWith_kTypeNeighborTableLookupFailure_1)1408 TEST_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);
1419   ExpectResolveTargetServerIPAddressEndSuccess(kIPv6ServerAddress);
1420   ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingTargetServer,
1421                              kIPv6ServerAddress);
1422   ExpectPingHostEndFailure(ConnectionDiagnostics::kTypePingTargetServer,
1423                            kIPv6ServerAddress);
1424   ExpectFindRouteToHostStartSuccess(kIPv6ServerAddress);
1425   ExpectFindRouteToHostEndSuccess(kIPv6ServerAddress, false);
1426   ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingGateway,
1427                              kIPv6GatewayAddress);
1428   ExpectPingHostEndFailure(ConnectionDiagnostics::kTypePingGateway,
1429                            kIPv6GatewayAddress);
1430   ExpectNeighborTableLookupStartSuccess(kIPv6GatewayAddress);
1431   ExpectNeighborTableLookupEndFailureNotReachable(kIPv6GatewayAddress, true);
1432   VerifyStopped();
1433 }
1434 
TEST_F(ConnectionDiagnosticsTest,EndWith_kTypeNeighborTableLookupFailure_2)1435 TEST_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);
1445   ExpectResolveTargetServerIPAddressEndSuccess(kIPv6ServerAddress);
1446   ExpectPingHostStartSuccess(ConnectionDiagnostics::kTypePingTargetServer,
1447                              kIPv6ServerAddress);
1448   ExpectPingHostEndFailure(ConnectionDiagnostics::kTypePingTargetServer,
1449                            kIPv6ServerAddress);
1450   ExpectFindRouteToHostStartSuccess(kIPv6ServerAddress);
1451   ExpectFindRouteToHostEndSuccess(kIPv6ServerAddress, true);
1452   ExpectNeighborTableLookupStartSuccess(kIPv6ServerAddress);
1453   ExpectNeighborTableLookupEndFailureNoEntry(kIPv6ServerAddress, false);
1454   VerifyStopped();
1455 }
1456 
1457 }  // namespace shill
1458