1 /*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <android-base/logging.h>
18 #include <android-base/strings.h>
19 #include <android/hardware/automotive/can/1.0/ICanBus.h>
20 #include <android/hardware/automotive/can/1.0/ICanController.h>
21 #include <android/hardware/automotive/can/1.0/types.h>
22 #include <android/hidl/manager/1.2/IServiceManager.h>
23 #include <can-vts-utils/bus-enumerator.h>
24 #include <can-vts-utils/can-hal-printers.h>
25 #include <gmock/gmock.h>
26 #include <hidl-utils/hidl-utils.h>
27 #include <hidl/GtestPrinter.h>
28 #include <hidl/ServiceManagement.h>
29
30 namespace android::hardware::automotive::can::V1_0::vts {
31
32 using hardware::hidl_vec;
33 using InterfaceType = ICanController::InterfaceType;
34 using IfId = ICanController::BusConfig::InterfaceId;
35
36 struct Bus {
37 DISALLOW_COPY_AND_ASSIGN(Bus);
38
Busandroid::hardware::automotive::can::V1_0::vts::Bus39 Bus(sp<ICanController> controller, const ICanController::BusConfig& config)
40 : mIfname(config.name), mController(controller) {
41 // Don't bring up the bus, we just need a wrapper for the ICanBus object
42 /* Not using ICanBus::getService here, since it ignores interfaces not in the manifest
43 * file -- this is a test, so we don't want to add fake services to a device manifest. */
44 auto manager = hidl::manager::V1_2::IServiceManager::getService();
45 auto service = manager->get(ICanBus::descriptor, config.name);
46 mBus = ICanBus::castFrom(service);
47 }
48
operator ->android::hardware::automotive::can::V1_0::vts::Bus49 ICanBus* operator->() const { return mBus.get(); }
getandroid::hardware::automotive::can::V1_0::vts::Bus50 sp<ICanBus> get() { return mBus; }
51
sendandroid::hardware::automotive::can::V1_0::vts::Bus52 Return<Result> send(const CanMessage& msg) { return mBus->send(msg); }
53
54 private:
55 const std::string mIfname;
56 sp<ICanController> mController;
57 sp<ICanBus> mBus;
58 };
59
60 class CanControllerHalTest : public ::testing::TestWithParam<std::string> {
61 protected:
62 virtual void SetUp() override;
63 virtual void TearDown() override;
64 static void SetUpTestCase();
65
66 Bus makeBus(const std::string ifaceName);
67
68 hidl_vec<InterfaceType> getSupportedInterfaceTypes();
69 bool isSupported(InterfaceType iftype);
70
71 bool up(InterfaceType iftype, const std::string srvname, std::string ifname,
72 ICanController::Result expected);
73 void assertRegistered(const std::string srvname, const std::string ifaceName,
74 bool expectRegistered);
75
76 sp<ICanController> mCanController;
77 static hidl_vec<hidl_string> mBusNames;
78
79 private:
80 static bool mTestCaseInitialized;
81 };
82
83 hidl_vec<hidl_string> CanControllerHalTest::mBusNames;
84 bool CanControllerHalTest::mTestCaseInitialized = false;
85
SetUp()86 void CanControllerHalTest::SetUp() {
87 ASSERT_TRUE(mTestCaseInitialized);
88
89 mCanController = ICanController::getService(GetParam());
90 ASSERT_TRUE(mCanController) << "Couldn't open CAN Controller: " << GetParam();
91 }
92
TearDown()93 void CanControllerHalTest::TearDown() {
94 mCanController.clear();
95 }
96
SetUpTestCase()97 void CanControllerHalTest::SetUpTestCase() {
98 mBusNames = utils::getBusNames();
99 ASSERT_NE(0u, mBusNames.size()) << "No ICanBus HALs defined in device manifest";
100
101 mTestCaseInitialized = true;
102 }
103
getSupportedInterfaceTypes()104 hidl_vec<InterfaceType> CanControllerHalTest::getSupportedInterfaceTypes() {
105 hidl_vec<InterfaceType> iftypesResult;
106 mCanController->getSupportedInterfaceTypes(hidl_utils::fill(&iftypesResult)).assertOk();
107 return iftypesResult;
108 }
109
isSupported(InterfaceType iftype)110 bool CanControllerHalTest::isSupported(InterfaceType iftype) {
111 const auto supported = getSupportedInterfaceTypes();
112 return std::find(supported.begin(), supported.end(), iftype) != supported.end();
113 }
114
up(InterfaceType iftype,std::string srvname,std::string ifname,ICanController::Result expected)115 bool CanControllerHalTest::up(InterfaceType iftype, std::string srvname, std::string ifname,
116 ICanController::Result expected) {
117 ICanController::BusConfig config = {};
118 config.name = srvname;
119
120 // TODO(b/146214370): move interfaceId constructors to a library
121 if (iftype == InterfaceType::SOCKETCAN) {
122 IfId::Socketcan socketcan = {};
123 socketcan.ifname(ifname);
124 config.interfaceId.socketcan(socketcan);
125 } else if (iftype == InterfaceType::SLCAN) {
126 IfId::Slcan slcan = {};
127 slcan.ttyname(ifname);
128 config.interfaceId.slcan(slcan);
129 } else if (iftype == InterfaceType::VIRTUAL) {
130 config.interfaceId.virtualif({ifname});
131 } else {
132 EXPECT_TRUE(false) << "Unexpected iftype: " << toString(iftype);
133 }
134
135 const auto upresult = mCanController->upInterface(config);
136
137 if (!isSupported(iftype)) {
138 LOG(INFO) << iftype << " interfaces not supported";
139 EXPECT_EQ(ICanController::Result::NOT_SUPPORTED, upresult);
140 return false;
141 }
142
143 EXPECT_EQ(expected, upresult);
144 return true;
145 }
146
assertRegistered(const std::string srvname,const std::string ifaceName,bool expectRegistered)147 void CanControllerHalTest::assertRegistered(const std::string srvname, const std::string ifaceName,
148 bool expectRegistered) {
149 /* Not using ICanBus::tryGetService here, since it ignores interfaces not in the manifest
150 * file -- this is a test, so we don't want to add fake services to a device manifest. */
151 auto manager = hidl::manager::V1_2::IServiceManager::getService();
152 auto busService = manager->get(ICanBus::descriptor, srvname);
153 if (!expectRegistered) {
154 /* We can't unregister a HIDL interface defined in the manifest, so we'll just check to make
155 * sure that the interface behind it is down */
156 auto bus = makeBus(ifaceName);
157 const auto result = bus->send({});
158 ASSERT_EQ(Result::INTERFACE_DOWN, result);
159 return;
160 }
161 ASSERT_EQ(expectRegistered, busService.withDefault(nullptr) != nullptr)
162 << "ICanBus/" << srvname << (expectRegistered ? " is not " : " is ") << "registered"
163 << " (should be otherwise)";
164 }
165
makeBus(const std::string ifaceName)166 Bus CanControllerHalTest::makeBus(const std::string ifaceName) {
167 ICanController::BusConfig config = {};
168 config.name = mBusNames[0];
169 config.interfaceId.virtualif({ifaceName});
170
171 return Bus(mCanController, config);
172 }
173
TEST_P(CanControllerHalTest,SupportsSomething)174 TEST_P(CanControllerHalTest, SupportsSomething) {
175 const auto supported = getSupportedInterfaceTypes();
176 ASSERT_GT(supported.size(), 0u);
177 }
178
TEST_P(CanControllerHalTest,BringUpDown)179 TEST_P(CanControllerHalTest, BringUpDown) {
180 const std::string name = mBusNames[0];
181 const std::string iface = "vcan57";
182 mCanController->downInterface(name);
183
184 assertRegistered(name, iface, false);
185
186 if (!up(InterfaceType::VIRTUAL, name, iface, ICanController::Result::OK)) GTEST_SKIP();
187 assertRegistered(name, iface, true);
188
189 const auto dnresult = mCanController->downInterface(name);
190 ASSERT_TRUE(dnresult);
191 assertRegistered(name, iface, false);
192 }
193
TEST_P(CanControllerHalTest,DownFake)194 TEST_P(CanControllerHalTest, DownFake) {
195 const auto result = mCanController->downInterface("imnotup");
196 ASSERT_FALSE(result);
197 }
198
TEST_P(CanControllerHalTest,UpTwice)199 TEST_P(CanControllerHalTest, UpTwice) {
200 const std::string name = mBusNames[0];
201 const std::string iface = "vcan72";
202
203 assertRegistered(name, iface, false);
204 if (!up(InterfaceType::VIRTUAL, name, iface, ICanController::Result::OK)) GTEST_SKIP();
205 assertRegistered(name, iface, true);
206 if (!up(InterfaceType::VIRTUAL, name, "vcan73", ICanController::Result::INVALID_STATE)) {
207 GTEST_SKIP();
208 }
209 assertRegistered(name, iface, true);
210
211 const auto result = mCanController->downInterface(name);
212 ASSERT_TRUE(result);
213 assertRegistered(name, iface, false);
214 }
215
TEST_P(CanControllerHalTest,ConfigCompatibility)216 TEST_P(CanControllerHalTest, ConfigCompatibility) {
217 // using random-ish addresses, which may not be valid - we can't test the success case
218 // TODO(b/146214370): move interfaceId constructors to a library
219 IfId virtualCfg = {};
220 virtualCfg.virtualif({"vcan70"});
221
222 IfId::Socketcan socketcanIfname = {};
223 socketcanIfname.ifname("can0");
224 IfId socketcanIfnameCfg = {};
225 socketcanIfnameCfg.socketcan(socketcanIfname);
226
227 IfId::Socketcan socketcanSerial = {};
228 socketcanSerial.serialno({"1234", "2345"});
229 IfId socketcanSerialCfg = {};
230 socketcanSerialCfg.socketcan(socketcanSerial);
231
232 IfId::Slcan slcanTtyname = {};
233 slcanTtyname.ttyname("/dev/ttyUSB0");
234 IfId slcanTtynameCfg = {};
235 slcanTtynameCfg.slcan(slcanTtyname);
236
237 IfId::Slcan slcanSerial = {};
238 slcanSerial.serialno({"dead", "beef"});
239 IfId slcanSerialCfg = {};
240 slcanSerialCfg.slcan(slcanSerial);
241
242 IfId indexedCfg = {};
243 indexedCfg.indexed({0});
244
245 static const std::vector<std::pair<InterfaceType, IfId>> compatMatrix = {
246 {InterfaceType::VIRTUAL, virtualCfg},
247 {InterfaceType::SOCKETCAN, socketcanIfnameCfg},
248 {InterfaceType::SOCKETCAN, socketcanSerialCfg},
249 {InterfaceType::SLCAN, slcanTtynameCfg},
250 {InterfaceType::SLCAN, slcanSerialCfg},
251 {InterfaceType::INDEXED, indexedCfg},
252 };
253
254 for (const auto [iftype, cfg] : compatMatrix) {
255 LOG(INFO) << "Compatibility testing: " << iftype << " / " << cfg;
256
257 ICanController::BusConfig config = {};
258 config.name = "compattestsrv";
259 config.bitrate = 125000;
260 config.interfaceId = cfg;
261
262 const auto upresult = mCanController->upInterface(config);
263
264 if (!isSupported(iftype)) {
265 ASSERT_EQ(ICanController::Result::NOT_SUPPORTED, upresult);
266 continue;
267 }
268 ASSERT_NE(ICanController::Result::NOT_SUPPORTED, upresult);
269
270 if (upresult == ICanController::Result::OK) {
271 const auto dnresult = mCanController->downInterface(config.name);
272 ASSERT_TRUE(dnresult);
273 continue;
274 }
275 }
276 }
277
TEST_P(CanControllerHalTest,FailEmptyName)278 TEST_P(CanControllerHalTest, FailEmptyName) {
279 const std::string name = "";
280 const std::string iface = "vcan57";
281
282 assertRegistered(name, iface, false);
283 if (!up(InterfaceType::VIRTUAL, name, iface, ICanController::Result::BAD_SERVICE_NAME)) {
284 GTEST_SKIP();
285 }
286 assertRegistered(name, iface, false);
287 }
288
TEST_P(CanControllerHalTest,FailBadName)289 TEST_P(CanControllerHalTest, FailBadName) {
290 // 33 characters (name can be at most 32 characters long)
291 const std::string name = "ab012345678901234567890123456789c";
292 const std::string iface = "vcan57";
293
294 assertRegistered(name, iface, false);
295 if (!up(InterfaceType::VIRTUAL, name, iface, ICanController::Result::BAD_SERVICE_NAME)) {
296 GTEST_SKIP();
297 }
298 assertRegistered(name, iface, false);
299 }
300
TEST_P(CanControllerHalTest,FailBadVirtualAddress)301 TEST_P(CanControllerHalTest, FailBadVirtualAddress) {
302 const std::string name = mBusNames[0];
303 const std::string iface = "";
304
305 assertRegistered(name, iface, false);
306 if (!up(InterfaceType::VIRTUAL, name, iface, ICanController::Result::BAD_INTERFACE_ID)) {
307 GTEST_SKIP();
308 }
309 assertRegistered(name, iface, false);
310 }
311
TEST_P(CanControllerHalTest,FailBadSocketcanAddress)312 TEST_P(CanControllerHalTest, FailBadSocketcanAddress) {
313 const std::string name = mBusNames[0];
314 const std::string iface = "can87";
315
316 assertRegistered(name, iface, false);
317 if (!up(InterfaceType::SOCKETCAN, name, iface, ICanController::Result::BAD_INTERFACE_ID)) {
318 GTEST_SKIP();
319 }
320 assertRegistered(name, iface, false);
321
322 auto supported =
323 up(InterfaceType::SOCKETCAN, name, "", ICanController::Result::BAD_INTERFACE_ID);
324 ASSERT_TRUE(supported);
325 assertRegistered(name, iface, false);
326 }
327
TEST_P(CanControllerHalTest,FailBadSlcanAddress)328 TEST_P(CanControllerHalTest, FailBadSlcanAddress) {
329 const std::string name = mBusNames[0];
330 const std::string iface = "/dev/shouldnotexist123";
331
332 assertRegistered(name, iface, false);
333 if (!up(InterfaceType::SLCAN, name, iface, ICanController::Result::BAD_INTERFACE_ID)) {
334 GTEST_SKIP();
335 }
336 assertRegistered(name, iface, false);
337
338 auto supported = up(InterfaceType::SLCAN, name, "", ICanController::Result::BAD_INTERFACE_ID);
339 ASSERT_TRUE(supported);
340 assertRegistered(name, iface, false);
341 }
342
343 /**
344 * Example manual invocation:
345 * adb shell /data/nativetest64/VtsHalCanControllerV1_0TargetTest/VtsHalCanControllerV1_0TargetTest
346 */
347 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(CanControllerHalTest);
348 INSTANTIATE_TEST_SUITE_P(PerInstance, CanControllerHalTest,
349 testing::ValuesIn(getAllHalInstanceNames(ICanController::descriptor)),
350 PrintInstanceNameToString);
351
352 } // namespace android::hardware::automotive::can::V1_0::vts
353