// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "shill/device.h"

#include <ctype.h>
#include <sys/socket.h>
#include <linux/if.h>  // NOLINT - Needs typedefs from sys/socket.h.

#include <algorithm>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include <base/bind.h>
#include <base/callback.h>
#include <base/macros.h>
#include <chromeos/dbus/service_constants.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "shill/dhcp/dhcp_provider.h"
#include "shill/dhcp/mock_dhcp_config.h"
#include "shill/dhcp/mock_dhcp_properties.h"
#include "shill/dhcp/mock_dhcp_provider.h"
#include "shill/dns_server_tester.h"
#include "shill/event_dispatcher.h"
#include "shill/mock_adaptors.h"
#include "shill/mock_connection.h"
#include "shill/mock_control.h"
#include "shill/mock_device.h"
#include "shill/mock_device_info.h"
#include "shill/mock_event_dispatcher.h"
#include "shill/mock_ipconfig.h"
#include "shill/mock_link_monitor.h"
#include "shill/mock_manager.h"
#include "shill/mock_metrics.h"
#include "shill/mock_portal_detector.h"
#include "shill/mock_service.h"
#include "shill/mock_store.h"
#include "shill/mock_traffic_monitor.h"
#include "shill/net/mock_rtnl_handler.h"
#include "shill/net/mock_time.h"
#include "shill/net/ndisc.h"
#include "shill/portal_detector.h"
#include "shill/property_store_test.h"
#include "shill/static_ip_parameters.h"
#include "shill/technology.h"
#include "shill/testing.h"
#include "shill/tethering.h"
#include "shill/traffic_monitor.h"

using base::Callback;
using std::string;
using std::vector;
using ::testing::_;
using ::testing::AtLeast;
using ::testing::DoAll;
using ::testing::HasSubstr;
using ::testing::Invoke;
using ::testing::Mock;
using ::testing::NiceMock;
using ::testing::Ref;
using ::testing::Return;
using ::testing::ReturnRef;
using ::testing::SetArgPointee;
using ::testing::StrEq;
using ::testing::StrictMock;
using ::testing::Test;

namespace shill {

class TestDevice : public Device {
 public:
  TestDevice(ControlInterface* control_interface,
             EventDispatcher* dispatcher,
             Metrics* metrics,
             Manager* manager,
             const std::string& link_name,
             const std::string& address,
             int interface_index,
             Technology::Identifier technology)
      : Device(control_interface, dispatcher, metrics, manager, link_name,
               address, interface_index, technology) {
    ON_CALL(*this, IsIPv6Allowed())
        .WillByDefault(Invoke(this, &TestDevice::DeviceIsIPv6Allowed));
    ON_CALL(*this, SetIPFlag(_, _, _))
        .WillByDefault(Invoke(this, &TestDevice::DeviceSetIPFlag));
    ON_CALL(*this, IsTrafficMonitorEnabled())
        .WillByDefault(Invoke(this,
                              &TestDevice::DeviceIsTrafficMonitorEnabled));
    ON_CALL(*this, StartDNSTest(_, _, _))
        .WillByDefault(Invoke(
            this,
            &TestDevice::DeviceStartDNSTest));
    ON_CALL(*this, ShouldBringNetworkInterfaceDownAfterDisabled())
        .WillByDefault(Invoke(
            this,
            &TestDevice::DeviceShouldBringNetworkInterfaceDownAfterDisabled));
  }

  ~TestDevice() {}

  virtual void Start(Error* error,
                     const EnabledStateChangedCallback& callback) {
    DCHECK(error);
  }

  virtual void Stop(Error* error,
                    const EnabledStateChangedCallback& callback) {
    DCHECK(error);
  }

  MOCK_CONST_METHOD0(IsIPv6Allowed, bool());
  MOCK_CONST_METHOD0(IsTrafficMonitorEnabled, bool());
  MOCK_CONST_METHOD0(ShouldBringNetworkInterfaceDownAfterDisabled, bool());

  MOCK_METHOD3(SetIPFlag, bool(IPAddress::Family family,
                               const std::string& flag,
                               const std::string& value));

  MOCK_METHOD3(StartDNSTest, bool(
      const std::vector<std::string>& dns_servers,
      const bool retry_until_success,
      const base::Callback<void(const DnsServerTester::Status)>& callback));

  MOCK_METHOD1(StartConnectionDiagnosticsAfterPortalDetection,
               bool(const PortalDetector::Result& result));

  virtual bool DeviceIsIPv6Allowed() const {
    return Device::IsIPv6Allowed();
  }

  virtual bool DeviceIsTrafficMonitorEnabled() const {
    return Device::IsTrafficMonitorEnabled();
  }

  virtual bool DeviceSetIPFlag(IPAddress::Family family,
                               const std::string& flag,
                               const std::string& value) {
    return Device::SetIPFlag(family, flag, value);
  }

  virtual bool DeviceStartDNSTest(
      const std::vector<std::string>& dns_servers,
      const bool retry_until_success,
      const base::Callback<void(const DnsServerTester::Status)>& callback) {
    return Device::StartDNSTest(dns_servers, retry_until_success, callback);
  }

  virtual bool DeviceShouldBringNetworkInterfaceDownAfterDisabled() const {
    return Device::ShouldBringNetworkInterfaceDownAfterDisabled();
  }
};

class DeviceTest : public PropertyStoreTest {
 public:
  DeviceTest()
      : device_(new TestDevice(control_interface(),
                               dispatcher(),
                               nullptr,
                               manager(),
                               kDeviceName,
                               kDeviceAddress,
                               kDeviceInterfaceIndex,
                               Technology::kUnknown)),
        device_info_(control_interface(), nullptr, nullptr, nullptr),
        metrics_(dispatcher()) {
    DHCPProvider::GetInstance()->control_interface_ = control_interface();
    DHCPProvider::GetInstance()->dispatcher_ = dispatcher();
    device_->time_ = &time_;
  }
  virtual ~DeviceTest() {}

  void SetUp() override {
    device_->metrics_ = &metrics_;
    device_->rtnl_handler_ = &rtnl_handler_;
  }

 protected:
  static const char kDeviceName[];
  static const char kDeviceAddress[];
  static const int kDeviceInterfaceIndex;

  void OnIPConfigUpdated(const IPConfigRefPtr& ipconfig) {
    device_->OnIPConfigUpdated(ipconfig, true);
  }

  void OnIPConfigFailed(const IPConfigRefPtr& ipconfig) {
    device_->OnIPConfigFailed(ipconfig);
  }

  void OnIPConfigExpired(const IPConfigRefPtr& ipconfig) {
    device_->OnIPConfigExpired(ipconfig);
  }

  void SelectService(const ServiceRefPtr service) {
    device_->SelectService(service);
  }

  void SetConnection(ConnectionRefPtr connection) {
    device_->connection_ = connection;
  }

  void SetLinkMonitor(LinkMonitor* link_monitor) {
    device_->set_link_monitor(link_monitor);  // Passes ownership.
  }

  bool HasLinkMonitor() {
    return device_->link_monitor();
  }

  bool StartLinkMonitor() {
    return device_->StartLinkMonitor();
  }

  void StopLinkMonitor() {
    device_->StopLinkMonitor();
  }

  uint64_t GetLinkMonitorResponseTime(Error* error) {
    return device_->GetLinkMonitorResponseTime(error);
  }

  MockTrafficMonitor* SetTrafficMonitor(
      std::unique_ptr<MockTrafficMonitor> traffic_monitor) {
    MockTrafficMonitor* underlying_traffic_monitor = traffic_monitor.get();
    device_->set_traffic_monitor_for_test(std::move(traffic_monitor));
    return underlying_traffic_monitor;
  }

  void StartTrafficMonitor() {
    device_->StartTrafficMonitor();
  }

  void StopTrafficMonitor() {
    device_->StopTrafficMonitor();
  }

  void NetworkProblemDetected(int reason) {
    device_->OnEncounterNetworkProblem(reason);
  }

  DeviceMockAdaptor* GetDeviceMockAdaptor() {
    return static_cast<DeviceMockAdaptor*>(device_->adaptor_.get());
  }

  void SetManager(Manager* manager) {
    device_->manager_ = manager;
  }

  MOCK_METHOD0(ReliableLinkCallback, void());
  void SetReliableLinkCallback() {
    device_->reliable_link_callback_.Reset(
        base::Bind(&DeviceTest::ReliableLinkCallback, base::Unretained(this)));
  }

  bool ReliableLinkCallbackIsCancelled() {
    return device_->reliable_link_callback_.IsCancelled();
  }

  void SetupIPv6Config() {
    const char kAddress[] = "2001:db8::1";
    const char kDnsServer1[] = "2001:db8::2";
    const char kDnsServer2[] = "2001:db8::3";
    IPConfig::Properties properties;
    properties.address = kAddress;
    properties.dns_servers.push_back(kDnsServer1);
    properties.dns_servers.push_back(kDnsServer2);

    device_->ip6config_ = new MockIPConfig(control_interface(), kDeviceName);
    device_->ip6config_->set_properties(properties);
  }

  bool SetHostname(const string& hostname) {
    return device_->SetHostname(hostname);
  }

