blob: 1de745dcd3ef139caa889e036caf865eb1caf725 [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>
Garrick Evans209a80a2020-11-30 14:42:40 +090013#include <base/bind_helpers.h>
Garrick Evans54861622019-07-19 09:05:09 +090014
15#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;
Garrick Evans209a80a2020-11-30 14:42:40 +090028using testing::Pair;
Garrick Evansc7071122020-04-17 12:31:57 +090029using testing::Pointee;
Garrick Evans54861622019-07-19 09:05:09 +090030using testing::Return;
Garrick Evansb4eb3892019-11-13 12:07:07 +090031using testing::ReturnRef;
Garrick Evans54861622019-07-19 09:05:09 +090032using testing::StrEq;
Garrick Evans02e6e872020-11-30 11:53:13 +090033using testing::UnorderedElementsAre;
Garrick Evans54861622019-07-19 09:05:09 +090034
Garrick Evans3388a032020-03-24 11:25:55 +090035namespace patchpanel {
Garrick Evans54861622019-07-19 09:05:09 +090036namespace {
Garrick Evansb4eb3892019-11-13 12:07:07 +090037constexpr pid_t kTestPID = -2;
Garrick Evansb4eb3892019-11-13 12:07:07 +090038constexpr uint32_t kTestCID = 2;
Garrick Evans7a1a9ee2020-01-28 11:03:57 +090039constexpr uint32_t kArcHostIP = Ipv4Addr(100, 115, 92, 1);
40constexpr uint32_t kArcGuestIP = Ipv4Addr(100, 115, 92, 2);
Hugo Benichiad1bdd92020-06-12 13:48:37 +090041constexpr uint32_t kFirstEthHostIP = Ipv4Addr(100, 115, 92, 5);
42constexpr uint32_t kFirstEthGuestIP = Ipv4Addr(100, 115, 92, 6);
Garrick Evans86c7d9c2020-03-17 09:25:48 +090043constexpr uint32_t kSecondEthHostIP = Ipv4Addr(100, 115, 92, 9);
44constexpr uint32_t kFirstWifiHostIP = Ipv4Addr(100, 115, 92, 13);
45constexpr uint32_t kSecondWifiHostIP = Ipv4Addr(100, 115, 92, 17);
46constexpr uint32_t kFirstCellHostIP = Ipv4Addr(100, 115, 92, 21);
Garrick Evansc7071122020-04-17 12:31:57 +090047constexpr MacAddress kArcVmArc0MacAddr = {0x42, 0x37, 0x05, 0x13, 0x17, 0x01};
Garrick Evans54861622019-07-19 09:05:09 +090048
Garrick Evans2e5c9ab2020-03-05 14:33:58 +090049class MockTrafficForwarder : public TrafficForwarder {
50 public:
51 MockTrafficForwarder() = default;
52 ~MockTrafficForwarder() = default;
53
Jason Jeremy Iman0e9f8262020-03-06 14:50:49 +090054 MOCK_METHOD4(StartForwarding,
Garrick Evans2e5c9ab2020-03-05 14:33:58 +090055 void(const std::string& ifname_physical,
56 const std::string& ifname_virtual,
Garrick Evans2e5c9ab2020-03-05 14:33:58 +090057 bool ipv6,
58 bool multicast));
59
60 MOCK_METHOD4(StopForwarding,
61 void(const std::string& ifname_physical,
62 const std::string& ifname_virtual,
63 bool ipv6,
64 bool multicast));
65};
66
Garrick Evans54861622019-07-19 09:05:09 +090067} // namespace
68
69class ArcServiceTest : public testing::Test {
70 public:
Garrick Evans4ee5ce22020-03-18 07:05:17 +090071 ArcServiceTest() : testing::Test() {}
Garrick Evans54861622019-07-19 09:05:09 +090072
73 protected:
74 void SetUp() override {
Taoyu Li179dcc62019-10-17 11:21:08 +090075 runner_ = std::make_unique<FakeProcessRunner>();
Garrick Evans54861622019-07-19 09:05:09 +090076 runner_->Capture(false);
Jason Jeremy Imana7273a32020-08-04 11:25:31 +090077 datapath_ = std::make_unique<MockDatapath>(runner_.get(), &firewall_);
Garrick Evans69b85872020-02-04 11:40:26 +090078 shill_client_ = shill_helper_.Client();
Garrick Evans4ee5ce22020-03-18 07:05:17 +090079 addr_mgr_ = std::make_unique<AddressManager>();
Garrick Evans209a80a2020-11-30 14:42:40 +090080 guest_devices_.clear();
Garrick Evans54861622019-07-19 09:05:09 +090081 }
82
Hugo Benichiad1bdd92020-06-12 13:48:37 +090083 std::unique_ptr<ArcService> NewService(GuestMessage::GuestType guest) {
Garrick Evans209a80a2020-11-30 14:42:40 +090084 return std::make_unique<ArcService>(
85 shill_client_.get(), datapath_.get(), addr_mgr_.get(), &forwarder_,
86 guest,
87 base::BindRepeating(&ArcServiceTest::DeviceHandler,
88 base::Unretained(this)));
89 }
90
91 void DeviceHandler(const Device& device,
92 Device::ChangeEvent event,
93 GuestMessage::GuestType guest_type) {
94 guest_devices_[device.host_ifname()] = event;
Garrick Evans54861622019-07-19 09:05:09 +090095 }
96
Garrick Evans69b85872020-02-04 11:40:26 +090097 FakeShillClientHelper shill_helper_;
98 std::unique_ptr<ShillClient> shill_client_;
Garrick Evans4ee5ce22020-03-18 07:05:17 +090099 std::unique_ptr<AddressManager> addr_mgr_;
Garrick Evans2e5c9ab2020-03-05 14:33:58 +0900100 MockTrafficForwarder forwarder_;
Taoyu Li179dcc62019-10-17 11:21:08 +0900101 std::unique_ptr<MockDatapath> datapath_;
102 std::unique_ptr<FakeProcessRunner> runner_;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900103 MockFirewall firewall_;
Garrick Evans209a80a2020-11-30 14:42:40 +0900104 std::map<std::string, Device::ChangeEvent> guest_devices_;
Garrick Evans54861622019-07-19 09:05:09 +0900105};
106
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900107TEST_F(ArcServiceTest, NotStarted_AddDevice) {
108 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), _, _)).Times(0);
Hugo Benichi8d622b52020-08-13 15:24:12 +0900109 EXPECT_CALL(*datapath_,
110 StartRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"), _, _))
111 .Times(0);
Garrick Evans54861622019-07-19 09:05:09 +0900112
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900113 auto svc = NewService(GuestMessage::ARC);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900114 svc->OnDevicesChanged({"eth0"}, {});
115 EXPECT_TRUE(svc->devices_.find("eth0") == svc->devices_.end());
116 EXPECT_FALSE(svc->shill_devices_.find("eth0") == svc->shill_devices_.end());
Garrick Evans54861622019-07-19 09:05:09 +0900117}
118
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900119TEST_F(ArcServiceTest, NotStarted_AddRemoveDevice) {
120 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), _, _)).Times(0);
Hugo Benichi8d622b52020-08-13 15:24:12 +0900121 EXPECT_CALL(*datapath_,
122 StartRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"), _, _))
123 .Times(0);
124 EXPECT_CALL(*datapath_,
125 StopRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"), _, _))
126 .Times(0);
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900127 EXPECT_CALL(*datapath_, RemoveBridge(StrEq("arc_eth0"))).Times(0);
Garrick Evans54861622019-07-19 09:05:09 +0900128
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900129 auto svc = NewService(GuestMessage::ARC);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900130 svc->OnDevicesChanged({"eth0"}, {});
131 svc->OnDevicesChanged({}, {"eth0"});
Garrick Evans6e4eb3b2020-03-09 07:18:31 +0900132 EXPECT_TRUE(svc->devices_.find("eth0") == svc->devices_.end());
Hugo Benichif0f10c72020-07-09 10:42:45 +0900133 EXPECT_TRUE(svc->shill_devices_.find("eth0") == svc->shill_devices_.end());
Garrick Evans54861622019-07-19 09:05:09 +0900134}
135
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900136TEST_F(ArcServiceTest, VerifyAddrConfigs) {
Hugo Benichi33860d72020-07-09 16:34:01 +0900137 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
138 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900139 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
140 .WillOnce(Return(true));
141 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900142 .WillOnce(Return(true));
143 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth1"), kSecondEthHostIP, 30))
144 .WillOnce(Return(true));
145 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_wlan0"), kFirstWifiHostIP, 30))
146 .WillOnce(Return(true));
147 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_wlan1"), kSecondWifiHostIP, 30))
148 .WillOnce(Return(true));
149 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_wwan0"), kFirstCellHostIP, 30))
150 .WillOnce(Return(true));
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900151 EXPECT_CALL(*datapath_,
152 ConnectVethPair(kTestPID, StrEq("arc_netns"), _, _, _, _, _, _))
Hugo Benichif0f10c72020-07-09 10:42:45 +0900153 .WillRepeatedly(Return(true));
154 EXPECT_CALL(*datapath_, AddToBridge(_, _)).WillRepeatedly(Return(true));
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900155
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900156 auto svc = NewService(GuestMessage::ARC);
157 svc->Start(kTestPID);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900158 svc->OnDevicesChanged({"eth0", "eth1", "wlan0", "wlan1", "wwan0"}, {});
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900159}
160
161TEST_F(ArcServiceTest, VerifyAddrOrder) {
Hugo Benichi33860d72020-07-09 16:34:01 +0900162 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
163 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900164 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
165 .WillOnce(Return(true));
166 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900167 .Times(2)
168 .WillRepeatedly(Return(true));
169 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_wlan0"), kFirstWifiHostIP, 30))
170 .WillOnce(Return(true));
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900171 EXPECT_CALL(*datapath_,
172 ConnectVethPair(kTestPID, StrEq("arc_netns"), _, _, _, _, _, _))
Hugo Benichif0f10c72020-07-09 10:42:45 +0900173 .WillRepeatedly(Return(true));
174 EXPECT_CALL(*datapath_, AddToBridge(_, _)).WillRepeatedly(Return(true));
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900175
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900176 auto svc = NewService(GuestMessage::ARC);
177 svc->Start(kTestPID);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900178 svc->OnDevicesChanged({"wlan0"}, {});
179 svc->OnDevicesChanged({"eth0"}, {});
180 svc->OnDevicesChanged({}, {"eth0"});
181 svc->OnDevicesChanged({"eth0"}, {});
Garrick Evans86c7d9c2020-03-17 09:25:48 +0900182}
183
Garrick Evansc7071122020-04-17 12:31:57 +0900184TEST_F(ArcServiceTest, StableArcVmMacAddrs) {
185 EXPECT_CALL(*datapath_, AddTAP(StrEq(""), _, nullptr, StrEq("crosvm")))
186 .WillRepeatedly(Return("vmtap"));
187 EXPECT_CALL(*datapath_, AddBridge(_, _, 30)).WillRepeatedly(Return(true));
188 EXPECT_CALL(*datapath_, AddToBridge(_, _)).WillRepeatedly(Return(true));
189
190 auto svc = NewService(GuestMessage::ARC_VM);
191 svc->Start(kTestCID);
192 auto configs = svc->GetDeviceConfigs();
193 EXPECT_EQ(configs.size(), 6);
194 auto mac_addr = kArcVmArc0MacAddr;
195 for (const auto* config : configs) {
196 EXPECT_EQ(config->mac_addr(), mac_addr);
197 mac_addr[5]++;
198 }
199}
200
Garrick Evansb4eb3892019-11-13 12:07:07 +0900201// ContainerImpl
202
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900203TEST_F(ArcServiceTest, ContainerImpl_Start) {
Hugo Benichi33860d72020-07-09 16:34:01 +0900204 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
205 .WillOnce(Return(true));
Garrick Evansb4eb3892019-11-13 12:07:07 +0900206 EXPECT_CALL(*datapath_,
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900207 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetharc0"),
208 StrEq("arc0"), _, kArcGuestIP, 30, false))
Garrick Evans2470caa2020-03-04 14:15:41 +0900209 .WillOnce(Return(true));
Garrick Evans2f581a02020-05-11 10:43:35 +0900210 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vetharc0")))
Garrick Evans2470caa2020-03-04 14:15:41 +0900211 .WillOnce(Return(true));
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900212 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
213 .WillOnce(Return(true));
Jason Jeremy Iman0e9f8262020-03-06 14:50:49 +0900214 EXPECT_CALL(forwarder_, StartForwarding(_, _, _, _)).Times(0);
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900215
216 auto svc = NewService(GuestMessage::ARC);
217 svc->Start(kTestPID);
Garrick Evansb4eb3892019-11-13 12:07:07 +0900218}
219
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900220TEST_F(ArcServiceTest, ContainerImpl_FailsToCreateInterface) {
Hugo Benichi33860d72020-07-09 16:34:01 +0900221 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
222 .WillOnce(Return(true));
Garrick Evans63378b32020-01-14 10:36:16 +0900223 EXPECT_CALL(*datapath_,
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900224 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetharc0"),
225 StrEq("arc0"), _, kArcGuestIP, 30, false))
Garrick Evans2470caa2020-03-04 14:15:41 +0900226 .WillOnce(Return(false));
Hugo Benichif0f10c72020-07-09 10:42:45 +0900227 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30)).Times(0);
Garrick Evans63378b32020-01-14 10:36:16 +0900228 EXPECT_CALL(*datapath_, RemoveBridge(_)).Times(0);
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900229
230 auto svc = NewService(GuestMessage::ARC);
231 svc->Start(kTestPID);
Garrick Evans63378b32020-01-14 10:36:16 +0900232}
233
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900234TEST_F(ArcServiceTest, ContainerImpl_FailsToAddInterfaceToBridge) {
Hugo Benichi33860d72020-07-09 16:34:01 +0900235 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
236 .WillOnce(Return(true));
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900237 EXPECT_CALL(*datapath_,
238 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetharc0"),
239 StrEq("arc0"), _, kArcGuestIP, 30, false))
240 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900241 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
242 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900243 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vetharc0")))
244 .WillOnce(Return(false));
245
246 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vetharc0")));
247 EXPECT_CALL(*datapath_, RemoveBridge(_)).Times(0);
248
249 auto svc = NewService(GuestMessage::ARC);
250 svc->Start(kTestPID);
251}
252
253TEST_F(ArcServiceTest, ContainerImpl_OnStartDevice) {
Hugo Benichi33860d72020-07-09 16:34:01 +0900254 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
255 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900256 // Expectations for arc0 setup.
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900257 EXPECT_CALL(*datapath_,
258 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetharc0"),
259 StrEq("arc0"), _, kArcGuestIP, 30, false))
260 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900261 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
262 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900263 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vetharc0")))
264 .WillOnce(Return(true));
265 // Expectations for eth0 setup.
Garrick Evansb4eb3892019-11-13 12:07:07 +0900266 EXPECT_CALL(*datapath_,
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900267 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetheth0"),
268 StrEq("eth0"), _, kFirstEthGuestIP, 30, false))
Garrick Evansb4eb3892019-11-13 12:07:07 +0900269 .WillOnce(Return(true));
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900270 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
Garrick Evans2470caa2020-03-04 14:15:41 +0900271 .WillOnce(Return(true));
Garrick Evans2f581a02020-05-11 10:43:35 +0900272 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_eth0"), StrEq("vetheth0")))
Garrick Evans2470caa2020-03-04 14:15:41 +0900273 .WillOnce(Return(true));
Jason Jeremy Iman0e9f8262020-03-06 14:50:49 +0900274 EXPECT_CALL(forwarder_,
275 StartForwarding(StrEq("eth0"), StrEq("arc_eth0"), _, _));
Hugo Benichi8d622b52020-08-13 15:24:12 +0900276 EXPECT_CALL(*datapath_,
277 StartRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"),
278 kFirstEthGuestIP, TrafficSource::ARC));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900279
280 auto svc = NewService(GuestMessage::ARC);
281 svc->Start(kTestPID);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900282 svc->OnDevicesChanged({"eth0"}, {});
283}
284
Garrick Evans02e6e872020-11-30 11:53:13 +0900285TEST_F(ArcServiceTest, ContainerImpl_ScanDevices) {
286 EXPECT_CALL(*datapath_, NetnsAttachName(_, _)).WillRepeatedly(Return(true));
287 EXPECT_CALL(*datapath_, ConnectVethPair(_, _, _, _, _, _, _, _))
288 .WillRepeatedly(Return(true));
289 EXPECT_CALL(*datapath_, AddBridge(_, _, _)).WillRepeatedly(Return(true));
290 EXPECT_CALL(*datapath_, AddToBridge(_, _)).WillRepeatedly(Return(true));
291
292 auto svc = NewService(GuestMessage::ARC);
293 svc->Start(kTestPID);
294 svc->OnDevicesChanged({"eth0", "wlan0"}, {});
295
296 std::vector<std::string> devs;
297 svc->ScanDevices(base::BindRepeating(
298 [](std::vector<std::string>* list, const Device& device) {
299 list->push_back(device.host_ifname());
300 },
301 &devs));
302
303 EXPECT_EQ(devs.size(), 2);
304 EXPECT_THAT(devs,
305 UnorderedElementsAre(StrEq("arc_eth0"), StrEq("arc_wlan0")));
306}
307
Garrick Evans209a80a2020-11-30 14:42:40 +0900308TEST_F(ArcServiceTest, ContainerImpl_DeviceHandler) {
309 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
318 svc->OnDevicesChanged({"eth0", "wlan0"}, {});
319 EXPECT_EQ(guest_devices_.size(), 2);
320 EXPECT_THAT(guest_devices_,
321 UnorderedElementsAre(
322 Pair(StrEq("arc_eth0"), Device::ChangeEvent::ADDED),
323 Pair(StrEq("arc_wlan0"), Device::ChangeEvent::ADDED)));
324
325 svc->OnDevicesChanged({}, {"wlan0"});
326 EXPECT_THAT(guest_devices_,
327 UnorderedElementsAre(
328 Pair(StrEq("arc_eth0"), Device::ChangeEvent::ADDED),
329 Pair(StrEq("arc_wlan0"), Device::ChangeEvent::REMOVED)));
330
331 guest_devices_.clear();
332 svc->OnDevicesChanged({"wlan0"}, {});
333 EXPECT_THAT(guest_devices_,
334 UnorderedElementsAre(
335 Pair(StrEq("arc_wlan0"), Device::ChangeEvent::ADDED)));
336}
337
Hugo Benichif0f10c72020-07-09 10:42:45 +0900338TEST_F(ArcServiceTest, ContainerImpl_StartAfterDevice) {
339 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
340 .WillOnce(Return(true));
341 // Expectations for arc0 setup.
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900342 EXPECT_CALL(*datapath_,
343 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetharc0"),
344 StrEq("arc0"), _, kArcGuestIP, 30, false))
345 .WillOnce(Return(true));
Hugo Benichif0f10c72020-07-09 10:42:45 +0900346 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
347 .WillOnce(Return(true));
Hugo Benichif0f10c72020-07-09 10:42:45 +0900348 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vetharc0")))
349 .WillOnce(Return(true));
350 // Expectations for eth0 setup.
Hugo Benichif0f10c72020-07-09 10:42:45 +0900351 EXPECT_CALL(*datapath_,
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900352 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetheth0"),
353 StrEq("eth0"), _, kFirstEthGuestIP, 30, false))
Hugo Benichif0f10c72020-07-09 10:42:45 +0900354 .WillOnce(Return(true));
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900355 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
Hugo Benichif0f10c72020-07-09 10:42:45 +0900356 .WillOnce(Return(true));
357 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_eth0"), StrEq("vetheth0")))
358 .WillOnce(Return(true));
359 EXPECT_CALL(forwarder_,
360 StartForwarding(StrEq("eth0"), StrEq("arc_eth0"), _, _));
Hugo Benichi8d622b52020-08-13 15:24:12 +0900361 EXPECT_CALL(*datapath_,
362 StartRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"),
363 kFirstEthGuestIP, TrafficSource::ARC));
Hugo Benichif0f10c72020-07-09 10:42:45 +0900364
365 auto svc = NewService(GuestMessage::ARC);
366 svc->OnDevicesChanged({"eth0"}, {});
367 svc->Start(kTestPID);
Garrick Evansb4eb3892019-11-13 12:07:07 +0900368}
369
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900370TEST_F(ArcServiceTest, ContainerImpl_Stop) {
Hugo Benichi33860d72020-07-09 16:34:01 +0900371 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
372 .WillOnce(Return(true));
373 EXPECT_CALL(*datapath_, NetnsDeleteName(StrEq("arc_netns")))
374 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900375 // Expectations for arc0 setup.
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900376 EXPECT_CALL(*datapath_,
377 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetharc0"),
378 StrEq("arc0"), _, kArcGuestIP, 30, false))
379 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900380 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
381 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900382 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vetharc0")))
383 .WillOnce(Return(true));
384 // Expectations for arc0 teardown.
385 EXPECT_CALL(*datapath_,
386 MaskInterfaceFlags(StrEq("arcbr0"), IFF_DEBUG, IFF_UP))
387 .WillOnce(Return(true));
Garrick Evans2f581a02020-05-11 10:43:35 +0900388 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vetharc0")));
Garrick Evans2e5c9ab2020-03-05 14:33:58 +0900389 EXPECT_CALL(forwarder_, StopForwarding(_, _, _, _)).Times(0);
Garrick Evanse94b6de2020-02-20 09:19:13 +0900390
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900391 auto svc = NewService(GuestMessage::ARC);
392 svc->Start(kTestPID);
393 svc->Stop(kTestPID);
Garrick Evansb4eb3892019-11-13 12:07:07 +0900394}
395
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900396TEST_F(ArcServiceTest, ContainerImpl_OnStopDevice) {
Hugo Benichi33860d72020-07-09 16:34:01 +0900397 EXPECT_CALL(*datapath_, NetnsAttachName(StrEq("arc_netns"), kTestPID))
398 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900399 // Expectations for arc0 setup.
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900400 EXPECT_CALL(*datapath_,
401 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetharc0"),
402 StrEq("arc0"), _, kArcGuestIP, 30, false))
403 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900404 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
405 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900406 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vetharc0")))
407 .WillOnce(Return(true));
408 // Expectations for eth0 setup.
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900409 EXPECT_CALL(*datapath_,
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900410 ConnectVethPair(kTestPID, StrEq("arc_netns"), StrEq("vetheth0"),
411 StrEq("eth0"), _, kFirstEthGuestIP, 30, false))
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900412 .WillOnce(Return(true));
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900413 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900414 .WillOnce(Return(true));
415 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_eth0"), StrEq("vetheth0")))
416 .WillOnce(Return(true));
417 // Expectations for eth0 teardown.
Garrick Evans2e5c9ab2020-03-05 14:33:58 +0900418 EXPECT_CALL(forwarder_,
419 StopForwarding(StrEq("eth0"), StrEq("arc_eth0"), _, _));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900420 EXPECT_CALL(*datapath_,
Hugo Benichi8d622b52020-08-13 15:24:12 +0900421 StopRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"),
422 Ipv4Addr(100, 115, 92, 6), TrafficSource::ARC));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900423 EXPECT_CALL(*datapath_, RemoveBridge(StrEq("arc_eth0")));
Garrick Evanse94b6de2020-02-20 09:19:13 +0900424
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900425 auto svc = NewService(GuestMessage::ARC);
426 svc->Start(kTestPID);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900427 svc->OnDevicesChanged({"eth0"}, {});
428 svc->OnDevicesChanged({}, {"eth0"});
Garrick Evansb4eb3892019-11-13 12:07:07 +0900429}
430
Garrick Evansb4eb3892019-11-13 12:07:07 +0900431// VM Impl
432
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900433TEST_F(ArcServiceTest, VmImpl_Start) {
434 // Expectations for tap devices pre-creation.
Garrick Evansc7071122020-04-17 12:31:57 +0900435 EXPECT_CALL(*datapath_, AddTAP(StrEq(""), _, nullptr, StrEq("crosvm")))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900436 .WillOnce(Return("vmtap0"))
437 .WillOnce(Return("vmtap1"))
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900438 .WillOnce(Return("vmtap2"))
439 .WillOnce(Return("vmtap3"))
440 .WillOnce(Return("vmtap4"))
441 .WillOnce(Return("vmtap5"));
442 // Expectations for "arc0" setup.
443 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900444 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900445 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vmtap0")))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900446 .WillOnce(Return(true));
447
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900448 auto svc = NewService(GuestMessage::ARC_VM);
449 svc->Start(kTestPID);
Garrick Evans2961c7c2020-04-03 11:34:40 +0900450}
451
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900452TEST_F(ArcServiceTest, VmImpl_StartDevice) {
453 // Expectations for tap devices pre-creation.
Garrick Evansc7071122020-04-17 12:31:57 +0900454 EXPECT_CALL(*datapath_, AddTAP(StrEq(""), _, nullptr, StrEq("crosvm")))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900455 .WillOnce(Return("vmtap0"))
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900456 .WillOnce(Return("vmtap1"))
457 .WillOnce(Return("vmtap2"))
458 .WillOnce(Return("vmtap3"))
459 .WillOnce(Return("vmtap4"))
460 .WillOnce(Return("vmtap5"));
461 // Expectations for "arc0" setup.
462 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900463 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900464 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vmtap0")))
465 .WillOnce(Return(true));
466 // Expectations for eth0 setup.
467 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900468 .WillOnce(Return(true));
469 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_eth0"), StrEq("vmtap1")))
470 .WillOnce(Return(true));
Hugo Benichi8d622b52020-08-13 15:24:12 +0900471 EXPECT_CALL(*datapath_, StartRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"),
472 Ipv4Addr(100, 115, 92, 6),
473 TrafficSource::ARC));
Garrick Evans2961c7c2020-04-03 11:34:40 +0900474 EXPECT_CALL(forwarder_,
475 StartForwarding(StrEq("eth0"), StrEq("arc_eth0"), _, _));
476
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900477 auto svc = NewService(GuestMessage::ARC_VM);
478 svc->Start(kTestPID);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900479 svc->OnDevicesChanged({"eth0"}, {});
Garrick Evans2961c7c2020-04-03 11:34:40 +0900480}
481
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900482TEST_F(ArcServiceTest, VmImpl_StartMultipleDevices) {
483 // Expectations for tap devices pre-creation.
Garrick Evansc7071122020-04-17 12:31:57 +0900484 EXPECT_CALL(*datapath_, AddTAP(StrEq(""), _, nullptr, StrEq("crosvm")))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900485 .WillOnce(Return("vmtap0"))
486 .WillOnce(Return("vmtap1"))
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900487 .WillOnce(Return("vmtap2"))
488 .WillOnce(Return("vmtap3"))
489 .WillOnce(Return("vmtap4"))
490 .WillOnce(Return("vmtap5"));
491 // Expectations for "arc0" setup.
492 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900493 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900494 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vmtap0")))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900495 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900496 // Expectations for eth0 setup.
497 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
498 .WillOnce(Return(true));
499 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_eth0"), StrEq("vmtap1")))
500 .WillOnce(Return(true));
Hugo Benichi8d622b52020-08-13 15:24:12 +0900501 EXPECT_CALL(*datapath_, StartRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"),
502 Ipv4Addr(100, 115, 92, 6),
503 TrafficSource::ARC));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900504 EXPECT_CALL(forwarder_,
505 StartForwarding(StrEq("eth0"), StrEq("arc_eth0"), _, _));
506 // Expectations for wlan0 setup.
507 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_wlan0"), kFirstWifiHostIP, 30))
508 .WillOnce(Return(true));
509 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_wlan0"), StrEq("vmtap3")))
510 .WillOnce(Return(true));
Hugo Benichi8d622b52020-08-13 15:24:12 +0900511 EXPECT_CALL(*datapath_, StartRoutingDevice(StrEq("wlan0"), StrEq("arc_wlan0"),
512 Ipv4Addr(100, 115, 92, 14),
513 TrafficSource::ARC));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900514 EXPECT_CALL(forwarder_,
515 StartForwarding(StrEq("wlan0"), StrEq("arc_wlan0"), _, _));
516 // Expectations for eth1 setup.
517 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth1"), kSecondEthHostIP, 30))
518 .WillOnce(Return(true));
519 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_eth1"), StrEq("vmtap2")))
520 .WillOnce(Return(true));
Hugo Benichi8d622b52020-08-13 15:24:12 +0900521 EXPECT_CALL(*datapath_, StartRoutingDevice(StrEq("eth1"), StrEq("arc_eth1"),
522 Ipv4Addr(100, 115, 92, 10),
523 TrafficSource::ARC));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900524 EXPECT_CALL(forwarder_,
525 StartForwarding(StrEq("eth1"), StrEq("arc_eth1"), _, _));
526
527 auto svc = NewService(GuestMessage::ARC_VM);
528 svc->Start(kTestPID);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900529 svc->OnDevicesChanged({"eth0"}, {});
530 svc->OnDevicesChanged({"wlan0"}, {});
531 svc->OnDevicesChanged({"eth1"}, {});
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900532}
533
534TEST_F(ArcServiceTest, VmImpl_Stop) {
535 // Expectations for tap devices pre-creation.
536 EXPECT_CALL(*datapath_, AddTAP(StrEq(""), _, nullptr, StrEq("crosvm")))
537 .WillOnce(Return("vmtap0"))
538 .WillOnce(Return("vmtap1"))
539 .WillOnce(Return("vmtap2"))
540 .WillOnce(Return("vmtap3"))
541 .WillOnce(Return("vmtap4"))
542 .WillOnce(Return("vmtap5"));
543 // Expectations for "arc0" setup.
544 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
545 .WillOnce(Return(true));
546 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vmtap0")))
547 .WillOnce(Return(true));
548 // Expectations for "arc0" teardown.
549 EXPECT_CALL(*datapath_,
550 MaskInterfaceFlags(StrEq("arcbr0"), IFF_DEBUG, IFF_UP))
551 .WillOnce(Return(true));
552 // Expectations for tap devices teardown
Garrick Evans2961c7c2020-04-03 11:34:40 +0900553 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vmtap0")));
554 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vmtap1")));
555 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vmtap2")));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900556 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vmtap3")));
557 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vmtap4")));
558 EXPECT_CALL(*datapath_, RemoveInterface(StrEq("vmtap5")));
Garrick Evans2961c7c2020-04-03 11:34:40 +0900559
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900560 auto svc = NewService(GuestMessage::ARC_VM);
561 svc->Start(kTestPID);
562 svc->Stop(kTestPID);
Garrick Evans2961c7c2020-04-03 11:34:40 +0900563}
564
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900565TEST_F(ArcServiceTest, VmImpl_StopDevice) {
566 // Expectations for tap devices pre-creation.
Garrick Evansc7071122020-04-17 12:31:57 +0900567 EXPECT_CALL(*datapath_, AddTAP(StrEq(""), _, nullptr, StrEq("crosvm")))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900568 .WillOnce(Return("vmtap0"))
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900569 .WillOnce(Return("vmtap1"))
570 .WillOnce(Return("vmtap2"))
571 .WillOnce(Return("vmtap3"))
572 .WillOnce(Return("vmtap4"))
573 .WillOnce(Return("vmtap5"));
574 // Expectations for "arc0" setup.
575 EXPECT_CALL(*datapath_, AddBridge(StrEq("arcbr0"), kArcHostIP, 30))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900576 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900577 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arcbr0"), StrEq("vmtap0")))
Garrick Evans2961c7c2020-04-03 11:34:40 +0900578 .WillOnce(Return(true));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900579 // Expectations for eth0 setup.
580 EXPECT_CALL(*datapath_, AddBridge(StrEq("arc_eth0"), kFirstEthHostIP, 30))
581 .WillOnce(Return(true));
582 EXPECT_CALL(*datapath_, AddToBridge(StrEq("arc_eth0"), StrEq("vmtap1")))
583 .WillOnce(Return(true));
Hugo Benichi8d622b52020-08-13 15:24:12 +0900584 EXPECT_CALL(*datapath_, StartRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"),
585 Ipv4Addr(100, 115, 92, 6),
586 TrafficSource::ARC));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900587 EXPECT_CALL(forwarder_,
588 StartForwarding(StrEq("eth0"), StrEq("arc_eth0"), _, _));
589 // Expectations for eth0 teardown.
Garrick Evans2961c7c2020-04-03 11:34:40 +0900590 EXPECT_CALL(forwarder_,
591 StopForwarding(StrEq("eth0"), StrEq("arc_eth0"), _, _));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900592 EXPECT_CALL(*datapath_,
Hugo Benichi8d622b52020-08-13 15:24:12 +0900593 StopRoutingDevice(StrEq("eth0"), StrEq("arc_eth0"),
594 Ipv4Addr(100, 115, 92, 6), TrafficSource::ARC));
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900595 EXPECT_CALL(*datapath_, RemoveBridge(StrEq("arc_eth0")));
Garrick Evans2961c7c2020-04-03 11:34:40 +0900596
Hugo Benichiad1bdd92020-06-12 13:48:37 +0900597 auto svc = NewService(GuestMessage::ARC_VM);
598 svc->Start(kTestPID);
Hugo Benichif0f10c72020-07-09 10:42:45 +0900599 svc->OnDevicesChanged({"eth0"}, {});
600 svc->OnDevicesChanged({}, {"eth0"});
Garrick Evans2961c7c2020-04-03 11:34:40 +0900601}
Garrick Evans3388a032020-03-24 11:25:55 +0900602
Garrick Evans02e6e872020-11-30 11:53:13 +0900603TEST_F(ArcServiceTest, VmImpl_ScanDevices) {
604 // Expectations for tap devices pre-creation.
605 EXPECT_CALL(*datapath_, AddTAP(StrEq(""), _, nullptr, StrEq("crosvm")))
606 .WillOnce(Return("vmtap0"))
607 .WillOnce(Return("vmtap1"))
608 .WillOnce(Return("vmtap2"))
609 .WillOnce(Return("vmtap3"))
610 .WillOnce(Return("vmtap4"))
611 .WillOnce(Return("vmtap5"));
612 EXPECT_CALL(*datapath_, AddBridge(_, _, _)).WillRepeatedly(Return(true));
613 EXPECT_CALL(*datapath_, AddToBridge(_, _)).WillRepeatedly(Return(true));
614
615 auto svc = NewService(GuestMessage::ARC_VM);
616 svc->Start(kTestPID);
617 svc->OnDevicesChanged({"eth0", "wlan0", "eth1"}, {});
618
619 std::vector<std::string> devs;
620 svc->ScanDevices(base::BindRepeating(
621 [](std::vector<std::string>* list, const Device& device) {
622 list->push_back(device.host_ifname());
623 },
624 &devs));
625
626 EXPECT_EQ(devs.size(), 3);
627 EXPECT_THAT(devs, UnorderedElementsAre(StrEq("arc_eth0"), StrEq("arc_wlan0"),
628 StrEq("arc_eth1")));
629}
630
Garrick Evans209a80a2020-11-30 14:42:40 +0900631TEST_F(ArcServiceTest, VmImpl_DeviceHandler) {
632 // Expectations for tap devices pre-creation.
633 EXPECT_CALL(*datapath_, AddTAP(StrEq(""), _, nullptr, StrEq("crosvm")))
634 .WillOnce(Return("vmtap0"))
635 .WillOnce(Return("vmtap1"))
636 .WillOnce(Return("vmtap2"))
637 .WillOnce(Return("vmtap3"))
638 .WillOnce(Return("vmtap4"))
639 .WillOnce(Return("vmtap5"));
640 EXPECT_CALL(*datapath_, AddBridge(_, _, _)).WillRepeatedly(Return(true));
641 EXPECT_CALL(*datapath_, AddToBridge(_, _)).WillRepeatedly(Return(true));
642
643 auto svc = NewService(GuestMessage::ARC_VM);
644 svc->Start(kTestPID);
645
646 svc->OnDevicesChanged({"eth0", "wlan0"}, {});
647 EXPECT_EQ(guest_devices_.size(), 2);
648 EXPECT_THAT(guest_devices_,
649 UnorderedElementsAre(
650 Pair(StrEq("arc_eth0"), Device::ChangeEvent::ADDED),
651 Pair(StrEq("arc_wlan0"), Device::ChangeEvent::ADDED)));
652
653 svc->OnDevicesChanged({}, {"wlan0"});
654 EXPECT_THAT(guest_devices_,
655 UnorderedElementsAre(
656 Pair(StrEq("arc_eth0"), Device::ChangeEvent::ADDED),
657 Pair(StrEq("arc_wlan0"), Device::ChangeEvent::REMOVED)));
658
659 guest_devices_.clear();
660 svc->OnDevicesChanged({"wlan0"}, {});
661 EXPECT_THAT(guest_devices_,
662 UnorderedElementsAre(
663 Pair(StrEq("arc_wlan0"), Device::ChangeEvent::ADDED)));
664}
665
Garrick Evans3388a032020-03-24 11:25:55 +0900666} // namespace patchpanel