Home | History | Annotate | Download | only in shill
      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:
    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_)) {}
    157   virtual ~ConnectionDiagnosticsTest() {}
    158 
    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 
    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());
    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 
    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));
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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) {
    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.
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    893 TEST_F(ConnectionDiagnosticsTest, StartWhileRunning) {
    894   ExpectPortalDetectionStartSuccess(kURL);  // Start diagnostics;
    895   EXPECT_FALSE(Start(kURL));
    896 }
    897 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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