blob: 0b033b6d3c1f80f19d0f07ddb4dee64051e3073d [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>
10#include <vector>
11
Garrick Evansf2e11f02018-12-25 15:25:39 +090012#include <chromeos/dbus/service_constants.h>
Garrick Evansf2e11f02018-12-25 15:25:39 +090013#include <gmock/gmock.h>
14#include <gtest/gtest.h>
15
Garrick Evans3388a032020-03-24 11:25:55 +090016#include "patchpanel/fake_shill_client.h"
Garrick Evansf2e11f02018-12-25 15:25:39 +090017
Garrick Evans3388a032020-03-24 11:25:55 +090018namespace patchpanel {
Garrick Evansf2e11f02018-12-25 15:25:39 +090019
Garrick Evansf2e11f02018-12-25 15:25:39 +090020class ShillClientTest : public testing::Test {
21 protected:
22 void SetUp() override {
Garrick Evansef6b20d2019-05-31 13:29:24 +090023 helper_ = std::make_unique<FakeShillClientHelper>();
24 client_ = helper_->FakeClient();
Garrick Evansf2e11f02018-12-25 15:25:39 +090025 client_->RegisterDefaultInterfaceChangedHandler(
26 base::Bind(&ShillClientTest::DefaultInterfaceChangedHandler,
27 base::Unretained(this)));
28 client_->RegisterDevicesChangedHandler(base::Bind(
29 &ShillClientTest::DevicesChangedHandler, base::Unretained(this)));
30 default_ifname_.clear();
Garrick Evans139708f2020-02-06 14:38:59 +090031 added_.clear();
32 removed_.clear();
Garrick Evansf2e11f02018-12-25 15:25:39 +090033 }
34
Garrick Evans1b1f67c2020-02-04 16:21:25 +090035 void DefaultInterfaceChangedHandler(const std::string& new_ifname,
36 const std::string& prev_ifname) {
37 default_ifname_ = new_ifname;
Garrick Evansf2e11f02018-12-25 15:25:39 +090038 }
39
Garrick Evans139708f2020-02-06 14:38:59 +090040 void DevicesChangedHandler(const std::set<std::string>& added,
41 const std::set<std::string>& removed) {
42 added_ = added;
43 removed_ = removed;
Garrick Evansf2e11f02018-12-25 15:25:39 +090044 }
45
46 protected:
47 std::string default_ifname_;
Garrick Evans139708f2020-02-06 14:38:59 +090048 std::set<std::string> added_;
49 std::set<std::string> removed_;
Garrick Evansf2e11f02018-12-25 15:25:39 +090050 std::unique_ptr<FakeShillClient> client_;
Garrick Evansef6b20d2019-05-31 13:29:24 +090051 std::unique_ptr<FakeShillClientHelper> helper_;
Garrick Evansf2e11f02018-12-25 15:25:39 +090052};
53
54TEST_F(ShillClientTest, DevicesChangedHandlerCalledOnDevicesPropertyChange) {
55 std::vector<dbus::ObjectPath> devices = {dbus::ObjectPath("eth0"),
56 dbus::ObjectPath("wlan0")};
57 auto value = brillo::Any(devices);
58 client_->NotifyManagerPropertyChange(shill::kDevicesProperty, value);
Garrick Evans139708f2020-02-06 14:38:59 +090059 EXPECT_EQ(added_.size(), devices.size());
60 EXPECT_EQ(removed_.size(), 0);
Manoj Guptab0044522020-03-07 08:44:20 -080061 for (const auto& d : devices) {
Garrick Evans139708f2020-02-06 14:38:59 +090062 EXPECT_NE(added_.find(d.value()), added_.end());
Garrick Evansf2e11f02018-12-25 15:25:39 +090063 }
Hugo Benichiddee2812019-05-10 16:03:43 +090064 // Implies the default callback was run;
65 EXPECT_NE(default_ifname_, "");
Garrick Evans139708f2020-02-06 14:38:59 +090066 EXPECT_NE(added_.find(default_ifname_), added_.end());
67
68 devices.pop_back();
69 devices.emplace_back(dbus::ObjectPath("eth1"));
70 value = brillo::Any(devices);
71 client_->NotifyManagerPropertyChange(shill::kDevicesProperty, value);
72 EXPECT_EQ(added_.size(), 1);
73 EXPECT_EQ(*added_.begin(), "eth1");
74 EXPECT_EQ(removed_.size(), 1);
75 EXPECT_EQ(*removed_.begin(), "wlan0");
Garrick Evansf2e11f02018-12-25 15:25:39 +090076}
77
78TEST_F(ShillClientTest, VerifyDevicesPrefixStripped) {
79 std::vector<dbus::ObjectPath> devices = {dbus::ObjectPath("/device/eth0")};
80 auto value = brillo::Any(devices);
81 client_->NotifyManagerPropertyChange(shill::kDevicesProperty, value);
Garrick Evans139708f2020-02-06 14:38:59 +090082 EXPECT_EQ(added_.size(), 1);
83 EXPECT_EQ(*added_.begin(), "eth0");
Hugo Benichiddee2812019-05-10 16:03:43 +090084 // Implies the default callback was run;
85 EXPECT_EQ(default_ifname_, "eth0");
Garrick Evansf2e11f02018-12-25 15:25:39 +090086}
87
88TEST_F(ShillClientTest,
89 DefaultInterfaceChangedHandlerCalledOnNewDefaultInterface) {
Hugo Benichiddee2812019-05-10 16:03:43 +090090 client_->SetFakeDefaultInterface("eth0");
Garrick Evansf2e11f02018-12-25 15:25:39 +090091 client_->NotifyManagerPropertyChange(shill::kDefaultServiceProperty,
Garrick Evansd4742832019-05-20 11:51:40 +090092 brillo::Any() /* ignored */);
Garrick Evansf2e11f02018-12-25 15:25:39 +090093 EXPECT_EQ(default_ifname_, "eth0");
Hugo Benichiddee2812019-05-10 16:03:43 +090094
95 client_->SetFakeDefaultInterface("wlan0");
96 client_->NotifyManagerPropertyChange(shill::kDefaultServiceProperty,
Garrick Evansd4742832019-05-20 11:51:40 +090097 brillo::Any() /* ignored */);
Hugo Benichiddee2812019-05-10 16:03:43 +090098 EXPECT_EQ(default_ifname_, "wlan0");
Garrick Evansf2e11f02018-12-25 15:25:39 +090099}
100
101TEST_F(ShillClientTest, DefaultInterfaceChangedHandlerNotCalledForSameDefault) {
Hugo Benichiddee2812019-05-10 16:03:43 +0900102 client_->SetFakeDefaultInterface("eth0");
Garrick Evansf2e11f02018-12-25 15:25:39 +0900103 client_->NotifyManagerPropertyChange(shill::kDefaultServiceProperty,
Garrick Evansd4742832019-05-20 11:51:40 +0900104 brillo::Any() /* ignored */);
Hugo Benichiddee2812019-05-10 16:03:43 +0900105 EXPECT_EQ(default_ifname_, "eth0");
106
107 default_ifname_.clear();
108 client_->NotifyManagerPropertyChange(shill::kDefaultServiceProperty,
Garrick Evansd4742832019-05-20 11:51:40 +0900109 brillo::Any() /* ignored */);
Hugo Benichiddee2812019-05-10 16:03:43 +0900110 // Implies the callback was not run the second time.
111 EXPECT_EQ(default_ifname_, "");
112}
113
114TEST_F(ShillClientTest, DefaultInterfaceFallbackUsingDevices) {
115 // One network device appears.
116 std::vector<dbus::ObjectPath> devices = {dbus::ObjectPath("wlan0")};
117 auto value = brillo::Any(devices);
118 client_->NotifyManagerPropertyChange(shill::kDevicesProperty, value);
119 // That device is used as the fallback default interface.
120 EXPECT_EQ(default_ifname_, "wlan0");
121
122 // A second device appears.
123 default_ifname_.clear();
124 devices = {dbus::ObjectPath("eth0"), dbus::ObjectPath("wlan0")};
125 value = brillo::Any(devices);
126 client_->NotifyManagerPropertyChange(shill::kDevicesProperty, value);
127 // The first device is still used as the fallback, the callback is not run.
128 EXPECT_EQ(default_ifname_, "");
129
130 // The second device becomes the default interface.
131 client_->SetFakeDefaultInterface("eth0");
132 client_->NotifyManagerPropertyChange(shill::kDefaultServiceProperty,
Garrick Evansd4742832019-05-20 11:51:40 +0900133 brillo::Any() /* ignored */);
Hugo Benichiddee2812019-05-10 16:03:43 +0900134 // The real default interface is preferred over the fallback interface.
135 EXPECT_EQ(default_ifname_, "eth0");
136
137 // The system loses the default interface.
138 client_->SetFakeDefaultInterface("");
139 client_->NotifyManagerPropertyChange(shill::kDefaultServiceProperty,
Garrick Evansd4742832019-05-20 11:51:40 +0900140 brillo::Any() /* ignored */);
Hugo Benichiddee2812019-05-10 16:03:43 +0900141 // The fallback interface is used instead.
142 EXPECT_EQ(default_ifname_, "wlan0");
143
144 // The first device disappears.
145 devices = {dbus::ObjectPath("eth0")};
146 value = brillo::Any(devices);
147 client_->NotifyManagerPropertyChange(shill::kDevicesProperty, value);
148 // The fallback interface is updated.
149 EXPECT_EQ(default_ifname_, "eth0");
150
151 // All devices have disappeared.
152 devices = {};
153 value = brillo::Any(devices);
154 client_->NotifyManagerPropertyChange(shill::kDevicesProperty, value);
155 // No device is used as the fallback default interface.
156 EXPECT_EQ(default_ifname_, "");
Garrick Evansf2e11f02018-12-25 15:25:39 +0900157}
158
Garrick Evans3388a032020-03-24 11:25:55 +0900159} // namespace patchpanel