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
23using ::testing::ext::TestSize;
24
25class UdevTestDevice : public TestDevice {
26public:
27    UdevTestDevice()
28    {
29        udev_ = udev_new();
30    }
31
32    ~UdevTestDevice()
33    {
34        if (udevDevice_ != nullptr) {
35            udevDevice_ = udev_device_unref(udevDevice_);
36        }
37        udev_unref(udev_);
38    }
39
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
48    auto GetUdev() const
49    {
50        return udev_;
51    }
52
53    auto GetDevice() const
54    {
55        return udevDevice_;
56    }
57
58private:
59    struct udev* udev_{};
60    struct udev_device* udevDevice_{};
61};
62
63class CustomUdevTest : public ::testing::Test {
64public:
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 */
75HWTEST_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 */
97HWTEST_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 */
116HWTEST_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 */
148HWTEST_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 */
179HWTEST_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 */
195HWTEST_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 */
211HWTEST_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 */
227HWTEST_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 */
248HWTEST_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 */
276HWTEST_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 */
294HWTEST_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
320HWTEST_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
338HWTEST_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
351HWTEST_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
365HWTEST_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
378HWTEST_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
391HWTEST_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
404HWTEST_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
417HWTEST_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
430HWTEST_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
443HWTEST_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
456HWTEST_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