// 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/ethernet/ethernet.h"

#include <netinet/ether.h>
#include <linux/if.h>  // NOLINT - Needs definitions from netinet/ether.h
#include <linux/sockios.h>

#include <memory>
#include <utility>
#include <vector>

#include <base/callback.h>
#include <base/files/file_path.h>
#include <base/memory/ref_counted.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "shill/dhcp/mock_dhcp_config.h"
#include "shill/dhcp/mock_dhcp_provider.h"
#include "shill/ethernet/mock_ethernet_provider.h"
#include "shill/ethernet/mock_ethernet_service.h"
#include "shill/mock_control.h"
#include "shill/mock_device_info.h"
#include "shill/mock_event_dispatcher.h"
#include "shill/mock_log.h"
#include "shill/mock_manager.h"
#include "shill/mock_metrics.h"
#include "shill/mock_profile.h"
#include "shill/mock_service.h"
#include "shill/net/mock_rtnl_handler.h"
#include "shill/net/mock_sockets.h"
#include "shill/testing.h"

#if !defined(DISABLE_WIRED_8021X)
#include "shill/ethernet/mock_ethernet_eap_provider.h"
#include "shill/mock_eap_credentials.h"
#include "shill/mock_eap_listener.h"
#include "shill/supplicant/mock_supplicant_interface_proxy.h"
#include "shill/supplicant/mock_supplicant_process_proxy.h"
#include "shill/supplicant/supplicant_manager.h"
#include "shill/supplicant/wpa_supplicant.h"
#endif  // DISABLE_WIRED_8021X

using std::pair;
using std::string;
using std::vector;
using testing::_;
using testing::AnyNumber;
using testing::ByMove;
using testing::DoAll;
using testing::EndsWith;
using testing::Eq;
using testing::InSequence;
using testing::Invoke;
using testing::Mock;
using testing::NiceMock;
using testing::Return;
using testing::SaveArg;
using testing::SetArgPointee;
using testing::StrictMock;
using testing::WithArg;

namespace shill {

class TestEthernet : public Ethernet {
 public:
  TestEthernet(Manager* manager,
               const string& link_name,
               const string& mac_address,
               int interface_index)
      : Ethernet(manager, link_name, mac_address, interface_index) {}

  ~TestEthernet() override = default;

  MOCK_METHOD(std::string,
              ReadMacAddressFromFile,
              (const base::FilePath& file_path),
              (override));
};

class EthernetTest : public testing::Test {
 public:
  EthernetTest()
      : manager_(&control_interface_, &dispatcher_, &metrics_),
        device_info_(&manager_),
        ethernet_(new TestEthernet(
            &manager_, kDeviceName, kDeviceAddress, kInterfaceIndex)),
        dhcp_config_(new MockDHCPConfig(&control_interface_, kDeviceName)),
#if !defined(DISABLE_WIRED_8021X)
        eap_listener_(new MockEapListener()),
        mock_eap_service_(new MockService(&manager_)),
        supplicant_interface_proxy_(
            new NiceMock<MockSupplicantInterfaceProxy>()),
        supplicant_process_proxy_(new NiceMock<MockSupplicantProcessProxy>()),
#endif  // DISABLE_WIRED_8021X
        mock_sockets_(new StrictMock<MockSockets>()),
        mock_service_(new MockEthernetService(
            &manager_, ethernet_->weak_ptr_factory_.GetWeakPtr())) {
  }
  ~EthernetTest() override {}

  void SetUp() override {
    ethernet_->rtnl_handler_ = &rtnl_handler_;
    ethernet_->sockets_.reset(mock_sockets_);  // Transfers ownership.

    ethernet_->set_dhcp_provider(&dhcp_provider_);
    ON_CALL(manager_, device_info()).WillByDefault(Return(&device_info_));
    EXPECT_CALL(manager_, UpdateEnabledTechnologies()).Times(AnyNumber());

#if !defined(DISABLE_WIRED_8021X)
    ethernet_->eap_listener_.reset(eap_listener_);  // Transfers ownership.
    EXPECT_CALL(manager_, ethernet_eap_provider())
        .WillRepeatedly(Return(&ethernet_eap_provider_));
    ethernet_eap_provider_.set_service(mock_eap_service_);
    // Transfers ownership.
    manager_.supplicant_manager()->set_proxy(supplicant_process_proxy_);
#endif  // DISABLE_WIRED_8021X

    EXPECT_CALL(manager_, ethernet_provider())
        .WillRepeatedly(Return(&ethernet_provider_));

    ON_CALL(*mock_service_, technology())
        .WillByDefault(Return(Technology::kEthernet));
  }

