• 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 
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