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