1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <libudev.h>
17 
18 #include <gmock/gmock.h>
19 #include <gtest/gtest.h>
20 
21 #include "test_device.h"
22 
23 using ::testing::ext::TestSize;
24 
25 class UdevTestDevice : public TestDevice {
26 public:
UdevTestDevice()27     UdevTestDevice()
28     {
29         udev_ = udev_new();
30     }
31 
~UdevTestDevice()32     ~UdevTestDevice()
33     {
34         if (udevDevice_ != nullptr) {
35             udevDevice_ = udev_device_unref(udevDevice_);
36         }
37         udev_unref(udev_);
38     }
39 
Init(bool def = true)40     void Init(bool def = true)
41     {
42         ASSERT_NE(udev_, nullptr);
43         ASSERT_NO_FATAL_FAILURE(TestDevice::Init(def));
44         udevDevice_ = udev_device_new_from_devnum(udev_, 'c', GetDevNum());
45         ASSERT_NE(udevDevice_, nullptr);
46     }
47 
GetUdev() const48     auto GetUdev() const
49     {
50         return udev_;
51     }
52 
GetDevice() const53     auto GetDevice() const
54     {
55         return udevDevice_;
56     }
57 
58 private:
59     struct udev* udev_{};
60     struct udev_device* udevDevice_{};
61 };
62 
63 class CustomUdevTest : public ::testing::Test {
64 public:
65     UdevTestDevice testDevice_;
66 };
67 
68 /*
69  * Tests:
70  * udev_device_new_from_devnum (uses udev_device_new_from_syspath)
71  * udev_device_get_udev
72  * udev_device_ref
73  * udev_device_unref
74  */
HWTEST_F(CustomUdevTest, TestBasics, TestSize.Level1)75 HWTEST_F(CustomUdevTest, TestBasics, TestSize.Level1)
76 {
77     ASSERT_NO_FATAL_FAILURE(testDevice_.Init());
78     auto* device = testDevice_.GetDevice();
79 
80     EXPECT_EQ(udev_device_get_udev(device), testDevice_.GetUdev());
81 
82     auto* res = udev_device_ref(device);
83     EXPECT_NE(res, nullptr);
84     EXPECT_EQ(res, device);
85 
86     res = udev_device_unref(device);
87     EXPECT_EQ(res, nullptr);
88 }
89 
90 /*
91  * Tests negative cases for:
92  * udev_device_new_from_devnum (uses udev_device_new_from_syspath)
93  * udev_device_get_udev
94  * udev_device_ref
95  * udev_device_unref
96  */
HWTEST_F(CustomUdevTest, TestBasicsFail, TestSize.Level1)97 HWTEST_F(CustomUdevTest, TestBasicsFail, TestSize.Level1)
98 {
99     errno = 0;
100     EXPECT_EQ(udev_device_get_udev(nullptr), nullptr);
101     EXPECT_NE(errno, 0);
102 
103     errno = 0;
104     EXPECT_EQ(udev_device_ref(nullptr), nullptr);
105     EXPECT_EQ(errno, 0);
106 
107     errno = 0;
108     EXPECT_EQ(udev_device_unref(nullptr), nullptr);
109     EXPECT_EQ(errno, 0);
110 }
111 
112 /*
113  * Tests negative cases for:
114  * udev_device_new_from_devnum
115  */
HWTEST_F(CustomUdevTest, TestNewFail1, TestSize.Level1)116 HWTEST_F(CustomUdevTest, TestNewFail1, TestSize.Level1)
117 {
118     ASSERT_NO_FATAL_FAILURE(testDevice_.Init());
119     auto* device = testDevice_.GetDevice();
120     auto devnum = testDevice_.GetDevNum();
121     auto* udev = udev_device_get_udev(device);
122     ASSERT_NE(udev, nullptr);
123 
124     errno = 0;
125     EXPECT_EQ(udev_device_new_from_devnum(nullptr, 'c', devnum), nullptr);
126     EXPECT_EQ(errno, EINVAL);
127 
128     errno = 0;
129     // Invalid device type
130     EXPECT_EQ(udev_device_new_from_devnum(udev, 'a', devnum), nullptr);
131     EXPECT_EQ(errno, EINVAL);
132 
133     errno = 0;
134     // Wrong devnum
135     EXPECT_EQ(udev_device_new_from_devnum(udev, 'b', devnum), nullptr);
136     EXPECT_EQ(errno, ENOENT);
137 
138     errno = 0;
139     // Invalid devnum
140     EXPECT_EQ(udev_device_new_from_devnum(udev, 'c', 0), nullptr);
141     EXPECT_EQ(errno, ENOENT);
142 }
143 
144 /*
145  * Tests negative cases for:
146  * udev_device_new_from_syspath
147  */
HWTEST_F(CustomUdevTest, TestNewFail2, TestSize.Level1)148 HWTEST_F(CustomUdevTest, TestNewFail2, TestSize.Level1)
149 {
150     ASSERT_NO_FATAL_FAILURE(testDevice_.Init());
151     auto* udev = udev_device_get_udev(testDevice_.GetDevice());
152     ASSERT_NE(udev, nullptr);
153 
154     errno = 0;
155     EXPECT_EQ(udev_device_new_from_syspath(nullptr, testDevice_.GetSysPath()), nullptr);
156     EXPECT_EQ(errno, EINVAL);
157 
158     errno = 0;
159     EXPECT_EQ(udev_device_new_from_syspath(udev, nullptr), nullptr);
160     EXPECT_EQ(errno, EINVAL);
161 
162     errno = 0;
163     EXPECT_EQ(udev_device_new_from_syspath(udev, "/system"), nullptr);
164     EXPECT_EQ(errno, EINVAL);
165 
166     errno = 0;
167     EXPECT_EQ(udev_device_new_from_syspath(udev, "/sys/unknown"), nullptr);
168     EXPECT_EQ(errno, ENOENT);
169 
170     errno = 0;
171     EXPECT_EQ(udev_device_new_from_syspath(udev, "/sys/char/0:0"), nullptr);
172     EXPECT_EQ(errno, ENOENT);
173 }
174 
175 /*
176  * Tests:
177  * udev_device_get_is_initialized()
178  */
HWTEST_F(CustomUdevTest, TestIsInitialized, TestSize.Level1)179 HWTEST_F(CustomUdevTest, TestIsInitialized, TestSize.Level1)
180 {
181     ASSERT_NO_FATAL_FAILURE(testDevice_.Init());
182     auto* device = testDevice_.GetDevice();
183 
184     EXPECT_EQ(udev_device_get_is_initialized(device), 1);
185 
186     errno = 0;
187     EXPECT_LT(udev_device_get_is_initialized(nullptr), 0);
188     EXPECT_EQ(errno, 0);
189 }
190 
191 /*
192  * Tests:
193  * udev_device_get_devnode()
194  */
HWTEST_F(CustomUdevTest, TestGetDevnode, TestSize.Level1)195 HWTEST_F(CustomUdevTest, TestGetDevnode, TestSize.Level1)
196 {
197     ASSERT_NO_FATAL_FAILURE(testDevice_.Init());
198     auto* device = testDevice_.GetDevice();
199 
200     EXPECT_STREQ(udev_device_get_devnode(device), testDevice_.GetDevNode());
201 
202     errno = 0;
203     EXPECT_EQ(udev_device_get_devnode(nullptr), nullptr);
204     EXPECT_EQ(errno, 0);
205 }
206 
207 /*
208  * Test for:
209  * udev_device_get_sysname()
210  */
HWTEST_F(CustomUdevTest, TestGetSysname, TestSize.Level1)211 HWTEST_F(CustomUdevTest, TestGetSysname, TestSize.Level1)
212 {
213     ASSERT_NO_FATAL_FAILURE(testDevice_.Init());
214     auto* device = testDevice_.GetDevice();
215 
216     EXPECT_EQ(std::string("/dev/input/") + udev_device_get_sysname(device), testDevice_.GetDevNode());
217 
218     errno = 0;
219     EXPECT_EQ(udev_device_get_sysname(nullptr), nullptr);
220     EXPECT_EQ(errno, 0);
221 }
222 
223 /*
224  * Test for:
225  * udev_device_get_syspath()
226  */
HWTEST_F(CustomUdevTest, TestGetSyspath, TestSize.Level1)227 HWTEST_F(CustomUdevTest, TestGetSyspath, TestSize.Level1)
228 {
229     ASSERT_NO_FATAL_FAILURE(testDevice_.Init());
230     auto* device = testDevice_.GetDevice();
231 
232     EXPECT_EQ(udev_device_get_syspath(device),
233         testDevice_.GetSysPath() + std::string("/") + udev_device_get_sysname(device));
234 
235     errno = 0;
236     EXPECT_EQ(udev_device_get_syspath(nullptr), nullptr);
237     EXPECT_EQ(errno, 0);
238 }
239 
240 /*
241  * Test for:
242  * udev_device_get_property_value()
243  * Properties:
244  * - DEVNAME
245  * - MAJOR
246  * - MINOR
247  */
HWTEST_F(CustomUdevTest, TestGetProperty, TestSize.Level1)248 HWTEST_F(CustomUdevTest, TestGetProperty, TestSize.Level1)
249 {
250     ASSERT_NO_FATAL_FAILURE(testDevice_.Init());
251     auto* device = testDevice_.GetDevice();
252 
253     EXPECT_STREQ(udev_device_get_property_value(device, "DEVNAME"), testDevice_.GetDevNode());
254 
255     auto devnum = testDevice_.GetDevNum();
256     EXPECT_EQ(udev_device_get_property_value(device, "MINOR"), std::to_string(minor(devnum)));
257     EXPECT_EQ(udev_device_get_property_value(device, "MAJOR"), std::to_string(major(devnum)));
258 
259     errno = 0;
260     EXPECT_EQ(udev_device_get_property_value(nullptr, "DEVNAME"), nullptr);
261     EXPECT_EQ(errno, 0);
262 
263     errno = 0;
264     EXPECT_EQ(udev_device_get_property_value(device, nullptr), nullptr);
265     EXPECT_EQ(errno, 0);
266 
267     errno = 0;
268     EXPECT_EQ(udev_device_get_property_value(device, "UNKNOWN"), nullptr);
269     EXPECT_EQ(errno, 0);
270 }
271 
272 /*
273  * Test for:
274  * udev_device_get_parent()
275  */
HWTEST_F(CustomUdevTest, TestGetParent1, TestSize.Level1)276 HWTEST_F(CustomUdevTest, TestGetParent1, TestSize.Level1)
277 {
278     ASSERT_NO_FATAL_FAILURE(testDevice_.Init());
279     auto* device = testDevice_.GetDevice();
280 
281     auto* parent = udev_device_get_parent(device);
282     ASSERT_NE(parent, nullptr);
283     EXPECT_STREQ(udev_device_get_syspath(parent), testDevice_.GetSysPath());
284 
285     errno = 0;
286     EXPECT_EQ(udev_device_get_parent(nullptr), nullptr);
287     EXPECT_EQ(errno, EINVAL);
288 }
289 
290 /*
291  * Test for:
292  * udev_device_get_parent_with_subsystem_devtype()
293  */
HWTEST_F(CustomUdevTest, TestGetParent2, TestSize.Level1)294 HWTEST_F(CustomUdevTest, TestGetParent2, TestSize.Level1)
295 {
296     ASSERT_NO_FATAL_FAILURE(testDevice_.Init());
297     auto* device = testDevice_.GetDevice();
298 
299     auto* parent = udev_device_get_parent_with_subsystem_devtype(device, "input", nullptr);
300     ASSERT_EQ(parent, nullptr);
301     EXPECT_NE(udev_device_get_syspath(parent), testDevice_.GetSysPath());
302 
303     errno = 0;
304     EXPECT_EQ(udev_device_get_parent_with_subsystem_devtype(nullptr, "input", nullptr), nullptr);
305     EXPECT_EQ(errno, 0);
306 
307     errno = 0;
308     EXPECT_NE(udev_device_get_parent_with_subsystem_devtype(device, "input", ""), nullptr);
309     EXPECT_NE(errno, EINVAL);
310 
311     errno = 0;
312     EXPECT_EQ(udev_device_get_parent_with_subsystem_devtype(device, nullptr, nullptr), nullptr);
313     EXPECT_EQ(errno, EINVAL);
314 
315     errno = 0;
316     EXPECT_EQ(udev_device_get_parent_with_subsystem_devtype(device, "unknown", nullptr), nullptr);
317     EXPECT_EQ(errno, 0);
318 }
319 
HWTEST_F(CustomUdevTest, TestUdevPropsDefault, TestSize.Level1)320 HWTEST_F(CustomUdevTest, TestUdevPropsDefault, TestSize.Level1)
321 {
322     ASSERT_NO_FATAL_FAILURE(testDevice_.Init());
323     auto* device = testDevice_.GetDevice();
324 
325     auto* parent = udev_device_get_parent(device);
326     ASSERT_NE(parent, nullptr);
327 
328     std::string expectedName = std::string{"\""} + TestDevice::TEST_NAME + "\"";
329     EXPECT_STREQ(udev_device_get_property_value(parent, "NAME"), expectedName.c_str());
330     std::stringstream expectedProduct;
331     expectedProduct << std::hex << TestDevice::TEST_BUS << '/' << TestDevice::TEST_VENDOR << '/' <<
332         TestDevice::TEST_PRODUCT << '/' << TestDevice::TEST_VERSION;
333     EXPECT_STREQ(udev_device_get_property_value(parent, "PRODUCT"), expectedProduct.str().c_str());
334     EXPECT_STREQ(udev_device_get_property_value(parent, "ID_INPUT"), "1");
335     EXPECT_STREQ(udev_device_get_property_value(parent, "ID_INPUT_MOUSE"), "1");
336 }
337 
HWTEST_F(CustomUdevTest, TestUdevWheel, TestSize.Level1)338 HWTEST_F(CustomUdevTest, TestUdevWheel, TestSize.Level1)
339 {
340     testDevice_.WheelSetup();
341     ASSERT_NO_FATAL_FAILURE(testDevice_.Init(false));
342     auto* device = testDevice_.GetDevice();
343 
344     auto* parent = udev_device_get_parent(device);
345     ASSERT_NE(parent, nullptr);
346 
347     EXPECT_STREQ(udev_device_get_property_value(parent, "ID_INPUT"), "1");
348     EXPECT_STREQ(udev_device_get_property_value(parent, "ID_INPUT_KEY"), "1");
349 }
350 
HWTEST_F(CustomUdevTest, TestUdevPropsKey, TestSize.Level1)351 HWTEST_F(CustomUdevTest, TestUdevPropsKey, TestSize.Level1)
352 {
353     testDevice_.KeyboardSetup();
354     ASSERT_NO_FATAL_FAILURE(testDevice_.Init(false));
355     auto* device = testDevice_.GetDevice();
356 
357     auto* parent = udev_device_get_parent(device);
358     ASSERT_NE(parent, nullptr);
359 
360     EXPECT_STREQ(udev_device_get_property_value(parent, "ID_INPUT"), "1");
361     EXPECT_STREQ(udev_device_get_property_value(parent, "ID_INPUT_KEY"), "1");
362     EXPECT_STREQ(udev_device_get_property_value(parent, "ID_INPUT_KEYBOARD"), "1");
363 }
364 
HWTEST_F(CustomUdevTest, TestUdevPropsSwitch, TestSize.Level1)365 HWTEST_F(CustomUdevTest, TestUdevPropsSwitch, TestSize.Level1)
366 {
367     testDevice_.SwitchSetup();
368     ASSERT_NO_FATAL_FAILURE(testDevice_.Init(false));
369     auto* device = testDevice_.GetDevice();
370 
371     auto* parent = udev_device_get_parent(device);
372     ASSERT_NE(parent, nullptr);
373 
374     EXPECT_STREQ(udev_device_get_property_value(parent, "ID_INPUT"), "1");
375     EXPECT_STREQ(udev_device_get_property_value(parent, "ID_INPUT_SWITCH"), "1");
376 }
377 
HWTEST_F(CustomUdevTest, TestUdevPropsAccel, TestSize.Level1)378 HWTEST_F(CustomUdevTest, TestUdevPropsAccel, TestSize.Level1)
379 {
380     testDevice_.AccelerometerSetup();
381     ASSERT_NO_FATAL_FAILURE(testDevice_.Init(false));
382     auto* device = testDevice_.GetDevice();
383 
384     auto* parent = udev_device_get_parent(device);
385     ASSERT_NE(parent, nullptr);
386 
387     EXPECT_STREQ(udev_device_get_property_value(parent, "ID_INPUT"), "1");
388     EXPECT_STREQ(udev_device_get_property_value(parent, "ID_INPUT_ACCELEROMETER"), "1");
389 }
390 
HWTEST_F(CustomUdevTest, TestUdevPropsStick, TestSize.Level1)391 HWTEST_F(CustomUdevTest, TestUdevPropsStick, TestSize.Level1)
392 {
393     testDevice_.StickSetup();
394     ASSERT_NO_FATAL_FAILURE(testDevice_.Init(false));
395     auto* device = testDevice_.GetDevice();
396 
397     auto* parent = udev_device_get_parent(device);
398     ASSERT_NE(parent, nullptr);
399 
400     EXPECT_STREQ(udev_device_get_property_value(parent, "ID_INPUT"), "1");
401     EXPECT_STREQ(udev_device_get_property_value(parent, "ID_INPUT_POINTINGSTICK"), "1");
402 }
403 
HWTEST_F(CustomUdevTest, TestUdevPropsTouchpad, TestSize.Level1)404 HWTEST_F(CustomUdevTest, TestUdevPropsTouchpad, TestSize.Level1)
405 {
406     testDevice_.TouchpadSetup();
407     ASSERT_NO_FATAL_FAILURE(testDevice_.Init(false));
408     auto* device = testDevice_.GetDevice();
409 
410     auto* parent = udev_device_get_parent(device);
411     ASSERT_NE(parent, nullptr);
412 
413     EXPECT_STREQ(udev_device_get_property_value(parent, "ID_INPUT"), "1");
414     EXPECT_STREQ(udev_device_get_property_value(parent, "ID_INPUT_TOUCHPAD"), "1");
415 }
416 
HWTEST_F(CustomUdevTest, TestUdevPropsTouchscreen, TestSize.Level1)417 HWTEST_F(CustomUdevTest, TestUdevPropsTouchscreen, TestSize.Level1)
418 {
419     testDevice_.TouchscreenSetup();
420     ASSERT_NO_FATAL_FAILURE(testDevice_.Init(false));
421     auto* device = testDevice_.GetDevice();
422 
423     auto* parent = udev_device_get_parent(device);
424     ASSERT_NE(parent, nullptr);
425 
426     EXPECT_STREQ(udev_device_get_property_value(parent, "ID_INPUT"), "1");
427     EXPECT_STREQ(udev_device_get_property_value(parent, "ID_INPUT_TOUCHSCREEN"), "1");
428 }
429 
HWTEST_F(CustomUdevTest, TestUdevPropsJoystick, TestSize.Level1)430 HWTEST_F(CustomUdevTest, TestUdevPropsJoystick, TestSize.Level1)
431 {
432     testDevice_.JoystickSetup();
433     ASSERT_NO_FATAL_FAILURE(testDevice_.Init(false));
434     auto* device = testDevice_.GetDevice();
435 
436     auto* parent = udev_device_get_parent(device);
437     ASSERT_NE(parent, nullptr);
438 
439     EXPECT_STREQ(udev_device_get_property_value(parent, "ID_INPUT"), "1");
440     EXPECT_STREQ(udev_device_get_property_value(parent, "ID_INPUT_JOYSTICK"), "1");
441 }
442 
HWTEST_F(CustomUdevTest, TestUdevPropsJoystick1, TestSize.Level1)443 HWTEST_F(CustomUdevTest, TestUdevPropsJoystick1, TestSize.Level1)
444 {
445     testDevice_.JoystickSetup1();
446     ASSERT_NO_FATAL_FAILURE(testDevice_.Init(false));
447     auto* device = testDevice_.GetDevice();
448 
449     auto* parent = udev_device_get_parent(device);
450     ASSERT_NE(parent, nullptr);
451 
452     EXPECT_STREQ(udev_device_get_property_value(parent, "ID_INPUT"), "1");
453     EXPECT_STREQ(udev_device_get_property_value(parent, "ID_INPUT_JOYSTICK"), "1");
454 }
455 
HWTEST_F(CustomUdevTest, TestUdevPropsTablet, TestSize.Level1)456 HWTEST_F(CustomUdevTest, TestUdevPropsTablet, TestSize.Level1)
457 {
458     testDevice_.TabletSetup();
459     ASSERT_NO_FATAL_FAILURE(testDevice_.Init(false));
460     auto* device = testDevice_.GetDevice();
461 
462     auto* parent = udev_device_get_parent(device);
463     ASSERT_NE(parent, nullptr);
464 
465     EXPECT_STREQ(udev_device_get_property_value(parent, "ID_INPUT"), "1");
466     EXPECT_STREQ(udev_device_get_property_value(parent, "ID_INPUT_TABLET"), "1");
467 }
468