  void TearDown() override {
#if !defined(DISABLE_WIRED_8021X)
    ethernet_eap_provider_.set_service(nullptr);
    ethernet_->eap_listener_.reset();
#endif  // DISABLE_WIRED_8021X
    ethernet_->set_dhcp_provider(nullptr);
    ethernet_->sockets_.reset();
    Mock::VerifyAndClearExpectations(&manager_);
  }

  MOCK_METHOD(void, ErrorCallback, (const Error& error));

 protected:
  static const char kDeviceName[];
  static const char kDeviceAddress[];
  static const RpcIdentifier kInterfacePath;
  static const int kInterfaceIndex;

  bool GetLinkUp() { return ethernet_->link_up_; }
  void SetLinkUp(bool link_up) { ethernet_->link_up_ = link_up; }
  const ServiceRefPtr& GetSelectedService() {
    return ethernet_->selected_service();
  }
  ServiceRefPtr GetService() { return ethernet_->service_; }
  void SetService(const EthernetServiceRefPtr& service) {
    ethernet_->service_ = service;
  }
  const PropertyStore& GetStore() { return ethernet_->store(); }
  void StartEthernet() {
    EXPECT_CALL(ethernet_provider_, CreateService(_))
        .WillOnce(Return(mock_service_));
    EXPECT_CALL(ethernet_provider_, RegisterService(Eq(mock_service_)));
    EXPECT_CALL(rtnl_handler_,
                SetInterfaceFlags(kInterfaceIndex, IFF_UP, IFF_UP));
    ethernet_->Start(nullptr, EnabledStateChangedCallback());
  }
  void StopEthernet() {
    EXPECT_CALL(ethernet_provider_, DeregisterService(Eq(mock_service_)));
    ethernet_->Stop(nullptr, EnabledStateChangedCallback());
  }
  void SetUsbEthernetMacAddressSource(const std::string& source,
                                      Error* error,
                                      const ResultCallback& callback) {
    ethernet_->SetUsbEthernetMacAddressSource(source, error, callback);
  }
  std::string GetUsbEthernetMacAddressSource(Error* error) {
    return ethernet_->GetUsbEthernetMacAddressSource(error);
  }

  void SetMacAddress(const std::string& mac_address) {
    ethernet_->set_mac_address(mac_address);
  }

  void SetBusType(const std::string& bus_type) {
    ethernet_->bus_type_ = bus_type;
  }

#if !defined(DISABLE_WIRED_8021X)
  bool GetIsEapAuthenticated() { return ethernet_->is_eap_authenticated_; }
  void SetIsEapAuthenticated(bool is_eap_authenticated) {
    ethernet_->is_eap_authenticated_ = is_eap_authenticated;
  }
  bool GetIsEapDetected() { return ethernet_->is_eap_detected_; }
  void SetIsEapDetected(bool is_eap_detected) {
    ethernet_->is_eap_detected_ = is_eap_detected;
  }
  const SupplicantInterfaceProxyInterface* GetSupplicantInterfaceProxy() {
    return ethernet_->supplicant_interface_proxy_.get();
  }
  const RpcIdentifier& GetSupplicantInterfacePath() {
    return ethernet_->supplicant_interface_path_;
  }
  const RpcIdentifier& GetSupplicantNetworkPath() {
    return ethernet_->supplicant_network_path_;
  }
  void SetSupplicantNetworkPath(const RpcIdentifier& network_path) {
    ethernet_->supplicant_network_path_ = network_path;
  }
  bool InvokeStartSupplicant() { return ethernet_->StartSupplicant(); }
  void InvokeStopSupplicant() { return ethernet_->StopSupplicant(); }
  bool InvokeStartEapAuthentication() {
    return ethernet_->StartEapAuthentication();
  }
  void StartSupplicant() {
    MockSupplicantInterfaceProxy* interface_proxy =
        ExpectCreateSupplicantInterfaceProxy();
    EXPECT_CALL(*supplicant_process_proxy_, CreateInterface(_, _))
        .WillOnce(DoAll(SetArgPointee<1>(kInterfacePath), Return(true)));
    EXPECT_TRUE(InvokeStartSupplicant());
    EXPECT_EQ(interface_proxy, GetSupplicantInterfaceProxy());
    EXPECT_EQ(kInterfacePath, GetSupplicantInterfacePath());
  }
  void TriggerOnEapDetected() { ethernet_->OnEapDetected(); }
  void TriggerCertification(const string& subject, uint32_t depth) {
    ethernet_->CertificationTask(subject, depth);
  }
  void TriggerTryEapAuthentication() { ethernet_->TryEapAuthenticationTask(); }

