1 /*
2 * Copyright (c) 2022 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 <cerrno>
17 #include <string>
18 #include <vector>
19 #include <iostream>
20 #include <memory>
21 #include <gtest/gtest.h>
22 #include <sys/stat.h>
23 #include <dirent.h>
24 #include <fcntl.h>
25 #include <selinux/selinux.h>
26
27 #include "param_stub.h"
28 #include "ueventd.h"
29 #include "ueventd_device_handler.h"
30 #include "ueventd_socket.h"
31
32 using namespace testing::ext;
33
34 namespace UeventdUt {
35 namespace {
36 std::string g_testRoot{"/data/ueventd"};
37 int g_oldRootFd = -1;
38 }
39
40 class UeventdEventUnitTest : public testing::Test {
41 public:
SetUpTestCase(void)42 static void SetUpTestCase(void)
43 {
44 struct stat st{};
45 bool isExist = true;
46
47 if (stat(g_testRoot.c_str(), &st) < 0) {
48 if (errno != ENOENT) {
49 std::cout << "Cannot get stat of " << g_testRoot << std::endl;
50 // If we cannot get root for ueventd tests
51 // There is no reason to continue.
52 ASSERT_TRUE(false);
53 }
54 isExist = false;
55 }
56
57 if (isExist) {
58 RemoveDir(g_testRoot);
59 }
60 int ret = mkdir(g_testRoot.c_str(), S_IRWXU | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
61 if (ret < 0) {
62 std::cout << "Cannot create directory " << g_testRoot << " err = " << errno << std::endl;
63 ASSERT_TRUE(0);
64 }
65 if (SwitchRoot() < 0) {
66 // If we cannot do this, there is not reason to continue
67 ASSERT_TRUE(0);
68 }
69 }
70
TearDownTestCase(void)71 static void TearDownTestCase(void)
72 {
73 // Switch back to old root
74 if (g_oldRootFd < 0) {
75 std::cout << "Old root directory is not valid\n";
76 return;
77 }
78
79 if (fchdir(g_oldRootFd) < 0) {
80 std::cout << "Failed to change working directory to '/', err = " << errno << std::endl;
81 }
82
83 if (chroot(".") < 0) {
84 std::cout << "Failed to change root directory to '/', err = " << errno << std::endl;
85 }
86 close(g_oldRootFd);
87 g_oldRootFd = -1;
88 std::cout << "Change root back done\n";
89 // Remove test data
90 if (RemoveDir(g_testRoot) < 0) {
91 std::cout << "Failed to remove " << g_testRoot << ", err = " << errno << std::endl;
92 }
93 }
94
RemoveDir(const std::string & path)95 static int RemoveDir(const std::string &path)
96 {
97 if (path.empty()) {
98 // Treat it as OK
99 return 0;
100 }
101 auto dir = std::unique_ptr<DIR, decltype(&closedir)>(opendir(path.c_str()), closedir);
102 if (dir == nullptr) {
103 std::cout << "Cannot open dir " << path << ", err = " << errno << std::endl;
104 return -1;
105 }
106
107 struct dirent *dp = nullptr;
108 while ((dp = readdir(dir.get())) != nullptr) {
109 // Skip hidden files
110 if (dp->d_name[0] == '.') {
111 continue;
112 }
113 bool endsWithSlash = (path.find_last_of("/") == path.size() - 1);
114 std::string fullPath {};
115 if (endsWithSlash) {
116 fullPath = path + dp->d_name;
117 } else {
118 fullPath = path + "/" + dp->d_name;
119 }
120 struct stat st {};
121 if (stat(fullPath.c_str(), &st) < 0) {
122 std::cout << "Failed to get stat of " << fullPath << std::endl;
123 continue; // Should we continue?
124 }
125 if (S_ISDIR(st.st_mode)) {
126 if (RemoveDir(fullPath) < 0) {
127 std::cout << "Failed to remove directory " << fullPath << std::endl;
128 return -1;
129 }
130 } else {
131 if (unlink(fullPath.c_str()) < 0) {
132 std::cout << "Failed to unlink file " << fullPath << std::endl;
133 return -1;
134 }
135 }
136 }
137 return rmdir(path.c_str());
138 }
139
SwitchRoot()140 static int SwitchRoot()
141 {
142 if (g_oldRootFd >= 0) {
143 close(g_oldRootFd);
144 g_oldRootFd = -1;
145 }
146 // Save old root
147 DIR *dir = opendir("/");
148 if (dir == nullptr) {
149 std::cout << "Failed to open root directory\n";
150 return -1;
151 }
152 g_oldRootFd = dirfd(dir);
153 if (g_oldRootFd < 0) {
154 std::cout << "Failed to pen root directory, err = " << errno << std::endl;
155 return -1;
156 }
157
158 // Changing working directory to "/data/ueventd"
159 if (chdir(g_testRoot.c_str()) < 0) {
160 std::cout << "Failed to change working directory to " << g_testRoot << ", err = " << errno << std::endl;
161 close(g_oldRootFd);
162 g_oldRootFd = -1;
163 }
164
165 if (chroot(g_testRoot.c_str()) < 0) {
166 std::cout << "Failed to change root directory to " << g_testRoot << ", err = " << errno << std::endl;
167 close(g_oldRootFd);
168 g_oldRootFd = -1;
169 }
170 std::cout << "Change root to " << g_testRoot << " done\n";
171 return 0;
172 }
173
SetUp()174 void SetUp() {};
TearDown()175 void TearDown() {};
176 };
177
178 // Generate uevent buffer from struct uevent.
179 // extra data used to break uevent buffer to check
180 // if ueventd will handle this situation correctly
GenerateUeventBuffer(struct Uevent & uevent,std::vector<std::string> & extraData)181 std::string GenerateUeventBuffer(struct Uevent &uevent, std::vector<std::string> &extraData)
182 {
183 std::string ueventdBuffer{};
184 if (uevent.syspath != nullptr) {
185 ueventdBuffer.append(std::string("DEVPATH=") + uevent.syspath + '\000');
186 }
187 if (uevent.subsystem != nullptr) {
188 ueventdBuffer.append(std::string("SUBSYSTEM=") + uevent.subsystem + '\000');
189 }
190 ueventdBuffer.append(std::string("ACTION=") + ActionString(uevent.action) + '\000');
191 if (uevent.deviceName != nullptr) {
192 ueventdBuffer.append(std::string("DEVNAME=") + uevent.deviceName + '\000');
193 }
194 if (uevent.partitionName != nullptr) {
195 ueventdBuffer.append(std::string("PARTNAME=") + uevent.partitionName + '\000');
196 }
197 ueventdBuffer.append(std::string("PARTN=") + std::to_string(uevent.partitionNum) + '\000');
198 ueventdBuffer.append(std::string("MAJOR=") + std::to_string(uevent.major) + '\000');
199 ueventdBuffer.append(std::string("MINOR=") + std::to_string(uevent.minor) + '\000');
200 ueventdBuffer.append(std::string("DEVUID=") + std::to_string(uevent.ug.uid) + '\000');
201 ueventdBuffer.append(std::string("DEVGID=") + std::to_string(uevent.ug.gid) + '\000');
202 if (uevent.firmware != nullptr) {
203 ueventdBuffer.append(std::string("FIRMWARE=") + uevent.firmware + '\000');
204 }
205 ueventdBuffer.append(std::string("BUSNUM=") + std::to_string(uevent.busNum) + '\000');
206 ueventdBuffer.append(std::string("DEVNUM=") + std::to_string(uevent.devNum) + '\000');
207
208 if (!extraData.empty()) {
209 for (const auto &data : extraData) {
210 ueventdBuffer.append(data);
211 }
212 }
213 return ueventdBuffer;
214 }
215
IsFileExist(const std::string & file)216 bool IsFileExist(const std::string &file)
217 {
218 struct stat st{};
219 if (file.empty()) {
220 return false;
221 }
222
223 if (stat(file.c_str(), &st) < 0) {
224 if (errno == ENOENT) {
225 std::cout << "File " << file << " is not exist\n";
226 }
227 return false;
228 }
229 return true;
230 }
231
TestHandleBlockDeviceEvent(const struct Uevent * uevent)232 static int TestHandleBlockDeviceEvent(const struct Uevent *uevent)
233 {
234 HandleBlockDeviceEvent(uevent);
235 return 0;
236 }
237
TestHandleOtherDeviceEvent(const struct Uevent * uevent)238 static int TestHandleOtherDeviceEvent(const struct Uevent *uevent)
239 {
240 HandleOtherDeviceEvent(uevent);
241 return 0;
242 }
243
TestRetriggerUeventByPath(int sockFd,char * path)244 static int TestRetriggerUeventByPath(int sockFd, char *path)
245 {
246 RetriggerUeventByPath(sockFd, path);
247 return 0;
248 }
249
RetriggerSpecialUevent(int sockFd,char * path,CompareUevent compare,struct Uevent * event)250 static int RetriggerSpecialUevent(int sockFd, char *path, CompareUevent compare, struct Uevent *event)
251 {
252 if (event == NULL || compare == NULL) {
253 return -1;
254 }
255 return compare(event);
256 }
257
TestRetriggerSpecialUevent(int sockFd,char * path,CompareUevent compare,struct Uevent * event)258 static int TestRetriggerSpecialUevent(int sockFd, char *path, CompareUevent compare, struct Uevent *event)
259 {
260 return RetriggerSpecialUevent(sockFd, path, compare, event);
261 }
262
CompareUserData(struct Uevent * uevent)263 static int CompareUserData(struct Uevent *uevent)
264 {
265 if (uevent == nullptr) {
266 return -1;
267 }
268 return strcmp(uevent->partitionName, "userdata");
269 }
270
271 HWTEST_F(UeventdEventUnitTest, Init_UeventdEventUnitTest_ParseUeventdEvent001, TestSize.Level1)
272 {
273 struct Uevent uevent = {
274 .subsystem = "block",
275 .syspath = "/block/mmc/test",
276 .deviceName = "test",
277 .partitionName = "userdata",
278 .firmware = "",
279 .action = ACTION_ADD,
280 .partitionNum = 3,
281 .major = 1,
282 .minor = 2,
283 .ug = {
284 .uid = 0,
285 .gid = 0,
286 },
287 .busNum = 1,
288 .devNum = 2,
289 };
290
291 std::vector<std::string> extraData{};
292 auto ueventBuffer = GenerateUeventBuffer(uevent, extraData);
293 std::cout << "ueventBuffer = [" << ueventBuffer << "]. size = " << ueventBuffer.length() << std::endl;
294 struct Uevent outEvent;
295 ParseUeventMessage(ueventBuffer.data(), ueventBuffer.length(), &outEvent);
296 EXPECT_EQ(outEvent.action, ACTION_ADD);
297 EXPECT_EQ(outEvent.busNum, 1);
298 EXPECT_STREQ(outEvent.subsystem, "block");
299 EXPECT_STREQ(outEvent.deviceName, "test");
300 EXPECT_EQ(outEvent.devNum, 2);
301 EXPECT_EQ(outEvent.major, 1);
302 EXPECT_EQ(outEvent.minor, 2);
303 EXPECT_EQ(outEvent.partitionNum, 3);
304 EXPECT_STREQ(outEvent.partitionName, "userdata");
305 EXPECT_STREQ(outEvent.syspath, "/block/mmc/test");
306 EXPECT_EQ(outEvent.ug.gid, 0);
307 EXPECT_EQ(outEvent.ug.uid, 0);
308 HandleUevent(&outEvent);
309 }
310
311 HWTEST_F(UeventdEventUnitTest, Init_UeventdEventUnitTest_Actions001, TestSize.Level1)
312 {
313 struct Uevent uevent = {
314 .subsystem = "block",
315 .syspath = "/block/mmc/test",
316 .deviceName = "test",
317 .partitionName = "userdata",
318 .action = ACTION_UNKNOWN,
319 };
320 std::vector<std::string> extraData {};
321 auto ueventBuffer = GenerateUeventBuffer(uevent, extraData);
322 std::cout << "ueventBuffer = [" << ueventBuffer << "]. size = " << ueventBuffer.length() << std::endl;
323 struct Uevent outEvent;
324 ParseUeventMessage(ueventBuffer.data(), ueventBuffer.length(), &outEvent);
325 EXPECT_EQ(outEvent.action, ACTION_UNKNOWN);
326 HandleUevent(&outEvent);
327 }
328
329 HWTEST_F(UeventdEventUnitTest, Init_UeventdEventUnitTest_HandleBlockDevicesInvalidParameters001, TestSize.Level1)
330 {
331 int ret = TestHandleBlockDeviceEvent(nullptr);
332 EXPECT_EQ(ret, 0);
333 // Not block device
334 struct Uevent noBlockUevent = {
335 .subsystem = "char",
336 };
337 ret = TestHandleBlockDeviceEvent(&noBlockUevent);
338 EXPECT_EQ(ret, 0);
339
340 struct Uevent invalidDevNoUevent = {
341 .subsystem = "block",
342 .major = -1,
343 .minor = -1,
344 };
345 ret = TestHandleBlockDeviceEvent(&invalidDevNoUevent);
346 EXPECT_EQ(ret, 0);
347
348 struct Uevent invalidSysPathUevent = {
349 .subsystem = "block",
350 .syspath = nullptr,
351 .major = 1,
352 .minor = 1,
353 };
354 ret = TestHandleBlockDeviceEvent(&invalidSysPathUevent);
355 EXPECT_EQ(ret, 0);
356 }
357
358 HWTEST_F(UeventdEventUnitTest, Init_UeventdEventUnitTest_HandleBlockDevicesValidParameters002, TestSize.Level1)
359 {
360 struct Uevent uevent = {
361 .subsystem = "block",
362 .syspath = "/block/mmc/block_device_test",
363 .deviceName = "block_device_test",
364 .partitionName = "block_device_test",
365 .firmware = "",
366 .action = ACTION_ADD,
367 .partitionNum = 3,
368 .major = 5,
369 .minor = 15,
370 .ug = {
371 .uid = 0,
372 .gid = 0,
373 },
374 .busNum = 1,
375 .devNum = 2,
376 };
377
378 HandleBlockDeviceEvent(&uevent);
379 // Check results
380 std::string blockDevice = "/dev/block/block_device_test";
381 struct stat st{};
382 int ret = stat(blockDevice.c_str(), &st);
383 EXPECT_EQ(ret, 0);
384 bool isBlock = S_ISBLK(st.st_mode);
385 EXPECT_TRUE(isBlock);
386 }
387
388 HWTEST_F(UeventdEventUnitTest, Init_UeventdEventUnitTest_HandleBlockDevicesRemoved001, TestSize.Level1)
389 {
390 struct Uevent uevent = {
391 .subsystem = "block",
392 .syspath = "/block/mmc/block_device_test",
393 .deviceName = "block_device_test",
394 .partitionName = "block_device_test",
395 .firmware = "",
396 .action = ACTION_REMOVE,
397 .partitionNum = 3,
398 .major = 5,
399 .minor = 15,
400 .ug = {
401 .uid = 0,
402 .gid = 0,
403 },
404 .busNum = 1,
405 .devNum = 2,
406 };
407 std::string blockDevice = "/dev/block/block_device_test";
408 struct stat st{};
409 int ret = stat(blockDevice.c_str(), &st);
410 if (ret < 0) {
411 // This should not happen actually, because we've created the device node before.
412 std::cout << "Warning. Block device " << blockDevice << " is not exist.\n";
413 }
414 HandleBlockDeviceEvent(&uevent);
415 ret = stat(blockDevice.c_str(), &st);
416 EXPECT_EQ(ret, -1);
417 EXPECT_EQ(errno, ENOENT);
418 }
419
420 HWTEST_F(UeventdEventUnitTest, Init_UeventdEventUnitTest_HandleBlockDevicesChanged001, TestSize.Level1)
421 {
422 struct Uevent uevent = {
423 .subsystem = "block",
424 .syspath = "/block/mmc/block_device_test",
425 .deviceName = "block_device_test",
426 .partitionName = "block_device_test",
427 .firmware = "",
428 .action = ACTION_REMOVE,
429 .partitionNum = 3,
430 .major = 5,
431 .minor = 15,
432 .ug = {
433 .uid = 0,
434 .gid = 0,
435 },
436 .busNum = 1,
437 .devNum = 2,
438 };
439 int ret = TestHandleBlockDeviceEvent(&uevent);
440 EXPECT_EQ(ret, 0);
441 }
442
443 HWTEST_F(UeventdEventUnitTest, Init_UeventdEventUnitTest_HandleOtherDevicesInvalidParameters001, TestSize.Level1)
444 {
445 int ret = TestHandleOtherDeviceEvent(nullptr);
446 EXPECT_EQ(ret, 0);
447 // Not Character device
448 struct Uevent invalidDevNoUevent = {
449 .subsystem = "test",
450 .major = -1,
451 .minor = -1,
452 };
453 ret = TestHandleOtherDeviceEvent(&invalidDevNoUevent);
454 EXPECT_EQ(ret, 0);
455
456 struct Uevent invalidSysPathUevent = {
457 .subsystem = "test",
458 .syspath = nullptr,
459 .major = 5,
460 .minor = 9,
461 };
462 ret = TestHandleOtherDeviceEvent(&invalidSysPathUevent);
463 EXPECT_EQ(ret, 0);
464
465 struct Uevent invalidSubsystemUevent = {
466 .subsystem = "",
467 .syspath = "/devices/test/char",
468 .major = 5,
469 .minor = 9,
470 };
471 ret = TestHandleOtherDeviceEvent(&invalidSubsystemUevent);
472 EXPECT_EQ(ret, 0);
473 }
474
475 HWTEST_F(UeventdEventUnitTest, Init_UeventdEventUnitTest_HandleOtherDevicesValidParameters001, TestSize.Level1)
476 {
477 struct Uevent uevent = {
478 .subsystem = "extcon3",
479 .syspath = "/devices/platform/headset/extcon/extcon3",
480 .deviceName = "extcon3-1",
481 .major = 5,
482 .minor = 9,
483 };
484 HandleOtherDeviceEvent(&uevent);
485 auto exist = IsFileExist("/dev/extcon3-1");
486 EXPECT_TRUE(exist);
487 exist = IsFileExist("/dev/extcon3");
488 EXPECT_FALSE(exist);
489 }
490
491 HWTEST_F(UeventdEventUnitTest, Init_UeventdEventUnitTest_HandleUsbDevicesWithDeviceName001, TestSize.Level1)
492 {
493 struct Uevent uevent = {
494 .subsystem = "usb",
495 .syspath = "/devices/platform/headset/extcon/usb-dev",
496 .deviceName = "usb-dev",
497 .major = 8,
498 .minor = 9,
499 };
500 HandleOtherDeviceEvent(&uevent);
501 auto exist = IsFileExist("/dev/usb-dev");
502 EXPECT_TRUE(exist);
503 }
504
505 HWTEST_F(UeventdEventUnitTest, Init_UeventdEventUnitTest_HandleInvalidUsbDevices001, TestSize.Level1)
506 {
507 struct Uevent uevent = {
508 .subsystem = "usb",
509 .syspath = "/devices/platform/headset/extcon/usb-dev-1",
510 .major = 8,
511 .minor = 10,
512 .busNum = -1,
513 .devNum = -1,
514 };
515 HandleOtherDeviceEvent(&uevent);
516 auto exist = IsFileExist("/dev/usb-dev-1");
517 EXPECT_FALSE(exist);
518 }
519
520 HWTEST_F(UeventdEventUnitTest, Init_UeventdEventUnitTest_HandleUsbDevicesWithBusNo001, TestSize.Level1)
521 {
522 struct Uevent uevent = {
523 .subsystem = "usb",
524 .syspath = "/devices/platform/headset/extcon/usb-dev",
525 .major = 8,
526 .minor = 9,
527 .busNum = 3,
528 .devNum = 4,
529 };
530 HandleOtherDeviceEvent(&uevent);
531 auto exist = IsFileExist("/dev/bus/usb/003/004");
532 EXPECT_TRUE(exist);
533 }
534
535 HWTEST_F(UeventdEventUnitTest, Init_UeventdEventUnitTest_Handle001, TestSize.Level1)
536 {
537 char path[] = {"/data/ueventd"};
538 int ret = TestRetriggerUeventByPath(g_oldRootFd, path);
539 EXPECT_EQ(ret, 0);
540 struct Uevent uevent = {
541 .partitionName = "userdata",
542 };
543 ret = TestRetriggerSpecialUevent(g_oldRootFd, path, CompareUserData, &uevent);
544 EXPECT_EQ(ret, 0);
545 }
546
547 HWTEST_F(UeventdEventUnitTest, Init_UeventdEventUnitTest_FirmwareUevent001, TestSize.Level1)
548 {
549 struct Uevent uevent = {
550 .subsystem = "firmware",
551 .syspath = "/block/mmc/test",
552 .deviceName = "test",
553 .partitionName = "userdata",
554 .firmware = "",
555 .action = ACTION_ADD,
556 .partitionNum = 3,
557 .major = 1,
558 .minor = 2,
559 .ug = {
560 .uid = 0,
561 .gid = 0,
562 },
563 .busNum = 1,
564 .devNum = 2,
565 };
566
567 std::vector<std::string> extraData{};
568 auto ueventBuffer = GenerateUeventBuffer(uevent, extraData);
569 struct Uevent outEvent;
570 ParseUeventMessage(ueventBuffer.data(), ueventBuffer.length(), &outEvent);
571 EXPECT_EQ(outEvent.action, ACTION_ADD);
572 EXPECT_EQ(outEvent.busNum, 1);
573 EXPECT_STREQ(outEvent.subsystem, "firmware");
574 EXPECT_STREQ(outEvent.deviceName, "test");
575 EXPECT_EQ(outEvent.devNum, 2);
576 EXPECT_EQ(outEvent.major, 1);
577 EXPECT_EQ(outEvent.minor, 2);
578 EXPECT_EQ(outEvent.partitionNum, 3);
579 EXPECT_STREQ(outEvent.partitionName, "userdata");
580 EXPECT_STREQ(outEvent.syspath, "/block/mmc/test");
581 EXPECT_EQ(outEvent.ug.gid, 0);
582 EXPECT_EQ(outEvent.ug.uid, 0);
583 HandleUevent(&outEvent);
584 }
585
586 HWTEST_F(UeventdEventUnitTest, Init_UeventdEventTest_PlatformEvent001, TestSize.Level1)
587 {
588 struct Uevent uevent = {
589 .subsystem = "platform",
590 .syspath = "/block/mmc/test",
591 .deviceName = "test",
592 .partitionName = "userdata",
593 .firmware = "",
594 .action = ACTION_ADD,
595 .partitionNum = 3,
596 .major = 1,
597 .minor = 2,
598 .ug = {
599 .uid = 0,
600 .gid = 0,
601 },
602 .busNum = 1,
603 .devNum = 2,
604 };
605
606 std::vector<std::string> extraData{};
607 auto ueventBuffer = GenerateUeventBuffer(uevent, extraData);
608 struct Uevent outEvent;
609 ParseUeventMessage(ueventBuffer.data(), ueventBuffer.length(), &outEvent);
610 EXPECT_EQ(outEvent.action, ACTION_ADD);
611 EXPECT_EQ(outEvent.busNum, 1);
612 EXPECT_STREQ(outEvent.subsystem, "platform");
613 EXPECT_STREQ(outEvent.deviceName, "test");
614 EXPECT_EQ(outEvent.devNum, 2);
615 EXPECT_EQ(outEvent.major, 1);
616 EXPECT_EQ(outEvent.minor, 2);
617 EXPECT_EQ(outEvent.partitionNum, 3);
618 EXPECT_STREQ(outEvent.partitionName, "userdata");
619 EXPECT_STREQ(outEvent.syspath, "/block/mmc/test");
620 EXPECT_EQ(outEvent.ug.gid, 0);
621 EXPECT_EQ(outEvent.ug.uid, 0);
622 HandleUevent(&outEvent);
623 }
624
625 HWTEST_F(UeventdEventUnitTest, Init_UeventdEventUnitTest_PlatformEventUsb001, TestSize.Level1)
626 {
627 struct Uevent uevent = {
628 .subsystem = "usb",
629 .syspath = "/block/mmc/test",
630 .deviceName = "test",
631 .partitionName = "userdata",
632 .firmware = "",
633 .action = ACTION_ADD,
634 .partitionNum = 3,
635 .major = 1,
636 .minor = 2,
637 .ug = {
638 .uid = 0,
639 .gid = 0,
640 },
641 .busNum = 1,
642 .devNum = 2,
643 };
644
645 std::vector<std::string> extraData{};
646 auto ueventBuffer = GenerateUeventBuffer(uevent, extraData);
647 struct Uevent outEvent;
648 ParseUeventMessage(ueventBuffer.data(), ueventBuffer.length(), &outEvent);
649 EXPECT_EQ(outEvent.action, ACTION_ADD);
650 EXPECT_EQ(outEvent.busNum, 1);
651 EXPECT_STREQ(outEvent.subsystem, "usb");
652 EXPECT_STREQ(outEvent.deviceName, "test");
653 EXPECT_EQ(outEvent.devNum, 2);
654 EXPECT_EQ(outEvent.major, 1);
655 EXPECT_EQ(outEvent.minor, 2);
656 EXPECT_EQ(outEvent.partitionNum, 3);
657 EXPECT_STREQ(outEvent.partitionName, "userdata");
658 EXPECT_STREQ(outEvent.syspath, "/block/mmc/test");
659 EXPECT_EQ(outEvent.ug.gid, 0);
660 EXPECT_EQ(outEvent.ug.uid, 0);
661 HandleUevent(&outEvent);
662 }
663
TestUeventAction(ACTION action)664 static void TestUeventAction(ACTION action)
665 {
666 struct Uevent uevent = {
667 .subsystem = "block",
668 .syspath = "/block/mmc/test",
669 .deviceName = "test",
670 .partitionName = "userdata",
671 .firmware = "",
672 .action = action,
673 .partitionNum = 3,
674 .major = 1,
675 .minor = 2,
676 .ug = {
677 .uid = 0,
678 .gid = 0,
679 },
680 .busNum = 1,
681 .devNum = 2,
682 };
683
684 std::vector<std::string> extraData{};
685 auto ueventBuffer = GenerateUeventBuffer(uevent, extraData);
686 struct Uevent outEvent;
687 ParseUeventMessage(ueventBuffer.data(), ueventBuffer.length(), &outEvent);
688 EXPECT_EQ(outEvent.action, action);
689 HandleUevent(&outEvent);
690 }
691
692 HWTEST_F(UeventdEventUnitTest, Init_UeventdEventUnitTest_ActionAdd001, TestSize.Level1)
693 {
694 TestUeventAction(ACTION_ADD);
695 TestUeventAction(ACTION_REMOVE);
696 TestUeventAction(ACTION_CHANGE);
697 TestUeventAction(ACTION_MOVE);
698 TestUeventAction(ACTION_ONLINE);
699
700 TestUeventAction(ACTION_OFFLINE);
701 TestUeventAction(ACTION_BIND);
702 TestUeventAction(ACTION_UNBIND);
703 TestUeventAction(ACTION_UNKNOWN);
704 }
705 } // UeventdUt