  MockControl control_interface_;
  scoped_refptr<TestDevice> device_;
  MockDeviceInfo device_info_;
  MockMetrics metrics_;
  MockTime time_;
  StrictMock<MockRTNLHandler> rtnl_handler_;
};

const char DeviceTest::kDeviceName[] = "testdevice";
const char DeviceTest::kDeviceAddress[] = "address";
const int DeviceTest::kDeviceInterfaceIndex = 0;

TEST_F(DeviceTest, Contains) {
  EXPECT_TRUE(device_->store().Contains(kNameProperty));
  EXPECT_FALSE(device_->store().Contains(""));
}

TEST_F(DeviceTest, GetProperties) {
  brillo::VariantDictionary props;
  Error error;
  device_->store().GetProperties(&props, &error);
  ASSERT_FALSE(props.find(kNameProperty) == props.end());
  EXPECT_TRUE(props[kNameProperty].IsTypeCompatible<string>());
  EXPECT_EQ(props[kNameProperty].Get<string>(), string(kDeviceName));
}

// Note: there are currently no writeable Device properties that
// aren't registered in a subclass.
TEST_F(DeviceTest, SetReadOnlyProperty) {
  Error error;
  // Ensure that an attempt to write a R/O property returns InvalidArgs error.
  EXPECT_FALSE(device_->mutable_store()->SetAnyProperty(
      kAddressProperty, PropertyStoreTest::kStringV, &error));
  EXPECT_EQ(Error::kInvalidArguments, error.type());
}

TEST_F(DeviceTest, ClearReadOnlyProperty) {
  Error error;
  EXPECT_FALSE(device_->mutable_store()->SetAnyProperty(
      kAddressProperty, PropertyStoreTest::kStringV, &error));
}

TEST_F(DeviceTest, ClearReadOnlyDerivedProperty) {
  Error error;
  EXPECT_FALSE(device_->mutable_store()->SetAnyProperty(
      kIPConfigsProperty, PropertyStoreTest::kStringsV, &error));
}

TEST_F(DeviceTest, DestroyIPConfig) {
  ASSERT_FALSE(device_->ipconfig_.get());
  device_->ipconfig_ = new IPConfig(control_interface(), kDeviceName);
  device_->ip6config_ = new IPConfig(control_interface(), kDeviceName);
  device_->dhcpv6_config_ = new IPConfig(control_interface(), kDeviceName);
  device_->DestroyIPConfig();
  ASSERT_FALSE(device_->ipconfig_.get());
  ASSERT_FALSE(device_->ip6config_.get());
  ASSERT_FALSE(device_->dhcpv6_config_.get());
}

TEST_F(DeviceTest, DestroyIPConfigNULL) {
  ASSERT_FALSE(device_->ipconfig_.get());
  ASSERT_FALSE(device_->ip6config_.get());
  ASSERT_FALSE(device_->dhcpv6_config_.get());
  device_->DestroyIPConfig();
  ASSERT_FALSE(device_->ipconfig_.get());
  ASSERT_FALSE(device_->ip6config_.get());
  ASSERT_FALSE(device_->dhcpv6_config_.get());
}

MATCHER_P(IsCombinedDhcpProperties, dhcp_props, "") {
  return dhcp_props == arg.properties();
}

TEST_F(DeviceTest, AcquireIPConfigWithSelectedService) {
  device_->ipconfig_ = new IPConfig(control_interface(), "randomname");
  auto dhcp_provider = std::make_unique<MockDHCPProvider>();
  device_->dhcp_provider_ = dhcp_provider.get();

  scoped_refptr<MockDHCPConfig> dhcp_config(
      new MockDHCPConfig(control_interface(), kDeviceName));
  NiceMock<MockStore> storage;
  const string service_storage_id = "service_storage_id";
  EXPECT_CALL(storage, GetString(service_storage_id,
                                 "DHCPProperty.Hostname", _))
      .WillOnce(DoAll(SetArgPointee<2>(string("name of host")),
                      Return(true)));
  EXPECT_CALL(storage, GetString(service_storage_id,
                                 "DHCPProperty.VendorClass", _))
      .WillOnce(Return(false));

  auto service_dhcp_properties = std::make_unique<DhcpProperties>();
  service_dhcp_properties->Load(&storage, service_storage_id);

  scoped_refptr<MockService> service(
      new NiceMock<MockService>(control_interface(),
                                dispatcher(),
                                metrics(),
                                manager()));
  SelectService(service);

  const string default_profile_storage_id = "default_profile_storage_id";
  NiceMock<MockStore> default_profile_storage;
  EXPECT_CALL(default_profile_storage, GetString(default_profile_storage_id,
                                 "DHCPProperty.VendorClass", _))
      .WillOnce(DoAll(SetArgPointee<2>(string("vendorclass")),
                      Return(true)));
  EXPECT_CALL(default_profile_storage, GetString(default_profile_storage_id,
                                 "DHCPProperty.Hostname", _))
      .WillOnce(Return(false));

  auto manager_dhcp_properties = std::make_unique<DhcpProperties>();
  manager_dhcp_properties->Load(&default_profile_storage,
                                default_profile_storage_id);
  std::unique_ptr<DhcpProperties> combined_props =
      DhcpProperties::Combine(*manager_dhcp_properties,
                              *service_dhcp_properties);
  service->dhcp_properties_ = std::move(service_dhcp_properties);
#ifndef DISABLE_DHCPV6
  MockManager manager(control_interface(),
                      dispatcher(),
                      metrics());
  manager.set_mock_device_info(&device_info_);
  SetManager(&manager);
  device_->dhcpv6_config_ = new IPConfig(control_interface(), "randomname");
  scoped_refptr<MockDHCPConfig> dhcpv6_config(
      new MockDHCPConfig(control_interface(), kDeviceName));

  EXPECT_CALL(manager, IsDHCPv6EnabledForDevice(kDeviceName))
      .WillOnce(Return(true));
  EXPECT_CALL(*dhcp_provider, CreateIPv6Config(_, _))
      .WillOnce(Return(dhcpv6_config));
  EXPECT_CALL(*dhcpv6_config, RequestIP()).WillOnce(Return(true));
#endif  // DISABLE_DHCPV6
  device_->manager_->dhcp_properties_ = std::move(manager_dhcp_properties);
  EXPECT_CALL(*dhcp_provider,
              CreateIPv4Config(_, _, _,
                               IsCombinedDhcpProperties(
                                   combined_props->properties())))
      .WillOnce(Return(dhcp_config));
  EXPECT_CALL(*dhcp_config, RequestIP())
      .WillOnce(Return(true));
  EXPECT_TRUE(device_->AcquireIPConfig());
  ASSERT_TRUE(device_->ipconfig_.get());
  EXPECT_EQ(kDeviceName, device_->ipconfig_->device_name());
  EXPECT_FALSE(device_->ipconfig_->update_callback_.is_null());
#ifndef DISABLE_DHCPV6
  EXPECT_EQ(kDeviceName, device_->dhcpv6_config_->device_name());
  EXPECT_FALSE(device_->dhcpv6_config_->update_callback_.is_null());
#endif  // DISABLE_DHCPV6
  device_->dhcp_provider_ = nullptr;
}

TEST_F(DeviceTest, AcquireIPConfigWithoutSelectedService) {
  device_->ipconfig_ = new IPConfig(control_interface(), "randomname");
  auto dhcp_provider = std::make_unique<MockDHCPProvider>();
  device_->dhcp_provider_ = dhcp_provider.get();
  scoped_refptr<MockDHCPConfig> dhcp_config(
      new MockDHCPConfig(control_interface(), kDeviceName));
  auto manager_dhcp_properties = std::make_unique<DhcpProperties>();
  device_->manager_->dhcp_properties_ = std::move(manager_dhcp_properties);
#ifndef DISABLE_DHCPV6
  MockManager manager(control_interface(),
                      dispatcher(),
                      metrics());
  manager.set_mock_device_info(&device_info_);
  SetManager(&manager);
  device_->dhcpv6_config_ = new IPConfig(control_interface(), "randomname");
  scoped_refptr<MockDHCPConfig> dhcpv6_config(
      new MockDHCPConfig(control_interface(), kDeviceName));

  EXPECT_CALL(manager, IsDHCPv6EnabledForDevice(kDeviceName))
      .WillOnce(Return(true));
  EXPECT_CALL(*dhcp_provider, CreateIPv6Config(_, _))
      .WillOnce(Return(dhcpv6_config));
  EXPECT_CALL(*dhcpv6_config, RequestIP()).WillOnce(Return(true));
#endif  // DISABLE_DHCPV6

  EXPECT_CALL(*dhcp_provider,
              CreateIPv4Config(_, _, _,
                               Ref(*(device_->manager_->dhcp_properties_))))
      .WillOnce(Return(dhcp_config));
  EXPECT_CALL(*dhcp_config, RequestIP())
      .WillOnce(Return(true));
  EXPECT_TRUE(device_->AcquireIPConfig());
  ASSERT_TRUE(device_->ipconfig_.get());
  EXPECT_EQ(kDeviceName, device_->ipconfig_->device_name());
  EXPECT_FALSE(device_->ipconfig_->update_callback_.is_null());
#ifndef DISABLE_DHCPV6
  EXPECT_EQ(kDeviceName, device_->dhcpv6_config_->device_name());
  EXPECT_FALSE(device_->dhcpv6_config_->update_callback_.is_null());
#endif  // DISABLE_DHCPV6
  device_->dhcp_provider_ = nullptr;
}

TEST_F(DeviceTest, ConfigWithMinimumMTU) {
  const int minimum_mtu = 1500;

  MockManager manager(control_interface(),
                      dispatcher(),
                      metrics());
  manager.set_mock_device_info(&device_info_);
  SetManager(&manager);

  EXPECT_CALL(manager, GetMinimumMTU()).WillOnce(Return(minimum_mtu));

  device_->ipconfig_ = new IPConfig(control_interface(), "anothername");
  auto dhcp_provider = std::make_unique<MockDHCPProvider>();
  device_->dhcp_provider_ = dhcp_provider.get();

  scoped_refptr<MockDHCPConfig> dhcp_config(
      new MockDHCPConfig(control_interface(), kDeviceName));
  EXPECT_CALL(*dhcp_provider, CreateIPv4Config(_, _, _, _))
      .WillOnce(Return(dhcp_config));
  EXPECT_CALL(*dhcp_config, set_minimum_mtu(minimum_mtu));

  device_->AcquireIPConfig();
}

TEST_F(DeviceTest, EnableIPv6) {
  EXPECT_CALL(*device_, SetIPFlag(IPAddress::kFamilyIPv6,
                                  StrEq(Device::kIPFlagDisableIPv6),
                                  StrEq("0")))
      .WillOnce(Return(true));
  EXPECT_CALL(*device_, SetIPFlag(IPAddress::kFamilyIPv6,
      StrEq(Device::kIPFlagAcceptRouterAdvertisements), StrEq("2")))
      .WillOnce(Return(true));
  device_->EnableIPv6();
}

TEST_F(DeviceTest, EnableIPv6NotAllowed) {
  EXPECT_CALL(*device_, IsIPv6Allowed()).WillOnce(Return(false));
  EXPECT_CALL(*device_, SetIPFlag(_, _, _)).Times(0);
  device_->EnableIPv6();
}

TEST_F(DeviceTest, MultiHomed) {
  // Device should have multi-homing disabled by default.
  EXPECT_CALL(*device_, SetIPFlag(_, _, _)).Times(0);
  device_->SetIsMultiHomed(false);
  Mock::VerifyAndClearExpectations(device_.get());

  // Disabled -> enabled should change flags on the device.
  EXPECT_CALL(*device_, SetIPFlag(IPAddress::kFamilyIPv4, StrEq("arp_announce"),
                                  StrEq("2"))).WillOnce(Return(true));
  EXPECT_CALL(*device_, SetIPFlag(IPAddress::kFamilyIPv4, StrEq("arp_ignore"),
                                  StrEq("1"))).WillOnce(Return(true));
  EXPECT_CALL(*device_, SetIPFlag(IPAddress::kFamilyIPv4, StrEq("rp_filter"),
                                  StrEq("2"))).WillOnce(Return(true));
  device_->SetIsMultiHomed(true);
  Mock::VerifyAndClearExpectations(device_.get());

  // Enabled -> enabled should be a no-op.
  EXPECT_CALL(*device_, SetIPFlag(_, _, _)).Times(0);
  device_->SetIsMultiHomed(true);

  // Disabling or enabling reverse-path filtering should also be a no-op
  // (since it is disabled due to multi-homing).
  device_->SetLooseRouting(false);
  device_->SetLooseRouting(true);
  Mock::VerifyAndClearExpectations(device_.get());

  // Enabled -> disabled should reset the flags back to the default, but
  // because non-default routing is enabled, rp_filter will be left
  // in loose mode.
  EXPECT_CALL(*device_, SetIPFlag(IPAddress::kFamilyIPv4, StrEq("arp_announce"),
                                  StrEq("0"))).WillOnce(Return(true));
  EXPECT_CALL(*device_, SetIPFlag(IPAddress::kFamilyIPv4, StrEq("arp_ignore"),
                                  StrEq("0"))).WillOnce(Return(true));
  device_->SetIsMultiHomed(false);
  Mock::VerifyAndClearExpectations(device_.get());

  // Re-enable reverse-path filtering.
  EXPECT_CALL(*device_, SetIPFlag(IPAddress::kFamilyIPv4, StrEq("rp_filter"),
                                  StrEq("1"))).WillOnce(Return(true));
  device_->SetLooseRouting(false);
  Mock::VerifyAndClearExpectations(device_.get());
}

TEST_F(DeviceTest, Load) {
  NiceMock<MockStore> storage;
  const string id = device_->GetStorageIdentifier();
  EXPECT_CALL(storage, ContainsGroup(id)).WillOnce(Return(true));
  EXPECT_CALL(storage, GetBool(id, Device::kStoragePowered, _))
      .WillOnce(Return(true));
  EXPECT_CALL(storage, GetUint64(id, Device::kStorageReceiveByteCount, _))
      .WillOnce(Return(true));
  EXPECT_CALL(storage, GetUint64(id, Device::kStorageTransmitByteCount, _))
      .WillOnce(Return(true));
  EXPECT_TRUE(device_->Load(&storage));
}

TEST_F(DeviceTest, Save) {
  NiceMock<MockStore> storage;
  const string id = device_->GetStorageIdentifier();
  EXPECT_CALL(storage, SetBool(id, Device::kStoragePowered, _))
      .WillOnce(Return(true));
  EXPECT_CALL(storage, SetUint64(id, Device::kStorageReceiveByteCount, _))
      .WillOnce(Return(true));
  EXPECT_CALL(storage, SetUint64(id, Device::kStorageTransmitByteCount, _))
      .Times(AtLeast(true));
  EXPECT_TRUE(device_->Save(&storage));
}

TEST_F(DeviceTest, SelectedService) {
  EXPECT_FALSE(device_->selected_service_.get());
  device_->SetServiceState(Service::kStateAssociating);
  scoped_refptr<MockService> service(
      new StrictMock<MockService>(control_interface(),
                                  dispatcher(),
                                  metrics(),
                                  manager()));
  SelectService(service);
  EXPECT_TRUE(device_->selected_service_.get() == service.get());

  EXPECT_CALL(*service, SetState(Service::kStateConfiguring));
  device_->SetServiceState(Service::kStateConfiguring);
  EXPECT_CALL(*service, SetFailure(Service::kFailureOutOfRange));
  device_->SetServiceFailure(Service::kFailureOutOfRange);

  // Service should be returned to "Idle" state
  EXPECT_CALL(*service, state())
    .WillOnce(Return(Service::kStateUnknown));
  EXPECT_CALL(*service, SetState(Service::kStateIdle));
  EXPECT_CALL(*service, SetConnection(IsNullRefPtr()));
  SelectService(nullptr);

  // A service in the "Failure" state should not be reset to "Idle"
  SelectService(service);
  EXPECT_CALL(*service, state())
    .WillOnce(Return(Service::kStateFailure));
  EXPECT_CALL(*service, SetConnection(IsNullRefPtr()));
  SelectService(nullptr);
}

TEST_F(DeviceTest, ResetConnection) {
  EXPECT_FALSE(device_->selected_service_.get());
  device_->SetServiceState(Service::kStateAssociating);
  scoped_refptr<MockService> service(
      new StrictMock<MockService>(control_interface(),
                                  dispatcher(),
                                  metrics(),
                                  manager()));
  SelectService(service);
  EXPECT_TRUE(device_->selected_service_.get() == service.get());

  // ResetConnection() should drop the connection and the selected service,
  // but should not change the service state.
  EXPECT_CALL(*service, SetState(_)).Times(0);
  EXPECT_CALL(*service, SetConnection(IsNullRefPtr()));
  device_->ResetConnection();
  EXPECT_FALSE(device_->selected_service_.get());
}

TEST_F(DeviceTest, LinkMonitorFailure) {
  scoped_refptr<MockService> service(
      new StrictMock<MockService>(control_interface(),
                                  dispatcher(),
                                  metrics(),
                                  manager()));
  SelectService(service);
  EXPECT_TRUE(device_->selected_service().get() == service.get());

  time_t current_time = 1000;

  // Initial link monitor failure.
  EXPECT_CALL(time_, GetSecondsBoottime(_)).WillOnce(
      DoAll(SetArgPointee<0>(current_time), Return(true)));
  EXPECT_CALL(metrics_, NotifyUnreliableLinkSignalStrength(_, _)).Times(0);
  device_->OnLinkMonitorFailure();
  EXPECT_FALSE(service->unreliable());

  // Another link monitor failure after 3 minutes, report signal strength.
  current_time += 180;
  EXPECT_CALL(time_, GetSecondsBoottime(_)).WillOnce(
      DoAll(SetArgPointee<0>(current_time), Return(true)));
  EXPECT_CALL(metrics_, NotifyUnreliableLinkSignalStrength(_, _)).Times(1);
  device_->OnLinkMonitorFailure();
  EXPECT_TRUE(service->unreliable());

  // Device is connected with the reliable link callback setup, then
  // another link monitor failure after 3 minutes, which implies link is
  // still unreliable, reliable link callback should be cancelled.
  current_time += 180;
  SetReliableLinkCallback();
  EXPECT_CALL(time_, GetSecondsBoottime(_)).WillOnce(
      DoAll(SetArgPointee<0>(current_time), Return(true)));
  EXPECT_CALL(metrics_, NotifyUnreliableLinkSignalStrength(_, _)).Times(1);
  device_->OnLinkMonitorFailure();
  EXPECT_TRUE(service->unreliable());
  EXPECT_TRUE(ReliableLinkCallbackIsCancelled());

  // Another link monitor failure after an hour, link is still reliable, signal
  // strength not reported.
  current_time += 3600;
  service->set_unreliable(false);
  EXPECT_CALL(time_, GetSecondsBoottime(_)).WillOnce(
      DoAll(SetArgPointee<0>(current_time), Return(true)));
  EXPECT_CALL(metrics_, NotifyUnreliableLinkSignalStrength(_, _)).Times(0);
  device_->OnLinkMonitorFailure();
  EXPECT_FALSE(service->unreliable());
}

TEST_F(DeviceTest, LinkStatusResetOnSelectService) {
  scoped_refptr<MockService> service(
      new StrictMock<MockService>(control_interface(),
                                  dispatcher(),
                                  metrics(),
                                  manager()));
  SelectService(service);
  service->set_unreliable(true);
  SetReliableLinkCallback();
  EXPECT_FALSE(ReliableLinkCallbackIsCancelled());

  // Service is deselected, link status of the service should be resetted.
  EXPECT_CALL(*service, state())
      .WillOnce(Return(Service::kStateIdle));
  EXPECT_CALL(*service, SetState(_));
  EXPECT_CALL(*service, SetConnection(_));
  SelectService(nullptr);
  EXPECT_FALSE(service->unreliable());
  EXPECT_TRUE(ReliableLinkCallbackIsCancelled());
}

TEST_F(DeviceTest, IPConfigUpdatedFailure) {
  scoped_refptr<MockIPConfig> ipconfig = new MockIPConfig(control_interface(),
                                                          kDeviceName);
  scoped_refptr<MockService> service(
      new StrictMock<MockService>(control_interface(),
                                  dispatcher(),
                                  metrics(),
                                  manager()));
  SelectService(service);
  EXPECT_CALL(*service, DisconnectWithFailure(Service::kFailureDHCP,
                                              _,
                                              HasSubstr("OnIPConfigFailure")));
  EXPECT_CALL(*service, SetConnection(IsNullRefPtr()));
  EXPECT_CALL(*ipconfig, ResetProperties());
  OnIPConfigFailed(ipconfig.get());
}

TEST_F(DeviceTest, IPConfigUpdatedFailureWithIPv6Config) {
  // Setup IPv6 configuration.
  SetupIPv6Config();
  EXPECT_THAT(device_->ip6config_, NotNullRefPtr());

  // IPv4 configuration failed, fallback to use IPv6 configuration.
  scoped_refptr<MockIPConfig> ipconfig = new MockIPConfig(control_interface(),
                                                          kDeviceName);
  scoped_refptr<MockService> service(
      new StrictMock<MockService>(control_interface(),
                                  dispatcher(),
                                  metrics(),
                                  manager()));
  SelectService(service);
  scoped_refptr<MockConnection> connection(
      new StrictMock<MockConnection>(&device_info_));
  SetConnection(connection.get());

  EXPECT_CALL(*ipconfig, ResetProperties());
  EXPECT_CALL(*connection, IsIPv6())
      .WillRepeatedly(Return(false));
  EXPECT_CALL(*connection, UpdateFromIPConfig(device_->ip6config_));
  EXPECT_CALL(*service, state())
      .WillOnce(Return(Service::kStateConfiguring));
  EXPECT_CALL(*service, SetState(Service::kStateConnected));
  EXPECT_CALL(*service, IsConnected())
      .WillRepeatedly(Return(true));
  EXPECT_CALL(*service, IsPortalDetectionDisabled())
      .WillRepeatedly(Return(true));
  EXPECT_CALL(*service, SetState(Service::kStateOnline));
  EXPECT_CALL(*service, SetConnection(NotNullRefPtr()));
  OnIPConfigFailed(ipconfig.get());
}

// IPv4 configuration failed with existing IPv6 connection.
TEST_F(DeviceTest, IPConfigUpdatedFailureWithIPv6Connection) {
  // Setup IPv6 configuration.
  SetupIPv6Config();
  EXPECT_THAT(device_->ip6config_, NotNullRefPtr());

  scoped_refptr<MockIPConfig> ipconfig = new MockIPConfig(control_interface(),
                                                          kDeviceName);
  scoped_refptr<MockService> service(
      new StrictMock<MockService>(control_interface(),
                                  dispatcher(),
                                  metrics(),
                                  manager()));
  SelectService(service);
  scoped_refptr<MockConnection> connection(
      new StrictMock<MockConnection>(&device_info_));
  SetConnection(connection.get());

  EXPECT_CALL(*ipconfig, ResetProperties());
  EXPECT_CALL(*connection, IsIPv6())
      .WillRepeatedly(Return(true));
  EXPECT_CALL(*service, DisconnectWithFailure(_, _, _)).Times(0);
  EXPECT_CALL(*service, SetConnection(IsNullRefPtr())).Times(0);
  OnIPConfigFailed(ipconfig.get());
  // Verify connection not teardown.
  EXPECT_THAT(device_->connection(), NotNullRefPtr());
}

TEST_F(DeviceTest, IPConfigUpdatedFailureWithStatic) {
  scoped_refptr<MockIPConfig> ipconfig = new MockIPConfig(control_interface(),
                                                          kDeviceName);
  scoped_refptr<MockService> service(
      new StrictMock<MockService>(control_interface(),
                                  dispatcher(),
                                  metrics(),
                                  manager()));
  SelectService(service);
  service->static_ip_parameters_.args_.SetString(kAddressProperty, "1.1.1.1");
  service->static_ip_parameters_.args_.SetInt(kPrefixlenProperty, 16);
  // Even though we won't call DisconnectWithFailure, we should still have
  // the service learn from the failed DHCP attempt.
  EXPECT_CALL(*service, DisconnectWithFailure(_, _, _)).Times(0);
  EXPECT_CALL(*service, SetConnection(_)).Times(0);
  // The IPConfig should retain the previous values.
  EXPECT_CALL(*ipconfig, ResetProperties()).Times(0);
  OnIPConfigFailed(ipconfig.get());
}

TEST_F(DeviceTest, IPConfigUpdatedSuccess) {
  scoped_refptr<MockService> service(
      new StrictMock<MockService>(control_interface(),
                                  dispatcher(),
                                  metrics(),
                                  manager()));
  SelectService(service);
  scoped_refptr<MockIPConfig> ipconfig = new MockIPConfig(control_interface(),
                                                          kDeviceName);
  device_->set_ipconfig(ipconfig);
  EXPECT_CALL(*service, state())
      .WillOnce(Return(Service::kStateConfiguring));
  EXPECT_CALL(*service, SetState(Service::kStateConnected));
  EXPECT_CALL(metrics_,
              NotifyNetworkConnectionIPType(
                  device_->technology(),
                  Metrics::kNetworkConnectionIPTypeIPv4));
  EXPECT_CALL(metrics_,
              NotifyIPv6ConnectivityStatus(device_->technology(), false));
  EXPECT_CALL(*service, IsConnected())
      .WillRepeatedly(Return(true));
  EXPECT_CALL(*service, IsPortalDetectionDisabled())
      .WillRepeatedly(Return(true));
  EXPECT_CALL(*service, HasStaticNameServers())
      .WillRepeatedly(Return(false));
  EXPECT_CALL(*service, SetState(Service::kStateOnline));
  EXPECT_CALL(*service, SetConnection(NotNullRefPtr()));
  EXPECT_CALL(*GetDeviceMockAdaptor(),
              EmitRpcIdentifierArrayChanged(
                  kIPConfigsProperty,
                  vector<string>{ IPConfigMockAdaptor::kRpcId }));

  OnIPConfigUpdated(ipconfig.get());
}

TEST_F(DeviceTest, IPConfigUpdatedAlreadyOnline) {
  // The service is already Online and selected, so it should not transition
  // back to Connected.
  scoped_refptr<MockService> service(
      new StrictMock<MockService>(control_interface(),
                                  dispatcher(),
                                  metrics(),
                                  manager()));
  SelectService(service);
  scoped_refptr<MockIPConfig> ipconfig = new MockIPConfig(control_interface(),
                                                          kDeviceName);
  device_->set_ipconfig(ipconfig);
  EXPECT_CALL(*service, state())
      .WillOnce(Return(Service::kStateOnline));
  EXPECT_CALL(*service, SetState(Service::kStateConnected)).Times(0);
  EXPECT_CALL(metrics_,
              NotifyNetworkConnectionIPType(
                  device_->technology(),
                  Metrics::kNetworkConnectionIPTypeIPv4));
  EXPECT_CALL(metrics_,
              NotifyIPv6ConnectivityStatus(device_->technology(), false));
  EXPECT_CALL(*service, IsConnected())
      .WillRepeatedly(Return(true));
  EXPECT_CALL(*service, IsPortalDetectionDisabled())
      .WillRepeatedly(Return(true));
  EXPECT_CALL(*service, HasStaticNameServers())
      .WillRepeatedly(Return(false));

  // Successful portal (non-)detection forces the service Online.
  EXPECT_CALL(*service, SetState(Service::kStateOnline));
  EXPECT_CALL(*service, SetConnection(NotNullRefPtr()));
  EXPECT_CALL(*GetDeviceMockAdaptor(),
              EmitRpcIdentifierArrayChanged(
                  kIPConfigsProperty,
                  vector<string>{ IPConfigMockAdaptor::kRpcId }));

  OnIPConfigUpdated(ipconfig.get());
}

TEST_F(DeviceTest, IPConfigUpdatedSuccessNoSelectedService) {
  // Make sure shill doesn't crash if a service is disabled immediately
  // after receiving its IP config (selected_service_ is nullptr in this case).
  scoped_refptr<MockIPConfig> ipconfig = new MockIPConfig(control_interface(),
                                                          kDeviceName);
  SelectService(nullptr);
  OnIPConfigUpdated(ipconfig.get());
}

TEST_F(DeviceTest, OnIPConfigExpired) {
  scoped_refptr<MockIPConfig> ipconfig =
      new MockIPConfig(control_interface(), kDeviceName);
  const int kLeaseLength = 1234;
  ipconfig->properties_.lease_duration_seconds = kLeaseLength;

  EXPECT_CALL(metrics_,
              SendToUMA("Network.Shill.Unknown.ExpiredLeaseLengthSeconds2",
                        kLeaseLength,
                        Metrics::kMetricExpiredLeaseLengthSecondsMin,
                        Metrics::kMetricExpiredLeaseLengthSecondsMax,
                        Metrics::kMetricExpiredLeaseLengthSecondsNumBuckets));

  OnIPConfigExpired(ipconfig.get());
}

TEST_F(DeviceTest, SetEnabledNonPersistent) {
  EXPECT_FALSE(device_->enabled_);
  EXPECT_FALSE(device_->enabled_pending_);
  device_->enabled_persistent_ = false;
  StrictMock<MockManager> manager(control_interface(),
                                  dispatcher(),
                                  metrics());
  SetManager(&manager);
  Error error;
  device_->SetEnabledNonPersistent(true, &error, ResultCallback());
  EXPECT_FALSE(device_->enabled_persistent_);
  EXPECT_TRUE(device_->enabled_pending_);

  // Enable while already enabled.
  error.Populate(Error::kOperationInitiated);
  device_->enabled_persistent_ = false;
  device_->enabled_pending_ = true;
  device_->enabled_ = true;
  device_->SetEnabledNonPersistent(true, &error, ResultCallback());
  EXPECT_FALSE(device_->enabled_persistent_);
  EXPECT_TRUE(device_->enabled_pending_);
  EXPECT_TRUE(device_->enabled_);
  EXPECT_TRUE(error.IsSuccess());

  // Enable while enabled but disabling.
  error.Populate(Error::kOperationInitiated);
  device_->enabled_pending_ = false;
  device_->SetEnabledNonPersistent(true, &error, ResultCallback());
  EXPECT_FALSE(device_->enabled_persistent_);
  EXPECT_FALSE(device_->enabled_pending_);
  EXPECT_TRUE(device_->enabled_);
  EXPECT_TRUE(error.IsSuccess());

  // Disable while already disabled.
  error.Populate(Error::kOperationInitiated);
  device_->enabled_ = false;
  device_->SetEnabledNonPersistent(false, &error, ResultCallback());
  EXPECT_FALSE(device_->enabled_persistent_);
  EXPECT_FALSE(device_->enabled_pending_);
  EXPECT_FALSE(device_->enabled_);
  EXPECT_TRUE(error.IsSuccess());

  // Disable while already enabling.
  error.Populate(Error::kOperationInitiated);
  device_->enabled_pending_ = true;
  device_->SetEnabledNonPersistent(false, &error, ResultCallback());
  EXPECT_FALSE(device_->enabled_persistent_);
  EXPECT_TRUE(device_->enabled_pending_);
  EXPECT_FALSE(device_->enabled_);
  EXPECT_TRUE(error.IsSuccess());
}

TEST_F(DeviceTest, SetEnabledPersistent) {
  EXPECT_FALSE(device_->enabled_);
  EXPECT_FALSE(device_->enabled_pending_);
  device_->enabled_persistent_ = false;
  StrictMock<MockManager> manager(control_interface(),
                                  dispatcher(),
                                  metrics());
  EXPECT_CALL(manager, UpdateDevice(_));
  SetManager(&manager);
  Error error;
  device_->SetEnabledPersistent(true, &error, ResultCallback());
  EXPECT_TRUE(device_->enabled_persistent_);
  EXPECT_TRUE(device_->enabled_pending_);

  // Enable while already enabled.
  error.Populate(Error::kOperationInitiated);
  device_->enabled_persistent_ = false;
  device_->enabled_pending_ = true;
  device_->enabled_ = true;
  device_->SetEnabledPersistent(true, &error, ResultCallback());
  EXPECT_FALSE(device_->enabled_persistent_);
  EXPECT_TRUE(device_->enabled_pending_);
  EXPECT_TRUE(device_->enabled_);
  EXPECT_TRUE(error.IsSuccess());

  // Enable while enabled but disabling.
  error.Populate(Error::kOperationInitiated);
  device_->enabled_pending_ = false;
  device_->SetEnabledPersistent(true, &error, ResultCallback());
  EXPECT_FALSE(device_->enabled_persistent_);
  EXPECT_FALSE(device_->enabled_pending_);
  EXPECT_TRUE(device_->enabled_);
  EXPECT_EQ(Error::kOperationFailed, error.type());

  // Disable while already disabled.
  error.Populate(Error::kOperationInitiated);
  device_->enabled_ = false;
  device_->SetEnabledPersistent(false, &error, ResultCallback());
  EXPECT_FALSE(device_->enabled_persistent_);
  EXPECT_FALSE(device_->enabled_pending_);
  EXPECT_FALSE(device_->enabled_);
  EXPECT_TRUE(error.IsSuccess());

  // Disable while already enabling.
  error.Populate(Error::kOperationInitiated);
  device_->enabled_pending_ = true;
  device_->SetEnabledPersistent(false, &error, ResultCallback());
  EXPECT_FALSE(device_->enabled_persistent_);
  EXPECT_TRUE(device_->enabled_pending_);
  EXPECT_FALSE(device_->enabled_);
  EXPECT_EQ(Error::kOperationFailed, error.type());
}

TEST_F(DeviceTest, Start) {
  EXPECT_FALSE(device_->running_);
  EXPECT_FALSE(device_->enabled_);
  EXPECT_FALSE(device_->enabled_pending_);
  device_->SetEnabled(true);
  EXPECT_TRUE(device_->running_);
  EXPECT_TRUE(device_->enabled_pending_);
  device_->OnEnabledStateChanged(ResultCallback(),
                                 Error(Error::kOperationFailed));
  EXPECT_FALSE(device_->enabled_pending_);
}

TEST_F(DeviceTest, Stop) {
  device_->enabled_ = true;
  device_->enabled_pending_ = true;
  device_->ipconfig_ = new IPConfig(&control_interface_, kDeviceName);
  scoped_refptr<MockService> service(
      new NiceMock<MockService>(&control_interface_,
                                dispatcher(),
                                metrics(),
                                manager()));
  SelectService(service);

  EXPECT_CALL(*service, state()).
      WillRepeatedly(Return(Service::kStateConnected));
  EXPECT_CALL(*GetDeviceMockAdaptor(),
              EmitBoolChanged(kPoweredProperty, false));
  EXPECT_CALL(rtnl_handler_, SetInterfaceFlags(_, 0, IFF_UP));
  device_->SetEnabled(false);
  device_->OnEnabledStateChanged(ResultCallback(), Error());

  EXPECT_FALSE(device_->ipconfig_.get());
  EXPECT_FALSE(device_->selected_service_.get());
}

TEST_F(DeviceTest, StopWithFixedIpParams) {
  device_->SetFixedIpParams(true);
  device_->enabled_ = true;
  device_->enabled_pending_ = true;
  device_->ipconfig_ = new IPConfig(&control_interface_, kDeviceName);
  scoped_refptr<MockService> service(new NiceMock<MockService>(
      &control_interface_, dispatcher(), metrics(), manager()));
  SelectService(service);

  EXPECT_CALL(*service, state())
      .WillRepeatedly(Return(Service::kStateConnected));
  EXPECT_CALL(*GetDeviceMockAdaptor(),
              EmitBoolChanged(kPoweredProperty, false));
  EXPECT_CALL(rtnl_handler_, SetInterfaceFlags(_, _, _)).Times(0);
  device_->SetEnabled(false);
  device_->OnEnabledStateChanged(ResultCallback(), Error());

  EXPECT_FALSE(device_->ipconfig_.get());
  EXPECT_FALSE(device_->selected_service_.get());
}

TEST_F(DeviceTest, StopWithNetworkInterfaceDisabledAfterward) {
  device_->enabled_ = true;
  device_->enabled_pending_ = true;
  device_->ipconfig_ = new IPConfig(&control_interface_, kDeviceName);
  scoped_refptr<MockService> service(new NiceMock<MockService>(
      &control_interface_, dispatcher(), metrics(), manager()));
  SelectService(service);

  EXPECT_CALL(*device_, ShouldBringNetworkInterfaceDownAfterDisabled())
      .WillRepeatedly(Return(true));
  EXPECT_CALL(*service, state())
      .WillRepeatedly(Return(Service::kStateConnected));
  EXPECT_CALL(*GetDeviceMockAdaptor(),
              EmitBoolChanged(kPoweredProperty, false));
  device_->SetEnabled(false);
  EXPECT_CALL(rtnl_handler_, SetInterfaceFlags(_, 0, IFF_UP));
  device_->OnEnabledStateChanged(ResultCallback(), Error());

  EXPECT_FALSE(device_->ipconfig_.get());
  EXPECT_FALSE(device_->selected_service_.get());
}

TEST_F(DeviceTest, StartProhibited) {
  DeviceRefPtr device(new TestDevice(control_interface(),
                                     dispatcher(),
                                     nullptr,
                                     manager(),
                                     kDeviceName,
                                     kDeviceAddress,
                                     kDeviceInterfaceIndex,
                                     Technology::kWifi));
  {
    Error error;
    manager()->SetProhibitedTechnologies("wifi", &error);
    EXPECT_TRUE(error.IsSuccess());
  }

  device->SetEnabled(true);
  EXPECT_FALSE(device->running());

  {
    Error error;
    manager()->SetProhibitedTechnologies("", &error);
    EXPECT_TRUE(error.IsSuccess());
  }
  device->SetEnabled(true);
  EXPECT_TRUE(device->running());
}

TEST_F(DeviceTest, Reset) {
  Error e;
  device_->Reset(&e, ResultCallback());
  EXPECT_EQ(Error::kNotSupported, e.type());
  EXPECT_EQ("Device doesn't support Reset.", e.message());
}

TEST_F(DeviceTest, ResumeWithIPConfig) {
  scoped_refptr<MockIPConfig> ipconfig =
      new MockIPConfig(control_interface(), kDeviceName);
  device_->set_ipconfig(ipconfig);
  EXPECT_CALL(*ipconfig, RenewIP());
  device_->OnAfterResume();
}

TEST_F(DeviceTest, ResumeWithoutIPConfig) {
  // Just test that we don't crash in this case.
  ASSERT_EQ(nullptr, device_->ipconfig().get());
  device_->OnAfterResume();
}

TEST_F(DeviceTest, ResumeWithLinkMonitor) {
  MockLinkMonitor* link_monitor = new StrictMock<MockLinkMonitor>();
  SetLinkMonitor(link_monitor);  // Passes ownership.
  EXPECT_CALL(*link_monitor, OnAfterResume());
  device_->OnAfterResume();
}

TEST_F(DeviceTest, ResumeWithoutLinkMonitor) {
  // Just test that we don't crash in this case.
  EXPECT_FALSE(HasLinkMonitor());
  device_->OnAfterResume();
}

TEST_F(DeviceTest, ResumeWithUnreliableLink) {
  scoped_refptr<MockService> service(
      new StrictMock<MockService>(control_interface(),
                                  dispatcher(),
                                  metrics(),
                                  manager()));
  SelectService(service);
  service->set_unreliable(true);
  SetReliableLinkCallback();

  // Link status should be resetted upon resume.
  device_->OnAfterResume();
  EXPECT_FALSE(service->unreliable());
  EXPECT_TRUE(ReliableLinkCallbackIsCancelled());
}

TEST_F(DeviceTest, OnConnected) {
  scoped_refptr<MockService> service(
      new StrictMock<MockService>(control_interface(),
                                  dispatcher(),
                                  metrics(),
                                  manager()));
  SelectService(service);

  // Link is reliable, no need to post delayed task to reset link status.
  device_->OnConnected();
  EXPECT_TRUE(ReliableLinkCallbackIsCancelled());

  // Link is unreliable when connected, delayed task is posted to reset the
  // link state.
  service->set_unreliable(true);
  device_->OnConnected();
  EXPECT_FALSE(ReliableLinkCallbackIsCancelled());
}

TEST_F(DeviceTest, LinkMonitor) {
  scoped_refptr<MockConnection> connection(
      new StrictMock<MockConnection>(&device_info_));
  MockManager manager(control_interface(),
                      dispatcher(),
                      metrics());
  scoped_refptr<MockService> service(
      new StrictMock<MockService>(control_interface(),
                                  dispatcher(),
                                  metrics(),
                                  &manager));
  SelectService(service);
  SetConnection(connection.get());
  MockLinkMonitor* link_monitor = new StrictMock<MockLinkMonitor>();
  SetLinkMonitor(link_monitor);  // Passes ownership.
  SetManager(&manager);
  EXPECT_CALL(*link_monitor, Start()).Times(0);
  EXPECT_CALL(manager, IsTechnologyLinkMonitorEnabled(Technology::kUnknown))
      .WillOnce(Return(false))
      .WillRepeatedly(Return(true));
  EXPECT_FALSE(StartLinkMonitor());

  EXPECT_CALL(*link_monitor, Start()).Times(0);
  EXPECT_CALL(*service, link_monitor_disabled())
      .WillOnce(Return(true))
      .WillRepeatedly(Return(false));
  EXPECT_FALSE(StartLinkMonitor());

  EXPECT_CALL(*link_monitor, Start())
      .WillOnce(Return(false))
      .WillOnce(Return(true));
  EXPECT_FALSE(StartLinkMonitor());
  EXPECT_TRUE(StartLinkMonitor());

  unsigned int kResponseTime = 123;
  EXPECT_CALL(*link_monitor, GetResponseTimeMilliseconds())
      .WillOnce(Return(kResponseTime));
  {
    Error error;
    EXPECT_EQ(kResponseTime, GetLinkMonitorResponseTime(&error));
    EXPECT_TRUE(error.IsSuccess());
  }
  StopLinkMonitor();
  {
    Error error;
    EXPECT_EQ(0, GetLinkMonitorResponseTime(&error));
    EXPECT_FALSE(error.IsSuccess());
  }
}

TEST_F(DeviceTest, LinkMonitorCancelledOnSelectService) {
  scoped_refptr<MockConnection> connection(
      new StrictMock<MockConnection>(&device_info_));
  MockManager manager(control_interface(),
                      dispatcher(),
                      metrics());
  scoped_refptr<MockService> service(
      new StrictMock<MockService>(control_interface(),
                                  dispatcher(),
                                  metrics(),
                                  &manager));
  SelectService(service);
  SetConnection(connection.get());
  MockLinkMonitor* link_monitor = new StrictMock<MockLinkMonitor>();
  SetLinkMonitor(link_monitor);  // Passes ownership.
  SetManager(&manager);
  EXPECT_CALL(*service, state())
      .WillOnce(Return(Service::kStateIdle));
  EXPECT_CALL(*service, SetState(_));
  EXPECT_CALL(*service, SetConnection(_));
  EXPECT_TRUE(HasLinkMonitor());
  SelectService(nullptr);
  EXPECT_FALSE(HasLinkMonitor());
}

TEST_F(DeviceTest, TrafficMonitor) {
  scoped_refptr<MockConnection> connection(
      new StrictMock<MockConnection>(&device_info_));
  MockManager manager(control_interface(),
                      dispatcher(),
                      metrics());
  scoped_refptr<MockService> service(
      new StrictMock<MockService>(control_interface(),
                                  dispatcher(),
                                  metrics(),
                                  &manager));
  SelectService(service);
  SetConnection(connection.get());
  MockTrafficMonitor* traffic_monitor =
      SetTrafficMonitor(std::make_unique<StrictMock<MockTrafficMonitor>>());
  SetManager(&manager);

  EXPECT_CALL(*device_, IsTrafficMonitorEnabled()).WillRepeatedly(Return(true));
  EXPECT_CALL(*traffic_monitor, Start());
  StartTrafficMonitor();
  EXPECT_CALL(*traffic_monitor, Stop());
  StopTrafficMonitor();
  Mock::VerifyAndClearExpectations(traffic_monitor);

  EXPECT_CALL(metrics_, NotifyNetworkProblemDetected(_,
      Metrics::kNetworkProblemDNSFailure)).Times(1);
  NetworkProblemDetected(TrafficMonitor::kNetworkProblemDNSFailure);

  // Verify traffic monitor not running when it is disabled.
  traffic_monitor =
      SetTrafficMonitor(std::make_unique<StrictMock<MockTrafficMonitor>>());
  EXPECT_CALL(*device_, IsTrafficMonitorEnabled())
      .WillRepeatedly(Return(false));
  EXPECT_CALL(*traffic_monitor, Start()).Times(0);
  StartTrafficMonitor();
  EXPECT_CALL(*traffic_monitor, Stop()).Times(0);
  StopTrafficMonitor();
}

TEST_F(DeviceTest, TrafficMonitorCancelledOnSelectService) {
  scoped_refptr<MockConnection> connection(
      new StrictMock<MockConnection>(&device_info_));
  MockManager manager(control_interface(),
                      dispatcher(),
                      metrics());
  scoped_refptr<MockService> service(
      new StrictMock<MockService>(control_interface(),
                                  dispatcher(),
                                  metrics(),
                                  &manager));
  SelectService(service);
  SetConnection(connection.get());
  MockTrafficMonitor* traffic_monitor =
      SetTrafficMonitor(std::make_unique<StrictMock<MockTrafficMonitor>>());
  EXPECT_CALL(*device_, IsTrafficMonitorEnabled()).WillRepeatedly(Return(true));
  SetManager(&manager);
  EXPECT_CALL(*service, state())
      .WillOnce(Return(Service::kStateIdle));
  EXPECT_CALL(*service, SetState(_));
  EXPECT_CALL(*service, SetConnection(_));
  EXPECT_CALL(*traffic_monitor, Stop());
  SelectService(nullptr);
}

TEST_F(DeviceTest, ShouldUseArpGateway) {
  EXPECT_FALSE(device_->ShouldUseArpGateway());
}

TEST_F(DeviceTest, PerformTDLSOperation) {
  EXPECT_EQ(
      "", device_->PerformTDLSOperation("do something", "to someone", nullptr));
}

TEST_F(DeviceTest, IsConnectedViaTether) {
  EXPECT_FALSE(device_->IsConnectedViaTether());

  // An empty ipconfig doesn't mean we're tethered.
  device_->ipconfig_ = new IPConfig(control_interface(), kDeviceName);
  EXPECT_FALSE(device_->IsConnectedViaTether());

  // Add an ipconfig property that indicates this is an Android tether.
  IPConfig::Properties properties;
  properties.vendor_encapsulated_options =
      ByteArray(Tethering::kAndroidVendorEncapsulatedOptions,
                Tethering::kAndroidVendorEncapsulatedOptions +
                    strlen(Tethering::kAndroidVendorEncapsulatedOptions));
  device_->ipconfig_->UpdateProperties(properties, true);
  EXPECT_TRUE(device_->IsConnectedViaTether());

  const char kTestVendorEncapsulatedOptions[] = "Some other non-empty value";
  properties.vendor_encapsulated_options = ByteArray(
      kTestVendorEncapsulatedOptions,
      kTestVendorEncapsulatedOptions + sizeof(kTestVendorEncapsulatedOptions));
  device_->ipconfig_->UpdateProperties(properties, true);
  EXPECT_FALSE(device_->IsConnectedViaTether());
}

TEST_F(DeviceTest, AvailableIPConfigs) {
  EXPECT_EQ(vector<string>(), device_->AvailableIPConfigs(nullptr));
  device_->ipconfig_ = new IPConfig(control_interface(), kDeviceName);
  EXPECT_EQ(vector<string> { IPConfigMockAdaptor::kRpcId },
            device_->AvailableIPConfigs(nullptr));
  device_->ip6config_ = new IPConfig(control_interface(), kDeviceName);

  // We don't really care that the RPC IDs for all IPConfig mock adaptors
  // are the same, or their ordering.  We just need to see that there are two
  // of them when both IPv6 and IPv4 IPConfigs are available.
  EXPECT_EQ(2, device_->AvailableIPConfigs(nullptr).size());

  device_->dhcpv6_config_ = new IPConfig(control_interface(), kDeviceName);
  EXPECT_EQ(3, device_->AvailableIPConfigs(nullptr).size());

  device_->dhcpv6_config_ = nullptr;
  EXPECT_EQ(2, device_->AvailableIPConfigs(nullptr).size());

  device_->ipconfig_ = nullptr;
  EXPECT_EQ(vector<string> { IPConfigMockAdaptor::kRpcId },
            device_->AvailableIPConfigs(nullptr));

  device_->ip6config_ = nullptr;
  EXPECT_EQ(vector<string>(), device_->AvailableIPConfigs(nullptr));
}

TEST_F(DeviceTest, OnIPv6AddressChanged) {
  StrictMock<MockManager> manager(control_interface(),
                                  dispatcher(),
                                  metrics());
  manager.set_mock_device_info(&device_info_);
  EXPECT_CALL(manager, FilterPrependDNSServersByFamily(_))
      .WillRepeatedly(Return(vector<string>()));
  SetManager(&manager);

  // An IPv6 clear while ip6config_ is nullptr will not emit a change.
  EXPECT_CALL(device_info_, GetPrimaryIPv6Address(kDeviceInterfaceIndex, _))
      .WillOnce(Return(false));
  EXPECT_CALL(*GetDeviceMockAdaptor(),
              EmitRpcIdentifierArrayChanged(kIPConfigsProperty, _)).Times(0);
  device_->OnIPv6AddressChanged();
  EXPECT_THAT(device_->ip6config_, IsNullRefPtr());
  Mock::VerifyAndClearExpectations(GetDeviceMockAdaptor());
  Mock::VerifyAndClearExpectations(&device_info_);

  IPAddress address0(IPAddress::kFamilyIPv6);
  const char kAddress0[] = "fe80::1aa9:5ff:abcd:1234";
  ASSERT_TRUE(address0.SetAddressFromString(kAddress0));

  // Add an IPv6 address while ip6config_ is nullptr.
  EXPECT_CALL(device_info_, GetPrimaryIPv6Address(kDeviceInterfaceIndex, _))
      .WillOnce(DoAll(SetArgPointee<1>(address0), Return(true)));
  EXPECT_CALL(*GetDeviceMockAdaptor(),
              EmitRpcIdentifierArrayChanged(
                  kIPConfigsProperty,
                  vector<string> { IPConfigMockAdaptor::kRpcId }));
  device_->OnIPv6AddressChanged();
  EXPECT_THAT(device_->ip6config_, NotNullRefPtr());
  EXPECT_EQ(kAddress0, device_->ip6config_->properties().address);
  Mock::VerifyAndClearExpectations(GetDeviceMockAdaptor());
  Mock::VerifyAndClearExpectations(&device_info_);

  // If the IPv6 address does not change, no signal is emitted.
  EXPECT_CALL(device_info_, GetPrimaryIPv6Address(kDeviceInterfaceIndex, _))
      .WillOnce(DoAll(SetArgPointee<1>(address0), Return(true)));
  EXPECT_CALL(*GetDeviceMockAdaptor(),
              EmitRpcIdentifierArrayChanged(kIPConfigsProperty, _)).Times(0);
  device_->OnIPv6AddressChanged();
  EXPECT_EQ(kAddress0, device_->ip6config_->properties().address);
  Mock::VerifyAndClearExpectations(GetDeviceMockAdaptor());
  Mock::VerifyAndClearExpectations(&device_info_);

  IPAddress address1(IPAddress::kFamilyIPv6);
  const char kAddress1[] = "fe80::1aa9:5ff:abcd:5678";
  ASSERT_TRUE(address1.SetAddressFromString(kAddress1));

  // If the IPv6 address changes, a signal is emitted.
  EXPECT_CALL(device_info_, GetPrimaryIPv6Address(kDeviceInterfaceIndex, _))
      .WillOnce(DoAll(SetArgPointee<1>(address1), Return(true)));
  EXPECT_CALL(*GetDeviceMockAdaptor(),
              EmitRpcIdentifierArrayChanged(
                  kIPConfigsProperty,
                  vector<string> { IPConfigMockAdaptor::kRpcId }));
  device_->OnIPv6AddressChanged();
  EXPECT_EQ(kAddress1, device_->ip6config_->properties().address);
  Mock::VerifyAndClearExpectations(GetDeviceMockAdaptor());
  Mock::VerifyAndClearExpectations(&device_info_);

  // If the IPv6 prefix changes, a signal is emitted.
  address1.set_prefix(64);
  EXPECT_CALL(device_info_, GetPrimaryIPv6Address(kDeviceInterfaceIndex, _))
      .WillOnce(DoAll(SetArgPointee<1>(address1), Return(true)));
  EXPECT_CALL(*GetDeviceMockAdaptor(),
              EmitRpcIdentifierArrayChanged(
                  kIPConfigsProperty,
                  vector<string> { IPConfigMockAdaptor::kRpcId }));
  device_->OnIPv6AddressChanged();
  EXPECT_EQ(kAddress1, device_->ip6config_->properties().address);

  // Return the IPv6 address to nullptr.
  EXPECT_CALL(device_info_, GetPrimaryIPv6Address(kDeviceInterfaceIndex, _))
      .WillOnce(Return(false));
  EXPECT_CALL(*GetDeviceMockAdaptor(),
              EmitRpcIdentifierArrayChanged(kIPConfigsProperty,
                                            vector<string>()));
  device_->OnIPv6AddressChanged();
  EXPECT_THAT(device_->ip6config_, IsNullRefPtr());
  Mock::VerifyAndClearExpectations(GetDeviceMockAdaptor());
  Mock::VerifyAndClearExpectations(&device_info_);
}

TEST_F(DeviceTest, OnIPv6DnsServerAddressesChanged_LeaseExpirationUpdated) {
  MockManager manager(control_interface(),
                      dispatcher(),
                      metrics());
  manager.set_mock_device_info(&device_info_);
  EXPECT_CALL(manager, FilterPrependDNSServersByFamily(_))
      .WillRepeatedly(Return(vector<string>()));
  SetManager(&manager);

  scoped_refptr<MockIPConfig> ip6config =
      new MockIPConfig(control_interface(), kDeviceName);
  device_->ip6config_ = ip6config;

  // Non-infinite lifetime should trigger an update of the current lease
  // expiration time.
  const uint32_t kExpiredLifetime = 1;
  EXPECT_CALL(device_info_,
              GetIPv6DnsServerAddresses(kDeviceInterfaceIndex, _, _))
      .WillOnce(DoAll(SetArgPointee<2>(kExpiredLifetime),
                      Return(true)));
  EXPECT_CALL(*ip6config, UpdateLeaseExpirationTime(_)).Times(1);
  EXPECT_CALL(*ip6config, ResetLeaseExpirationTime()).Times(0);
  device_->OnIPv6DnsServerAddressesChanged();

  // Infinite lifetime should cause a reset of the current lease expiration
  // time to its default value.
  const uint32_t kExpiredLifetimeInfinity = ND_OPT_LIFETIME_INFINITY;
  EXPECT_CALL(device_info_,
              GetIPv6DnsServerAddresses(kDeviceInterfaceIndex, _, _))
      .WillOnce(DoAll(SetArgPointee<2>(kExpiredLifetimeInfinity),
                      Return(true)));
  EXPECT_CALL(*ip6config, UpdateLeaseExpirationTime(_)).Times(0);
  EXPECT_CALL(*ip6config, ResetLeaseExpirationTime()).Times(1);
  device_->OnIPv6DnsServerAddressesChanged();
}

TEST_F(DeviceTest, OnIPv6DnsServerAddressesChanged) {
  StrictMock<MockManager> manager(control_interface(),
                                  dispatcher(),
                                  metrics());
  manager.set_mock_device_info(&device_info_);
  EXPECT_CALL(manager, FilterPrependDNSServersByFamily(_))
      .WillRepeatedly(Return(vector<string>()));
  SetManager(&manager);

  // With existing IPv4 connection, so no attempt to setup IPv6 connection.
  // IPv6 connection is being tested in OnIPv6ConfigurationCompleted test.
  scoped_refptr<MockConnection> connection(
      new StrictMock<MockConnection>(&device_info_));
  SetConnection(connection.get());
  EXPECT_CALL(*connection, IsIPv6())
      .WillRepeatedly(Return(false));

  // IPv6 DNS server addresses are not provided will not emit a change.
  EXPECT_CALL(device_info_,
              GetIPv6DnsServerAddresses(kDeviceInterfaceIndex, _, _))
      .WillOnce(Return(false));
  EXPECT_CALL(*GetDeviceMockAdaptor(),
              EmitRpcIdentifierArrayChanged(kIPConfigsProperty, _)).Times(0);
  device_->OnIPv6DnsServerAddressesChanged();
  EXPECT_THAT(device_->ip6config_, IsNullRefPtr());
  Mock::VerifyAndClearExpectations(GetDeviceMockAdaptor());
  Mock::VerifyAndClearExpectations(&device_info_);

  const char kAddress1[] = "fe80::1aa9:5ff:abcd:1234";
  const char kAddress2[] = "fe80::1aa9:5ff:abcd:1235";
  const uint32_t kInfiniteLifetime = 0xffffffff;
  IPAddress ipv6_address1(IPAddress::kFamilyIPv6);
  IPAddress ipv6_address2(IPAddress::kFamilyIPv6);
  ASSERT_TRUE(ipv6_address1.SetAddressFromString(kAddress1));
  ASSERT_TRUE(ipv6_address2.SetAddressFromString(kAddress2));
  vector<IPAddress> dns_server_addresses;
  dns_server_addresses.push_back(ipv6_address1);
  dns_server_addresses.push_back(ipv6_address2);
  vector<string> dns_server_addresses_str;
  dns_server_addresses_str.push_back(kAddress1);
  dns_server_addresses_str.push_back(kAddress2);

  // Add IPv6 DNS server addresses while ip6config_ is nullptr.
  EXPECT_CALL(device_info_,
              GetIPv6DnsServerAddresses(kDeviceInterfaceIndex, _, _))
      .WillOnce(DoAll(SetArgPointee<1>(dns_server_addresses),
                      SetArgPointee<2>(kInfiniteLifetime),
                      Return(true)));
  EXPECT_CALL(*GetDeviceMockAdaptor(),
              EmitRpcIdentifierArrayChanged(
                  kIPConfigsProperty,
                  vector<string> { IPConfigMockAdaptor::kRpcId }));
  device_->OnIPv6DnsServerAddressesChanged();
  EXPECT_THAT(device_->ip6config_, NotNullRefPtr());
  EXPECT_EQ(dns_server_addresses_str,
            device_->ip6config_->properties().dns_servers);
  Mock::VerifyAndClearExpectations(GetDeviceMockAdaptor());
  Mock::VerifyAndClearExpectations(&device_info_);

  // Add an IPv6 address while IPv6 DNS server addresses already existed.
  IPAddress address3(IPAddress::kFamilyIPv6);
  const char kAddress3[] = "fe80::1aa9:5ff:abcd:1236";
  ASSERT_TRUE(address3.SetAddressFromString(kAddress3));
  EXPECT_CALL(device_info_, GetPrimaryIPv6Address(kDeviceInterfaceIndex, _))
      .WillOnce(DoAll(SetArgPointee<1>(address3), Return(true)));
  EXPECT_CALL(*GetDeviceMockAdaptor(),
              EmitRpcIdentifierArrayChanged(
                  kIPConfigsProperty,
                  vector<string> { IPConfigMockAdaptor::kRpcId }));
  device_->OnIPv6AddressChanged();
  EXPECT_THAT(device_->ip6config_, NotNullRefPtr());
  EXPECT_EQ(kAddress3, device_->ip6config_->properties().address);
  EXPECT_EQ(dns_server_addresses_str,
            device_->ip6config_->properties().dns_servers);
  Mock::VerifyAndClearExpectations(GetDeviceMockAdaptor());
  Mock::VerifyAndClearExpectations(&device_info_);

  // If the IPv6 DNS server addresses does not change, no signal is emitted.
  EXPECT_CALL(device_info_,
              GetIPv6DnsServerAddresses(kDeviceInterfaceIndex, _, _))
      .WillOnce(DoAll(SetArgPointee<1>(dns_server_addresses),
                      SetArgPointee<2>(kInfiniteLifetime),
                      Return(true)));
  EXPECT_CALL(*GetDeviceMockAdaptor(),
              EmitRpcIdentifierArrayChanged(kIPConfigsProperty, _)).Times(0);
  device_->OnIPv6DnsServerAddressesChanged();
  EXPECT_EQ(dns_server_addresses_str,
            device_->ip6config_->properties().dns_servers);
  Mock::VerifyAndClearExpectations(GetDeviceMockAdaptor());
  Mock::VerifyAndClearExpectations(&device_info_);

  // Setting lifetime to 0 should expire and clear out the DNS server.
  const uint32_t kExpiredLifetime = 0;
  vector<string> empty_dns_server;
  EXPECT_CALL(device_info_,
              GetIPv6DnsServerAddresses(kDeviceInterfaceIndex, _, _))
      .WillOnce(DoAll(SetArgPointee<1>(dns_server_addresses),
                      SetArgPointee<2>(kExpiredLifetime),
                      Return(true)));
  EXPECT_CALL(*GetDeviceMockAdaptor(),
              EmitRpcIdentifierArrayChanged(
                  kIPConfigsProperty,
                  vector<string> { IPConfigMockAdaptor::kRpcId }));
  device_->OnIPv6DnsServerAddressesChanged();
  EXPECT_EQ(empty_dns_server, device_->ip6config_->properties().dns_servers);
  Mock::VerifyAndClearExpectations(GetDeviceMockAdaptor());
  Mock::VerifyAndClearExpectations(&device_info_);

  // Set DNS server with lifetime of 1 hour.
  const uint32_t kLifetimeOneHr = 3600;
  EXPECT_CALL(device_info_,
              GetIPv6DnsServerAddresses(kDeviceInterfaceIndex, _, _))
      .WillOnce(DoAll(SetArgPointee<1>(dns_server_addresses),
                      SetArgPointee<2>(kLifetimeOneHr),
                      Return(true)));
  EXPECT_CALL(*GetDeviceMockAdaptor(),
              EmitRpcIdentifierArrayChanged(
                  kIPConfigsProperty,
                  vector<string> { IPConfigMockAdaptor::kRpcId }));
  device_->OnIPv6DnsServerAddressesChanged();
  EXPECT_EQ(dns_server_addresses_str,
            device_->ip6config_->properties().dns_servers);
  Mock::VerifyAndClearExpectations(GetDeviceMockAdaptor());
  Mock::VerifyAndClearExpectations(&device_info_);

  // Return the DNS server addresses to nullptr.
  EXPECT_CALL(device_info_,
              GetIPv6DnsServerAddresses(kDeviceInterfaceIndex, _, _))
      .WillOnce(Return(false));
  EXPECT_CALL(*GetDeviceMockAdaptor(),
              EmitRpcIdentifierArrayChanged(
                  kIPConfigsProperty,
                  vector<string> { IPConfigMockAdaptor::kRpcId }));
  device_->OnIPv6DnsServerAddressesChanged();
  EXPECT_EQ(empty_dns_server, device_->ip6config_->properties().dns_servers);
  Mock::VerifyAndClearExpectations(GetDeviceMockAdaptor());
  Mock::VerifyAndClearExpectations(&device_info_);
}

TEST_F(DeviceTest, OnIPv6ConfigurationCompleted) {
  StrictMock<MockManager> manager(control_interface(),
                                  dispatcher(),
                                  metrics());
  manager.set_mock_device_info(&device_info_);
  EXPECT_CALL(manager, FilterPrependDNSServersByFamily(_))
      .WillRepeatedly(Return(vector<string>()));
  SetManager(&manager);
  scoped_refptr<MockService> service(
      new StrictMock<MockService>(control_interface(),
                                  dispatcher(),
                                  metrics(),
                                  &manager));
  SelectService(service);
  scoped_refptr<MockConnection> connection(
      new StrictMock<MockConnection>(&device_info_));
  SetConnection(connection.get());

  // Setup initial IPv6 configuration.
  SetupIPv6Config();
  EXPECT_THAT(device_->ip6config_, NotNullRefPtr());

  // IPv6 configuration update with non-IPv6 connection, no connection update.
  EXPECT_THAT(device_->connection(), NotNullRefPtr());
  IPAddress address1(IPAddress::kFamilyIPv6);
  const char kAddress1[] = "fe80::1aa9:5ff:abcd:1231";
  ASSERT_TRUE(address1.SetAddressFromString(kAddress1));
  EXPECT_CALL(device_info_, GetPrimaryIPv6Address(kDeviceInterfaceIndex, _))
      .WillOnce(DoAll(SetArgPointee<1>(address1), Return(true)));
  EXPECT_CALL(*GetDeviceMockAdaptor(),
              EmitRpcIdentifierArrayChanged(
                  kIPConfigsProperty,
                  vector<string> { IPConfigMockAdaptor::kRpcId }));
  EXPECT_CALL(*connection, IsIPv6())
      .WillRepeatedly(Return(false));
  EXPECT_CALL(*service, SetConnection(_)).Times(0);
  device_->OnIPv6AddressChanged();
  Mock::VerifyAndClearExpectations(GetDeviceMockAdaptor());
  Mock::VerifyAndClearExpectations(&device_info_);
  Mock::VerifyAndClearExpectations(service.get());
  Mock::VerifyAndClearExpectations(connection.get());

  // IPv6 configuration update with IPv6 connection, connection update.
  IPAddress address2(IPAddress::kFamilyIPv6);
  const char kAddress2[] = "fe80::1aa9:5ff:abcd:1232";
  ASSERT_TRUE(address2.SetAddressFromString(kAddress2));
  EXPECT_CALL(device_info_, GetPrimaryIPv6Address(kDeviceInterfaceIndex, _))
      .WillOnce(DoAll(SetArgPointee<1>(address2), Return(true)));
  EXPECT_CALL(*GetDeviceMockAdaptor(),
              EmitRpcIdentifierArrayChanged(
                  kIPConfigsProperty,
                  vector<string> { IPConfigMockAdaptor::kRpcId }));
  EXPECT_CALL(*connection, IsIPv6())
      .WillRepeatedly(Return(true));
  EXPECT_CALL(*connection, UpdateFromIPConfig(device_->ip6config_));
  EXPECT_CALL(metrics_,
              NotifyNetworkConnectionIPType(
                  device_->technology(),
                  Metrics::kNetworkConnectionIPTypeIPv6));
  EXPECT_CALL(metrics_,
              NotifyIPv6ConnectivityStatus(device_->technology(), true));
  EXPECT_CALL(*service, state())
      .WillOnce(Return(Service::kStateConfiguring));
  EXPECT_CALL(*service, SetState(Service::kStateConnected));
  EXPECT_CALL(*service, IsConnected())
      .WillRepeatedly(Return(true));
  EXPECT_CALL(*service, IsPortalDetectionDisabled())
      .WillRepeatedly(Return(true));
  EXPECT_CALL(*service, SetState(Service::kStateOnline));
  EXPECT_CALL(*service, SetConnection(NotNullRefPtr()));
  EXPECT_CALL(manager, IsTechnologyLinkMonitorEnabled(_))
      .WillRepeatedly(Return(false));
  device_->OnIPv6AddressChanged();
  Mock::VerifyAndClearExpectations(GetDeviceMockAdaptor());
  Mock::VerifyAndClearExpectations(&device_info_);
  Mock::VerifyAndClearExpectations(service.get());
  Mock::VerifyAndClearExpectations(connection.get());
}

TEST_F(DeviceTest, OnDHCPv6ConfigUpdated) {
  device_->dhcpv6_config_ = new IPConfig(control_interface(), kDeviceName);
  EXPECT_CALL(*GetDeviceMockAdaptor(),
              EmitRpcIdentifierArrayChanged(
                  kIPConfigsProperty,
                  vector<string> { IPConfigMockAdaptor::kRpcId }));
  device_->OnDHCPv6ConfigUpdated(device_->dhcpv6_config_.get(), true);
}

TEST_F(DeviceTest, OnDHCPv6ConfigFailed) {
  device_->dhcpv6_config_ = new IPConfig(control_interface(), kDeviceName);
  IPConfig::Properties properties;
  properties.dhcpv6_addresses =
      {{{kDhcpv6AddressProperty, "2001:db8:0:1::1"}}};
  properties.dhcpv6_delegated_prefixes =
      {{{kDhcpv6AddressProperty, "2001:db8:0:100::"}}};
  properties.lease_duration_seconds = 1;
  device_->dhcpv6_config_->set_properties(properties);
  EXPECT_CALL(*GetDeviceMockAdaptor(),
              EmitRpcIdentifierArrayChanged(
                  kIPConfigsProperty,
                  vector<string> { IPConfigMockAdaptor::kRpcId }));
  device_->OnDHCPv6ConfigFailed(device_->dhcpv6_config_.get());
  EXPECT_TRUE(device_->dhcpv6_config_->properties().dhcpv6_addresses.empty());
  EXPECT_TRUE(
      device_->dhcpv6_config_->properties().dhcpv6_delegated_prefixes.empty());
  EXPECT_EQ(0, device_->dhcpv6_config_->properties().lease_duration_seconds);
}

TEST_F(DeviceTest, OnDHCPv6ConfigExpired) {
  device_->dhcpv6_config_ = new IPConfig(control_interface(), kDeviceName);
  IPConfig::Properties properties;
  properties.dhcpv6_addresses =
      {{{kDhcpv6AddressProperty, "2001:db8:0:1::1"}}};
  properties.dhcpv6_delegated_prefixes =
      {{{kDhcpv6AddressProperty, "2001:db8:0:100::"}}};
  properties.lease_duration_seconds = 1;
  device_->dhcpv6_config_->set_properties(properties);
  EXPECT_CALL(*GetDeviceMockAdaptor(),
              EmitRpcIdentifierArrayChanged(
                  kIPConfigsProperty,
                  vector<string> { IPConfigMockAdaptor::kRpcId }));
  device_->OnDHCPv6ConfigExpired(device_->dhcpv6_config_.get());
  EXPECT_TRUE(device_->dhcpv6_config_->properties().dhcpv6_addresses.empty());
  EXPECT_TRUE(
      device_->dhcpv6_config_->properties().dhcpv6_delegated_prefixes.empty());
  EXPECT_EQ(0, device_->dhcpv6_config_->properties().lease_duration_seconds);
}

TEST_F(DeviceTest, PrependIPv4DNSServers) {
  MockManager manager(control_interface(), dispatcher(), metrics());
  manager.set_mock_device_info(&device_info_);
  SetManager(&manager);

  const struct {
    vector<string> ipconfig_servers;
    vector<string> prepend_servers;
    vector<string> expected_servers;
  } expectations[] = {
    {{}, {"8.8.8.8"}, {"8.8.8.8"}},
    {{"8.8.8.8"}, {}, {"8.8.8.8"}},
    {{"8.8.8.8"}, {"10.10.10.10"}, {"10.10.10.10", "8.8.8.8"}},
    {{"8.8.8.8", "10.10.10.10"}, {"10.10.10.10"}, {"10.10.10.10", "8.8.8.8"}},
    {{"8.8.8.8", "10.10.10.10"}, {"8.8.8.8"}, {"8.8.8.8", "10.10.10.10"}},
    {{"8.8.8.8", "9.9.9.9", "10.10.10.10"}, {"9.9.9.9"},
     {"9.9.9.9", "8.8.8.8", "10.10.10.10"}},
  };

  for (const auto& expectation : expectations) {
    scoped_refptr<IPConfig> ipconfig =
        new IPConfig(control_interface(), kDeviceName);

    EXPECT_CALL(manager, FilterPrependDNSServersByFamily(
        IPAddress::kFamilyIPv4)).WillOnce(Return(expectation.prepend_servers));
    IPConfig::Properties properties;
    properties.dns_servers = expectation.ipconfig_servers;
    properties.address_family = IPAddress::kFamilyIPv4;
    ipconfig->set_properties(properties);

    device_->set_ipconfig(ipconfig);
    OnIPConfigUpdated(ipconfig.get());
    EXPECT_EQ(expectation.expected_servers,
              device_->ipconfig()->properties().dns_servers);
  }
}

TEST_F(DeviceTest, PrependIPv6DNSServers) {
  MockManager manager(control_interface(), dispatcher(), metrics());
  manager.set_mock_device_info(&device_info_);
  SetManager(&manager);

  vector<IPAddress> dns_server_addresses = {
    IPAddress("2001:4860:4860::8888"),
    IPAddress("2001:4860:4860::8844")
  };

  const uint32_t kAddressLifetime = 1000;
  EXPECT_CALL(device_info_, GetIPv6DnsServerAddresses(_, _, _))
      .WillRepeatedly(DoAll(SetArgPointee<1>(dns_server_addresses),
                            SetArgPointee<2>(kAddressLifetime),
                            Return(true)));
  const vector<string> kOutputServers {"2001:4860:4860::8899"};
  EXPECT_CALL(manager, FilterPrependDNSServersByFamily(
      IPAddress::kFamilyIPv6)).WillOnce(Return(kOutputServers));
  device_->OnIPv6DnsServerAddressesChanged();

  const vector<string> kExpectedServers
      {"2001:4860:4860::8899", "2001:4860:4860::8888", "2001:4860:4860::8844"};
  EXPECT_EQ(kExpectedServers, device_->ip6config()->properties().dns_servers);
}

TEST_F(DeviceTest, PrependWithStaticConfiguration) {
  MockManager manager(control_interface(), dispatcher(), metrics());
  manager.set_mock_device_info(&device_info_);
  SetManager(&manager);

  scoped_refptr<IPConfig> ipconfig =
      new IPConfig(control_interface(), kDeviceName);

  device_->set_ipconfig(ipconfig);

  scoped_refptr<MockService> service = new MockService(control_interface(),
                                                       dispatcher(),
                                                       metrics(),
                                                       &manager);
  EXPECT_CALL(*service, IsPortalDetectionDisabled())
      .WillRepeatedly(Return(true));
  SelectService(service);

  auto parameters = service->mutable_static_ip_parameters();
  parameters->args_.SetString(kAddressProperty, "1.1.1.1");
  parameters->args_.SetInt(kPrefixlenProperty, 16);

  scoped_refptr<MockConnection> connection = new MockConnection(&device_info_);
  SetConnection(connection);

  // Ensure that in the absence of statically configured nameservers that the
  // prepend DNS servers are still prepended.
  EXPECT_CALL(*service, HasStaticNameServers()).WillOnce(Return(false));
  const vector<string> kOutputServers {"8.8.8.8"};
  EXPECT_CALL(manager, FilterPrependDNSServersByFamily(
      IPAddress::kFamilyIPv4)).WillRepeatedly(Return(kOutputServers));
  OnIPConfigUpdated(ipconfig.get());
  EXPECT_EQ(kOutputServers, device_->ipconfig()->properties().dns_servers);

  // Ensure that when nameservers are statically configured that the prepend DNS
  // servers are not used.
  const vector<string> static_servers = {"4.4.4.4", "5.5.5.5"};
  parameters->args_.SetStrings(kNameServersProperty, static_servers);
  EXPECT_CALL(*service, HasStaticNameServers()).WillOnce(Return(true));
  OnIPConfigUpdated(ipconfig.get());
  EXPECT_EQ(static_servers, device_->ipconfig()->properties().dns_servers);
}

TEST_F(DeviceTest, ResolvePeerMacAddress) {
  MockManager manager(control_interface(),
                      dispatcher(),
                      metrics());
  manager.set_mock_device_info(&device_info_);
  SetManager(&manager);

  // Invalid peer address (not a valid IP address nor MAC address).
  Error error;
  string result;
  const char kInvalidPeer[] = "peer";
  EXPECT_FALSE(device_->ResolvePeerMacAddress(kInvalidPeer, &result, &error));
  EXPECT_EQ(Error::kInvalidArguments, error.type());

  // No direct connectivity to the peer.
  const char kPeerIp[] = "192.168.1.1";
  error.Reset();
  EXPECT_CALL(device_info_,
              HasDirectConnectivityTo(device_->interface_index(), _))
      .WillOnce(Return(false));
  EXPECT_FALSE(device_->ResolvePeerMacAddress(kPeerIp, &result, &error));
  EXPECT_EQ(Error::kInvalidArguments, error.type());
  Mock::VerifyAndClearExpectations(&device_info_);

  // Provided IP address is in the ARP cache, return the resolved MAC address.
  const char kResolvedMac[] = "00:11:22:33:44:55";
  const ByteString kMacBytes(
      Device::MakeHardwareAddressFromString(kResolvedMac));
  error.Reset();
  EXPECT_CALL(device_info_,
              HasDirectConnectivityTo(device_->interface_index(), _))
      .WillOnce(Return(true));
  EXPECT_CALL(device_info_,
              GetMACAddressOfPeer(device_->interface_index(), _, _))
      .WillOnce(DoAll(SetArgPointee<2>(kMacBytes), Return(true)));
  EXPECT_TRUE(device_->ResolvePeerMacAddress(kPeerIp, &result, &error));
  EXPECT_EQ(kResolvedMac, result);
}

TEST_F(DeviceTest, SetHostnameWithEmptyHostname) {
  MockManager manager(control_interface(),
                      dispatcher(),
                      metrics());
  manager.set_mock_device_info(&device_info_);
  SetManager(&manager);

  EXPECT_CALL(manager, ShouldAcceptHostnameFrom(_)).Times(0);
  EXPECT_CALL(device_info_, SetHostname(_)).Times(0);
  EXPECT_FALSE(SetHostname(""));
}

TEST_F(DeviceTest, SetHostnameForDisallowedDevice) {
  MockManager manager(control_interface(),
                      dispatcher(),
                      metrics());
  manager.set_mock_device_info(&device_info_);
  SetManager(&manager);

  EXPECT_CALL(manager, ShouldAcceptHostnameFrom(kDeviceName))
      .WillOnce(Return(false));
  EXPECT_CALL(device_info_, SetHostname(_)).Times(0);
  EXPECT_FALSE(SetHostname("wilson"));
}

TEST_F(DeviceTest, SetHostnameWithFailingDeviceInfo) {
  MockManager manager(control_interface(),
                      dispatcher(),
                      metrics());
  manager.set_mock_device_info(&device_info_);
  SetManager(&manager);

  EXPECT_CALL(manager, ShouldAcceptHostnameFrom(kDeviceName))
      .WillOnce(Return(true));
  EXPECT_CALL(device_info_, SetHostname("wilson"))
      .WillOnce(Return(false));
  EXPECT_FALSE(SetHostname("wilson"));
}

TEST_F(DeviceTest, SetHostnameMaximumHostnameLength) {
  MockManager manager(control_interface(),
                      dispatcher(),
                      metrics());
  manager.set_mock_device_info(&device_info_);
  SetManager(&manager);

  EXPECT_CALL(manager, ShouldAcceptHostnameFrom(kDeviceName))
      .WillOnce(Return(true));
  EXPECT_CALL(device_info_, SetHostname(
      "wilson.was-a-good-ball.and-was.an-excellent-swimmer.in-high-seas"))
      .WillOnce(Return(true));
  EXPECT_TRUE(SetHostname(
      "wilson.was-a-good-ball.and-was.an-excellent-swimmer.in-high-seas"));
}

TEST_F(DeviceTest, SetHostnameTruncateDomainName) {
  MockManager manager(control_interface(),
                      dispatcher(),
                      metrics());
  manager.set_mock_device_info(&device_info_);
  SetManager(&manager);

  EXPECT_CALL(manager, ShouldAcceptHostnameFrom(kDeviceName))
      .WillOnce(Return(true));
  EXPECT_CALL(device_info_, SetHostname("wilson"))
      .WillOnce(Return(false));
  EXPECT_FALSE(SetHostname(
      "wilson.was-a-great-ball.and-was.an-excellent-swimmer.in-high-seas"));
}

TEST_F(DeviceTest, SetHostnameTruncateHostname) {
  MockManager manager(control_interface(),
                      dispatcher(),
                      metrics());
  manager.set_mock_device_info(&device_info_);
  SetManager(&manager);

  EXPECT_CALL(manager, ShouldAcceptHostnameFrom(kDeviceName))
      .WillOnce(Return(true));
  EXPECT_CALL(device_info_, SetHostname(
      "wilson-was-a-great-ball-and-was-an-excellent-swimmer-in-high-sea"))
      .WillOnce(Return(true));
  EXPECT_TRUE(SetHostname(
      "wilson-was-a-great-ball-and-was-an-excellent-swimmer-in-high-sea-chop"));
}

class DevicePortalDetectionTest : public DeviceTest {
 public:
  DevicePortalDetectionTest()
      : connection_(new StrictMock<MockConnection>(&device_info_)),
        manager_(control_interface(),
                 dispatcher(),
                 metrics()),
        service_(new StrictMock<MockService>(control_interface(),
                                             dispatcher(),
                                             metrics(),
                                             &manager_)),
        portal_detector_(new StrictMock<MockPortalDetector>(connection_)) {}
    virtual ~DevicePortalDetectionTest() {}
  void SetUp() override {
    DeviceTest::SetUp();
    SelectService(service_);
    SetConnection(connection_.get());
    device_->portal_detector_.reset(portal_detector_);  // Passes ownership.
    SetManager(&manager_);
  }

