• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
250 HWTEST_F(UeventdEventUnitTest, Init_UeventdEventUnitTest_ParseUeventdEvent001, TestSize.Level1)
251 {
252     struct Uevent uevent = {
253         .subsystem = "block",
254         .syspath = "/block/mmc/test",
255         .deviceName = "test",
256         .partitionName = "userdata",
257         .firmware = "",
258         .action = ACTION_ADD,
259         .partitionNum = 3,
260         .major = 1,
261         .minor = 2,
262         .ug = {
263             .uid = 0,
264             .gid = 0,
265         },
266         .busNum = 1,
267         .devNum = 2,
268     };
269 
270     std::vector<std::string> extraData{};
271     auto ueventBuffer = GenerateUeventBuffer(uevent, extraData);
272     std::cout << "ueventBuffer = [" << ueventBuffer << "]. size = " << ueventBuffer.length() << std::endl;
273     struct Uevent outEvent;
274     ParseUeventMessage(ueventBuffer.data(), ueventBuffer.length(), &outEvent);
275     EXPECT_EQ(outEvent.action, ACTION_ADD);
276     EXPECT_EQ(outEvent.busNum, 1);
277     EXPECT_STREQ(outEvent.subsystem, "block");
278     EXPECT_STREQ(outEvent.deviceName, "test");
279     EXPECT_EQ(outEvent.devNum, 2);
280     EXPECT_EQ(outEvent.major, 1);
281     EXPECT_EQ(outEvent.minor, 2);
282     EXPECT_EQ(outEvent.partitionNum, 3);
283     EXPECT_STREQ(outEvent.partitionName, "userdata");
284     EXPECT_STREQ(outEvent.syspath, "/block/mmc/test");
285     EXPECT_EQ(outEvent.ug.gid, 0);
286     EXPECT_EQ(outEvent.ug.uid, 0);
287     HandleUevent(&outEvent);
288 }
289 
290 HWTEST_F(UeventdEventUnitTest, Init_UeventdEventUnitTest_Actions001, TestSize.Level1)
291 {
292     struct Uevent uevent = {
293         .subsystem = "block",
294         .syspath = "/block/mmc/test",
295         .deviceName = "test",
296         .partitionName = "userdata",
297         .action = ACTION_UNKNOWN,
298     };
299     std::vector<std::string> extraData {};
300     auto ueventBuffer = GenerateUeventBuffer(uevent, extraData);
301     std::cout << "ueventBuffer = [" << ueventBuffer << "]. size = " << ueventBuffer.length() << std::endl;
302     struct Uevent outEvent;
303     ParseUeventMessage(ueventBuffer.data(), ueventBuffer.length(), &outEvent);
304     EXPECT_EQ(outEvent.action, ACTION_UNKNOWN);
305     HandleUevent(&outEvent);
306 }
307 
308 HWTEST_F(UeventdEventUnitTest, Init_UeventdEventUnitTest_HandleBlockDevicesInvalidParameters001, TestSize.Level1)
309 {
310     int ret = TestHandleBlockDeviceEvent(nullptr);
311     EXPECT_EQ(ret, 0);
312     // Not block device
313     struct Uevent noBlockUevent = {
314         .subsystem = "char",
315     };
316     ret = TestHandleBlockDeviceEvent(&noBlockUevent);
317     EXPECT_EQ(ret, 0);
318 
319     struct Uevent invalidDevNoUevent = {
320         .subsystem = "block",
321         .major = -1,
322         .minor = -1,
323     };
324     ret = TestHandleBlockDeviceEvent(&invalidDevNoUevent);
325     EXPECT_EQ(ret, 0);
326 
327     struct Uevent invalidSysPathUevent = {
328         .subsystem = "block",
329         .syspath = nullptr,
330         .major = 1,
331         .minor = 1,
332     };
333     ret = TestHandleBlockDeviceEvent(&invalidSysPathUevent);
334     EXPECT_EQ(ret, 0);
335 }
336 
337 HWTEST_F(UeventdEventUnitTest, Init_UeventdEventUnitTest_HandleBlockDevicesValidParameters002, TestSize.Level1)
338 {
339     struct Uevent uevent = {
340         .subsystem = "block",
341         .syspath = "/block/mmc/block_device_test",
342         .deviceName = "block_device_test",
343         .partitionName = "block_device_test",
344         .firmware = "",
345         .action = ACTION_ADD,
346         .partitionNum = 3,
347         .major = 5,
348         .minor = 15,
349         .ug = {
350             .uid = 0,
351             .gid = 0,
352         },
353         .busNum = 1,
354         .devNum = 2,
355     };
356 
357     HandleBlockDeviceEvent(&uevent);
358     // Check results
359     std::string blockDevice = "/dev/block/block_device_test";
360     struct stat st{};
361     int ret = stat(blockDevice.c_str(), &st);
362     EXPECT_EQ(ret, 0);
363     bool isBlock = S_ISBLK(st.st_mode);
364     EXPECT_TRUE(isBlock);
365 }
366 
367 HWTEST_F(UeventdEventUnitTest, Init_UeventdEventUnitTest_HandleBlockDevicesRemoved001, TestSize.Level1)
368 {
369     struct Uevent uevent = {
370         .subsystem = "block",
371         .syspath = "/block/mmc/block_device_test",
372         .deviceName = "block_device_test",
373         .partitionName = "block_device_test",
374         .firmware = "",
375         .action = ACTION_REMOVE,
376         .partitionNum = 3,
377         .major = 5,
378         .minor = 15,
379         .ug = {
380             .uid = 0,
381             .gid = 0,
382         },
383         .busNum = 1,
384         .devNum = 2,
385     };
386     std::string blockDevice = "/dev/block/block_device_test";
387     struct stat st{};
388     int ret = stat(blockDevice.c_str(), &st);
389     if (ret < 0) {
390         // This should not happen actually, because we've created the device node before.
391         std::cout << "Warning. Block device " << blockDevice << " is not exist.\n";
392     }
393     HandleBlockDeviceEvent(&uevent);
394     ret = stat(blockDevice.c_str(), &st);
395     EXPECT_EQ(ret, -1);
396     EXPECT_EQ(errno, ENOENT);
397 }
398 
399 HWTEST_F(UeventdEventUnitTest, Init_UeventdEventUnitTest_HandleBlockDevicesChanged001, TestSize.Level1)
400 {
401     struct Uevent uevent = {
402         .subsystem = "block",
403         .syspath = "/block/mmc/block_device_test",
404         .deviceName = "block_device_test",
405         .partitionName = "block_device_test",
406         .firmware = "",
407         .action = ACTION_REMOVE,
408         .partitionNum = 3,
409         .major = 5,
410         .minor = 15,
411         .ug = {
412             .uid = 0,
413             .gid = 0,
414         },
415         .busNum = 1,
416         .devNum = 2,
417     };
418     int ret = TestHandleBlockDeviceEvent(&uevent);
419     EXPECT_EQ(ret, 0);
420 }
421 
422 HWTEST_F(UeventdEventUnitTest, Init_UeventdEventUnitTest_HandleOtherDevicesInvalidParameters001, TestSize.Level1)
423 {
424     int ret = TestHandleOtherDeviceEvent(nullptr);
425     EXPECT_EQ(ret, 0);
426     // Not Character device
427     struct Uevent invalidDevNoUevent = {
428         .subsystem = "test",
429         .major = -1,
430         .minor = -1,
431     };
432     ret = TestHandleOtherDeviceEvent(&invalidDevNoUevent);
433     EXPECT_EQ(ret, 0);
434 
435     struct Uevent invalidSysPathUevent = {
436         .subsystem = "test",
437         .syspath = nullptr,
438         .major = 5,
439         .minor = 9,
440     };
441     ret = TestHandleOtherDeviceEvent(&invalidSysPathUevent);
442     EXPECT_EQ(ret, 0);
443 
444     struct Uevent invalidSubsystemUevent = {
445         .subsystem = "",
446         .syspath = "/devices/test/char",
447         .major = 5,
448         .minor = 9,
449     };
450     ret = TestHandleOtherDeviceEvent(&invalidSubsystemUevent);
451     EXPECT_EQ(ret, 0);
452 }
453 
454 HWTEST_F(UeventdEventUnitTest, Init_UeventdEventUnitTest_HandleOtherDevicesValidParameters001, TestSize.Level1)
455 {
456     struct Uevent uevent = {
457         .subsystem = "extcon3",
458         .syspath = "/devices/platform/headset/extcon/extcon3",
459         .deviceName = "extcon3-1",
460         .major = 5,
461         .minor = 9,
462     };
463     HandleOtherDeviceEvent(&uevent);
464     auto exist = IsFileExist("/dev/extcon3-1");
465     EXPECT_TRUE(exist);
466     exist = IsFileExist("/dev/extcon3");
467     EXPECT_FALSE(exist);
468 }
469 
470 HWTEST_F(UeventdEventUnitTest, Init_UeventdEventUnitTest_HandleUsbDevicesWithDeviceName001, TestSize.Level1)
471 {
472     struct Uevent uevent = {
473         .subsystem = "usb",
474         .syspath = "/devices/platform/headset/extcon/usb-dev",
475         .deviceName = "usb-dev",
476         .major = 8,
477         .minor = 9,
478     };
479     HandleOtherDeviceEvent(&uevent);
480     auto exist = IsFileExist("/dev/usb-dev");
481     EXPECT_TRUE(exist);
482 }
483 
484 HWTEST_F(UeventdEventUnitTest, Init_UeventdEventUnitTest_HandleInvalidUsbDevices001, TestSize.Level1)
485 {
486     struct Uevent uevent = {
487         .subsystem = "usb",
488         .syspath = "/devices/platform/headset/extcon/usb-dev-1",
489         .major = 8,
490         .minor = 10,
491         .busNum = -1,
492         .devNum = -1,
493     };
494     HandleOtherDeviceEvent(&uevent);
495     auto exist = IsFileExist("/dev/usb-dev-1");
496     EXPECT_FALSE(exist);
497 }
498 
499 HWTEST_F(UeventdEventUnitTest, Init_UeventdEventUnitTest_HandleUsbDevicesWithBusNo001, TestSize.Level1)
500 {
501     struct Uevent uevent = {
502         .subsystem = "usb",
503         .syspath = "/devices/platform/headset/extcon/usb-dev",
504         .major = 8,
505         .minor = 9,
506         .busNum = 3,
507         .devNum = 4,
508     };
509     HandleOtherDeviceEvent(&uevent);
510     auto exist = IsFileExist("/dev/bus/usb/003/004");
511     EXPECT_TRUE(exist);
512 }
513 
514 HWTEST_F(UeventdEventUnitTest, Init_UeventdEventUnitTest_Handle001, TestSize.Level1)
515 {
516     char path[] = {"/data/ueventd"};
517     int ret = TestRetriggerUeventByPath(g_oldRootFd, path);
518     EXPECT_EQ(ret, 0);
519 }
520 
521 HWTEST_F(UeventdEventUnitTest, Init_UeventdEventUnitTest_FirmwareUevent001, TestSize.Level1)
522 {
523     struct Uevent uevent = {
524         .subsystem = "firmware",
525         .syspath = "/block/mmc/test",
526         .deviceName = "test",
527         .partitionName = "userdata",
528         .firmware = "",
529         .action = ACTION_ADD,
530         .partitionNum = 3,
531         .major = 1,
532         .minor = 2,
533         .ug = {
534             .uid = 0,
535             .gid = 0,
536         },
537         .busNum = 1,
538         .devNum = 2,
539     };
540 
541     std::vector<std::string> extraData{};
542     auto ueventBuffer = GenerateUeventBuffer(uevent, extraData);
543     struct Uevent outEvent;
544     ParseUeventMessage(ueventBuffer.data(), ueventBuffer.length(), &outEvent);
545     EXPECT_EQ(outEvent.action, ACTION_ADD);
546     EXPECT_EQ(outEvent.busNum, 1);
547     EXPECT_STREQ(outEvent.subsystem, "firmware");
548     EXPECT_STREQ(outEvent.deviceName, "test");
549     EXPECT_EQ(outEvent.devNum, 2);
550     EXPECT_EQ(outEvent.major, 1);
551     EXPECT_EQ(outEvent.minor, 2);
552     EXPECT_EQ(outEvent.partitionNum, 3);
553     EXPECT_STREQ(outEvent.partitionName, "userdata");
554     EXPECT_STREQ(outEvent.syspath, "/block/mmc/test");
555     EXPECT_EQ(outEvent.ug.gid, 0);
556     EXPECT_EQ(outEvent.ug.uid, 0);
557     HandleUevent(&outEvent);
558 }
559 
560 HWTEST_F(UeventdEventUnitTest, Init_UeventdEventTest_PlatformEvent001, TestSize.Level1)
561 {
562     struct Uevent uevent = {
563         .subsystem = "platform",
564         .syspath = "/block/mmc/test",
565         .deviceName = "test",
566         .partitionName = "userdata",
567         .firmware = "",
568         .action = ACTION_ADD,
569         .partitionNum = 3,
570         .major = 1,
571         .minor = 2,
572         .ug = {
573             .uid = 0,
574             .gid = 0,
575         },
576         .busNum = 1,
577         .devNum = 2,
578     };
579 
580     std::vector<std::string> extraData{};
581     auto ueventBuffer = GenerateUeventBuffer(uevent, extraData);
582     struct Uevent outEvent;
583     ParseUeventMessage(ueventBuffer.data(), ueventBuffer.length(), &outEvent);
584     EXPECT_EQ(outEvent.action, ACTION_ADD);
585     EXPECT_EQ(outEvent.busNum, 1);
586     EXPECT_STREQ(outEvent.subsystem, "platform");
587     EXPECT_STREQ(outEvent.deviceName, "test");
588     EXPECT_EQ(outEvent.devNum, 2);
589     EXPECT_EQ(outEvent.major, 1);
590     EXPECT_EQ(outEvent.minor, 2);
591     EXPECT_EQ(outEvent.partitionNum, 3);
592     EXPECT_STREQ(outEvent.partitionName, "userdata");
593     EXPECT_STREQ(outEvent.syspath, "/block/mmc/test");
594     EXPECT_EQ(outEvent.ug.gid, 0);
595     EXPECT_EQ(outEvent.ug.uid, 0);
596     HandleUevent(&outEvent);
597 }
598 
599 HWTEST_F(UeventdEventUnitTest, Init_UeventdEventUnitTest_PlatformEventUsb001, TestSize.Level1)
600 {
601     struct Uevent uevent = {
602         .subsystem = "usb",
603         .syspath = "/block/mmc/test",
604         .deviceName = "test",
605         .partitionName = "userdata",
606         .firmware = "",
607         .action = ACTION_ADD,
608         .partitionNum = 3,
609         .major = 1,
610         .minor = 2,
611         .ug = {
612             .uid = 0,
613             .gid = 0,
614         },
615         .busNum = 1,
616         .devNum = 2,
617     };
618 
619     std::vector<std::string> extraData{};
620     auto ueventBuffer = GenerateUeventBuffer(uevent, extraData);
621     struct Uevent outEvent;
622     ParseUeventMessage(ueventBuffer.data(), ueventBuffer.length(), &outEvent);
623     EXPECT_EQ(outEvent.action, ACTION_ADD);
624     EXPECT_EQ(outEvent.busNum, 1);
625     EXPECT_STREQ(outEvent.subsystem, "usb");
626     EXPECT_STREQ(outEvent.deviceName, "test");
627     EXPECT_EQ(outEvent.devNum, 2);
628     EXPECT_EQ(outEvent.major, 1);
629     EXPECT_EQ(outEvent.minor, 2);
630     EXPECT_EQ(outEvent.partitionNum, 3);
631     EXPECT_STREQ(outEvent.partitionName, "userdata");
632     EXPECT_STREQ(outEvent.syspath, "/block/mmc/test");
633     EXPECT_EQ(outEvent.ug.gid, 0);
634     EXPECT_EQ(outEvent.ug.uid, 0);
635     HandleUevent(&outEvent);
636 }
637 
TestUeventAction(ACTION action)638 static void TestUeventAction(ACTION action)
639 {
640     struct Uevent uevent = {
641         .subsystem = "block",
642         .syspath = "/block/mmc/test",
643         .deviceName = "test",
644         .partitionName = "userdata",
645         .firmware = "",
646         .action = action,
647         .partitionNum = 3,
648         .major = 1,
649         .minor = 2,
650         .ug = {
651             .uid = 0,
652             .gid = 0,
653         },
654         .busNum = 1,
655         .devNum = 2,
656     };
657 
658     std::vector<std::string> extraData{};
659     auto ueventBuffer = GenerateUeventBuffer(uevent, extraData);
660     struct Uevent outEvent;
661     ParseUeventMessage(ueventBuffer.data(), ueventBuffer.length(), &outEvent);
662     EXPECT_EQ(outEvent.action, action);
663     HandleUevent(&outEvent);
664 }
665 
666 HWTEST_F(UeventdEventUnitTest, Init_UeventdEventUnitTest_ActionAdd001, TestSize.Level1)
667 {
668     TestUeventAction(ACTION_ADD);
669     TestUeventAction(ACTION_REMOVE);
670     TestUeventAction(ACTION_CHANGE);
671     TestUeventAction(ACTION_MOVE);
672     TestUeventAction(ACTION_ONLINE);
673 
674     TestUeventAction(ACTION_OFFLINE);
675     TestUeventAction(ACTION_BIND);
676     TestUeventAction(ACTION_UNBIND);
677     TestUeventAction(ACTION_UNKNOWN);
678 }
679 } // UeventdUt