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 <cerrno>
17 #include <cstdio>
18 #include <cstdlib>
19 #include <string>
20 #include <fcntl.h>
21 #include <unistd.h>
22 #include <vector>
23 #include <arpa/inet.h>
24 #include <gtest/gtest.h>
25 #include <netinet/in.h>
26 #include <sys/stat.h>
27 #include <sys/socket.h>
28 #include <sys/types.h>
29 #include <sys/uio.h>
30 #include "securec.h"
31
32 using namespace testing::ext;
33
34 static const char *WRITEV_TEST_FILE = "/data/local/tmp/tryWritev.txt";
35 static const int VEC_LEN = 2;
36 static const char *TEST_DATA = "Hello writev";
37 static const int TEST_DATA_LEN = strlen(TEST_DATA);
38 static const char *TEST_DATA_BUF1 = "Hello ";
39 static const int BUF1_LEN = strlen(TEST_DATA_BUF1);
40 static const char *TEST_DATA_BUF2 = "writev";
41 static const int BUF2_LEN = strlen(TEST_DATA_BUF2);
42
43 class HatsWritevTest : public testing::Test {
44 public:
45 static void SetUpTestCase();
46 static void TearDownTestCase();
47 void SetUp();
48 void TearDown();
49 private:
50 };
SetUp()51 void HatsWritevTest::SetUp()
52 {
53 }
TearDown()54 void HatsWritevTest::TearDown()
55 {
56 }
SetUpTestCase()57 void HatsWritevTest::SetUpTestCase()
58 {
59 }
TearDownTestCase()60 void HatsWritevTest::TearDownTestCase()
61 {
62 unlink(WRITEV_TEST_FILE);
63 }
64
65 /*
66 * @tc.number : SUB_KERNEL_SYSCALL_WRITEV_0100
67 * @tc.name : WritevWriteDataToFileSuccess_0001
68 * @tc.desc : writev writes data to file success.
69 * @tc.size : MediumTest
70 * @tc.type : Function
71 * @tc.level : Level 1
72 */
73 HWTEST_F(HatsWritevTest, WritevWriteDataToFileSuccess_0001, Function | MediumTest | Level1)
74 {
75 int fd;
76 struct iovec vec[VEC_LEN];
77 int ret;
78 char *iovBuf1 = nullptr;
79 char *iovBuf2 = nullptr;
80 char *readBuf = nullptr;
81 iovBuf1 = new char[BUF1_LEN];
82 memcpy_s(iovBuf1, BUF1_LEN, TEST_DATA_BUF1, BUF1_LEN);
83 iovBuf2 = new char[BUF2_LEN];
84 memcpy_s(iovBuf2, BUF2_LEN, TEST_DATA_BUF2, BUF2_LEN);
85 vec[0].iov_base = iovBuf1;
86 vec[0].iov_len = BUF1_LEN;
87 vec[1].iov_base = iovBuf2;
88 vec[1].iov_len = BUF2_LEN;
89 readBuf = new char[TEST_DATA_LEN + 1];
90
91 fd = open(WRITEV_TEST_FILE, O_WRONLY | O_CREAT | O_TRUNC, 0644);
92 EXPECT_TRUE(fd >= 3);
93
94 ret = writev(fd, vec, VEC_LEN);
95 EXPECT_TRUE(ret == TEST_DATA_LEN);
96 close(fd);
97
98 fd = open(WRITEV_TEST_FILE, O_RDONLY);
99 EXPECT_TRUE(fd >= 3);
100 ret = read(fd, readBuf, TEST_DATA_LEN);
101 EXPECT_TRUE(ret == TEST_DATA_LEN);
102 readBuf[TEST_DATA_LEN] = '\0';
103 ret = strcmp(readBuf, TEST_DATA);
104 EXPECT_TRUE(ret == 0);
105 close(fd);
106 delete[] iovBuf1;
107 delete[] iovBuf2;
108 delete[] readBuf;
109 }
110
111 /*
112 * @tc.number : SUB_KERNEL_SYSCALL_WRITEV_0200
113 * @tc.name : WritevWriteToPipeSuccess_0002
114 * @tc.desc : Writev write data to pipe success.
115 * @tc.size : MediumTest
116 * @tc.type : Function
117 * @tc.level : Level 1
118 */
119 HWTEST_F(HatsWritevTest, WritevWriteToPipeSuccess_0002, Function | MediumTest | Level1)
120 {
121 int pipefd[2];
122 struct iovec vec[VEC_LEN];
123 int ret;
124 char *iovBuf1 = nullptr;
125 char *iovBuf2 = nullptr;
126 char *readBuf = nullptr;
127 iovBuf1 = new char[BUF1_LEN];
128 memcpy_s(iovBuf1, BUF1_LEN, TEST_DATA_BUF1, BUF1_LEN);
129 iovBuf2 = new char[BUF2_LEN];
130 memcpy_s(iovBuf2, BUF2_LEN, TEST_DATA_BUF2, BUF2_LEN);
131 vec[0].iov_base = iovBuf1;
132 vec[0].iov_len = BUF1_LEN;
133 vec[1].iov_base = iovBuf2;
134 vec[1].iov_len = BUF2_LEN;
135 readBuf = new char[TEST_DATA_LEN + 1];
136
137 ret = pipe(pipefd);
138 EXPECT_TRUE(ret == 0);
139 ret = writev(pipefd[1], vec, VEC_LEN);
140 EXPECT_TRUE(ret == TEST_DATA_LEN);
141
142 ret = read(pipefd[0], readBuf, TEST_DATA_LEN);
143 EXPECT_TRUE(ret == TEST_DATA_LEN);
144 readBuf[TEST_DATA_LEN] = '\0';
145 ret = strcmp(readBuf, TEST_DATA);
146 EXPECT_TRUE(ret == 0);
147
148 close(pipefd[0]);
149 close(pipefd[1]);
150 delete[] iovBuf1;
151 delete[] iovBuf2;
152 delete[] readBuf;
153 }
154
155
156 /*
157 * @tc.number : SUB_KERNEL_SYSCALL_WRITEV_0300
158 * @tc.name : WritevInvalidVecLenFail_0003
159 * @tc.desc : Writv write with invalid iovec length fail.
160 * @tc.size : MediumTest
161 * @tc.type : Function
162 * @tc.level : Level 2
163 */
164 HWTEST_F(HatsWritevTest, WritevInvalidVecLenFail_0003, Function | MediumTest | Level2)
165 {
166 int fd;
167 struct iovec vec[VEC_LEN];
168 int ret;
169 int newVecLen;
170 char *iovBuf1 = nullptr;
171 char *iovBuf2 = nullptr;
172 iovBuf1 = new char[BUF1_LEN];
173 ret = memcpy_s(iovBuf1, BUF1_LEN, TEST_DATA_BUF1, BUF1_LEN);
174 iovBuf2 = new char[BUF2_LEN];
175 ret = memcpy_s(iovBuf2, BUF2_LEN, TEST_DATA_BUF2, BUF2_LEN);
176 vec[0].iov_base = iovBuf1;
177 vec[0].iov_len = BUF1_LEN;
178 vec[1].iov_base = iovBuf2;
179 vec[1].iov_len = BUF2_LEN;
180
181 fd = open(WRITEV_TEST_FILE, O_WRONLY | O_CREAT | O_TRUNC, 0644);
182 EXPECT_TRUE(fd >= 3);
183
184 newVecLen = -1;
185 errno = 0;
186 ret = writev(fd, vec, newVecLen);
187 EXPECT_TRUE(ret == -1);
188 EXPECT_EQ(errno, EINVAL);
189
190 close(fd);
191 delete[] iovBuf1;
192 delete[] iovBuf2;
193 }
194
195 /*
196 * @tc.number : SUB_KERNEL_SYSCALL_WRITEV_0400
197 * @tc.name : WritevInvalidFdFail_0004
198 * @tc.desc : writev write data into invalid fd fail.
199 * @tc.size : MediumTest
200 * @tc.type : Function
201 * @tc.level : Level 2
202 */
203 HWTEST_F(HatsWritevTest, WritevInvalidFdFail_0004, Function | MediumTest | Level2)
204 {
205 int fd;
206 struct iovec vec[VEC_LEN];
207 int ret;
208 char *iovBuf1 = nullptr;
209 char *iovBuf2 = nullptr;
210 iovBuf1 = new char[BUF1_LEN];
211 ret = memcpy_s(iovBuf1, BUF1_LEN, TEST_DATA_BUF1, BUF1_LEN);
212 iovBuf2 = new char[BUF2_LEN];
213 ret = memcpy_s(iovBuf2, BUF2_LEN, TEST_DATA_BUF2, BUF2_LEN);
214 vec[0].iov_base = iovBuf1;
215 vec[0].iov_len = BUF1_LEN;
216 vec[1].iov_base = iovBuf2;
217 vec[1].iov_len = BUF2_LEN;
218
219 fd = -1;
220 errno = 0;
221 ret = writev(fd, vec, VEC_LEN);
222 EXPECT_TRUE(ret == -1);
223 EXPECT_EQ(errno, EBADF);
224
225 delete[] iovBuf1;
226 delete[] iovBuf2;
227 }
228
229 /*
230 * @tc.number : SUB_KERNEL_SYSCALL_WRITEV_0500
231 * @tc.name : WritevFdNotInWriteModeFail_0005
232 * @tc.desc : writev fd is not in write mode fail.
233 * @tc.size : MediumTest
234 * @tc.type : Function
235 * @tc.level : Level 2
236 */
237 HWTEST_F(HatsWritevTest, WritevFdNotInWriteModeFail_0005, Function | MediumTest | Level2)
238 {
239 int fd;
240 struct iovec vec[VEC_LEN];
241 int ret;
242 char *iovBuf1 = nullptr;
243 char *iovBuf2 = nullptr;
244 iovBuf1 = new char[BUF1_LEN];
245 ret = memcpy_s(iovBuf1, BUF1_LEN, TEST_DATA_BUF1, BUF1_LEN);
246 iovBuf2 = new char[BUF2_LEN];
247 ret = memcpy_s(iovBuf2, BUF2_LEN, TEST_DATA_BUF2, BUF2_LEN);
248 vec[0].iov_base = iovBuf1;
249 vec[0].iov_len = BUF1_LEN;
250 vec[1].iov_base = iovBuf2;
251 vec[1].iov_len = BUF2_LEN;
252
253 fd = open(WRITEV_TEST_FILE, O_RDONLY | O_CREAT | O_TRUNC, 0644);
254 EXPECT_TRUE(fd >= 3);
255 errno = 0;
256 ret = writev(fd, vec, VEC_LEN);
257 EXPECT_TRUE(ret == -1);
258 EXPECT_EQ(errno, EBADF);
259 close(fd);
260
261 fd = open(WRITEV_TEST_FILE, O_APPEND | O_CREAT | O_TRUNC, 0644);
262 EXPECT_TRUE(fd >= 3);
263 errno = 0;
264 ret = writev(fd, vec, VEC_LEN);
265 EXPECT_TRUE(ret == -1);
266 EXPECT_EQ(errno, EBADF);
267 close(fd);
268
269 delete[] iovBuf1;
270 delete[] iovBuf2;
271 }
272