 protected:
  static const int kPortalAttempts;

  bool StartPortalDetection() { return device_->StartPortalDetection(); }
  void StopPortalDetection() { device_->StopPortalDetection(); }

  void PortalDetectorCallback(const PortalDetector::Result& result) {
    device_->PortalDetectorCallback(result);
  }
  bool RequestPortalDetection() {
    return device_->RequestPortalDetection();
  }
  void SetServiceConnectedState(Service::ConnectState state) {
    device_->SetServiceConnectedState(state);
  }
  void ExpectPortalDetectorReset() {
    EXPECT_FALSE(device_->portal_detector_.get());
  }
  void ExpectPortalDetectorSet() {
    EXPECT_TRUE(device_->portal_detector_.get());
  }
  void ExpectPortalDetectorIsMock() {
    EXPECT_EQ(portal_detector_, device_->portal_detector_.get());
  }
  void InvokeFallbackDNSResultCallback(DnsServerTester::Status status) {
    device_->FallbackDNSResultCallback(status);
  }
  void InvokeConfigDNSResultCallback(DnsServerTester::Status status) {
    device_->ConfigDNSResultCallback(status);
  }
  void DestroyConnection() { device_->DestroyConnection(); }
  scoped_refptr<MockConnection> connection_;
  StrictMock<MockManager> manager_;
  scoped_refptr<MockService> service_;

