blob: ebe9ba2c926cc1f88ca510402fcfb66fa77074c1 [file] [log] [blame]
// Copyright 2019 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 "arc/network/shill_client.h"
#include <memory>
#include <set>
#include <string>
#include <vector>
#include <base/memory/ref_counted.h>
#include <chromeos/dbus/service_constants.h>
#include <dbus/mock_bus.h>
#include <dbus/mock_object_proxy.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
using testing::_;
using testing::AnyNumber;
using testing::Return;
namespace arc_networkd {
class FakeShillClient : public ShillClient {
public:
explicit FakeShillClient(scoped_refptr<dbus::Bus> bus) : ShillClient(bus) {}
bool GetDefaultInterface(std::string* ifname) override {
*ifname = default_ifname_;
return true;
}
void SetNewDefaultInterface(const std::string& ifname) {
default_ifname_ = ifname;
}
void SetCurrentDefaultInterface(const std::string& ifname) {
default_interface_ = ifname;
}
void NotifyManagerPropertyChange(const std::string& name,
const brillo::Any& value) {
OnManagerPropertyChange(name, value);
}
private:
std::string default_ifname_;
};
class ShillClientTest : public testing::Test {
protected:
void SetUp() override {
mock_proxy_ = new dbus::MockObjectProxy(
mock_bus_.get(), "org.chromium.flimflam", dbus::ObjectPath("/path"));
// Set these expectations rather than just ignoring them to confirm
// the ShillClient obtains the expected proxy and registers for
// property changes.
EXPECT_CALL(*mock_bus_, GetObjectProxy("org.chromium.flimflam", _))
.WillRepeatedly(Return(mock_proxy_.get()));
EXPECT_CALL(*mock_proxy_, ConnectToSignal("org.chromium.flimflam.Manager",
"PropertyChanged", _, _))
.Times(AnyNumber());
client_ = std::make_unique<FakeShillClient>(mock_bus_);
client_->RegisterDefaultInterfaceChangedHandler(
base::Bind(&ShillClientTest::DefaultInterfaceChangedHandler,
base::Unretained(this)));
client_->RegisterDevicesChangedHandler(base::Bind(
&ShillClientTest::DevicesChangedHandler, base::Unretained(this)));
default_ifname_.clear();
devices_.clear();
}
void DefaultInterfaceChangedHandler(const std::string& name) {
default_ifname_ = name;
}
void DevicesChangedHandler(const std::set<std::string>& devices) {
devices_ = devices;
}
protected:
std::string default_ifname_;
std::set<std::string> devices_;
std::unique_ptr<FakeShillClient> client_;
private:
scoped_refptr<dbus::MockBus> mock_bus_{
new dbus::MockBus{dbus::Bus::Options{}}};
scoped_refptr<dbus::MockObjectProxy> mock_proxy_;
};
TEST_F(ShillClientTest, DevicesChangedHandlerCalledOnDevicesPropertyChange) {
std::vector<dbus::ObjectPath> devices = {dbus::ObjectPath("eth0"),
dbus::ObjectPath("wlan0")};
auto value = brillo::Any(devices);
client_->NotifyManagerPropertyChange(shill::kDevicesProperty, value);
EXPECT_EQ(devices.size(), devices_.size());
for (const auto d : devices) {
EXPECT_NE(devices_.find(d.value()), devices_.end());
}
}
TEST_F(ShillClientTest, VerifyDevicesPrefixStripped) {
std::vector<dbus::ObjectPath> devices = {dbus::ObjectPath("/device/eth0")};
auto value = brillo::Any(devices);
client_->NotifyManagerPropertyChange(shill::kDevicesProperty, value);
EXPECT_EQ(devices_.size(), 1);
EXPECT_EQ(*devices_.begin(), "eth0");
}
TEST_F(ShillClientTest,
DefaultInterfaceChangedHandlerCalledOnNewDefaultInterface) {
client_->SetCurrentDefaultInterface("");
client_->SetNewDefaultInterface("eth0");
client_->NotifyManagerPropertyChange(shill::kDefaultServiceProperty,
brillo::Any() /* ignored */);
EXPECT_EQ(default_ifname_, "eth0");
}
TEST_F(ShillClientTest, DefaultInterfaceChangedHandlerNotCalledForSameDefault) {
client_->SetCurrentDefaultInterface("eth0");
client_->SetNewDefaultInterface("eth0");
client_->NotifyManagerPropertyChange(shill::kDefaultServiceProperty,
brillo::Any() /* ignored */);
// Implies the callback was not run.
EXPECT_TRUE(default_ifname_.empty());
}
} // namespace arc_networkd