blob: 58c40d6d5284826d489bc4a5917d84521fedb393 [file] [log] [blame]
Tom Hughes4f300e52020-08-24 18:08:59 -07001// Copyright 2018 The Chromium OS Authors. All rights reserved.
Armando Miragliacd70cfa2018-06-04 15:24:09 +02002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "permission_broker/fake_libusb_wrapper.h"
6#include "permission_broker/usb_control.h"
7
8#include <gtest/gtest.h>
9
10#include <string>
11#include <utility>
12
13#include <brillo/message_loops/fake_message_loop.h>
14#include <brillo/message_loops/message_loop.h>
15
16using ::testing::_;
17using ::testing::Invoke;
18using ::testing::Return;
19using ::testing::SetArgPointee;
20
21namespace permission_broker {
22
23class UsbControlTest : public testing::Test {
24 public:
Tom Hughes4f300e52020-08-24 18:08:59 -070025 UsbControlTest() : loop_(nullptr) { loop_.SetAsCurrent(); }
Qijiang Fan6bc59e12020-11-11 02:51:06 +090026 UsbControlTest(const UsbControlTest&) = delete;
27 UsbControlTest& operator=(const UsbControlTest&) = delete;
28
Armando Miragliacd70cfa2018-06-04 15:24:09 +020029 ~UsbControlTest() override = default;
30
31 protected:
32 brillo::FakeMessageLoop loop_;
Armando Miragliacd70cfa2018-06-04 15:24:09 +020033};
34
Garrick Evansd48463e2020-06-22 14:09:10 +090035TEST_F(UsbControlTest, DeviceNotAllowed) {
Armando Miragliacd70cfa2018-06-04 15:24:09 +020036 auto manager = std::make_unique<FakeUsbDeviceManager>(
37 std::vector<std::unique_ptr<UsbDeviceInterface>>());
38 UsbControl usb_control(std::move(manager));
39
Garrick Evansd48463e2020-06-22 14:09:10 +090040 EXPECT_FALSE(usb_control.IsDeviceAllowed(0x0, 0x0011));
41 EXPECT_FALSE(usb_control.IsDeviceAllowed(0x2bd9, 0x0));
Armando Miragliacd70cfa2018-06-04 15:24:09 +020042}
43
Garrick Evansd48463e2020-06-22 14:09:10 +090044TEST_F(UsbControlTest, DeviceAllowed) {
Armando Miragliacd70cfa2018-06-04 15:24:09 +020045 auto manager = std::make_unique<FakeUsbDeviceManager>(
46 std::vector<std::unique_ptr<UsbDeviceInterface>>());
47 UsbControl usb_control(std::move(manager));
48
Garrick Evansd48463e2020-06-22 14:09:10 +090049 EXPECT_TRUE(usb_control.IsDeviceAllowed(0x2bd9, 0x0011));
Armando Miragliacd70cfa2018-06-04 15:24:09 +020050}
51
52void TestResultCallback(std::shared_ptr<bool> result_out, bool result) {
53 *result_out = result;
54}
55
56TEST_F(UsbControlTest, PowerCycleSingleDeviceSucceeds) {
57 // Create the fake valid device that will be used together with the associated
58 // device parent.
59 // - Target device.
60 FakeUsbDevice::State state(false, false);
61 UsbDeviceInfo info(0x2bd9, 0x0011);
62 UsbDeviceInfo parent_info(0x1111, 0x2222, LIBUSB_CLASS_HUB);
Tom Hughes4f300e52020-08-24 18:08:59 -070063 auto valid_device =
64 std::make_unique<FakeUsbDevice>(info, parent_info, &state);
Armando Miragliacd70cfa2018-06-04 15:24:09 +020065 // Add the device into the vector of extracted devices and create a manager
66 // that is capable of returing such a vector.
67 std::vector<std::unique_ptr<UsbDeviceInterface>> devices;
68 devices.push_back(std::move(valid_device));
69 auto manager = std::make_unique<FakeUsbDeviceManager>(std::move(devices));
70
71 // Test that usb_control is correctly able to power-cycle the device.
72 UsbControl usb_control(std::move(manager));
73 std::shared_ptr<bool> result = std::make_shared<bool>(false);
Tom Hughes4f300e52020-08-24 18:08:59 -070074 usb_control.PowerCycleUsbPorts(base::Bind(&TestResultCallback, result),
75 0x2bd9, 0x0011,
76 base::TimeDelta::FromMilliseconds(1));
Armando Miragliacd70cfa2018-06-04 15:24:09 +020077
78 EXPECT_EQ(state.power_off_counter, 1);
79 EXPECT_EQ(state.power_on_counter, 0);
80
81 loop_.RunOnce(true);
82
83 EXPECT_EQ(state.power_off_counter, 1);
84 EXPECT_EQ(state.power_on_counter, 1);
85 EXPECT_TRUE(*result);
86}
87
88TEST_F(UsbControlTest, PowerCycleMultipleDevicesSucceed) {
89 // Create two fake valid devices that will be used together with the
90 // associated device parent.
91 // - First target device.
92 UsbDeviceInfo info(0x2bd9, 0x0011);
93 UsbDeviceInfo parent_info(0x1111, 0x2222, LIBUSB_CLASS_HUB);
94 FakeUsbDevice::State state1(false, false);
Tom Hughes4f300e52020-08-24 18:08:59 -070095 auto valid_device1 =
96 std::make_unique<FakeUsbDevice>(info, parent_info, &state1);
Armando Miragliacd70cfa2018-06-04 15:24:09 +020097 // - Second target device.
98 FakeUsbDevice::State state2(false, false);
Tom Hughes4f300e52020-08-24 18:08:59 -070099 auto valid_device2 =
100 std::make_unique<FakeUsbDevice>(info, parent_info, &state2);
Armando Miragliacd70cfa2018-06-04 15:24:09 +0200101 // Add the device into the vector of extracted devices and create a manager
102 // that is capable of returing such a vector.
103 std::vector<std::unique_ptr<UsbDeviceInterface>> devices;
104 devices.push_back(std::move(valid_device1));
105 devices.push_back(std::move(valid_device2));
106 auto manager = std::make_unique<FakeUsbDeviceManager>(std::move(devices));
107
108 // Test that usb_control is correctly able to power-cycle the device.
109 UsbControl usb_control(std::move(manager));
110 std::shared_ptr<bool> result = std::make_shared<bool>(false);
Tom Hughes4f300e52020-08-24 18:08:59 -0700111 usb_control.PowerCycleUsbPorts(base::Bind(&TestResultCallback, result),
112 0x2bd9, 0x0011,
113 base::TimeDelta::FromMilliseconds(1));
Armando Miragliacd70cfa2018-06-04 15:24:09 +0200114
115 EXPECT_EQ(state1.power_off_counter, 1);
116 EXPECT_EQ(state1.power_on_counter, 0);
117 EXPECT_EQ(state2.power_off_counter, 1);
118 EXPECT_EQ(state2.power_on_counter, 0);
119
120 loop_.RunOnce(true);
121
122 EXPECT_EQ(state1.power_off_counter, 1);
123 EXPECT_EQ(state1.power_on_counter, 1);
124 EXPECT_EQ(state2.power_off_counter, 1);
125 EXPECT_EQ(state2.power_on_counter, 1);
126 EXPECT_TRUE(*result);
127}
128
129TEST_F(UsbControlTest, DeviceNotFound) {
130 // Create a fake manager that returns an empty vector when querying the
131 // available USB devices.
132 std::vector<std::unique_ptr<UsbDeviceInterface>> devices;
133 auto manager = std::make_unique<FakeUsbDeviceManager>(std::move(devices));
134
135 // Test that usb_control is not able to apply the requested operation because
136 // the device is not available.
137 UsbControl usb_control(std::move(manager));
138 std::shared_ptr<bool> result = std::make_shared<bool>(false);
Tom Hughes4f300e52020-08-24 18:08:59 -0700139 usb_control.PowerCycleUsbPorts(base::Bind(&TestResultCallback, result),
140 0x2bd9, 0x0011,
141 base::TimeDelta::FromMilliseconds(1));
Armando Miragliacd70cfa2018-06-04 15:24:09 +0200142
143 EXPECT_FALSE(*result);
144}
145
Garrick Evansd48463e2020-06-22 14:09:10 +0900146TEST_F(UsbControlTest, PowerCycleNotAllowedDevice) {
147 // Set up a target device that was not allowed.
Armando Miragliacd70cfa2018-06-04 15:24:09 +0200148 FakeUsbDevice::State state(false, false);
149 UsbDeviceInfo info(0x1234, 0x5678);
150 UsbDeviceInfo parent_info;
Tom Hughes4f300e52020-08-24 18:08:59 -0700151 auto invalid_device =
152 std::make_unique<FakeUsbDevice>(info, parent_info, &state);
Armando Miragliacd70cfa2018-06-04 15:24:09 +0200153
154 std::vector<std::unique_ptr<UsbDeviceInterface>> devices;
155 devices.push_back(std::move(invalid_device));
156 auto manager = std::make_unique<FakeUsbDeviceManager>(std::move(devices));
157
158 // Test that usb_control unable to powercycle the device that is not
Garrick Evansd48463e2020-06-22 14:09:10 +0900159 // allowed.
Armando Miragliacd70cfa2018-06-04 15:24:09 +0200160 UsbControl usb_control(std::move(manager));
161 std::shared_ptr<bool> result = std::make_shared<bool>(false);
Tom Hughes4f300e52020-08-24 18:08:59 -0700162 usb_control.PowerCycleUsbPorts(base::Bind(&TestResultCallback, result),
163 0x1234, 0x5678,
164 base::TimeDelta::FromMilliseconds(1));
Armando Miragliacd70cfa2018-06-04 15:24:09 +0200165
166 EXPECT_EQ(state.power_off_counter, 0);
167 EXPECT_EQ(state.power_on_counter, 0);
168 EXPECT_FALSE(*result);
169}
170
171TEST_F(UsbControlTest, PowerOffFails) {
172 // Create the fake valid device that will be used together with the associated
173 // device parent.
174 // - Target device.
175 FakeUsbDevice::State state(true, false);
176 UsbDeviceInfo info(0x2bd9, 0x0011);
177 UsbDeviceInfo parent_info(0x1111, 0x2222, LIBUSB_CLASS_HUB);
Tom Hughes4f300e52020-08-24 18:08:59 -0700178 auto device = std::make_unique<FakeUsbDevice>(info, parent_info, &state);
Armando Miragliacd70cfa2018-06-04 15:24:09 +0200179
180 std::vector<std::unique_ptr<UsbDeviceInterface>> devices;
181 devices.push_back(std::move(device));
182 auto manager = std::make_unique<FakeUsbDeviceManager>(std::move(devices));
183
184 // Test that usb_control will return false when the device to be powercycled
185 // failes to turn off.
186 std::shared_ptr<bool> result = std::make_shared<bool>(false);
187 UsbControl usb_control(std::move(manager));
Tom Hughes4f300e52020-08-24 18:08:59 -0700188 usb_control.PowerCycleUsbPorts(base::Bind(&TestResultCallback, result),
189 0x2bd9, 0x0011,
190 base::TimeDelta::FromMilliseconds(1));
Armando Miragliacd70cfa2018-06-04 15:24:09 +0200191
192 EXPECT_EQ(state.power_off_counter, 1);
193 EXPECT_EQ(state.power_on_counter, 0);
194
195 loop_.RunOnce(true);
196
197 EXPECT_EQ(state.power_off_counter, 1);
198 EXPECT_EQ(state.power_on_counter, 1);
199 EXPECT_FALSE(*result);
200}
201
202TEST_F(UsbControlTest, PowerOnFails) {
203 // Create the fake valid device that will be used together with the associated
204 // device parent.
205 // - Target device.
206 FakeUsbDevice::State state(false, true);
207 UsbDeviceInfo info(0x2bd9, 0x0011);
208 UsbDeviceInfo parent_info(0x1111, 0x2222, LIBUSB_CLASS_HUB);
Tom Hughes4f300e52020-08-24 18:08:59 -0700209 auto device = std::make_unique<FakeUsbDevice>(info, parent_info, &state);
Armando Miragliacd70cfa2018-06-04 15:24:09 +0200210
211 std::vector<std::unique_ptr<UsbDeviceInterface>> devices;
212 devices.push_back(std::move(device));
213 auto manager = std::make_unique<FakeUsbDeviceManager>(std::move(devices));
214
215 // Test that usb_control will return false when the device to be powercycled
216 // failes to turn on.
217 std::shared_ptr<bool> result = std::make_shared<bool>(false);
218 UsbControl usb_control(std::move(manager));
Tom Hughes4f300e52020-08-24 18:08:59 -0700219 usb_control.PowerCycleUsbPorts(base::Bind(&TestResultCallback, result),
220 0x2bd9, 0x0011,
221 base::TimeDelta::FromMilliseconds(1));
Armando Miragliacd70cfa2018-06-04 15:24:09 +0200222
223 EXPECT_EQ(state.power_off_counter, 1);
224 EXPECT_EQ(state.power_on_counter, 0);
225
226 loop_.RunOnce(true);
227
228 EXPECT_EQ(state.power_off_counter, 1);
229 EXPECT_EQ(state.power_on_counter, 1);
230 EXPECT_FALSE(*result);
231}
232
233} // namespace permission_broker