  MockSupplicantInterfaceProxy* ExpectCreateSupplicantInterfaceProxy() {
    MockSupplicantInterfaceProxy* proxy = supplicant_interface_proxy_.get();
    EXPECT_CALL(control_interface_,
                CreateSupplicantInterfaceProxy(_, kInterfacePath))
        .WillOnce(Return(ByMove(std::move(supplicant_interface_proxy_))));
    return proxy;
  }
#endif  // DISABLE_WIRED_8021X

  StrictMock<MockEventDispatcher> dispatcher_;
  MockControl control_interface_;
  NiceMock<MockMetrics> metrics_;
  MockManager manager_;
  MockDeviceInfo device_info_;
  scoped_refptr<TestEthernet> ethernet_;
  MockDHCPProvider dhcp_provider_;
  scoped_refptr<MockDHCPConfig> dhcp_config_;

#if !defined(DISABLE_WIRED_8021X)
  MockEthernetEapProvider ethernet_eap_provider_;

  // Owned by Ethernet instance, but tracked here for expectations.
  MockEapListener* eap_listener_;

  scoped_refptr<MockService> mock_eap_service_;
  std::unique_ptr<MockSupplicantInterfaceProxy> supplicant_interface_proxy_;
  MockSupplicantProcessProxy* supplicant_process_proxy_;
#endif  // DISABLE_WIRED_8021X

  // Owned by Ethernet instance, but tracked here for expectations.
  MockSockets* mock_sockets_;

