1 /*
2  * Copyright (C) 2024 HiHope Open Source Organization.
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 <fcntl.h>
17 #include <string>
18 #include <unistd.h>
19 #include <gtest/gtest.h>
20 #include <sys/stat.h>
21 #include <sys/sysmacros.h>
22 #include <sys/types.h>
23 #include "securec.h"
24 
25 using namespace testing::ext;
26 using namespace std;
27 
28 static const char *OPEN_API_TEST_PATH = "/data/local/tmp";
29 static const char *TEST_PATH = "/data/local/tmp/test_path";
30 static const char *TEST_PATH_REG = "/data/local/tmp/test_reg";
31 static const char *TEST_PATH_CHR = "/data/local/tmp/test_chr";
32 static const char *TEST_PATH_BLK = "/data/local/tmp/test_blk";
33 static const char *TEST_PATH_SOCK = "/data/local/tmp/test_sock";
34 
35 class MknodatApiTest : public testing::Test {
36 public:
37     static void SetUpTestCase();
38     static void TearDownTestCase();
39     void SetUp();
40     void TearDown();
41 private:
42 };
SetUp()43 void MknodatApiTest::SetUp()
44 {
45 }
TearDown()46 void MknodatApiTest::TearDown()
47 {
48 }
SetUpTestCase()49 void MknodatApiTest::SetUpTestCase()
50 {
51 }
TearDownTestCase()52 void MknodatApiTest::TearDownTestCase()
53 {
54 }
55 
56 /*
57  * @tc.number : SUB_KERNEL_SYSCALL_MKNODAT_0100
58  * @tc.name   : MknodatCreateDirSuccess_0001
59  * @tc.desc   : mknodat create a directory by fd success.
60  * @tc.size   : MediumTest
61  * @tc.type   : Function
62  * @tc.level  : Level 1
63  */
HWTEST_F(MknodatApiTest, MknodatCreateDirSuccess_0001, Function | MediumTest | Level1)64 HWTEST_F(MknodatApiTest, MknodatCreateDirSuccess_0001, Function | MediumTest | Level1)
65 {
66     const char *testPath = "test_path";
67     mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO;
68     int dirFd = open(OPEN_API_TEST_PATH, O_RDONLY);
69     EXPECT_TRUE(dirFd > 0);
70 
71     int ret = mknodat(dirFd, testPath, S_IFIFO | mode, 0);
72     EXPECT_TRUE(ret == 0);
73     close(dirFd);
74     unlink(TEST_PATH);
75 }
76 /*
77  * @tc.number : SUB_KERNEL_SYSCALL_MKNODAT_0200
78  * @tc.name   : MknodatCreateExistDirFailed_0002
79  * @tc.desc   : mknodat create the exist directory failed, errno EEXIST.
80  * @tc.size   : MediumTest
81  * @tc.type   : Function
82  * @tc.level  : Level 2
83  */
HWTEST_F(MknodatApiTest, MknodatCreateExistDirFailed_0002, Function | MediumTest | Level2)84 HWTEST_F(MknodatApiTest, MknodatCreateExistDirFailed_0002, Function | MediumTest | Level2)
85 {
86     mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO;
87     errno = 0;
88     int ret = mknodat(AT_FDCWD, OPEN_API_TEST_PATH, mode, 0);
89     EXPECT_EQ(ret, -1);
90     EXPECT_EQ(errno, EEXIST);
91 }
92 
93 /*
94  * @tc.number : SUB_KERNEL_SYSCALL_MKNODAT_0300
95  * @tc.name   : MknodatCreatePathInNotExistDirFailed_0003
96  * @tc.desc   : mknodat path in not exist directory failed, errno ENOENT.
97  * @tc.size   : MediumTest
98  * @tc.type   : Function
99  * @tc.level  : Level 2
100  */
HWTEST_F(MknodatApiTest, MknodatCreatePathInNotExistDirFailed_0003, Function | MediumTest | Level2)101 HWTEST_F(MknodatApiTest, MknodatCreatePathInNotExistDirFailed_0003, Function | MediumTest | Level2)
102 {
103     const char *path = "/data/local/tmp/abcd/abcd";
104     mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO;
105     errno = 0;
106     int ret = mknodat(AT_FDCWD, path, mode, 0);
107     EXPECT_EQ(ret, -1);
108     EXPECT_EQ(errno, ENOENT);
109 }
110 
111 /*
112  * @tc.number : SUB_KERNEL_SYSCALL_MKNODAT_0400
113  * @tc.name   : MknodatUseInvalidFdFailed_0004
114  * @tc.desc   : mknodat use invalid fd failed, errno EBADF.
115  * @tc.size   : MediumTest
116  * @tc.type   : Function
117  * @tc.level  : Level 2
118  */
HWTEST_F(MknodatApiTest, MknodatUseInvalidFdFailed_0004, Function | MediumTest | Level2)119 HWTEST_F(MknodatApiTest, MknodatUseInvalidFdFailed_0004, Function | MediumTest | Level2)
120 {
121     const char *testPath = "test_path";
122     mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO;
123     errno = 0;
124     int ret = mknodat(-1, testPath, mode, 0);
125     EXPECT_EQ(ret, -1);
126     EXPECT_EQ(errno, EBADF);
127 }
128 
129 /*
130  * @tc.number : SUB_KERNEL_SYSCALL_MKNODAT_0500
131  * @tc.name   : MknodatCreateRegularFileSuccess_0005
132  * @tc.desc   : mknodat create a regular file by fd success.
133  * @tc.size   : MediumTest
134  * @tc.type   : Function
135  * @tc.level  : Level 1
136  */
HWTEST_F(MknodatApiTest, MknodatCreateRegularFileSuccess_0005, Function | MediumTest | Level1)137 HWTEST_F(MknodatApiTest, MknodatCreateRegularFileSuccess_0005, Function | MediumTest | Level1)
138 {
139     const char *testPath = TEST_PATH_REG;
140     mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO;
141     int dirFd = open(OPEN_API_TEST_PATH, O_RDONLY);
142     EXPECT_TRUE(dirFd > 0);
143 
144     int ret = mknodat(dirFd, testPath, S_IFREG | mode, 0);
145     EXPECT_TRUE(ret == 0);
146     close(dirFd);
147     unlink(testPath);
148 }
149 
150 /*
151  * @tc.number : SUB_KERNEL_SYSCALL_MKNODAT_0600
152  * @tc.name   : MknodatCreateCharacterDeviceSuccess_0006
153  * @tc.desc   : mknodat create a character device by fd success.
154  * @tc.size   : MediumTest
155  * @tc.type   : Function
156  * @tc.level  : Level 1
157  */
HWTEST_F(MknodatApiTest, MknodatCreateCharacterDeviceSuccess_0006, Function | MediumTest | Level1)158 HWTEST_F(MknodatApiTest, MknodatCreateCharacterDeviceSuccess_0006, Function | MediumTest | Level1)
159 {
160     const char *testPath = TEST_PATH_CHR;
161     mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO;
162     int dirFd = open(OPEN_API_TEST_PATH, O_RDONLY);
163     EXPECT_TRUE(dirFd > 0);
164 
165     int ret = mknodat(dirFd, testPath, S_IFCHR | mode, makedev(1, 3));
166     EXPECT_TRUE(ret == 0);
167     close(dirFd);
168     unlink(testPath);
169 }
170 
171 /*
172  * @tc.number : SUB_KERNEL_SYSCALL_MKNODAT_0700
173  * @tc.name   : MknodatCreateBlockDeviceSuccess_0007
174  * @tc.desc   : mknodat create a block device by fd success.
175  * @tc.size   : MediumTest
176  * @tc.type   : Function
177  * @tc.level  : Level 1
178  */
HWTEST_F(MknodatApiTest, MknodatCreateBlockDeviceSuccess_0007, Function | MediumTest | Level1)179 HWTEST_F(MknodatApiTest, MknodatCreateBlockDeviceSuccess_0007, Function | MediumTest | Level1)
180 {
181     const char *testPath = TEST_PATH_BLK;
182     mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO;
183     int dirFd = open(OPEN_API_TEST_PATH, O_RDONLY);
184     EXPECT_TRUE(dirFd > 0);
185 
186     int ret = mknodat(dirFd, testPath, S_IFBLK | mode, makedev(1, 4));
187     EXPECT_TRUE(ret == 0);
188     close(dirFd);
189     unlink(testPath);
190 }
191 
192 /*
193  * @tc.number : SUB_KERNEL_SYSCALL_MKNODAT_0800
194  * @tc.name   : MknodatCreateSocketSuccess_0008
195  * @tc.desc   : mknodat create a socket by fd success.
196  * @tc.size   : MediumTest
197  * @tc.type   : Function
198  * @tc.level  : Level 1
199  */
HWTEST_F(MknodatApiTest, MknodatCreateSocketSuccess_0008, Function | MediumTest | Level1)200 HWTEST_F(MknodatApiTest, MknodatCreateSocketSuccess_0008, Function | MediumTest | Level1)
201 {
202     const char *testPath = TEST_PATH_SOCK;
203     mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO;
204     int dirFd = open(OPEN_API_TEST_PATH, O_RDONLY);
205     EXPECT_TRUE(dirFd > 0);
206 
207     int ret = mknodat(dirFd, testPath, S_IFSOCK | mode, 0);
208     EXPECT_TRUE(ret == 0);
209     close(dirFd);
210     unlink(testPath);
211 }