  // Used only for EXPECT_CALL().  Object is owned by device.
  MockPortalDetector* portal_detector_;
};

const int DevicePortalDetectionTest::kPortalAttempts = 2;

TEST_F(DevicePortalDetectionTest, ServicePortalDetectionDisabled) {
  EXPECT_CALL(*service_, IsPortalDetectionDisabled()).WillOnce(Return(true));
  EXPECT_CALL(*service_, IsConnected()).WillRepeatedly(Return(true));
  EXPECT_CALL(*service_, SetState(Service::kStateOnline));
  EXPECT_FALSE(StartPortalDetection());
}

TEST_F(DevicePortalDetectionTest, TechnologyPortalDetectionDisabled) {
  EXPECT_CALL(*service_, IsPortalDetectionDisabled()).WillOnce(Return(false));
  EXPECT_CALL(*service_, IsConnected()).WillRepeatedly(Return(true));
  EXPECT_CALL(*service_, IsPortalDetectionAuto()).WillOnce(Return(true));
  EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
      .WillOnce(Return(false));
  EXPECT_CALL(*service_, SetState(Service::kStateOnline));
  EXPECT_FALSE(StartPortalDetection());
}

TEST_F(DevicePortalDetectionTest, PortalDetectionProxyConfig) {
  EXPECT_CALL(*service_, IsPortalDetectionDisabled()).WillOnce(Return(false));
  EXPECT_CALL(*service_, IsConnected()).WillRepeatedly(Return(true));
  EXPECT_CALL(*service_, HasProxyConfig()).WillOnce(Return(true));
  EXPECT_CALL(*service_, IsPortalDetectionAuto()).WillOnce(Return(true));
  EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
      .WillOnce(Return(true));
  EXPECT_CALL(*service_, SetState(Service::kStateOnline));
  EXPECT_FALSE(StartPortalDetection());
}

TEST_F(DevicePortalDetectionTest, PortalDetectionBadUrl) {
  EXPECT_CALL(*service_, IsPortalDetectionDisabled()).WillOnce(Return(false));
  EXPECT_CALL(*service_, IsConnected()).WillRepeatedly(Return(true));
  EXPECT_CALL(*service_, HasProxyConfig()).WillOnce(Return(false));
  EXPECT_CALL(*service_, IsPortalDetectionAuto()).WillOnce(Return(true));
  EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
      .WillOnce(Return(true));
  const string http_portal_url, https_portal_url;
  const vector<string> fallback_urls;
  EXPECT_CALL(manager_, GetPortalCheckHttpUrl())
      .WillRepeatedly(ReturnRef(http_portal_url));
  EXPECT_CALL(manager_, GetPortalCheckHttpsUrl())
      .WillRepeatedly(ReturnRef(https_portal_url));
  EXPECT_CALL(manager_, GetPortalCheckFallbackHttpUrls())
      .WillRepeatedly(ReturnRef(fallback_urls));
  EXPECT_CALL(*service_, SetState(Service::kStateOnline));
  EXPECT_FALSE(StartPortalDetection());
}

TEST_F(DevicePortalDetectionTest, PortalDetectionStart) {
  EXPECT_CALL(*service_, IsPortalDetectionDisabled()).WillOnce(Return(false));
  EXPECT_CALL(*service_, IsConnected()).WillRepeatedly(Return(true));
  EXPECT_CALL(*service_, HasProxyConfig()).WillOnce(Return(false));
  EXPECT_CALL(*service_, IsPortalDetectionAuto()).WillOnce(Return(true));
  EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
      .WillOnce(Return(true));
  const string http_portal_url(PortalDetector::kDefaultHttpUrl);
  const string https_portal_url(PortalDetector::kDefaultHttpsUrl);
  const vector<string> fallback_urls(PortalDetector::kDefaultFallbackHttpUrls);
  EXPECT_CALL(manager_, GetPortalCheckHttpUrl())
      .WillRepeatedly(ReturnRef(http_portal_url));
  EXPECT_CALL(manager_, GetPortalCheckHttpsUrl())
      .WillRepeatedly(ReturnRef(https_portal_url));
  EXPECT_CALL(manager_, GetPortalCheckFallbackHttpUrls())
      .WillRepeatedly(ReturnRef(fallback_urls));
  EXPECT_CALL(*service_, SetState(Service::kStateOnline)).Times(0);
  const string kInterfaceName("int0");
  EXPECT_CALL(*connection_, interface_name())
      .WillRepeatedly(ReturnRef(kInterfaceName));
  EXPECT_CALL(*connection_, IsIPv6()).WillRepeatedly(Return(false));
  const vector<string> kDNSServers;
  EXPECT_CALL(*connection_, dns_servers())
      .WillRepeatedly(ReturnRef(kDNSServers));
  EXPECT_TRUE(StartPortalDetection());

  // Drop all references to device_info before it falls out of scope.
  SetConnection(nullptr);
  StopPortalDetection();
}

TEST_F(DevicePortalDetectionTest, PortalDetectionStartIPv6) {
  EXPECT_CALL(*service_, IsPortalDetectionDisabled()).WillOnce(Return(false));
  EXPECT_CALL(*service_, IsConnected()).WillRepeatedly(Return(true));
  EXPECT_CALL(*service_, HasProxyConfig()).WillOnce(Return(false));
  EXPECT_CALL(*service_, IsPortalDetectionAuto()).WillOnce(Return(true));
  EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
      .WillOnce(Return(true));
  const string http_portal_url(PortalDetector::kDefaultHttpUrl);
  const string https_portal_url(PortalDetector::kDefaultHttpsUrl);
  const vector<string> fallback_urls(PortalDetector::kDefaultFallbackHttpUrls);
  EXPECT_CALL(manager_, GetPortalCheckHttpUrl())
      .WillRepeatedly(ReturnRef(http_portal_url));
  EXPECT_CALL(manager_, GetPortalCheckHttpsUrl())
      .WillRepeatedly(ReturnRef(https_portal_url));
  EXPECT_CALL(manager_, GetPortalCheckFallbackHttpUrls())
      .WillRepeatedly(ReturnRef(fallback_urls));
  EXPECT_CALL(*service_, SetState(Service::kStateOnline)).Times(0);
  const string kInterfaceName("int0");
  EXPECT_CALL(*connection_, interface_name())
      .WillRepeatedly(ReturnRef(kInterfaceName));
  EXPECT_CALL(*connection_, IsIPv6()).WillRepeatedly(Return(true));
  const vector<string> kDNSServers;
  EXPECT_CALL(*connection_, dns_servers())
      .WillRepeatedly(ReturnRef(kDNSServers));
  EXPECT_TRUE(StartPortalDetection());

  // Drop all references to device_info before it falls out of scope.
  SetConnection(nullptr);
  StopPortalDetection();
}

MATCHER_P(IsPortalDetectorResult, result, "") {
  return (result.num_attempts == arg.num_attempts &&
          result.phase == arg.phase && result.status == arg.status);
}

TEST_F(DevicePortalDetectionTest, PortalDetectionFailure) {
  PortalDetector::Result result(PortalDetector::Phase::kConnection,
                                PortalDetector::Status::kFailure,
                                kPortalAttempts);
  EXPECT_CALL(*service_, IsConnected()).WillOnce(Return(true));
  EXPECT_CALL(*service_,
              SetPortalDetectionFailure(kPortalDetectionPhaseConnection,
                                        kPortalDetectionStatusFailure));
  EXPECT_CALL(*service_, SetState(Service::kStatePortal));
  EXPECT_CALL(metrics_,
              SendEnumToUMA("Network.Shill.Unknown.PortalResult",
                            Metrics::kPortalResultConnectionFailure,
                            Metrics::kPortalResultMax));
  EXPECT_CALL(metrics_,
              SendToUMA("Network.Shill.Unknown.PortalAttemptsToOnline",
                        _, _, _, _)).Times(0);
  EXPECT_CALL(*connection_, IsDefault()).WillOnce(Return(false));
  EXPECT_CALL(*connection_, IsIPv6()).WillOnce(Return(false));
  EXPECT_CALL(*device_, StartConnectionDiagnosticsAfterPortalDetection(
                            IsPortalDetectorResult(result)));
  PortalDetectorCallback(result);
}

TEST_F(DevicePortalDetectionTest, PortalDetectionSuccess) {
  EXPECT_CALL(*service_, IsConnected()).WillOnce(Return(true));
  EXPECT_CALL(*service_, SetPortalDetectionFailure(_, _)).Times(0);
  EXPECT_CALL(*service_, SetState(Service::kStateOnline));
  EXPECT_CALL(metrics_,
              SendEnumToUMA("Network.Shill.Unknown.PortalResult",
                            Metrics::kPortalResultSuccess,
                            Metrics::kPortalResultMax));
  EXPECT_CALL(metrics_,
              SendToUMA("Network.Shill.Unknown.PortalAttemptsToOnline",
                        kPortalAttempts,
                        Metrics::kMetricPortalAttemptsToOnlineMin,
                        Metrics::kMetricPortalAttemptsToOnlineMax,
                        Metrics::kMetricPortalAttemptsToOnlineNumBuckets));
  EXPECT_CALL(metrics_,
              SendToUMA("Network.Shill.Unknown.PortalAttempts",
                        _, _, _, _)).Times(0);
  PortalDetectorCallback(PortalDetector::Result(
      PortalDetector::Phase::kContent, PortalDetector::Status::kSuccess,
      kPortalAttempts));
}

TEST_F(DevicePortalDetectionTest, PortalDetectionSuccessAfterFailure) {
  EXPECT_CALL(*service_, IsConnected()).WillRepeatedly(Return(true));
  EXPECT_CALL(*service_,
              SetPortalDetectionFailure(kPortalDetectionPhaseConnection,
                                        kPortalDetectionStatusFailure));
  EXPECT_CALL(*service_, SetState(Service::kStatePortal));
  EXPECT_CALL(metrics_,
              SendEnumToUMA("Network.Shill.Unknown.PortalResult",
                            Metrics::kPortalResultConnectionFailure,
                            Metrics::kPortalResultMax));
  EXPECT_CALL(metrics_,
              SendToUMA("Network.Shill.Unknown.PortalAttemptsToOnline",
                        _, _, _, _)).Times(0);
  EXPECT_CALL(*connection_, IsDefault()).WillOnce(Return(false));
  EXPECT_CALL(*connection_, IsIPv6()).WillOnce(Return(false));
  PortalDetectorCallback(PortalDetector::Result(
      PortalDetector::Phase::kConnection, PortalDetector::Status::kFailure,
      kPortalAttempts));
  Mock::VerifyAndClearExpectations(&metrics_);
  EXPECT_CALL(*service_, SetPortalDetectionFailure(_, _)).Times(0);
  EXPECT_CALL(*service_, SetState(Service::kStateOnline));
  EXPECT_CALL(metrics_,
              SendEnumToUMA("Network.Shill.Unknown.PortalResult",
                            Metrics::kPortalResultSuccess,
                            Metrics::kPortalResultMax));
  EXPECT_CALL(metrics_,
              SendToUMA("Network.Shill.Unknown.PortalAttemptsToOnline",
                        kPortalAttempts * 2,
                        Metrics::kMetricPortalAttemptsToOnlineMin,
                        Metrics::kMetricPortalAttemptsToOnlineMax,
                        Metrics::kMetricPortalAttemptsToOnlineNumBuckets));
  PortalDetectorCallback(PortalDetector::Result(
      PortalDetector::Phase::kContent, PortalDetector::Status::kSuccess,
      kPortalAttempts * 2));
}

TEST_F(DevicePortalDetectionTest, RequestPortalDetection) {
  EXPECT_CALL(*service_, state())
      .WillOnce(Return(Service::kStateOnline))
      .WillRepeatedly(Return(Service::kStatePortal));
  EXPECT_FALSE(RequestPortalDetection());

  EXPECT_CALL(*connection_, IsDefault())
      .WillOnce(Return(false))
      .WillRepeatedly(Return(true));
  EXPECT_FALSE(RequestPortalDetection());

  EXPECT_CALL(*portal_detector_, IsInProgress())
      .WillOnce(Return(true));
  // Portal detection already running.
  EXPECT_TRUE(RequestPortalDetection());

  // Make sure our running mock portal detector was not replaced.
  ExpectPortalDetectorIsMock();

  // Throw away our pre-fabricated portal detector, and have the device create
  // a new one.
  StopPortalDetection();
  EXPECT_CALL(*service_, IsPortalDetectionDisabled())
      .WillRepeatedly(Return(false));
  EXPECT_CALL(*service_, IsPortalDetectionAuto()).WillRepeatedly(Return(true));
  EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(*service_, HasProxyConfig()).WillRepeatedly(Return(false));
  const string kPortalCheckHttpUrl("http://portal");
  const string kPortalCheckHttpsUrl("https://portal");
  const vector<string> kPortalCheckFallbackHttpUrls(
      {"http://fallback", "http://other"});
  EXPECT_CALL(manager_, GetPortalCheckHttpUrl())
      .WillOnce(ReturnRef(kPortalCheckHttpUrl));
  EXPECT_CALL(manager_, GetPortalCheckHttpsUrl())
      .WillOnce(ReturnRef(kPortalCheckHttpsUrl));
  EXPECT_CALL(manager_, GetPortalCheckFallbackHttpUrls())
      .WillRepeatedly(ReturnRef(kPortalCheckFallbackHttpUrls));
  const string kInterfaceName("int0");
  EXPECT_CALL(*connection_, IsIPv6()).WillRepeatedly(Return(false));
  EXPECT_CALL(*connection_, interface_name())
      .WillRepeatedly(ReturnRef(kInterfaceName));
  const vector<string> kDNSServers;
  EXPECT_CALL(*connection_, dns_servers())
      .WillRepeatedly(ReturnRef(kDNSServers));
  EXPECT_TRUE(RequestPortalDetection());
}

TEST_F(DevicePortalDetectionTest, RequestStartConnectivityTest) {
  const string kInterfaceName("int0");
  EXPECT_CALL(*connection_, interface_name())
      .WillRepeatedly(ReturnRef(kInterfaceName));
  EXPECT_CALL(*connection_, IsIPv6()).WillRepeatedly(Return(false));
  const vector<string> kDNSServers;
  EXPECT_CALL(*connection_, dns_servers())
      .WillRepeatedly(ReturnRef(kDNSServers));

  EXPECT_EQ(nullptr, device_->connection_tester_);
  EXPECT_TRUE(device_->StartConnectivityTest());
  EXPECT_NE(nullptr, device_->connection_tester_);
}

TEST_F(DevicePortalDetectionTest, NotConnected) {
  EXPECT_CALL(*service_, IsConnected()).WillOnce(Return(false));
  SetServiceConnectedState(Service::kStatePortal);
  // We don't check for the portal detector to be reset here, because
  // it would have been reset as a part of disconnection.
}

TEST_F(DevicePortalDetectionTest, NotPortal) {
  EXPECT_CALL(*service_, IsConnected()).WillOnce(Return(true));
  EXPECT_CALL(*service_, SetState(Service::kStateOnline));
  SetServiceConnectedState(Service::kStateOnline);
  ExpectPortalDetectorReset();
}

TEST_F(DevicePortalDetectionTest, NotDefault) {
  EXPECT_CALL(*service_, IsConnected()).WillOnce(Return(true));
  EXPECT_CALL(*connection_, IsDefault()).WillOnce(Return(false));
  EXPECT_CALL(*service_, SetState(Service::kStatePortal));
  SetServiceConnectedState(Service::kStatePortal);
  ExpectPortalDetectorReset();
}

TEST_F(DevicePortalDetectionTest, PortalIntervalIsZero) {
  EXPECT_CALL(*service_, IsConnected()).WillOnce(Return(true));
  EXPECT_CALL(*connection_, IsDefault()).WillOnce(Return(true));
  device_->portal_check_interval_seconds_ = 0;
  EXPECT_CALL(*service_, SetState(Service::kStatePortal));
  SetServiceConnectedState(Service::kStatePortal);
  ExpectPortalDetectorReset();
}

TEST_F(DevicePortalDetectionTest, RestartPortalDetection) {
  int portal_check_interval = 3;
  device_->portal_check_interval_seconds_ = portal_check_interval;
  const string kPortalCheckHttpUrl("http://portal");
  const string kPortalCheckHttpsUrl("https://portal");
  const vector<string> kPortalCheckFallbackHttpUrls(
      {"http://fallback", "http://other"});
  PortalDetector::Properties props = PortalDetector::Properties(
      kPortalCheckHttpUrl, kPortalCheckHttpsUrl, kPortalCheckFallbackHttpUrls);
  for (int i = 0; i < 10; i++) {
    EXPECT_CALL(*service_, IsConnected()).WillOnce(Return(true));
    EXPECT_CALL(*connection_, IsDefault()).WillOnce(Return(true));
    EXPECT_CALL(manager_, GetPortalCheckHttpUrl())
        .WillOnce(ReturnRef(kPortalCheckHttpUrl));
    EXPECT_CALL(manager_, GetPortalCheckHttpsUrl())
        .WillOnce(ReturnRef(kPortalCheckHttpsUrl));
    EXPECT_CALL(manager_, GetPortalCheckFallbackHttpUrls())
        .WillRepeatedly(ReturnRef(kPortalCheckFallbackHttpUrls));
    EXPECT_CALL(*portal_detector_, AdjustStartDelay(portal_check_interval))
        .WillOnce(Return(portal_check_interval));
    EXPECT_CALL(*portal_detector_,
                StartAfterDelay(props, portal_check_interval))
        .WillOnce(Return(true));
    EXPECT_CALL(*service_, SetState(Service::kStatePortal));
    SetServiceConnectedState(Service::kStatePortal);
    portal_check_interval =
        std::min(portal_check_interval * 2,
                 PortalDetector::kMaxPortalCheckIntervalSeconds);
  }
  ExpectPortalDetectorSet();
}

TEST_F(DevicePortalDetectionTest, CancelledOnSelectService) {
  ExpectPortalDetectorSet();
  EXPECT_CALL(*service_, state()).WillOnce(Return(Service::kStateIdle));
  EXPECT_CALL(*service_, SetState(_));
  EXPECT_CALL(*service_, SetConnection(_));
  SelectService(nullptr);
  ExpectPortalDetectorReset();
}

TEST_F(DevicePortalDetectionTest, PortalDetectionDNSFailure) {
  static const char* const kGoogleDNSServers[] = {"8.8.8.8", "8.8.4.4"};
  vector<string> fallback_dns_servers(kGoogleDNSServers, kGoogleDNSServers + 2);
  const string kInterfaceName("int0");
  EXPECT_CALL(*connection_, interface_name())
      .WillRepeatedly(ReturnRef(kInterfaceName));

  // DNS Failure, start DNS test for fallback DNS servers.
  PortalDetector::Result result_dns_failure(PortalDetector::Phase::kDNS,
                                            PortalDetector::Status::kFailure,
                                            kPortalAttempts);
  EXPECT_CALL(*service_, IsConnected()).WillOnce(Return(true));
  EXPECT_CALL(*service_,
              SetPortalDetectionFailure(kPortalDetectionPhaseDns,
                                        kPortalDetectionStatusFailure));
  EXPECT_CALL(*service_, SetState(Service::kStatePortal));
  EXPECT_CALL(*connection_, IsDefault()).WillOnce(Return(false));
  EXPECT_CALL(*connection_, IsIPv6()).WillOnce(Return(false));
  EXPECT_CALL(*device_, StartConnectionDiagnosticsAfterPortalDetection(
                            IsPortalDetectorResult(result_dns_failure)));
  EXPECT_CALL(*device_, StartDNSTest(fallback_dns_servers, false, _)).Times(1);
  PortalDetectorCallback(result_dns_failure);
  Mock::VerifyAndClearExpectations(device_.get());

  // DNS Timeout, start DNS test for fallback DNS servers.
  PortalDetector::Result result_dns_timeout(PortalDetector::Phase::kDNS,
                                            PortalDetector::Status::kTimeout,
                                            kPortalAttempts);
  EXPECT_CALL(*service_, IsConnected()).WillOnce(Return(true));
  EXPECT_CALL(*service_,
              SetPortalDetectionFailure(kPortalDetectionPhaseDns,
                                        kPortalDetectionStatusTimeout));
  EXPECT_CALL(*service_, SetState(Service::kStatePortal));
  EXPECT_CALL(*connection_, IsDefault()).WillOnce(Return(false));
  EXPECT_CALL(*connection_, IsIPv6()).WillOnce(Return(false));
  EXPECT_CALL(*device_, StartConnectionDiagnosticsAfterPortalDetection(
                            IsPortalDetectorResult(result_dns_timeout)));
  EXPECT_CALL(*device_, StartDNSTest(fallback_dns_servers, false, _)).Times(1);
  PortalDetectorCallback(result_dns_timeout);
  Mock::VerifyAndClearExpectations(device_.get());

  // Other Failure, DNS server tester not started.
  PortalDetector::Result result_connection_failure(
      PortalDetector::Phase::kConnection, PortalDetector::Status::kFailure,
      kPortalAttempts);
  EXPECT_CALL(*service_, IsConnected()).WillOnce(Return(true));
  EXPECT_CALL(*service_,
              SetPortalDetectionFailure(kPortalDetectionPhaseConnection,
                                        kPortalDetectionStatusFailure));
  EXPECT_CALL(*service_, SetState(Service::kStatePortal));
  EXPECT_CALL(*connection_, IsDefault()).WillOnce(Return(false));
  EXPECT_CALL(*connection_, IsIPv6()).WillOnce(Return(false));
  EXPECT_CALL(*device_, StartConnectionDiagnosticsAfterPortalDetection(
                            IsPortalDetectorResult(result_connection_failure)));
  EXPECT_CALL(*device_, StartDNSTest(_, _, _)).Times(0);
  PortalDetectorCallback(result_connection_failure);
  Mock::VerifyAndClearExpectations(device_.get());
}

TEST_F(DevicePortalDetectionTest, FallbackDNSResultCallback) {
  scoped_refptr<MockIPConfig> ipconfig =
      new MockIPConfig(control_interface(), kDeviceName);
  device_->set_ipconfig(ipconfig);

  // Fallback DNS test failed.
  EXPECT_CALL(*connection_, UpdateDNSServers(_)).Times(0);
  EXPECT_CALL(*ipconfig, UpdateDNSServers(_)).Times(0);
  EXPECT_CALL(*device_, StartDNSTest(_, _, _)).Times(0);
  EXPECT_CALL(metrics_,
      NotifyFallbackDNSTestResult(_, Metrics::kFallbackDNSTestResultFailure))
          .Times(1);
  InvokeFallbackDNSResultCallback(DnsServerTester::kStatusFailure);
  Mock::VerifyAndClearExpectations(connection_.get());
  Mock::VerifyAndClearExpectations(ipconfig.get());
  Mock::VerifyAndClearExpectations(&metrics_);

  // Fallback DNS test succeed with auto fallback disabled.
  EXPECT_CALL(*service_, is_dns_auto_fallback_allowed())
      .WillOnce(Return(false));
  EXPECT_CALL(*connection_, UpdateDNSServers(_)).Times(0);
  EXPECT_CALL(*ipconfig, UpdateDNSServers(_)).Times(0);
  EXPECT_CALL(*service_, NotifyIPConfigChanges()).Times(0);
  EXPECT_CALL(*device_, StartDNSTest(_, _, _)).Times(0);
  EXPECT_CALL(metrics_,
      NotifyFallbackDNSTestResult(_, Metrics::kFallbackDNSTestResultSuccess))
          .Times(1);
  InvokeFallbackDNSResultCallback(DnsServerTester::kStatusSuccess);
  Mock::VerifyAndClearExpectations(service_.get());
  Mock::VerifyAndClearExpectations(connection_.get());
  Mock::VerifyAndClearExpectations(ipconfig.get());
  Mock::VerifyAndClearExpectations(&metrics_);

  // Fallback DNS test succeed with auto fallback enabled.
  EXPECT_CALL(*service_, is_dns_auto_fallback_allowed()).WillOnce(Return(true));
  EXPECT_CALL(*service_, IsPortalDetectionDisabled())
      .WillRepeatedly(Return(false));
  EXPECT_CALL(*service_, IsPortalDetectionAuto()).WillRepeatedly(Return(true));
  EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(*service_, HasProxyConfig()).WillRepeatedly(Return(false));
  const string kPortalCheckHttpUrl("http://portal");
  const string kPortalCheckHttpsUrl("https://portal");
  const vector<string> kPortalCheckFallbackHttpUrls(
      {"http://fallback", "http://other"});
  EXPECT_CALL(manager_, GetPortalCheckHttpUrl())
      .WillOnce(ReturnRef(kPortalCheckHttpUrl));
  EXPECT_CALL(manager_, GetPortalCheckHttpsUrl())
      .WillOnce(ReturnRef(kPortalCheckHttpsUrl));
  EXPECT_CALL(manager_, GetPortalCheckFallbackHttpUrls())
      .WillRepeatedly(ReturnRef(kPortalCheckFallbackHttpUrls));
  const string kInterfaceName("int0");
  EXPECT_CALL(*connection_, IsIPv6()).WillRepeatedly(Return(false));
  EXPECT_CALL(*connection_, interface_name())
      .WillRepeatedly(ReturnRef(kInterfaceName));
  const vector<string> kDNSServers;
  EXPECT_CALL(*connection_, dns_servers())
      .WillRepeatedly(ReturnRef(kDNSServers));

  EXPECT_CALL(*ipconfig, UpdateDNSServers(_)).Times(1);
  EXPECT_CALL(*connection_, UpdateDNSServers(_)).Times(1);
  EXPECT_CALL(*service_, NotifyIPConfigChanges()).Times(1);
  EXPECT_CALL(*device_, StartDNSTest(_, true, _)).Times(1);
  EXPECT_CALL(metrics_,
      NotifyFallbackDNSTestResult(_, Metrics::kFallbackDNSTestResultSuccess))
          .Times(1);
  InvokeFallbackDNSResultCallback(DnsServerTester::kStatusSuccess);
  Mock::VerifyAndClearExpectations(service_.get());
  Mock::VerifyAndClearExpectations(connection_.get());
  Mock::VerifyAndClearExpectations(ipconfig.get());
  Mock::VerifyAndClearExpectations(&metrics_);
}

TEST_F(DevicePortalDetectionTest, ConfigDNSResultCallback) {
  scoped_refptr<MockIPConfig> ipconfig =
      new MockIPConfig(control_interface(), kDeviceName);
  device_->set_ipconfig(ipconfig);

  // DNS test failed for configured DNS servers.
  EXPECT_CALL(*connection_, UpdateDNSServers(_)).Times(0);
  EXPECT_CALL(*ipconfig, UpdateDNSServers(_)).Times(0);
  InvokeConfigDNSResultCallback(DnsServerTester::kStatusFailure);
  Mock::VerifyAndClearExpectations(connection_.get());
  Mock::VerifyAndClearExpectations(ipconfig.get());

  // DNS test succeed for configured DNS servers.
  EXPECT_CALL(*service_, IsPortalDetectionDisabled())
      .WillRepeatedly(Return(false));
  EXPECT_CALL(*service_, IsPortalDetectionAuto()).WillRepeatedly(Return(true));
  EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(*service_, HasProxyConfig()).WillRepeatedly(Return(false));
  const string kPortalCheckHttpUrl("http://portal");
  const string kPortalCheckHttpsUrl("https://portal");
  const vector<string> kPortalCheckFallbackHttpUrls(
      {"http://fallback", "http://other"});
  EXPECT_CALL(manager_, GetPortalCheckHttpUrl())
      .WillOnce(ReturnRef(kPortalCheckHttpUrl));
  EXPECT_CALL(manager_, GetPortalCheckHttpsUrl())
      .WillOnce(ReturnRef(kPortalCheckHttpsUrl));
  EXPECT_CALL(manager_, GetPortalCheckFallbackHttpUrls())
      .WillRepeatedly(ReturnRef(kPortalCheckFallbackHttpUrls));
  const string kInterfaceName("int0");
  EXPECT_CALL(*connection_, IsIPv6()).WillRepeatedly(Return(false));
  EXPECT_CALL(*connection_, interface_name())
      .WillRepeatedly(ReturnRef(kInterfaceName));
  const vector<string> kDNSServers;
  EXPECT_CALL(*connection_, dns_servers())
      .WillRepeatedly(ReturnRef(kDNSServers));
  EXPECT_CALL(*connection_, UpdateDNSServers(_)).Times(1);
  EXPECT_CALL(*ipconfig, UpdateDNSServers(_)).Times(1);
  EXPECT_CALL(*service_, NotifyIPConfigChanges()).Times(1);
  InvokeConfigDNSResultCallback(DnsServerTester::kStatusSuccess);
  Mock::VerifyAndClearExpectations(service_.get());
  Mock::VerifyAndClearExpectations(connection_.get());
  Mock::VerifyAndClearExpectations(ipconfig.get());
}

TEST_F(DevicePortalDetectionTest, DestroyConnection) {
  scoped_refptr<MockConnection> connection =
      new NiceMock<MockConnection>(&device_info_);
  // This test holds a single reference to the mock connection.
  EXPECT_TRUE(connection->HasOneRef());

  SetConnection(connection);

  EXPECT_CALL(*service_, IsPortalDetectionDisabled()).WillOnce(Return(false));
  EXPECT_CALL(*service_, IsConnected()).WillRepeatedly(Return(true));
  EXPECT_CALL(*service_, HasProxyConfig()).WillOnce(Return(false));
  EXPECT_CALL(*service_, IsPortalDetectionAuto()).WillOnce(Return(true));
  EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
      .WillOnce(Return(true));
  const string http_portal_url(PortalDetector::kDefaultHttpUrl);
  const string https_portal_url(PortalDetector::kDefaultHttpsUrl);
  const vector<string> fallback_urls(PortalDetector::kDefaultFallbackHttpUrls);
  EXPECT_CALL(manager_, GetPortalCheckHttpUrl())
      .WillRepeatedly(ReturnRef(http_portal_url));
  EXPECT_CALL(manager_, GetPortalCheckHttpsUrl())
      .WillRepeatedly(ReturnRef(https_portal_url));
  EXPECT_CALL(manager_, GetPortalCheckFallbackHttpUrls())
      .WillRepeatedly(ReturnRef(fallback_urls));
  const string kInterfaceName("int0");
  EXPECT_CALL(*connection, interface_name())
      .WillRepeatedly(ReturnRef(kInterfaceName));
  EXPECT_CALL(*connection, IsIPv6()).WillRepeatedly(Return(false));
  const vector<string> kDNSServers;
  EXPECT_CALL(*connection, dns_servers())
      .WillRepeatedly(ReturnRef(kDNSServers));

  EXPECT_TRUE(device_->StartConnectivityTest());
  EXPECT_TRUE(StartPortalDetection());

  // Ensure that the DestroyConnection method removes all connection references
  // except the one left in this scope.
  EXPECT_CALL(*service_, SetConnection(IsNullRefPtr()));
  DestroyConnection();
  EXPECT_TRUE(connection->HasOneRef());
}

class DeviceByteCountTest : public DeviceTest {
 public:
  DeviceByteCountTest()
      : manager_(control_interface(),
                 dispatcher(),
                 metrics()),
        rx_byte_count_(0),
        tx_byte_count_(0),
        rx_stored_byte_count_(0),
        tx_stored_byte_count_(0) {}
  virtual ~DeviceByteCountTest() {}

