• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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