blob: 2820d29dcba3f6623919e8d79e4a22c7504a281b [file] [log] [blame]
Garrick Evansf2e11f02018-12-25 15:25:39 +09001// Copyright 2019 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Garrick Evans3388a032020-03-24 11:25:55 +09005#include "patchpanel/shill_client.h"
Garrick Evansf2e11f02018-12-25 15:25:39 +09006
7#include <memory>
8#include <set>
9#include <string>
Jie Jiang850a4712020-04-08 21:06:36 +090010#include <utility>
Garrick Evansf2e11f02018-12-25 15:25:39 +090011#include <vector>
12
Garrick Evansf2e11f02018-12-25 15:25:39 +090013#include <chromeos/dbus/service_constants.h>
Garrick Evansf2e11f02018-12-25 15:25:39 +090014#include <gmock/gmock.h>
15#include <gtest/gtest.h>
16
Garrick Evans3388a032020-03-24 11:25:55 +090017#include "patchpanel/fake_shill_client.h"
Garrick Evansf2e11f02018-12-25 15:25:39 +090018
Garrick Evans3388a032020-03-24 11:25:55 +090019namespace patchpanel {
Garrick Evansf2e11f02018-12-25 15:25:39 +090020
Garrick Evansf2e11f02018-12-25 15:25:39 +090021class ShillClientTest : public testing::Test {
22 protected:
23 void SetUp() override {
Garrick Evansef6b20d2019-05-31 13:29:24 +090024 helper_ = std::make_unique<FakeShillClientHelper>();
25 client_ = helper_->FakeClient();
Hugo Benichi78148a02020-10-30 18:37:00 +090026 client_->RegisterDefaultDeviceChangedHandler(base::Bind(
27 &ShillClientTest::DefaultDeviceChangedHandler, base::Unretained(this)));
Garrick Evansf2e11f02018-12-25 15:25:39 +090028 client_->RegisterDevicesChangedHandler(base::Bind(
29 &ShillClientTest::DevicesChangedHandler, base::Unretained(this)));
Jie Jiang850a4712020-04-08 21:06:36 +090030 client_->RegisterIPConfigsChangedHandler(base::Bind(
31 &ShillClientTest::IPConfigsChangedHandler, base::Unretained(this)));
Garrick Evansf2e11f02018-12-25 15:25:39 +090032 default_ifname_.clear();
Garrick Evans139708f2020-02-06 14:38:59 +090033 added_.clear();
34 removed_.clear();
Garrick Evansf2e11f02018-12-25 15:25:39 +090035 }
36
Hugo Benichi78148a02020-10-30 18:37:00 +090037 void DefaultDeviceChangedHandler(const ShillClient::Device& new_device,
38 const ShillClient::Device& prev_device) {
39 default_ifname_ = new_device.ifname;
Garrick Evansf2e11f02018-12-25 15:25:39 +090040 }
41
Garrick Evans139708f2020-02-06 14:38:59 +090042 void DevicesChangedHandler(const std::set<std::string>& added,
43 const std::set<std::string>& removed) {
44 added_ = added;
45 removed_ = removed;
Garrick Evansf2e11f02018-12-25 15:25:39 +090046 }
47
Jie Jiang850a4712020-04-08 21:06:36 +090048 void IPConfigsChangedHandler(const std::string& device,
49 const ShillClient::IPConfig& ipconfig) {
50 ipconfig_change_calls_.emplace_back(std::make_pair(device, ipconfig));
51 }
52
Garrick Evansf2e11f02018-12-25 15:25:39 +090053 protected:
54 std::string default_ifname_;
Garrick Evans139708f2020-02-06 14:38:59 +090055 std::set<std::string> added_;
56 std::set<std::string> removed_;
Jie Jiang850a4712020-04-08 21:06:36 +090057 std::vector<std::pair<std::string, ShillClient::IPConfig>>
58 ipconfig_change_calls_;
Garrick Evansf2e11f02018-12-25 15:25:39 +090059 std::unique_ptr<FakeShillClient> client_;
Garrick Evansef6b20d2019-05-31 13:29:24 +090060 std::unique_ptr<FakeShillClientHelper> helper_;
Garrick Evansf2e11f02018-12-25 15:25:39 +090061};
62
63TEST_F(ShillClientTest, DevicesChangedHandlerCalledOnDevicesPropertyChange) {
Hugo Benichi78148a02020-10-30 18:37:00 +090064 std::vector<dbus::ObjectPath> devices = {dbus::ObjectPath("/device/eth0"),
65 dbus::ObjectPath("/device/wlan0")};
Garrick Evansf2e11f02018-12-25 15:25:39 +090066 auto value = brillo::Any(devices);
Hugo Benichi78148a02020-10-30 18:37:00 +090067 client_->SetFakeDefaultDevice("eth0");
Garrick Evansf2e11f02018-12-25 15:25:39 +090068 client_->NotifyManagerPropertyChange(shill::kDevicesProperty, value);
Garrick Evans139708f2020-02-06 14:38:59 +090069 EXPECT_EQ(added_.size(), devices.size());
Hugo Benichi78148a02020-10-30 18:37:00 +090070 EXPECT_NE(added_.find("eth0"), added_.end());
71 EXPECT_NE(added_.find("wlan0"), added_.end());
Garrick Evans139708f2020-02-06 14:38:59 +090072 EXPECT_EQ(removed_.size(), 0);
Hugo Benichi78148a02020-10-30 18:37:00 +090073
Hugo Benichiddee2812019-05-10 16:03:43 +090074 // Implies the default callback was run;
Hugo Benichi78148a02020-10-30 18:37:00 +090075 EXPECT_EQ(default_ifname_, "eth0");
Garrick Evans139708f2020-02-06 14:38:59 +090076 EXPECT_NE(added_.find(default_ifname_), added_.end());
77
78 devices.pop_back();
Hugo Benichi78148a02020-10-30 18:37:00 +090079 devices.emplace_back(dbus::ObjectPath("/device/eth1"));
Garrick Evans139708f2020-02-06 14:38:59 +090080 value = brillo::Any(devices);
81 client_->NotifyManagerPropertyChange(shill::kDevicesProperty, value);
82 EXPECT_EQ(added_.size(), 1);
83 EXPECT_EQ(*added_.begin(), "eth1");
84 EXPECT_EQ(removed_.size(), 1);
85 EXPECT_EQ(*removed_.begin(), "wlan0");
Garrick Evansf2e11f02018-12-25 15:25:39 +090086}
87
88TEST_F(ShillClientTest, VerifyDevicesPrefixStripped) {
89 std::vector<dbus::ObjectPath> devices = {dbus::ObjectPath("/device/eth0")};
90 auto value = brillo::Any(devices);
Hugo Benichi78148a02020-10-30 18:37:00 +090091 client_->SetFakeDefaultDevice("eth0");
Garrick Evansf2e11f02018-12-25 15:25:39 +090092 client_->NotifyManagerPropertyChange(shill::kDevicesProperty, value);
Garrick Evans139708f2020-02-06 14:38:59 +090093 EXPECT_EQ(added_.size(), 1);
94 EXPECT_EQ(*added_.begin(), "eth0");
Hugo Benichiddee2812019-05-10 16:03:43 +090095 // Implies the default callback was run;
96 EXPECT_EQ(default_ifname_, "eth0");
Garrick Evansf2e11f02018-12-25 15:25:39 +090097}
98
Hugo Benichi78148a02020-10-30 18:37:00 +090099TEST_F(ShillClientTest, DefaultDeviceChangedHandlerCalledOnNewDefaultDevice) {
100 client_->SetFakeDefaultDevice("eth0");
Garrick Evansf2e11f02018-12-25 15:25:39 +0900101 client_->NotifyManagerPropertyChange(shill::kDefaultServiceProperty,
Garrick Evansd4742832019-05-20 11:51:40 +0900102 brillo::Any() /* ignored */);
Garrick Evansf2e11f02018-12-25 15:25:39 +0900103 EXPECT_EQ(default_ifname_, "eth0");
Hugo Benichiddee2812019-05-10 16:03:43 +0900104
Hugo Benichi78148a02020-10-30 18:37:00 +0900105 client_->SetFakeDefaultDevice("wlan0");
Hugo Benichiddee2812019-05-10 16:03:43 +0900106 client_->NotifyManagerPropertyChange(shill::kDefaultServiceProperty,
Garrick Evansd4742832019-05-20 11:51:40 +0900107 brillo::Any() /* ignored */);
Hugo Benichiddee2812019-05-10 16:03:43 +0900108 EXPECT_EQ(default_ifname_, "wlan0");
Garrick Evansf2e11f02018-12-25 15:25:39 +0900109}
110
Hugo Benichi78148a02020-10-30 18:37:00 +0900111TEST_F(ShillClientTest, DefaultDeviceChangedHandlerNotCalledForSameDefault) {
112 client_->SetFakeDefaultDevice("eth0");
Garrick Evansf2e11f02018-12-25 15:25:39 +0900113 client_->NotifyManagerPropertyChange(shill::kDefaultServiceProperty,
Garrick Evansd4742832019-05-20 11:51:40 +0900114 brillo::Any() /* ignored */);
Hugo Benichiddee2812019-05-10 16:03:43 +0900115 EXPECT_EQ(default_ifname_, "eth0");
116
117 default_ifname_.clear();
118 client_->NotifyManagerPropertyChange(shill::kDefaultServiceProperty,
Garrick Evansd4742832019-05-20 11:51:40 +0900119 brillo::Any() /* ignored */);
Hugo Benichiddee2812019-05-10 16:03:43 +0900120 // Implies the callback was not run the second time.
121 EXPECT_EQ(default_ifname_, "");
122}
123
Hugo Benichi78148a02020-10-30 18:37:00 +0900124TEST_F(ShillClientTest, DefaultDeviceChanges) {
Hugo Benichiddee2812019-05-10 16:03:43 +0900125 // One network device appears.
Hugo Benichi78148a02020-10-30 18:37:00 +0900126 std::vector<dbus::ObjectPath> devices = {dbus::ObjectPath("/device/wlan0")};
Hugo Benichiddee2812019-05-10 16:03:43 +0900127 auto value = brillo::Any(devices);
Hugo Benichi78148a02020-10-30 18:37:00 +0900128 client_->SetFakeDefaultDevice("wlan0");
Hugo Benichiddee2812019-05-10 16:03:43 +0900129 client_->NotifyManagerPropertyChange(shill::kDevicesProperty, value);
Hugo Benichiddee2812019-05-10 16:03:43 +0900130 EXPECT_EQ(default_ifname_, "wlan0");
131
132 // A second device appears.
133 default_ifname_.clear();
Hugo Benichi78148a02020-10-30 18:37:00 +0900134 devices = {dbus::ObjectPath("/device/eth0"),
135 dbus::ObjectPath("/device/wlan0")};
Hugo Benichiddee2812019-05-10 16:03:43 +0900136 value = brillo::Any(devices);
137 client_->NotifyManagerPropertyChange(shill::kDevicesProperty, value);
Hugo Benichiddee2812019-05-10 16:03:43 +0900138 EXPECT_EQ(default_ifname_, "");
139
140 // The second device becomes the default interface.
Hugo Benichi78148a02020-10-30 18:37:00 +0900141 client_->SetFakeDefaultDevice("eth0");
Hugo Benichiddee2812019-05-10 16:03:43 +0900142 client_->NotifyManagerPropertyChange(shill::kDefaultServiceProperty,
Garrick Evansd4742832019-05-20 11:51:40 +0900143 brillo::Any() /* ignored */);
Hugo Benichiddee2812019-05-10 16:03:43 +0900144 EXPECT_EQ(default_ifname_, "eth0");
145
Hugo Benichiddee2812019-05-10 16:03:43 +0900146 // The first device disappears.
Hugo Benichi78148a02020-10-30 18:37:00 +0900147 devices = {dbus::ObjectPath("/device/eth0")};
Hugo Benichiddee2812019-05-10 16:03:43 +0900148 value = brillo::Any(devices);
149 client_->NotifyManagerPropertyChange(shill::kDevicesProperty, value);
Hugo Benichi78148a02020-10-30 18:37:00 +0900150 // The default device is still the same.
Hugo Benichiddee2812019-05-10 16:03:43 +0900151 EXPECT_EQ(default_ifname_, "eth0");
152
153 // All devices have disappeared.
154 devices = {};
155 value = brillo::Any(devices);
Hugo Benichi78148a02020-10-30 18:37:00 +0900156 client_->SetFakeDefaultDevice("");
Hugo Benichiddee2812019-05-10 16:03:43 +0900157 client_->NotifyManagerPropertyChange(shill::kDevicesProperty, value);
Hugo Benichiddee2812019-05-10 16:03:43 +0900158 EXPECT_EQ(default_ifname_, "");
Garrick Evansf2e11f02018-12-25 15:25:39 +0900159}
160
Jie Jiang850a4712020-04-08 21:06:36 +0900161TEST_F(ShillClientTest, ListenToDeviceChangeSignalOnNewDevices) {
162 // Adds a device.
Hugo Benichi78148a02020-10-30 18:37:00 +0900163 std::vector<dbus::ObjectPath> devices = {dbus::ObjectPath("/device/wlan0")};
Jie Jiang850a4712020-04-08 21:06:36 +0900164 auto value = brillo::Any(devices);
165 EXPECT_CALL(*helper_->mock_proxy(),
166 DoConnectToSignal(shill::kFlimflamDeviceInterface,
167 shill::kMonitorPropertyChanged, _, _))
168 .Times(1);
169 client_->NotifyManagerPropertyChange(shill::kDevicesProperty, value);
170
171 // Adds another device. DoConnectToSignal() called only for the new added one.
Hugo Benichi78148a02020-10-30 18:37:00 +0900172 devices = {dbus::ObjectPath("/device/wlan0"),
173 dbus::ObjectPath("/device/eth0")};
Jie Jiang850a4712020-04-08 21:06:36 +0900174 value = brillo::Any(devices);
175 EXPECT_CALL(*helper_->mock_proxy(),
176 DoConnectToSignal(shill::kFlimflamDeviceInterface,
177 shill::kMonitorPropertyChanged, _, _))
178 .Times(1);
179 client_->NotifyManagerPropertyChange(shill::kDevicesProperty, value);
180}
181
182TEST_F(ShillClientTest, TriggerOnIPConfigsChangeHandlerOnce) {
183 // Adds a device.
Hugo Benichi78148a02020-10-30 18:37:00 +0900184 std::vector<dbus::ObjectPath> devices = {dbus::ObjectPath("/device/wlan0")};
Jie Jiang850a4712020-04-08 21:06:36 +0900185 auto devices_value = brillo::Any(devices);
186 client_->NotifyManagerPropertyChange(shill::kDevicesProperty, devices_value);
187 client_->NotifyDevicePropertyChange("wlan0", shill::kIPConfigsProperty,
188 brillo::Any());
189 ASSERT_EQ(ipconfig_change_calls_.size(), 1u);
190 EXPECT_EQ(ipconfig_change_calls_.back().first, "wlan0");
191
192 // Removes the device and adds it again.
193 client_->NotifyManagerPropertyChange(shill::kDevicesProperty, brillo::Any());
194 client_->NotifyManagerPropertyChange(shill::kDevicesProperty, devices_value);
195 client_->NotifyDevicePropertyChange("wlan0", shill::kIPConfigsProperty,
196 brillo::Any());
197 ASSERT_EQ(ipconfig_change_calls_.size(), 2u);
198 EXPECT_EQ(ipconfig_change_calls_.back().first, "wlan0");
199}
200
Garrick Evans3388a032020-03-24 11:25:55 +0900201} // namespace patchpanel