  void SetUp() override {
    DeviceTest::SetUp();
    EXPECT_CALL(manager_, device_info()).WillRepeatedly(Return(&device_info_));
    EXPECT_CALL(device_info_, GetByteCounts(kDeviceInterfaceIndex, _, _))
        .WillRepeatedly(Invoke(this, &DeviceByteCountTest::ReturnByteCounts));
    const string id = device_->GetStorageIdentifier();
    EXPECT_CALL(storage_, ContainsGroup(id)).WillRepeatedly(Return(true));
    EXPECT_CALL(storage_, GetUint64(id, Device::kStorageReceiveByteCount, _))
        .WillRepeatedly(
            Invoke(this, &DeviceByteCountTest::GetStoredReceiveCount));
    EXPECT_CALL(storage_, GetUint64(id, Device::kStorageTransmitByteCount, _))
        .WillRepeatedly(
            Invoke(this, &DeviceByteCountTest::GetStoredTransmitCount));
  }

  bool ReturnByteCounts(int interface_index, uint64_t* rx, uint64_t* tx) {
    *rx = rx_byte_count_;
    *tx = tx_byte_count_;
    return true;
  }

  bool ExpectByteCounts(DeviceRefPtr device,
                        int64_t expected_rx, int64_t expected_tx) {
    int64_t actual_rx = device->GetReceiveByteCount();
    int64_t actual_tx = device->GetTransmitByteCount();
    EXPECT_EQ(expected_rx, actual_rx);
    EXPECT_EQ(expected_tx, actual_tx);
    return expected_rx == actual_rx && expected_tx == actual_tx;
  }