  MockRTNLHandler rtnl_handler_;
  scoped_refptr<MockEthernetService> mock_service_;
  MockEthernetProvider ethernet_provider_;
};

// static
const char EthernetTest::kDeviceName[] = "eth0";
const char EthernetTest::kDeviceAddress[] = "000102030405";
const RpcIdentifier EthernetTest::kInterfacePath("/interface/path");
const int EthernetTest::kInterfaceIndex = 123;

TEST_F(EthernetTest, Construct) {
  EXPECT_FALSE(GetLinkUp());
#if !defined(DISABLE_WIRED_8021X)
  EXPECT_FALSE(GetIsEapAuthenticated());
  EXPECT_FALSE(GetIsEapDetected());
  EXPECT_TRUE(GetStore().Contains(kEapAuthenticationCompletedProperty));
  EXPECT_TRUE(GetStore().Contains(kEapAuthenticatorDetectedProperty));
#endif  // DISABLE_WIRED_8021X
  EXPECT_EQ(nullptr, GetService());
}

TEST_F(EthernetTest, StartStop) {
  StartEthernet();
  Service* service = GetService().get();
  EXPECT_EQ(service, mock_service_);
  StopEthernet();
}

TEST_F(EthernetTest, LinkEvent) {
  StartEthernet();

  // Link-down event while already down.
  EXPECT_CALL(manager_, DeregisterService(_)).Times(0);
#if !defined(DISABLE_WIRED_8021X)
  EXPECT_CALL(*eap_listener_, Start()).Times(0);
#endif  // DISABLE_WIRED_8021X
  ethernet_->LinkEvent(0, IFF_LOWER_UP);
  EXPECT_FALSE(GetLinkUp());
#if !defined(DISABLE_WIRED_8021X)
  EXPECT_FALSE(GetIsEapDetected());
#endif  // DISABLE_WIRED_8021X
  Mock::VerifyAndClearExpectations(&manager_);

  // Link-up event while down.
  int kFakeFd = 789;
  EXPECT_CALL(manager_, UpdateService(IsRefPtrTo(mock_service_)));
  EXPECT_CALL(*mock_service_, OnVisibilityChanged());
#if !defined(DISABLE_WIRED_8021X)
  EXPECT_CALL(*eap_listener_, Start());
#endif  // DISABLE_WIRED_8021X
  EXPECT_CALL(*mock_sockets_, Socket(_, _, _)).WillOnce(Return(kFakeFd));
  EXPECT_CALL(*mock_sockets_, Ioctl(kFakeFd, SIOCETHTOOL, _));
  EXPECT_CALL(*mock_sockets_, Close(kFakeFd));
  ethernet_->LinkEvent(IFF_LOWER_UP, 0);
  EXPECT_TRUE(GetLinkUp());
#if !defined(DISABLE_WIRED_8021X)
  EXPECT_FALSE(GetIsEapDetected());
#endif  // DISABLE_WIRED_8021X
  Mock::VerifyAndClearExpectations(&manager_);
  Mock::VerifyAndClearExpectations(mock_service_.get());

  // Link-up event while already up.
  EXPECT_CALL(manager_, UpdateService(_)).Times(0);
  EXPECT_CALL(*mock_service_, OnVisibilityChanged()).Times(0);
#if !defined(DISABLE_WIRED_8021X)
  EXPECT_CALL(*eap_listener_, Start()).Times(0);
#endif  // DISABLE_WIRED_8021X
  ethernet_->LinkEvent(IFF_LOWER_UP, 0);
  EXPECT_TRUE(GetLinkUp());
#if !defined(DISABLE_WIRED_8021X)
  EXPECT_FALSE(GetIsEapDetected());
#endif  // DISABLE_WIRED_8021X
  Mock::VerifyAndClearExpectations(&manager_);
  Mock::VerifyAndClearExpectations(mock_service_.get());

  // Link-down event while up.
#if !defined(DISABLE_WIRED_8021X)
  SetIsEapDetected(true);
  // This is done in SetUp, but we have to reestablish this after calling
  // VerifyAndClearExpectations() above.
  EXPECT_CALL(manager_, ethernet_eap_provider())
      .WillRepeatedly(Return(&ethernet_eap_provider_));
  EXPECT_CALL(ethernet_eap_provider_,
              ClearCredentialChangeCallback(ethernet_.get()));
  EXPECT_CALL(*eap_listener_, Stop());
#endif  // DISABLE_WIRED_8021X
  EXPECT_CALL(manager_, UpdateService(IsRefPtrTo(GetService().get())));
  EXPECT_CALL(*mock_service_, OnVisibilityChanged());
  ethernet_->LinkEvent(0, IFF_LOWER_UP);
  EXPECT_FALSE(GetLinkUp());
#if !defined(DISABLE_WIRED_8021X)
  EXPECT_FALSE(GetIsEapDetected());
#endif  // DISABLE_WIRED_8021X

  // Restore this expectation during shutdown.
  EXPECT_CALL(manager_, UpdateEnabledTechnologies()).Times(AnyNumber());
  EXPECT_CALL(manager_, ethernet_provider())
      .WillRepeatedly(Return(&ethernet_provider_));

  StopEthernet();
}

TEST_F(EthernetTest, ConnectToLinkDown) {
  StartEthernet();
  SetLinkUp(false);
  EXPECT_EQ(nullptr, GetSelectedService());
  EXPECT_CALL(dhcp_provider_, CreateIPv4Config(_, _, _, _)).Times(0);
  EXPECT_CALL(*dhcp_config_, RequestIP()).Times(0);
  EXPECT_CALL(dispatcher_, PostDelayedTask(_, _, 0)).Times(0);
  EXPECT_CALL(*mock_service_, SetState(_)).Times(0);
  ethernet_->ConnectTo(mock_service_.get());
  EXPECT_EQ(nullptr, GetSelectedService());
  StopEthernet();
}

TEST_F(EthernetTest, ConnectToFailure) {
  StartEthernet();
  SetLinkUp(true);
  EXPECT_EQ(nullptr, GetSelectedService());
  EXPECT_CALL(dhcp_provider_, CreateIPv4Config(_, _, _, _))
      .WillOnce(Return(dhcp_config_));
  EXPECT_CALL(*dhcp_config_, RequestIP()).WillOnce(Return(false));
  EXPECT_CALL(dispatcher_,
              PostDelayedTask(_, _, 0));  // Posts ConfigureStaticIPTask.
  EXPECT_CALL(*mock_service_, SetState(Service::kStateFailure));
  ethernet_->ConnectTo(mock_service_.get());
  EXPECT_EQ(mock_service_, GetSelectedService());
  StopEthernet();
}

TEST_F(EthernetTest, ConnectToSuccess) {
  StartEthernet();
  SetLinkUp(true);
  EXPECT_EQ(nullptr, GetSelectedService());
  EXPECT_CALL(dhcp_provider_, CreateIPv4Config(_, _, _, _))
      .WillOnce(Return(dhcp_config_));
  EXPECT_CALL(*dhcp_config_, RequestIP()).WillOnce(Return(true));
  EXPECT_CALL(dispatcher_,
              PostDelayedTask(_, _, 0));  // Posts ConfigureStaticIPTask.
  EXPECT_CALL(*mock_service_, SetState(Service::kStateConfiguring));
  ethernet_->ConnectTo(mock_service_.get());
  EXPECT_EQ(GetService(), GetSelectedService());
  Mock::VerifyAndClearExpectations(mock_service_.get());

  EXPECT_CALL(*mock_service_, SetState(Service::kStateIdle));
  ethernet_->DisconnectFrom(mock_service_.get());
  EXPECT_EQ(nullptr, GetSelectedService());
  StopEthernet();
}

#if !defined(DISABLE_WIRED_8021X)
TEST_F(EthernetTest, OnEapDetected) {
  EXPECT_FALSE(GetIsEapDetected());
  EXPECT_CALL(*eap_listener_, Stop());
  EXPECT_CALL(ethernet_eap_provider_,
              SetCredentialChangeCallback(ethernet_.get(), _));
  EXPECT_CALL(dispatcher_,
              PostDelayedTask(_, _, 0));  // Posts TryEapAuthenticationTask.
  TriggerOnEapDetected();
  EXPECT_TRUE(GetIsEapDetected());
}

TEST_F(EthernetTest, TryEapAuthenticationNotConnectableNotAuthenticated) {
  SetService(mock_service_);
  EXPECT_CALL(*mock_eap_service_, Is8021xConnectable()).WillOnce(Return(false));
  NiceScopedMockLog log;
  EXPECT_CALL(log, Log(logging::LOGGING_INFO, _,
                       EndsWith("EAP Service lacks 802.1X credentials; "
                                "not doing EAP authentication.")));
  TriggerTryEapAuthentication();
  SetService(nullptr);
}

TEST_F(EthernetTest, TryEapAuthenticationNotConnectableAuthenticated) {
  SetService(mock_service_);
  SetIsEapAuthenticated(true);
  EXPECT_CALL(*mock_eap_service_, Is8021xConnectable()).WillOnce(Return(false));
  NiceScopedMockLog log;
  EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
  EXPECT_CALL(log, Log(logging::LOGGING_INFO, _,
                       EndsWith("EAP Service lost 802.1X credentials; "
                                "terminating EAP authentication.")));
  TriggerTryEapAuthentication();
  EXPECT_FALSE(GetIsEapAuthenticated());
}

TEST_F(EthernetTest, TryEapAuthenticationEapNotDetected) {
  SetService(mock_service_);
  EXPECT_CALL(*mock_eap_service_, Is8021xConnectable()).WillOnce(Return(true));
  NiceScopedMockLog log;
  EXPECT_CALL(log, Log(logging::LOGGING_WARNING, _,
                       EndsWith("EAP authenticator not detected; "
                                "not doing EAP authentication.")));
  TriggerTryEapAuthentication();
}

TEST_F(EthernetTest, StartSupplicant) {
  // Save the mock proxy pointers before the Ethernet instance accepts it.
  MockSupplicantInterfaceProxy* interface_proxy =
      supplicant_interface_proxy_.get();
  MockSupplicantProcessProxy* process_proxy = supplicant_process_proxy_;

  StartSupplicant();

  // Starting it again should not invoke another call to create an interface.
  Mock::VerifyAndClearExpectations(process_proxy);
  EXPECT_CALL(*process_proxy, CreateInterface(_, _)).Times(0);
  EXPECT_TRUE(InvokeStartSupplicant());

  // Also, the mock pointers should remain; if the MockProxyFactory was
  // invoked again, they would be nullptr.
  EXPECT_EQ(interface_proxy, GetSupplicantInterfaceProxy());
  EXPECT_EQ(kInterfacePath, GetSupplicantInterfacePath());
}

TEST_F(EthernetTest, StartSupplicantWithInterfaceExistsException) {
  MockSupplicantProcessProxy* process_proxy = supplicant_process_proxy_;
  MockSupplicantInterfaceProxy* interface_proxy =
      ExpectCreateSupplicantInterfaceProxy();
  EXPECT_CALL(*process_proxy, CreateInterface(_, _)).WillOnce(Return(false));
  EXPECT_CALL(*process_proxy, GetInterface(kDeviceName, _))
      .WillOnce(DoAll(SetArgPointee<1>(kInterfacePath), Return(true)));
  EXPECT_TRUE(InvokeStartSupplicant());
  EXPECT_EQ(interface_proxy, GetSupplicantInterfaceProxy());
  EXPECT_EQ(kInterfacePath, GetSupplicantInterfacePath());
}

TEST_F(EthernetTest, StartSupplicantWithUnknownException) {
  MockSupplicantProcessProxy* process_proxy = supplicant_process_proxy_;
  EXPECT_CALL(*process_proxy, CreateInterface(_, _)).WillOnce(Return(false));
  EXPECT_CALL(*process_proxy, GetInterface(kDeviceName, _))
      .WillOnce(Return(false));
  EXPECT_FALSE(InvokeStartSupplicant());
  EXPECT_EQ(nullptr, GetSupplicantInterfaceProxy());
  EXPECT_EQ(RpcIdentifier(""), GetSupplicantInterfacePath());
}

TEST_F(EthernetTest, StartEapAuthentication) {
  MockSupplicantInterfaceProxy* interface_proxy =
      supplicant_interface_proxy_.get();

  StartSupplicant();
  SetService(mock_service_);

  EXPECT_CALL(*mock_service_, ClearEAPCertification());
  MockEapCredentials mock_eap_credentials;
  EXPECT_CALL(*mock_eap_service_, eap())
      .WillOnce(Return(&mock_eap_credentials));
  EXPECT_CALL(mock_eap_credentials, PopulateSupplicantProperties(_, _));
  EXPECT_CALL(*interface_proxy, RemoveNetwork(_)).Times(0);
  EXPECT_CALL(*interface_proxy, AddNetwork(_, _)).WillOnce(Return(false));
  EXPECT_CALL(*interface_proxy, SelectNetwork(_)).Times(0);
  EXPECT_CALL(*interface_proxy, EAPLogon()).Times(0);
  EXPECT_FALSE(InvokeStartEapAuthentication());
  Mock::VerifyAndClearExpectations(mock_service_.get());
  Mock::VerifyAndClearExpectations(mock_eap_service_.get());
  Mock::VerifyAndClearExpectations(interface_proxy);
  EXPECT_EQ(RpcIdentifier(""), GetSupplicantNetworkPath());

  EXPECT_CALL(*mock_service_, ClearEAPCertification());
  EXPECT_CALL(*interface_proxy, RemoveNetwork(_)).Times(0);
  EXPECT_CALL(*mock_eap_service_, eap())
      .WillOnce(Return(&mock_eap_credentials));
  EXPECT_CALL(mock_eap_credentials, PopulateSupplicantProperties(_, _));
  const RpcIdentifier kFirstNetworkPath("/network/first-path");
  EXPECT_CALL(*interface_proxy, AddNetwork(_, _))
      .WillOnce(DoAll(SetArgPointee<1>(kFirstNetworkPath), Return(true)));
  EXPECT_CALL(*interface_proxy, SelectNetwork(Eq(kFirstNetworkPath)));
  EXPECT_CALL(*interface_proxy, EAPLogon());
  EXPECT_TRUE(InvokeStartEapAuthentication());
  Mock::VerifyAndClearExpectations(mock_service_.get());
  Mock::VerifyAndClearExpectations(mock_eap_service_.get());
  Mock::VerifyAndClearExpectations(&mock_eap_credentials);
  Mock::VerifyAndClearExpectations(interface_proxy);
  EXPECT_EQ(kFirstNetworkPath, GetSupplicantNetworkPath());

  EXPECT_CALL(*mock_service_, ClearEAPCertification());
  EXPECT_CALL(*interface_proxy, RemoveNetwork(Eq(kFirstNetworkPath)))
      .WillOnce(Return(true));
  EXPECT_CALL(*mock_eap_service_, eap())
      .WillOnce(Return(&mock_eap_credentials));
  EXPECT_CALL(mock_eap_credentials, PopulateSupplicantProperties(_, _));
  const RpcIdentifier kSecondNetworkPath("/network/second-path");
  EXPECT_CALL(*interface_proxy, AddNetwork(_, _))
      .WillOnce(DoAll(SetArgPointee<1>(kSecondNetworkPath), Return(true)));
  EXPECT_CALL(*interface_proxy, SelectNetwork(Eq(kSecondNetworkPath)));
  EXPECT_CALL(*interface_proxy, EAPLogon());
  EXPECT_TRUE(InvokeStartEapAuthentication());
  EXPECT_EQ(kSecondNetworkPath, GetSupplicantNetworkPath());
}

TEST_F(EthernetTest, StopSupplicant) {
  MockSupplicantProcessProxy* process_proxy = supplicant_process_proxy_;
  MockSupplicantInterfaceProxy* interface_proxy =
      supplicant_interface_proxy_.get();
  StartSupplicant();
  SetIsEapAuthenticated(true);
  SetSupplicantNetworkPath(RpcIdentifier("/network/1"));
  EXPECT_CALL(*interface_proxy, EAPLogoff()).WillOnce(Return(true));
  EXPECT_CALL(*process_proxy, RemoveInterface(Eq(kInterfacePath)))
      .WillOnce(Return(true));
  InvokeStopSupplicant();
  EXPECT_EQ(nullptr, GetSupplicantInterfaceProxy());
  EXPECT_EQ(RpcIdentifier(""), GetSupplicantInterfacePath());
  EXPECT_EQ(RpcIdentifier(""), GetSupplicantNetworkPath());
  EXPECT_FALSE(GetIsEapAuthenticated());
}

TEST_F(EthernetTest, Certification) {
  StartEthernet();
  const string kSubjectName("subject-name");
  const uint32_t kDepth = 123;
  // Should not crash due to no service_.
  TriggerCertification(kSubjectName, kDepth);
  EXPECT_CALL(*mock_service_, AddEAPCertification(kSubjectName, kDepth));
  SetService(mock_service_);
  TriggerCertification(kSubjectName, kDepth);
  StopEthernet();
}
#endif  // DISABLE_WIRED_8021X

#if !defined(DISABLE_PPPOE)

MATCHER_P(TechnologyEq, technology, "") {
  return arg->technology() == technology;
}

TEST_F(EthernetTest, TogglePPPoE) {
  SetService(mock_service_);

  EXPECT_CALL(*mock_service_, technology())
      .WillRepeatedly(Return(Technology::kEthernet));
  EXPECT_CALL(ethernet_provider_, CreateService(_))
      .WillRepeatedly(Return(mock_service_));
  EXPECT_CALL(*mock_service_, Disconnect(_, _));
  EXPECT_CALL(manager_, HasService(_)).WillRepeatedly(Return(true));

  InSequence sequence;
  EXPECT_CALL(ethernet_provider_, DeregisterService(Eq(mock_service_)));
  EXPECT_CALL(manager_, RegisterService(TechnologyEq(Technology::kPPPoE)));
  EXPECT_CALL(manager_, DeregisterService(TechnologyEq(Technology::kPPPoE)));
  EXPECT_CALL(ethernet_provider_, RegisterService(_));

  const vector<pair<bool, Technology>> transitions = {
      {false, Technology::kEthernet},
      {true, Technology::kPPPoE},
      {false, Technology::kEthernet},
  };
  for (const auto& transition : transitions) {
    Error error;
    ethernet_->mutable_store()->SetBoolProperty(kPPPoEProperty,
                                                transition.first, &error);
    EXPECT_TRUE(error.IsSuccess());
    EXPECT_EQ(GetService()->technology(), transition.second);
  }
}

#else

TEST_F(EthernetTest, PPPoEDisabled) {
  Error error;
  ethernet_->mutable_store()->SetBoolProperty(kPPPoEProperty, true, &error);
  EXPECT_FALSE(error.IsSuccess());
}

#endif  // DISABLE_PPPOE

TEST_F(EthernetTest, SetUsbEthernetMacAddressSourceInvalidArguments) {
  SetBusType(kDeviceBusTypeUsb);
  Error error(Error::kOperationInitiated);
  SetUsbEthernetMacAddressSource(
      "invalid_value", &error,
      base::Bind(&EthernetTest::ErrorCallback, base::Unretained(this)));
  EXPECT_EQ(error.type(), Error::kInvalidArguments);
}

TEST_F(EthernetTest, SetUsbEthernetMacAddressSourceNotSupportedForNonUsb) {
  SetBusType(kDeviceBusTypePci);
  Error error(Error::kOperationInitiated);
  EXPECT_CALL(*this, ErrorCallback(_)).Times(0);
  SetUsbEthernetMacAddressSource(
      kUsbEthernetMacAddressSourceUsbAdapterMac, &error,
      base::Bind(&EthernetTest::ErrorCallback, base::Unretained(this)));
  EXPECT_EQ(error.type(), Error::kNotSupported);
}

TEST_F(EthernetTest,
       SetUsbEthernetMacAddressSourceNotSupportedEmptyFileWithMac) {
  SetBusType(kDeviceBusTypeUsb);
  Error error(Error::kOperationInitiated);
  EXPECT_CALL(*this, ErrorCallback(_)).Times(0);
  SetUsbEthernetMacAddressSource(
      kUsbEthernetMacAddressSourceDesignatedDockMac, &error,
      base::Bind(&EthernetTest::ErrorCallback, base::Unretained(this)));
  EXPECT_EQ(error.type(), Error::kNotSupported);
}

MATCHER_P(ErrorEquals, expected_error_type, "") {
  return arg.type() == expected_error_type;
}

TEST_F(EthernetTest, SetUsbEthernetMacAddressSourceNetlinkError) {
  SetBusType(kDeviceBusTypeUsb);

  constexpr char kBuiltinAdapterMacAddress[] = "abcdef123456";
  EXPECT_CALL(*ethernet_.get(), ReadMacAddressFromFile(_))
      .WillOnce(Return(kBuiltinAdapterMacAddress));

  EXPECT_CALL(rtnl_handler_, SetInterfaceMac(ethernet_->interface_index(),
                                             ByteString::CreateFromHexString(
                                                 kBuiltinAdapterMacAddress),
                                             _))
      .WillOnce(WithArg<2>(
          Invoke([](base::OnceCallback<void(int32_t)> response_callback) {
            ASSERT_TRUE(!response_callback.is_null());
            std::move(response_callback).Run(1 /* error */);
          })));

  EXPECT_CALL(*this, ErrorCallback(ErrorEquals(Error::kNotSupported)));

  Error error(Error::kOperationInitiated);
  SetUsbEthernetMacAddressSource(
      kUsbEthernetMacAddressSourceBuiltinAdapterMac, &error,
      base::Bind(&EthernetTest::ErrorCallback, base::Unretained(this)));

  EXPECT_EQ(kDeviceAddress, ethernet_->mac_address());
}

TEST_F(EthernetTest, SetUsbEthernetMacAddressSource) {
  SetBusType(kDeviceBusTypeUsb);

  constexpr char kBuiltinAdapterMacAddress[] = "abcdef123456";
  EXPECT_CALL(*ethernet_.get(), ReadMacAddressFromFile(_))
      .WillOnce(Return(kBuiltinAdapterMacAddress));
  EXPECT_CALL(rtnl_handler_, SetInterfaceMac(ethernet_->interface_index(),
                                             ByteString::CreateFromHexString(
                                                 kBuiltinAdapterMacAddress),
                                             _))
      .WillOnce(WithArg<2>(
          Invoke([](base::OnceCallback<void(int32_t)> response_callback) {
            ASSERT_FALSE(response_callback.is_null());
            std::move(response_callback).Run(0 /* error */);
          })));

  EXPECT_CALL(*this, ErrorCallback(ErrorEquals(Error::kSuccess)));

  Error error(Error::kOperationInitiated);
  SetUsbEthernetMacAddressSource(
      kUsbEthernetMacAddressSourceBuiltinAdapterMac, &error,
      base::Bind(&EthernetTest::ErrorCallback, base::Unretained(this)));

  EXPECT_EQ(kBuiltinAdapterMacAddress, ethernet_->mac_address());
  EXPECT_EQ(GetUsbEthernetMacAddressSource(nullptr),
            kUsbEthernetMacAddressSourceBuiltinAdapterMac);
}

TEST_F(EthernetTest, SetMacAddressNoServiceStorageIdentifierChange) {
  constexpr char kMacAddress[] = "123456abcdef";

  scoped_refptr<StrictMock<MockProfile>> mock_profile(
      new StrictMock<MockProfile>(&manager_));
  mock_service_->set_profile(mock_profile);
  mock_service_->SetStorageIdentifier("some_ethernet_identifier");
  EXPECT_CALL(*mock_profile.get(), AbandonService(_)).Times(0);
  EXPECT_CALL(*mock_profile.get(), AdoptService(_)).Times(0);

  SetMacAddress(kMacAddress);
  EXPECT_EQ(kMacAddress, ethernet_->mac_address());

  // Must set nullptr to avoid mock objects leakage.
  mock_service_->set_profile(nullptr);
}

TEST_F(EthernetTest, SetMacAddressServiceStorageIdentifierChange) {
  StartEthernet();
  constexpr char kMacAddress[] = "123456abcdef";

  scoped_refptr<StrictMock<MockProfile>> mock_profile(
      new StrictMock<MockProfile>(&manager_));
  mock_service_->set_profile(mock_profile);
  EXPECT_CALL(*mock_profile.get(), AbandonService(IsRefPtrTo(mock_service_)));
  EXPECT_CALL(*mock_profile.get(), AdoptService(IsRefPtrTo(mock_service_)));

  SetMacAddress(kMacAddress);
  EXPECT_EQ(kMacAddress, ethernet_->mac_address());

  // Must set nullptr to avoid mock objects leakage.
  mock_service_->set_profile(nullptr);
  StopEthernet();
}

}  // namespace shill
