blob: 35ee6750978df9b0f4b1aa9bf67cb826130063a9 [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();
Garrick Evansf2e11f02018-12-25 15:25:39 +090026 client_->RegisterDefaultInterfaceChangedHandler(
27 base::Bind(&ShillClientTest::DefaultInterfaceChangedHandler,
28 base::Unretained(this)));
29 client_->RegisterDevicesChangedHandler(base::Bind(
30 &ShillClientTest::DevicesChangedHandler, base::Unretained(this)));
Jie Jiang850a4712020-04-08 21:06:36 +090031 client_->RegisterIPConfigsChangedHandler(base::Bind(
32 &ShillClientTest::IPConfigsChangedHandler, base::Unretained(this)));
Garrick Evansf2e11f02018-12-25 15:25:39 +090033 default_ifname_.clear();
Garrick Evans139708f2020-02-06 14:38:59 +090034 added_.clear();
35 removed_.clear();
Garrick Evansf2e11f02018-12-25 15:25:39 +090036 }
37
Garrick Evans1b1f67c2020-02-04 16:21:25 +090038 void DefaultInterfaceChangedHandler(const std::string& new_ifname,
39 const std::string& prev_ifname) {
40 default_ifname_ = new_ifname;
Garrick Evansf2e11f02018-12-25 15:25:39 +090041 }
42
Garrick Evans139708f2020-02-06 14:38:59 +090043 void DevicesChangedHandler(const std::set<std::string>& added,
44 const std::set<std::string>& removed) {
45 added_ = added;
46 removed_ = removed;
Garrick Evansf2e11f02018-12-25 15:25:39 +090047 }
48
Jie Jiang850a4712020-04-08 21:06:36 +090049 void IPConfigsChangedHandler(const std::string& device,
50 const ShillClient::IPConfig& ipconfig) {
51 ipconfig_change_calls_.emplace_back(std::make_pair(device, ipconfig));
52 }
53
Garrick Evansf2e11f02018-12-25 15:25:39 +090054 protected:
55 std::string default_ifname_;
Garrick Evans139708f2020-02-06 14:38:59 +090056 std::set<std::string> added_;
57 std::set<std::string> removed_;
Jie Jiang850a4712020-04-08 21:06:36 +090058 std::vector<std::pair<std::string, ShillClient::IPConfig>>
59 ipconfig_change_calls_;
Garrick Evansf2e11f02018-12-25 15:25:39 +090060 std::unique_ptr<FakeShillClient> client_;
Garrick Evansef6b20d2019-05-31 13:29:24 +090061 std::unique_ptr<FakeShillClientHelper> helper_;
Garrick Evansf2e11f02018-12-25 15:25:39 +090062};
63
64TEST_F(ShillClientTest, DevicesChangedHandlerCalledOnDevicesPropertyChange) {
65 std::vector<dbus::ObjectPath> devices = {dbus::ObjectPath("eth0"),
66 dbus::ObjectPath("wlan0")};
67 auto value = brillo::Any(devices);
68 client_->NotifyManagerPropertyChange(shill::kDevicesProperty, value);
Garrick Evans139708f2020-02-06 14:38:59 +090069 EXPECT_EQ(added_.size(), devices.size());
70 EXPECT_EQ(removed_.size(), 0);
Manoj Guptab0044522020-03-07 08:44:20 -080071 for (const auto& d : devices) {
Garrick Evans139708f2020-02-06 14:38:59 +090072 EXPECT_NE(added_.find(d.value()), added_.end());
Garrick Evansf2e11f02018-12-25 15:25:39 +090073 }
Hugo Benichiddee2812019-05-10 16:03:43 +090074 // Implies the default callback was run;
75 EXPECT_NE(default_ifname_, "");
Garrick Evans139708f2020-02-06 14:38:59 +090076 EXPECT_NE(added_.find(default_ifname_), added_.end());
77
78 devices.pop_back();
79 devices.emplace_back(dbus::ObjectPath("eth1"));
80 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);
91 client_->NotifyManagerPropertyChange(shill::kDevicesProperty, value);
Garrick Evans139708f2020-02-06 14:38:59 +090092 EXPECT_EQ(added_.size(), 1);
93 EXPECT_EQ(*added_.begin(), "eth0");
Hugo Benichiddee2812019-05-10 16:03:43 +090094 // Implies the default callback was run;
95 EXPECT_EQ(default_ifname_, "eth0");
Garrick Evansf2e11f02018-12-25 15:25:39 +090096}
97
98TEST_F(ShillClientTest,
99 DefaultInterfaceChangedHandlerCalledOnNewDefaultInterface) {
Hugo Benichiddee2812019-05-10 16:03:43 +0900100 client_->SetFakeDefaultInterface("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
105 client_->SetFakeDefaultInterface("wlan0");
106 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
111TEST_F(ShillClientTest, DefaultInterfaceChangedHandlerNotCalledForSameDefault) {
Hugo Benichiddee2812019-05-10 16:03:43 +0900112 client_->SetFakeDefaultInterface("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
124TEST_F(ShillClientTest, DefaultInterfaceFallbackUsingDevices) {
125 // One network device appears.
126 std::vector<dbus::ObjectPath> devices = {dbus::ObjectPath("wlan0")};
127 auto value = brillo::Any(devices);
128 client_->NotifyManagerPropertyChange(shill::kDevicesProperty, value);
129 // That device is used as the fallback default interface.
130 EXPECT_EQ(default_ifname_, "wlan0");
131
132 // A second device appears.
133 default_ifname_.clear();
134 devices = {dbus::ObjectPath("eth0"), dbus::ObjectPath("wlan0")};
135 value = brillo::Any(devices);
136 client_->NotifyManagerPropertyChange(shill::kDevicesProperty, value);
137 // The first device is still used as the fallback, the callback is not run.
138 EXPECT_EQ(default_ifname_, "");
139
140 // The second device becomes the default interface.
141 client_->SetFakeDefaultInterface("eth0");
142 client_->NotifyManagerPropertyChange(shill::kDefaultServiceProperty,
Garrick Evansd4742832019-05-20 11:51:40 +0900143 brillo::Any() /* ignored */);
Hugo Benichiddee2812019-05-10 16:03:43 +0900144 // The real default interface is preferred over the fallback interface.
145 EXPECT_EQ(default_ifname_, "eth0");
146
147 // The system loses the default interface.
148 client_->SetFakeDefaultInterface("");
149 client_->NotifyManagerPropertyChange(shill::kDefaultServiceProperty,
Garrick Evansd4742832019-05-20 11:51:40 +0900150 brillo::Any() /* ignored */);
Hugo Benichiddee2812019-05-10 16:03:43 +0900151 // The fallback interface is used instead.
152 EXPECT_EQ(default_ifname_, "wlan0");
153
154 // The first device disappears.
155 devices = {dbus::ObjectPath("eth0")};
156 value = brillo::Any(devices);
157 client_->NotifyManagerPropertyChange(shill::kDevicesProperty, value);
158 // The fallback interface is updated.
159 EXPECT_EQ(default_ifname_, "eth0");
160
161 // All devices have disappeared.
162 devices = {};
163 value = brillo::Any(devices);
164 client_->NotifyManagerPropertyChange(shill::kDevicesProperty, value);
165 // No device is used as the fallback default interface.
166 EXPECT_EQ(default_ifname_, "");
Garrick Evansf2e11f02018-12-25 15:25:39 +0900167}
168
Jie Jiang850a4712020-04-08 21:06:36 +0900169TEST_F(ShillClientTest, ListenToDeviceChangeSignalOnNewDevices) {
170 // Adds a device.
171 std::vector<dbus::ObjectPath> devices = {dbus::ObjectPath("/wlan0")};
172 auto value = brillo::Any(devices);
173 EXPECT_CALL(*helper_->mock_proxy(),
174 DoConnectToSignal(shill::kFlimflamDeviceInterface,
175 shill::kMonitorPropertyChanged, _, _))
176 .Times(1);
177 client_->NotifyManagerPropertyChange(shill::kDevicesProperty, value);
178
179 // Adds another device. DoConnectToSignal() called only for the new added one.
180 devices = {dbus::ObjectPath("/wlan0"), dbus::ObjectPath("/eth0")};
181 value = brillo::Any(devices);
182 EXPECT_CALL(*helper_->mock_proxy(),
183 DoConnectToSignal(shill::kFlimflamDeviceInterface,
184 shill::kMonitorPropertyChanged, _, _))
185 .Times(1);
186 client_->NotifyManagerPropertyChange(shill::kDevicesProperty, value);
187}
188
189TEST_F(ShillClientTest, TriggerOnIPConfigsChangeHandlerOnce) {
190 // Adds a device.
191 std::vector<dbus::ObjectPath> devices = {dbus::ObjectPath("/wlan0")};
192 auto devices_value = brillo::Any(devices);
193 client_->NotifyManagerPropertyChange(shill::kDevicesProperty, devices_value);
194 client_->NotifyDevicePropertyChange("wlan0", shill::kIPConfigsProperty,
195 brillo::Any());
196 ASSERT_EQ(ipconfig_change_calls_.size(), 1u);
197 EXPECT_EQ(ipconfig_change_calls_.back().first, "wlan0");
198
199 // Removes the device and adds it again.
200 client_->NotifyManagerPropertyChange(shill::kDevicesProperty, brillo::Any());
201 client_->NotifyManagerPropertyChange(shill::kDevicesProperty, devices_value);
202 client_->NotifyDevicePropertyChange("wlan0", shill::kIPConfigsProperty,
203 brillo::Any());
204 ASSERT_EQ(ipconfig_change_calls_.size(), 2u);
205 EXPECT_EQ(ipconfig_change_calls_.back().first, "wlan0");
206}
207
Garrick Evans3388a032020-03-24 11:25:55 +0900208} // namespace patchpanel