blob: e2ceed768587acb823e21ac264c1edb110dfd608 [file] [log] [blame]
Garrick Evans54861622019-07-19 09:05:09 +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/arc_service.h"
Garrick Evans54861622019-07-19 09:05:09 +09006
Garrick Evanse94b6de2020-02-20 09:19:13 +09007#include <net/if.h>
8
Garrick Evans54861622019-07-19 09:05:09 +09009#include <utility>
10#include <vector>
11
12#include <base/bind.h>
hscham4ce3c992021-02-19 16:37:23 +090013#include <base/callback_helpers.h>
Hugo Benichi84d96c42021-02-26 14:20:13 +090014#include <dbus/mock_bus.h>
Garrick Evans54861622019-07-19 09:05:09 +090015#include <gmock/gmock.h>
16#include <gtest/gtest.h>
17
Garrick Evans3388a032020-03-24 11:25:55 +090018#include "patchpanel/address_manager.h"
19#include "patchpanel/fake_process_runner.h"
20#include "patchpanel/fake_shill_client.h"
21#include "patchpanel/mock_datapath.h"
Jason Jeremy Imana7273a32020-08-04 11:25:31 +090022#include "patchpanel/mock_firewall.h"
Garrick Evans3388a032020-03-24 11:25:55 +090023#include "patchpanel/net_util.h"
Garrick Evans54861622019-07-19 09:05:09 +090024
25using testing::_;
Garrick Evanse94b6de2020-02-20 09:19:13 +090026using testing::AnyNumber;
Garrick Evansc7071122020-04-17 12:31:57 +090027using testing::Eq;
Hugo Benichi84d96c42021-02-26 14:20:13 +090028using testing::Invoke;
Garrick Evans209a80a2020-11-30 14:42:40 +090029using testing::Pair;
Garrick Evansc7071122020-04-17 12:31:57 +090030using testing::Pointee;
Garrick Evans54861622019-07-19 09:05:09 +090031using testing::Return;
Garrick Evansb4eb3892019-11-13 12:07:07 +090032using testing::ReturnRef;
Garrick Evans54861622019-07-19 09:05:09 +090033using testing::StrEq;
Garrick Evans02e6e872020-11-30 11:53:13 +090034using testing::UnorderedElementsAre;
Garrick Evans54861622019-07-19 09:05:09 +090035
Garrick Evans3388a032020-03-24 11:25:55 +090036namespace patchpanel {
Garrick Evans54861622019-07-19 09:05:09 +090037namespace {
Garrick Evansb4eb3892019-11-13 12:07:07 +090038constexpr pid_t kTestPID = -2;
Garrick Evansb4eb3892019-11-13 12:07:07 +090039constexpr uint32_t kTestCID = 2;
Garrick Evans7a1a9ee2020-01-28 11:03:57 +090040constexpr uint32_t kArcHostIP = Ipv4Addr(100, 115, 92, 1);
41constexpr uint32_t kArcGuestIP = Ipv4Addr(100, 115, 92, 2);
Hugo Benichiad1bdd92020-06-12 13:48:37 +090042constexpr uint32_t kFirstEthHostIP = Ipv4Addr(100, 115, 92, 5);
43constexpr uint32_t kFirstEthGuestIP = Ipv4Addr(100, 115, 92, 6);
Garrick Evans86c7d9c2020-03-17 09:25:48 +090044constexpr uint32_t kSecondEthHostIP = Ipv4Addr(100, 115, 92, 9);
45constexpr uint32_t kFirstWifiHostIP = Ipv4Addr(100, 115, 92, 13);
46constexpr uint32_t kSecondWifiHostIP = Ipv4Addr(100, 115, 92, 17);
47constexpr uint32_t kFirstCellHostIP = Ipv4Addr(100, 115, 92, 21);
Garrick Evansc7071122020-04-17 12:31:57 +090048constexpr MacAddress kArcVmArc0MacAddr = {0x42, 0x37, 0x05, 0x13, 0x17, 0x01};
Garrick Evans54861622019-07-19 09:05:09 +090049
Hugo Benichi84d96c42021-02-26 14:20:13 +090050class MockShillClient : public ShillClient {
51 public:
52 explicit MockShillClient(scoped_refptr<dbus::MockBus> bus)
53 : ShillClient(bus) {}
54 ~MockShillClient() = default;
55
56 MOCK_METHOD2(GetDeviceProperties,
57 bool(const std::string& ifname, ShillClient::Device* device));
58};
59
60void ExpectGetDeviceProperties(MockShillClient& shill_client,
61 const std::string& iface,
62 ShillClient::Device::Type type) {
63 EXPECT_CALL(shill_client, GetDeviceProperties(StrEq(iface), _))
64 .WillRepeatedly(
65 Invoke([type](const std::string& _, ShillClient::Device* device) {
66 device->type = type;
67 return true;
68 }));
69}
70
Garrick Evans54861622019-07-19 09:05:09 +090071} // namespace
72
73class ArcServiceTest : public testing::Test {
74 public:
Garrick Evans4ee5ce22020-03-18 07:05:17 +090075 ArcServiceTest() : testing::Test() {}
Garrick Evans54861622019-07-19 09:05:09 +090076
77 protected:
78 void SetUp() override {
Taoyu Li179dcc62019-10-17 11:21:08 +090079 runner_ = std::make_unique<FakeProcessRunner>();
Garrick Evans54861622019-07-19 09:05:09 +090080 runner_->Capture(false);
Jason Jeremy Imana7273a32020-08-04 11:25:31 +090081 datapath_ = std::make_unique<MockDatapath>(runner_.get(), &firewall_);
Hugo Benichi84d96c42021-02-26 14:20:13 +090082 shill_client_ = std::make_unique<MockShillClient>(shill_helper_.mock_bus());
Garrick Evans4ee5ce22020-03-18 07:05:17 +090083 addr_mgr_ = std::make_unique<AddressManager>();
Garrick Evans209a80a2020-11-30 14:42:40 +090084 guest_devices_.clear();
Garrick Evans54861622019-07-19 09:05:09 +090085 }
86
Hugo Benichiad1bdd92020-06-12 13:48:37 +090087 std::unique_ptr<ArcService> NewService(GuestMessage::GuestType guest) {
Garrick Evans209a80a2020-11-30 14:42:40 +090088 return std::make_unique<ArcService>(
Hugo Benichib9d123e2021-02-27 23:37:16 +090089 shill_client_.get(), datapath_.get(), addr_mgr_.get(), guest,
Garrick Evans209a80a2020-11-30 14:42:40 +090090 base::BindRepeating(&ArcServiceTest::DeviceHandler,
91 base::Unretained(this)));
92 }
93
94 void DeviceHandler(const Device& device,
95 Device::ChangeEvent event,
96 GuestMessage::GuestType guest_type) {
97 guest_devices_[device.host_ifname()] = event;
Garrick Evans54861622019-07-19 09:05:09 +090098 }
99
Garrick Evans69b85872020-02-04 11:40:26 +0900100 FakeShillClientHelper shill_helper_;
Hugo Benichi84d96c42021-02-26 14:20:13 +0900101 std::unique_ptr<MockShillClient> shill_client_;
Garrick Evans4ee5ce22020-03-18 07:05:17 +0900102 std::unique_ptr<AddressManager> addr_mgr_;
Taoyu Li179dcc62019-10-17 11:21:08 +0900103 std::unique_ptr<MockDatapath> datapath_;
104 std::unique_ptr<FakeProcessRunner> runner_;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900105 MockFirewall firewall_;
Garrick Evans209a80a2020-11-30 14:42:40 +0900106 std::map<std::string, Device::ChangeEvent> guest_devices_;
Garrick Evans54861622019-07-19 09:05:09 +0900107};
108
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900109TEST_F(ArcServiceTest, NotStarted_AddDevice) {
Hugo Benichi84d96c42021-02-26 14:20:13 +0900110 ExpectGetDeviceProperties(*shill_client_, "eth0",
111 ShillClient::Device::Type::kEthernet);
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900112 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), _, _)).Times(0);
Hugo Benichi8d622b52020-08-13 15:24:12 +0900113 EXPECT_CALL(*datapath_,
Hugo Benichi93306e52020-12-04 16:08:00 +0900114 StartRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"), _, _, false))
Hugo Benichi8d622b52020-08-13 15:24:12 +0900115 .Times(0);
Garrick Evans54861622019-07-19 09:05:09 +0900116
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900117 auto svc = NewService(GuestMessage::ARC);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900118 svc->OnDevicesChanged({"eth0"}, {});
119 EXPECT_TRUE(svc->devices_.find("eth0") == svc->devices_.end());
120 EXPECT_FALSE(svc->shill_devices_.find("eth0") == svc->shill_devices_.end());
Garrick Evans54861622019-07-19 09:05:09 +0900121}
122
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900123TEST_F(ArcServiceTest, NotStarted_AddRemoveDevice) {
Hugo Benichi84d96c42021-02-26 14:20:13 +0900124 ExpectGetDeviceProperties(*shill_client_, "eth0",
125 ShillClient::Device::Type::kEthernet);
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900126 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), _, _)).Times(0);
Hugo Benichi8d622b52020-08-13 15:24:12 +0900127 EXPECT_CALL(*datapath_,
Hugo Benichi93306e52020-12-04 16:08:00 +0900128 StartRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"), _, _, false))
Hugo Benichi8d622b52020-08-13 15:24:12 +0900129 .Times(0);
130 EXPECT_CALL(*datapath_,
Hugo Benichi93306e52020-12-04 16:08:00 +0900131 StopRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"), _, _, false))
Hugo Benichi8d622b52020-08-13 15:24:12 +0900132 .Times(0);
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900133 EXPECT_CALL(*datapath_, RemoveBridge(StrEq("arc_eth0"))).Times(0);
Garrick Evans54861622019-07-19 09:05:09 +0900134
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900135 auto svc = NewService(GuestMessage::ARC);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900136 svc->OnDevicesChanged({"eth0"}, {});
137 svc->OnDevicesChanged({}, {"eth0"});
Garrick Evans6e4eb3b2020-03-09 07:18:31 +0900138 EXPECT_TRUE(svc->devices_.find("eth0") == svc->devices_.end());
Hugo Benichif0f10c72020-07-09 10:42:45 +0900139 EXPECT_TRUE(svc->shill_devices_.find("eth0") == svc->shill_devices_.end());
Garrick Evans54861622019-07-19 09:05:09 +0900140}
141
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900142TEST_F(ArcServiceTest, VerifyAddrConfigs) {
Hugo Benichi84d96c42021-02-26 14:20:13 +0900143 ExpectGetDeviceProperties(*shill_client_, "eth0",
144 ShillClient::Device::Type::kEthernet);
145 ExpectGetDeviceProperties(*shill_client_, "eth1",
146 ShillClient::Device::Type::kEthernet);
147 ExpectGetDeviceProperties(*shill_client_, "wlan0",
148 ShillClient::Device::Type::kWifi);
149 ExpectGetDeviceProperties(*shill_client_, "wlan1",
150 ShillClient::Device::Type::kWifi);
151 ExpectGetDeviceProperties(*shill_client_, "wwan0",
152 ShillClient::Device::Type::kCellular);
Hugo Benichi33860d72020-07-09 16:34:01 +0900153 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
154 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900155 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
156 .WillOnce(Return(true));
157 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900158 .WillOnce(Return(true));
159 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth1"), kSecondEthHostIP, 30))
160 .WillOnce(Return(true));
161 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_wlan0"), kFirstWifiHostIP, 30))
162 .WillOnce(Return(true));
163 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_wlan1"), kSecondWifiHostIP, 30))
164 .WillOnce(Return(true));
165 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_wwan0"), kFirstCellHostIP, 30))
166 .WillOnce(Return(true));
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900167 EXPECT_CALL(*datapath_,
168 ConnectVethPair(kTestPID, StrEq("arc_netns"), _, _, _, _, _, _))
Hugo Benichif0f10c72020-07-09 10:42:45 +0900169 .WillRepeatedly(Return(true));
170 EXPECT_CALL(*datapath_, AddToBridge(_, _)).WillRepeatedly(Return(true));
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900171
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900172 auto svc = NewService(GuestMessage::ARC);
173 svc->Start(kTestPID);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900174 svc->OnDevicesChanged({"eth0", "eth1", "wlan0", "wlan1", "wwan0"}, {});
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900175}
176
177TEST_F(ArcServiceTest, VerifyAddrOrder) {
Hugo Benichi84d96c42021-02-26 14:20:13 +0900178 ExpectGetDeviceProperties(*shill_client_, "wlan0",
179 ShillClient::Device::Type::kWifi);
180 ExpectGetDeviceProperties(*shill_client_, "eth0",
181 ShillClient::Device::Type::kEthernet);
Hugo Benichi33860d72020-07-09 16:34:01 +0900182 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
183 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900184 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
185 .WillOnce(Return(true));
186 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900187 .Times(2)
188 .WillRepeatedly(Return(true));
189 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_wlan0"), kFirstWifiHostIP, 30))
190 .WillOnce(Return(true));
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900191 EXPECT_CALL(*datapath_,
192 ConnectVethPair(kTestPID, StrEq("arc_netns"), _, _, _, _, _, _))
Hugo Benichif0f10c72020-07-09 10:42:45 +0900193 .WillRepeatedly(Return(true));
194 EXPECT_CALL(*datapath_, AddToBridge(_, _)).WillRepeatedly(Return(true));
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900195
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900196 auto svc = NewService(GuestMessage::ARC);
197 svc->Start(kTestPID);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900198 svc->OnDevicesChanged({"wlan0"}, {});
199 svc->OnDevicesChanged({"eth0"}, {});
200 svc->OnDevicesChanged({}, {"eth0"});
201 svc->OnDevicesChanged({"eth0"}, {});
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900202}
203
Garrick Evansc7071122020-04-17 12:31:57 +0900204TEST_F(ArcServiceTest, StableArcVmMacAddrs) {
205 EXPECT_CALL(*datapath_, AddTAP(StrEq(""), _, nullptr, StrEq("crosvm")))
206 .WillRepeatedly(Return("vmtap"));
207 EXPECT_CALL(*datapath_, AddBridge(_, _, 30)).WillRepeatedly(Return(true));
208 EXPECT_CALL(*datapath_, AddToBridge(_, _)).WillRepeatedly(Return(true));
209
210 auto svc = NewService(GuestMessage::ARC_VM);
211 svc->Start(kTestCID);
212 auto configs = svc->GetDeviceConfigs();
213 EXPECT_EQ(configs.size(), 6);
214 auto mac_addr = kArcVmArc0MacAddr;
215 for (const auto* config : configs) {
216 EXPECT_EQ(config->mac_addr(), mac_addr);
217 mac_addr[5]++;
218 }
219}
220
Garrick Evansb4eb3892019-11-13 12:07:07 +0900221// ContainerImpl
222
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900223TEST_F(ArcServiceTest, ContainerImpl_Start) {
Hugo Benichi33860d72020-07-09 16:34:01 +0900224 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
225 .WillOnce(Return(true));
Garrick Evansb4eb3892019-11-13 12:07:07 +0900226 EXPECT_CALL(*datapath_,
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900227 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetharc0"),
228 StrEq("arc0"), _, kArcGuestIP, 30, false))
Garrick Evans2470caa2020-03-04 14:15:41 +0900229 .WillOnce(Return(true));
Garrick Evans2f581a02020-05-11 10:43:35 +0900230 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vetharc0")))
Garrick Evans2470caa2020-03-04 14:15:41 +0900231 .WillOnce(Return(true));
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900232 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
233 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900234
235 auto svc = NewService(GuestMessage::ARC);
236 svc->Start(kTestPID);
Garrick Evansb4eb3892019-11-13 12:07:07 +0900237}
238
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900239TEST_F(ArcServiceTest, ContainerImpl_FailsToCreateInterface) {
Hugo Benichi33860d72020-07-09 16:34:01 +0900240 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
241 .WillOnce(Return(true));
Garrick Evans63378b32020-01-14 10:36:16 +0900242 EXPECT_CALL(*datapath_,
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900243 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetharc0"),
244 StrEq("arc0"), _, kArcGuestIP, 30, false))
Garrick Evans2470caa2020-03-04 14:15:41 +0900245 .WillOnce(Return(false));
Hugo Benichif0f10c72020-07-09 10:42:45 +0900246 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30)).Times(0);
Garrick Evans63378b32020-01-14 10:36:16 +0900247 EXPECT_CALL(*datapath_, RemoveBridge(_)).Times(0);
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900248
249 auto svc = NewService(GuestMessage::ARC);
250 svc->Start(kTestPID);
Garrick Evans63378b32020-01-14 10:36:16 +0900251}
252
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900253TEST_F(ArcServiceTest, ContainerImpl_FailsToAddInterfaceToBridge) {
Hugo Benichi33860d72020-07-09 16:34:01 +0900254 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
255 .WillOnce(Return(true));
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900256 EXPECT_CALL(*datapath_,
257 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetharc0"),
258 StrEq("arc0"), _, kArcGuestIP, 30, false))
259 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900260 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
261 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900262 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vetharc0")))
263 .WillOnce(Return(false));
264
265 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vetharc0")));
266 EXPECT_CALL(*datapath_, RemoveBridge(_)).Times(0);
267
268 auto svc = NewService(GuestMessage::ARC);
269 svc->Start(kTestPID);
270}
271
272TEST_F(ArcServiceTest, ContainerImpl_OnStartDevice) {
Hugo Benichi84d96c42021-02-26 14:20:13 +0900273 ExpectGetDeviceProperties(*shill_client_, "eth0",
274 ShillClient::Device::Type::kEthernet);
Hugo Benichi33860d72020-07-09 16:34:01 +0900275 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
276 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900277 // Expectations for arc0 setup.
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900278 EXPECT_CALL(*datapath_,
279 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetharc0"),
280 StrEq("arc0"), _, kArcGuestIP, 30, false))
281 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900282 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
283 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900284 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vetharc0")))
285 .WillOnce(Return(true));
286 // Expectations for eth0 setup.
Garrick Evansb4eb3892019-11-13 12:07:07 +0900287 EXPECT_CALL(*datapath_,
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900288 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetheth0"),
289 StrEq("eth0"), _, kFirstEthGuestIP, 30, false))
Garrick Evansb4eb3892019-11-13 12:07:07 +0900290 .WillOnce(Return(true));
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900291 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
Garrick Evans2470caa2020-03-04 14:15:41 +0900292 .WillOnce(Return(true));
Garrick Evans2f581a02020-05-11 10:43:35 +0900293 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_eth0"), StrEq("vetheth0")))
Garrick Evans2470caa2020-03-04 14:15:41 +0900294 .WillOnce(Return(true));
Hugo Benichi8d622b52020-08-13 15:24:12 +0900295 EXPECT_CALL(*datapath_,
296 StartRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"),
Hugo Benichi93306e52020-12-04 16:08:00 +0900297 kFirstEthGuestIP, TrafficSource::ARC, false));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900298
299 auto svc = NewService(GuestMessage::ARC);
300 svc->Start(kTestPID);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900301 svc->OnDevicesChanged({"eth0"}, {});
302}
303
Garrick Evans02e6e872020-11-30 11:53:13 +0900304TEST_F(ArcServiceTest, ContainerImpl_ScanDevices) {
Hugo Benichi84d96c42021-02-26 14:20:13 +0900305 ExpectGetDeviceProperties(*shill_client_, "eth0",
306 ShillClient::Device::Type::kEthernet);
307 ExpectGetDeviceProperties(*shill_client_, "wlan0",
308 ShillClient::Device::Type::kWifi);
Garrick Evans02e6e872020-11-30 11:53:13 +0900309 EXPECT_CALL(*datapath_, NetnsAttachName(_, _)).WillRepeatedly(Return(true));
310 EXPECT_CALL(*datapath_, ConnectVethPair(_, _, _, _, _, _, _, _))
311 .WillRepeatedly(Return(true));
312 EXPECT_CALL(*datapath_, AddBridge(_, _, _)).WillRepeatedly(Return(true));
313 EXPECT_CALL(*datapath_, AddToBridge(_, _)).WillRepeatedly(Return(true));
314
315 auto svc = NewService(GuestMessage::ARC);
316 svc->Start(kTestPID);
317 svc->OnDevicesChanged({"eth0", "wlan0"}, {});
318
319 std::vector<std::string> devs;
320 svc->ScanDevices(base::BindRepeating(
321 [](std::vector<std::string>* list, const Device& device) {
322 list->push_back(device.host_ifname());
323 },
324 &devs));
325
326 EXPECT_EQ(devs.size(), 2);
327 EXPECT_THAT(devs,
328 UnorderedElementsAre(StrEq("arc_eth0"), StrEq("arc_wlan0")));
329}
330
Garrick Evans209a80a2020-11-30 14:42:40 +0900331TEST_F(ArcServiceTest, ContainerImpl_DeviceHandler) {
Hugo Benichi84d96c42021-02-26 14:20:13 +0900332 ExpectGetDeviceProperties(*shill_client_, "eth0",
333 ShillClient::Device::Type::kEthernet);
334 ExpectGetDeviceProperties(*shill_client_, "wlan0",
335 ShillClient::Device::Type::kWifi);
Garrick Evans209a80a2020-11-30 14:42:40 +0900336 EXPECT_CALL(*datapath_, NetnsAttachName(_, _)).WillRepeatedly(Return(true));
337 EXPECT_CALL(*datapath_, ConnectVethPair(_, _, _, _, _, _, _, _))
338 .WillRepeatedly(Return(true));
339 EXPECT_CALL(*datapath_, AddBridge(_, _, _)).WillRepeatedly(Return(true));
340 EXPECT_CALL(*datapath_, AddToBridge(_, _)).WillRepeatedly(Return(true));
341
342 auto svc = NewService(GuestMessage::ARC);
343 svc->Start(kTestPID);
344
345 svc->OnDevicesChanged({"eth0", "wlan0"}, {});
346 EXPECT_EQ(guest_devices_.size(), 2);
347 EXPECT_THAT(guest_devices_,
348 UnorderedElementsAre(
349 Pair(StrEq("arc_eth0"), Device::ChangeEvent::ADDED),
350 Pair(StrEq("arc_wlan0"), Device::ChangeEvent::ADDED)));
351
352 svc->OnDevicesChanged({}, {"wlan0"});
353 EXPECT_THAT(guest_devices_,
354 UnorderedElementsAre(
355 Pair(StrEq("arc_eth0"), Device::ChangeEvent::ADDED),
356 Pair(StrEq("arc_wlan0"), Device::ChangeEvent::REMOVED)));
357
358 guest_devices_.clear();
359 svc->OnDevicesChanged({"wlan0"}, {});
360 EXPECT_THAT(guest_devices_,
361 UnorderedElementsAre(
362 Pair(StrEq("arc_wlan0"), Device::ChangeEvent::ADDED)));
363}
364
Hugo Benichif0f10c72020-07-09 10:42:45 +0900365TEST_F(ArcServiceTest, ContainerImpl_StartAfterDevice) {
Hugo Benichi84d96c42021-02-26 14:20:13 +0900366 ExpectGetDeviceProperties(*shill_client_, "eth0",
367 ShillClient::Device::Type::kEthernet);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900368 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
369 .WillOnce(Return(true));
370 // Expectations for arc0 setup.
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900371 EXPECT_CALL(*datapath_,
372 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetharc0"),
373 StrEq("arc0"), _, kArcGuestIP, 30, false))
374 .WillOnce(Return(true));
Hugo Benichif0f10c72020-07-09 10:42:45 +0900375 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
376 .WillOnce(Return(true));
Hugo Benichif0f10c72020-07-09 10:42:45 +0900377 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vetharc0")))
378 .WillOnce(Return(true));
379 // Expectations for eth0 setup.
Hugo Benichif0f10c72020-07-09 10:42:45 +0900380 EXPECT_CALL(*datapath_,
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900381 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetheth0"),
382 StrEq("eth0"), _, kFirstEthGuestIP, 30, false))
Hugo Benichif0f10c72020-07-09 10:42:45 +0900383 .WillOnce(Return(true));
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900384 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
Hugo Benichif0f10c72020-07-09 10:42:45 +0900385 .WillOnce(Return(true));
386 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_eth0"), StrEq("vetheth0")))
387 .WillOnce(Return(true));
Hugo Benichi8d622b52020-08-13 15:24:12 +0900388 EXPECT_CALL(*datapath_,
389 StartRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"),
Hugo Benichi93306e52020-12-04 16:08:00 +0900390 kFirstEthGuestIP, TrafficSource::ARC, false));
Hugo Benichif0f10c72020-07-09 10:42:45 +0900391
392 auto svc = NewService(GuestMessage::ARC);
393 svc->OnDevicesChanged({"eth0"}, {});
394 svc->Start(kTestPID);
Garrick Evansb4eb3892019-11-13 12:07:07 +0900395}
396
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900397TEST_F(ArcServiceTest, ContainerImpl_Stop) {
Hugo Benichi33860d72020-07-09 16:34:01 +0900398 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
399 .WillOnce(Return(true));
400 EXPECT_CALL(*datapath_, NetnsDeleteName(StrEq("arc_netns")))
401 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900402 // Expectations for arc0 setup.
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900403 EXPECT_CALL(*datapath_,
404 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetharc0"),
405 StrEq("arc0"), _, kArcGuestIP, 30, false))
406 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900407 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
408 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900409 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vetharc0")))
410 .WillOnce(Return(true));
411 // Expectations for arc0 teardown.
412 EXPECT_CALL(*datapath_,
413 MaskInterfaceFlags(StrEq("arcbr0"), IFF_DEBUG, IFF_UP))
414 .WillOnce(Return(true));
Garrick Evans2f581a02020-05-11 10:43:35 +0900415 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vetharc0")));
Garrick Evanse94b6de2020-02-20 09:19:13 +0900416
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900417 auto svc = NewService(GuestMessage::ARC);
418 svc->Start(kTestPID);
419 svc->Stop(kTestPID);
Garrick Evansb4eb3892019-11-13 12:07:07 +0900420}
421
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900422TEST_F(ArcServiceTest, ContainerImpl_OnStopDevice) {
Hugo Benichi84d96c42021-02-26 14:20:13 +0900423 ExpectGetDeviceProperties(*shill_client_, "eth0",
424 ShillClient::Device::Type::kEthernet);
Hugo Benichi33860d72020-07-09 16:34:01 +0900425 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
426 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900427 // Expectations for arc0 setup.
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900428 EXPECT_CALL(*datapath_,
429 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetharc0"),
430 StrEq("arc0"), _, kArcGuestIP, 30, false))
431 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900432 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
433 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900434 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vetharc0")))
435 .WillOnce(Return(true));
436 // Expectations for eth0 setup.
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900437 EXPECT_CALL(*datapath_,
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900438 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetheth0"),
439 StrEq("eth0"), _, kFirstEthGuestIP, 30, false))
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900440 .WillOnce(Return(true));
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900441 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900442 .WillOnce(Return(true));
443 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_eth0"), StrEq("vetheth0")))
444 .WillOnce(Return(true));
445 // Expectations for eth0 teardown.
Hugo Benichi93306e52020-12-04 16:08:00 +0900446 EXPECT_CALL(*datapath_, StopRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"),
447 Ipv4Addr(100, 115, 92, 6),
448 TrafficSource::ARC, false));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900449 EXPECT_CALL(*datapath_, RemoveBridge(StrEq("arc_eth0")));
Garrick Evanse94b6de2020-02-20 09:19:13 +0900450
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900451 auto svc = NewService(GuestMessage::ARC);
452 svc->Start(kTestPID);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900453 svc->OnDevicesChanged({"eth0"}, {});
454 svc->OnDevicesChanged({}, {"eth0"});
Garrick Evansb4eb3892019-11-13 12:07:07 +0900455}
456
Garrick Evansb4eb3892019-11-13 12:07:07 +0900457// VM Impl
458
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900459TEST_F(ArcServiceTest, VmImpl_Start) {
460 // Expectations for tap devices pre-creation.
Garrick Evansc7071122020-04-17 12:31:57 +0900461 EXPECT_CALL(*datapath_, AddTAP(StrEq(""), _, nullptr, StrEq("crosvm")))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900462 .WillOnce(Return("vmtap0"))
463 .WillOnce(Return("vmtap1"))
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900464 .WillOnce(Return("vmtap2"))
465 .WillOnce(Return("vmtap3"))
466 .WillOnce(Return("vmtap4"))
467 .WillOnce(Return("vmtap5"));
468 // Expectations for "arc0" setup.
469 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900470 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900471 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vmtap0")))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900472 .WillOnce(Return(true));
473
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900474 auto svc = NewService(GuestMessage::ARC_VM);
475 svc->Start(kTestPID);
Garrick Evans2961c7c2020-04-03 11:34:40 +0900476}
477
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900478TEST_F(ArcServiceTest, VmImpl_StartDevice) {
Hugo Benichi84d96c42021-02-26 14:20:13 +0900479 ExpectGetDeviceProperties(*shill_client_, "eth0",
480 ShillClient::Device::Type::kEthernet);
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900481 // Expectations for tap devices pre-creation.
Garrick Evansc7071122020-04-17 12:31:57 +0900482 EXPECT_CALL(*datapath_, AddTAP(StrEq(""), _, nullptr, StrEq("crosvm")))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900483 .WillOnce(Return("vmtap0"))
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900484 .WillOnce(Return("vmtap1"))
485 .WillOnce(Return("vmtap2"))
486 .WillOnce(Return("vmtap3"))
487 .WillOnce(Return("vmtap4"))
488 .WillOnce(Return("vmtap5"));
489 // Expectations for "arc0" setup.
490 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900491 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900492 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vmtap0")))
493 .WillOnce(Return(true));
494 // Expectations for eth0 setup.
495 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900496 .WillOnce(Return(true));
497 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_eth0"), StrEq("vmtap1")))
498 .WillOnce(Return(true));
Hugo Benichi8d622b52020-08-13 15:24:12 +0900499 EXPECT_CALL(*datapath_, StartRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"),
500 Ipv4Addr(100, 115, 92, 6),
Hugo Benichi93306e52020-12-04 16:08:00 +0900501 TrafficSource::ARC, false));
Garrick Evans2961c7c2020-04-03 11:34:40 +0900502
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900503 auto svc = NewService(GuestMessage::ARC_VM);
504 svc->Start(kTestPID);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900505 svc->OnDevicesChanged({"eth0"}, {});
Garrick Evans2961c7c2020-04-03 11:34:40 +0900506}
507
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900508TEST_F(ArcServiceTest, VmImpl_StartMultipleDevices) {
Hugo Benichi84d96c42021-02-26 14:20:13 +0900509 ExpectGetDeviceProperties(*shill_client_, "eth0",
510 ShillClient::Device::Type::kEthernet);
511 ExpectGetDeviceProperties(*shill_client_, "eth1",
512 ShillClient::Device::Type::kEthernet);
513 ExpectGetDeviceProperties(*shill_client_, "wlan0",
514 ShillClient::Device::Type::kWifi);
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900515 // Expectations for tap devices pre-creation.
Garrick Evansc7071122020-04-17 12:31:57 +0900516 EXPECT_CALL(*datapath_, AddTAP(StrEq(""), _, nullptr, StrEq("crosvm")))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900517 .WillOnce(Return("vmtap0"))
518 .WillOnce(Return("vmtap1"))
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900519 .WillOnce(Return("vmtap2"))
520 .WillOnce(Return("vmtap3"))
521 .WillOnce(Return("vmtap4"))
522 .WillOnce(Return("vmtap5"));
523 // Expectations for "arc0" setup.
524 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900525 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900526 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vmtap0")))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900527 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900528 // Expectations for eth0 setup.
529 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
530 .WillOnce(Return(true));
531 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_eth0"), StrEq("vmtap1")))
532 .WillOnce(Return(true));
Hugo Benichi8d622b52020-08-13 15:24:12 +0900533 EXPECT_CALL(*datapath_, StartRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"),
534 Ipv4Addr(100, 115, 92, 6),
Hugo Benichi93306e52020-12-04 16:08:00 +0900535 TrafficSource::ARC, false));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900536 // Expectations for wlan0 setup.
537 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_wlan0"), kFirstWifiHostIP, 30))
538 .WillOnce(Return(true));
539 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_wlan0"), StrEq("vmtap3")))
540 .WillOnce(Return(true));
Hugo Benichi8d622b52020-08-13 15:24:12 +0900541 EXPECT_CALL(*datapath_, StartRoutingDevice(StrEq("wlan0"), StrEq("arc_wlan0"),
542 Ipv4Addr(100, 115, 92, 14),
Hugo Benichi93306e52020-12-04 16:08:00 +0900543 TrafficSource::ARC, false));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900544 // Expectations for eth1 setup.
545 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth1"), kSecondEthHostIP, 30))
546 .WillOnce(Return(true));
547 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_eth1"), StrEq("vmtap2")))
548 .WillOnce(Return(true));
Hugo Benichi8d622b52020-08-13 15:24:12 +0900549 EXPECT_CALL(*datapath_, StartRoutingDevice(StrEq("eth1"), StrEq("arc_eth1"),
550 Ipv4Addr(100, 115, 92, 10),
Hugo Benichi93306e52020-12-04 16:08:00 +0900551 TrafficSource::ARC, false));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900552
553 auto svc = NewService(GuestMessage::ARC_VM);
554 svc->Start(kTestPID);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900555 svc->OnDevicesChanged({"eth0"}, {});
556 svc->OnDevicesChanged({"wlan0"}, {});
557 svc->OnDevicesChanged({"eth1"}, {});
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900558}
559
560TEST_F(ArcServiceTest, VmImpl_Stop) {
561 // Expectations for tap devices pre-creation.
562 EXPECT_CALL(*datapath_, AddTAP(StrEq(""), _, nullptr, StrEq("crosvm")))
563 .WillOnce(Return("vmtap0"))
564 .WillOnce(Return("vmtap1"))
565 .WillOnce(Return("vmtap2"))
566 .WillOnce(Return("vmtap3"))
567 .WillOnce(Return("vmtap4"))
568 .WillOnce(Return("vmtap5"));
569 // Expectations for "arc0" setup.
570 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
571 .WillOnce(Return(true));
572 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vmtap0")))
573 .WillOnce(Return(true));
574 // Expectations for "arc0" teardown.
575 EXPECT_CALL(*datapath_,
576 MaskInterfaceFlags(StrEq("arcbr0"), IFF_DEBUG, IFF_UP))
577 .WillOnce(Return(true));
578 // Expectations for tap devices teardown
Garrick Evans2961c7c2020-04-03 11:34:40 +0900579 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vmtap0")));
580 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vmtap1")));
581 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vmtap2")));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900582 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vmtap3")));
583 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vmtap4")));
584 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vmtap5")));
Garrick Evans2961c7c2020-04-03 11:34:40 +0900585
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900586 auto svc = NewService(GuestMessage::ARC_VM);
587 svc->Start(kTestPID);
588 svc->Stop(kTestPID);
Garrick Evans2961c7c2020-04-03 11:34:40 +0900589}
590
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900591TEST_F(ArcServiceTest, VmImpl_StopDevice) {
Hugo Benichi84d96c42021-02-26 14:20:13 +0900592 ExpectGetDeviceProperties(*shill_client_, "eth0",
593 ShillClient::Device::Type::kEthernet);
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900594 // Expectations for tap devices pre-creation.
Garrick Evansc7071122020-04-17 12:31:57 +0900595 EXPECT_CALL(*datapath_, AddTAP(StrEq(""), _, nullptr, StrEq("crosvm")))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900596 .WillOnce(Return("vmtap0"))
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900597 .WillOnce(Return("vmtap1"))
598 .WillOnce(Return("vmtap2"))
599 .WillOnce(Return("vmtap3"))
600 .WillOnce(Return("vmtap4"))
601 .WillOnce(Return("vmtap5"));
602 // Expectations for "arc0" setup.
603 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900604 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900605 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vmtap0")))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900606 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900607 // Expectations for eth0 setup.
608 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
609 .WillOnce(Return(true));
610 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_eth0"), StrEq("vmtap1")))
611 .WillOnce(Return(true));
Hugo Benichi8d622b52020-08-13 15:24:12 +0900612 EXPECT_CALL(*datapath_, StartRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"),
613 Ipv4Addr(100, 115, 92, 6),
Hugo Benichi93306e52020-12-04 16:08:00 +0900614 TrafficSource::ARC, false));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900615 // Expectations for eth0 teardown.
Hugo Benichi93306e52020-12-04 16:08:00 +0900616 EXPECT_CALL(*datapath_, StopRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"),
617 Ipv4Addr(100, 115, 92, 6),
618 TrafficSource::ARC, false));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900619 EXPECT_CALL(*datapath_, RemoveBridge(StrEq("arc_eth0")));
Garrick Evans2961c7c2020-04-03 11:34:40 +0900620
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900621 auto svc = NewService(GuestMessage::ARC_VM);
622 svc->Start(kTestPID);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900623 svc->OnDevicesChanged({"eth0"}, {});
624 svc->OnDevicesChanged({}, {"eth0"});
Garrick Evans2961c7c2020-04-03 11:34:40 +0900625}
Garrick Evans3388a032020-03-24 11:25:55 +0900626
Garrick Evans02e6e872020-11-30 11:53:13 +0900627TEST_F(ArcServiceTest, VmImpl_ScanDevices) {
Hugo Benichi84d96c42021-02-26 14:20:13 +0900628 ExpectGetDeviceProperties(*shill_client_, "eth0",
629 ShillClient::Device::Type::kEthernet);
630 ExpectGetDeviceProperties(*shill_client_, "eth1",
631 ShillClient::Device::Type::kEthernet);
632 ExpectGetDeviceProperties(*shill_client_, "wlan0",
633 ShillClient::Device::Type::kWifi);
Garrick Evans02e6e872020-11-30 11:53:13 +0900634 // Expectations for tap devices pre-creation.
635 EXPECT_CALL(*datapath_, AddTAP(StrEq(""), _, nullptr, StrEq("crosvm")))
636 .WillOnce(Return("vmtap0"))
637 .WillOnce(Return("vmtap1"))
638 .WillOnce(Return("vmtap2"))
639 .WillOnce(Return("vmtap3"))
640 .WillOnce(Return("vmtap4"))
641 .WillOnce(Return("vmtap5"));
642 EXPECT_CALL(*datapath_, AddBridge(_, _, _)).WillRepeatedly(Return(true));
643 EXPECT_CALL(*datapath_, AddToBridge(_, _)).WillRepeatedly(Return(true));
644
645 auto svc = NewService(GuestMessage::ARC_VM);
646 svc->Start(kTestPID);
647 svc->OnDevicesChanged({"eth0", "wlan0", "eth1"}, {});
648
649 std::vector<std::string> devs;
650 svc->ScanDevices(base::BindRepeating(
651 [](std::vector<std::string>* list, const Device& device) {
652 list->push_back(device.host_ifname());
653 },
654 &devs));
655
656 EXPECT_EQ(devs.size(), 3);
657 EXPECT_THAT(devs, UnorderedElementsAre(StrEq("arc_eth0"), StrEq("arc_wlan0"),
658 StrEq("arc_eth1")));
659}
660
Garrick Evans209a80a2020-11-30 14:42:40 +0900661TEST_F(ArcServiceTest, VmImpl_DeviceHandler) {
Hugo Benichi84d96c42021-02-26 14:20:13 +0900662 ExpectGetDeviceProperties(*shill_client_, "eth0",
663 ShillClient::Device::Type::kEthernet);
664 ExpectGetDeviceProperties(*shill_client_, "wlan0",
665 ShillClient::Device::Type::kWifi);
Garrick Evans209a80a2020-11-30 14:42:40 +0900666 // Expectations for tap devices pre-creation.
667 EXPECT_CALL(*datapath_, AddTAP(StrEq(""), _, nullptr, StrEq("crosvm")))
668 .WillOnce(Return("vmtap0"))
669 .WillOnce(Return("vmtap1"))
670 .WillOnce(Return("vmtap2"))
671 .WillOnce(Return("vmtap3"))
672 .WillOnce(Return("vmtap4"))
673 .WillOnce(Return("vmtap5"));
674 EXPECT_CALL(*datapath_, AddBridge(_, _, _)).WillRepeatedly(Return(true));
675 EXPECT_CALL(*datapath_, AddToBridge(_, _)).WillRepeatedly(Return(true));
676
677 auto svc = NewService(GuestMessage::ARC_VM);
678 svc->Start(kTestPID);
679
680 svc->OnDevicesChanged({"eth0", "wlan0"}, {});
681 EXPECT_EQ(guest_devices_.size(), 2);
682 EXPECT_THAT(guest_devices_,
683 UnorderedElementsAre(
684 Pair(StrEq("arc_eth0"), Device::ChangeEvent::ADDED),
685 Pair(StrEq("arc_wlan0"), Device::ChangeEvent::ADDED)));
686
687 svc->OnDevicesChanged({}, {"wlan0"});
688 EXPECT_THAT(guest_devices_,
689 UnorderedElementsAre(
690 Pair(StrEq("arc_eth0"), Device::ChangeEvent::ADDED),
691 Pair(StrEq("arc_wlan0"), Device::ChangeEvent::REMOVED)));
692
693 guest_devices_.clear();
694 svc->OnDevicesChanged({"wlan0"}, {});
695 EXPECT_THAT(guest_devices_,
696 UnorderedElementsAre(
697 Pair(StrEq("arc_wlan0"), Device::ChangeEvent::ADDED)));
698}
699
Garrick Evans3388a032020-03-24 11:25:55 +0900700} // namespace patchpanel