  void ExpectSavedCounts(DeviceRefPtr device,
                         int64_t expected_rx, int64_t expected_tx) {
    EXPECT_CALL(storage_,
        SetUint64(_, Device::kStorageReceiveByteCount, expected_rx))
        .WillOnce(Return(true));
    EXPECT_CALL(storage_,
        SetUint64(_, Device::kStorageTransmitByteCount, expected_tx))
        .WillOnce(Return(true));
    EXPECT_TRUE(device->Save(&storage_));
  }


  bool GetStoredReceiveCount(const string& group, const string& key,
                             uint64_t* value) {
    if (!rx_stored_byte_count_) {
      return false;
    }
    *value = rx_stored_byte_count_;
    return true;
  }

  bool GetStoredTransmitCount(const string& group, const string& key,
                              uint64_t* value) {
    if (!tx_stored_byte_count_) {
      return false;
    }
    *value = tx_stored_byte_count_;
    return true;
  }

 protected:
  NiceMock<MockManager> manager_;
  NiceMock<MockStore> storage_;
  uint64_t rx_byte_count_;
  uint64_t tx_byte_count_;
  uint64_t rx_stored_byte_count_;
  uint64_t tx_stored_byte_count_;
};


TEST_F(DeviceByteCountTest, GetByteCounts) {
  // On Device initialization, byte counts should be zero, independent of
  // the byte counts reported by the interface.
  rx_byte_count_ = 123;
  tx_byte_count_ = 456;
  DeviceRefPtr device(new TestDevice(control_interface(),
                                     dispatcher(),
                                     nullptr,
                                     &manager_,
                                     kDeviceName,
                                     kDeviceAddress,
                                     kDeviceInterfaceIndex,
                                     Technology::kUnknown));
  EXPECT_TRUE(ExpectByteCounts(device, 0, 0));

  // Device should report any increase in the byte counts reported in the
  // interface.
  const int64_t delta_rx_count = 789;
  const int64_t delta_tx_count = 12;
  rx_byte_count_ += delta_rx_count;
  tx_byte_count_ += delta_tx_count;
  EXPECT_TRUE(ExpectByteCounts(device, delta_rx_count, delta_tx_count));

  // Expect the correct values to be saved to the profile.
  ExpectSavedCounts(device, delta_rx_count, delta_tx_count);

  // If Device is loaded from a profile that does not contain stored byte
  // counts, the byte counts reported should remain unchanged.
  EXPECT_TRUE(device->Load(&storage_));
  EXPECT_TRUE(ExpectByteCounts(device, delta_rx_count, delta_tx_count));

  // If Device is loaded from a profile that contains stored byte
  // counts, the byte counts reported should now reflect the stored values.
  rx_stored_byte_count_ = 345;
  tx_stored_byte_count_ = 678;
  EXPECT_TRUE(device->Load(&storage_));
  EXPECT_TRUE(ExpectByteCounts(
      device, rx_stored_byte_count_, tx_stored_byte_count_));

  // Increases to the interface receive count should be reflected as offsets
  // to the stored byte counts.
  rx_byte_count_ += delta_rx_count;
  tx_byte_count_ += delta_tx_count;
  EXPECT_TRUE(ExpectByteCounts(device,
                               rx_stored_byte_count_ + delta_rx_count,
                               tx_stored_byte_count_ + delta_tx_count));

  // Expect the correct values to be saved to the profile.
  ExpectSavedCounts(device,
                    rx_stored_byte_count_ + delta_rx_count,
                    tx_stored_byte_count_ + delta_tx_count);

  // Expect that after resetting byte counts, read-back values return to zero,
  // and that the device requests this information to be persisted.
  EXPECT_CALL(manager_, UpdateDevice(device));
  device->ResetByteCounters();
  EXPECT_TRUE(ExpectByteCounts(device, 0, 0));
}

}  // namespace shill
