1 /*
2 * Copyright (c) 2021-2025 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 <cstdio>
18 #include <cstdlib>
19 #include <string>
20 #include <vector>
21 #include <fcntl.h>
22 #include <unistd.h>
23 #include <gtest/gtest.h>
24 #include <sys/ipc.h>
25 #include <sys/types.h>
26 #include <sys/syscall.h>
27 #include "securec.h"
28 #include <mqueue.h>
29 #include <ctime>
30 #include <unistd.h>
31
32 using namespace testing::ext;
33 using namespace std;
34
35 #define QUEUE_NAME "test_queue"
36 #define MAX_SIZE 1024
37 #define MSG_STOP "exit"
38
39 class MqueueApiTest : public testing::Test {
40 public:
41 static void SetUpTestCase();
42 static void TearDownTestCase();
43 void SetUp();
44 void TearDown();
45 private:
46 };
SetUp()47 void MqueueApiTest::SetUp()
48 {
49 }
TearDown()50 void MqueueApiTest::TearDown()
51 {
52 }
SetUpTestCase()53 void MqueueApiTest::SetUpTestCase()
54 {
55 }
TearDownTestCase()56 void MqueueApiTest::TearDownTestCase()
57 {
58 }
59
60 /*
61 * @tc.number : SUB_KERNEL_SYSCALL_MQUEUE_0100
62 * @tc.name : MqueueApiTest_0001
63 * @tc.desc : remove and open message queue success.
64 * @tc.size : MediumTest
65 * @tc.type : Function
66 * @tc.level : Level 1
67 */
68 HWTEST_F(MqueueApiTest, MqueueApiTest_0001, Function | MediumTest | Level1)
69 {
70 mqd_t mq;
71
72 mq = syscall(__NR_mq_open, QUEUE_NAME, O_CREAT | O_RDWR, 0644, nullptr);
73 EXPECT_TRUE(mq > 0);
74
75 int ret = syscall(__NR_mq_unlink, QUEUE_NAME);
76 EXPECT_EQ(ret, 0);
77 }
78
79 /*
80 * @tc.number : SUB_KERNEL_SYSCALL_MQUEUE_0200
81 * @tc.name : MqueueApiTest_0002
82 * @tc.desc : open the exists message name to failed.
83 * @tc.size : MediumTest
84 * @tc.type : Function
85 * @tc.level : Level 1
86 */
87 HWTEST_F(MqueueApiTest, MqueueApiTest_0002, Function | MediumTest | Level1)
88 {
89 mqd_t mq;
90
91 mq = syscall(__NR_mq_open, QUEUE_NAME, O_CREAT | O_RDWR, 0644, nullptr);
92 EXPECT_TRUE(mq > 0);
93
94 errno = 0;
95 mq = syscall(__NR_mq_open, QUEUE_NAME, O_CREAT | O_EXCL, 0644, nullptr);
96 EXPECT_EQ(errno, EEXIST);
97 EXPECT_TRUE(mq == -1);
98
99 int ret = syscall(__NR_mq_unlink, QUEUE_NAME);
100 EXPECT_EQ(ret, 0);
101 }
102
103 /*
104 * @tc.number : SUB_KERNEL_SYSCALL_MQUEUE_0300
105 * @tc.name : MqueueApiTest_0003
106 * @tc.desc : the O_RDONLY to send message will failed.
107 * @tc.size : MediumTest
108 * @tc.type : Function
109 * @tc.level : Level 1
110 */
111 HWTEST_F(MqueueApiTest, MqueueApiTest_0003, Function | MediumTest | Level1)
112 {
113 mqd_t mq;
114 const char *buffer = "hello world";
115 struct timespec ts;
116
117 mq = syscall(__NR_mq_open, QUEUE_NAME, O_CREAT | O_RDONLY, 0644, nullptr);
118 EXPECT_TRUE(mq > 0);
119
120 errno = 0;
121 int ret = syscall(__NR_mq_timedsend, mq, buffer, strlen(buffer) + 1, 0, &ts);
122 EXPECT_EQ(errno, EBADF);
123 EXPECT_TRUE(ret == -1);
124
125 ret = syscall(__NR_mq_unlink, QUEUE_NAME);
126 EXPECT_EQ(ret, 0);
127 }
128
129 /*
130 * @tc.number : SUB_KERNEL_SYSCALL_MQUEUE_0400
131 * @tc.name : MqueueApiTest_0004
132 * @tc.desc : the O_WRONLY to recv message will failed.
133 * @tc.size : MediumTest
134 * @tc.type : Function
135 * @tc.level : Level 1
136 */
137 HWTEST_F(MqueueApiTest, MqueueApiTest_0004, Function | MediumTest | Level1)
138 {
139 mqd_t mq;
140 char recvBuf[MAX_SIZE] = { 0 };
141 struct timespec ts;
142
143 mq = syscall(__NR_mq_open, QUEUE_NAME, O_CREAT | O_WRONLY, 0644, nullptr);
144 EXPECT_TRUE(mq > 0);
145
146 errno = 0;
147 int ret = syscall(__NR_mq_timedreceive, mq, recvBuf, MAX_SIZE, nullptr, &ts);
148 EXPECT_EQ(errno, EBADF);
149 EXPECT_TRUE(ret == -1);
150
151 ret = syscall(__NR_mq_unlink, QUEUE_NAME);
152 EXPECT_EQ(ret, 0);
153 }
154
155 /*
156 * @tc.number : SUB_KERNEL_SYSCALL_MQUEUE_0500
157 * @tc.name : MqueueApiTest_0005
158 * @tc.desc : the O_NONBLOCK to recv message will failed.
159 * @tc.size : MediumTest
160 * @tc.type : Function
161 * @tc.level : Level 1
162 */
163 HWTEST_F(MqueueApiTest, MqueueApiTest_0005, Function | MediumTest | Level1)
164 {
165 mqd_t mq;
166 char recvBuf[MAX_SIZE] = { 0 };
167 struct timespec ts;
168 struct mq_attr attr;
169 attr.mq_flags = 0;
170 attr.mq_maxmsg = 10;
171 attr.mq_msgsize = MAX_SIZE;
172 attr.mq_curmsgs = 0;
173
174 mq = syscall(__NR_mq_open, QUEUE_NAME, O_CREAT | O_RDWR | O_NONBLOCK, 0644, &attr);
175 EXPECT_TRUE(mq > 0);
176
177 errno = 0;
178 clock_gettime(CLOCK_REALTIME, &ts);
179 ts.tv_sec += 2;
180 int bytesRead = syscall(__NR_mq_timedreceive, mq, recvBuf, MAX_SIZE, nullptr, &ts);
181 EXPECT_EQ(errno, EAGAIN);
182 EXPECT_TRUE(bytesRead == -1);
183
184 int ret = syscall(__NR_mq_unlink, QUEUE_NAME);
185 EXPECT_EQ(ret, 0);
186 }
187
188 /*
189 * @tc.number : SUB_KERNEL_SYSCALL_MQUEUE_0600
190 * @tc.name : MqueueApiTest_0006
191 * @tc.desc : send message buffer size low mq_maxmsg size will failed.
192 * @tc.size : MediumTest
193 * @tc.type : Function
194 * @tc.level : Level 2
195 */
196 HWTEST_F(MqueueApiTest, MqueueApiTest_0006, Function | MediumTest | Level2)
197 {
198 int ret;
199 mqd_t mq;
200 const char *buffer = "hello world";
201 struct timespec ts;
202 struct mq_attr attr;
203 attr.mq_flags = 0;
204 attr.mq_maxmsg = 1;
205 attr.mq_msgsize = 2;
206 attr.mq_curmsgs = 0;
207
208 clock_gettime(CLOCK_REALTIME, &ts);
209 ts.tv_sec += 2;
210
211 mq = syscall(__NR_mq_open, QUEUE_NAME, O_CREAT | O_RDWR | O_NONBLOCK, 0644, &attr);
212 EXPECT_TRUE(mq > 0);
213
214 errno = 0;
215 ret = syscall(__NR_mq_timedsend, mq, buffer, strlen(buffer) + 1, 0, &ts);
216 EXPECT_EQ(errno, EMSGSIZE);
217 EXPECT_EQ(ret, -1);
218
219 ret = syscall(__NR_mq_unlink, QUEUE_NAME);
220 EXPECT_EQ(ret, 0);
221 }
222
223 /*
224 * @tc.number : SUB_KERNEL_SYSCALL_MQUEUE_0700
225 * @tc.name : MqueueApiTest_0007
226 * @tc.desc : mqueue send message success.
227 * @tc.size : MediumTest
228 * @tc.type : Function
229 * @tc.level : Level 2
230 */
231 HWTEST_F(MqueueApiTest, MqueueApiTest_0007, Function | MediumTest | Level2)
232 {
233 int ret;
234 mqd_t mq;
235 const char *buffer = "hello world";
236 struct timespec ts;
237 struct mq_attr attr;
238 attr.mq_flags = 0;
239 attr.mq_maxmsg = 10;
240 attr.mq_msgsize = MAX_SIZE;
241 attr.mq_curmsgs = 0;
242
243 clock_gettime(CLOCK_REALTIME, &ts);
244 ts.tv_sec += 2;
245
246 mq = syscall(__NR_mq_open, QUEUE_NAME, O_CREAT | O_RDWR, 0644, &attr);
247 EXPECT_TRUE(mq > 0);
248
249 ret = syscall(__NR_mq_timedsend, mq, buffer, strlen(buffer) + 1, 0, &ts);
250 EXPECT_EQ(ret, 0);
251
252 ret = syscall(__NR_mq_unlink, QUEUE_NAME);
253 EXPECT_EQ(ret, 0);
254 }
255
256 /*
257 * @tc.number : SUB_KERNEL_SYSCALL_MQUEUE_0800
258 * @tc.name : MqueueApiTest_0008
259 * @tc.desc : recv message timeout and return failed.
260 * @tc.size : MediumTest
261 * @tc.type : Function
262 * @tc.level : Level 1
263 */
264 HWTEST_F(MqueueApiTest, MqueueApiTest_0008, Function | MediumTest | Level1)
265 {
266 mqd_t mq;
267 char buffer[MAX_SIZE] = { 0 };
268 struct timespec ts;
269 ssize_t bytesRead;
270
271 struct mq_attr attr;
272 attr.mq_flags = 0;
273 attr.mq_maxmsg = 10;
274 attr.mq_msgsize = MAX_SIZE;
275 attr.mq_curmsgs = 0;
276
277 mq = syscall(__NR_mq_open, QUEUE_NAME, O_CREAT | O_RDWR, 0644, &attr);
278 EXPECT_TRUE(mq > 0);
279
280 clock_gettime(CLOCK_REALTIME, &ts);
281 ts.tv_sec += 2;
282
283 errno = 0;
284 bytesRead = syscall(__NR_mq_timedreceive, mq, buffer, MAX_SIZE, NULL, &ts);
285 EXPECT_EQ(errno, ETIMEDOUT);
286 EXPECT_EQ(bytesRead, -1);
287
288 int ret = syscall(__NR_mq_unlink, QUEUE_NAME);
289 EXPECT_EQ(ret, 0);
290 }
291
292 /*
293 * @tc.number : SUB_KERNEL_SYSCALL_MQUEUE_0900
294 * @tc.name : MqueueApiTest_0009
295 * @tc.desc : remove message queue failed.
296 * @tc.size : MediumTest
297 * @tc.type : Function
298 * @tc.level : Level 1
299 */
300 HWTEST_F(MqueueApiTest, MqueueApiTest_0009, Function | MediumTest | Level1)
301 {
302 errno = 0;
303 int ret = syscall(__NR_mq_unlink, QUEUE_NAME);
304 EXPECT_EQ(ret, -1);
305 }
306
307 /*
308 * @tc.number : SUB_KERNEL_SYSCALL_MQUEUE_1000
309 * @tc.name : MqueueApiTest_0010
310 * @tc.desc : remove message queue success.
311 * @tc.size : MediumTest
312 * @tc.type : Function
313 * @tc.level : Level 2
314 */
315 HWTEST_F(MqueueApiTest, MqueueApiTest_0010, Function | MediumTest | Level2)
316 {
317 mqd_t mq = syscall(__NR_mq_open, QUEUE_NAME, O_RDWR | O_CREAT, 0644, NULL);
318 EXPECT_TRUE(mq > 0);
319
320 int ret = syscall(__NR_mq_unlink, QUEUE_NAME);
321 EXPECT_EQ(ret, 0);
322 }
323
324 /*
325 * @tc.number : SUB_KERNEL_SYSCALL_MQUEUE_1100
326 * @tc.name : MqueueApiTest_0011
327 * @tc.desc : mqueue send and receive success.
328 * @tc.size : MediumTest
329 * @tc.type : Function
330 * @tc.level : Level 2
331 */
332 HWTEST_F(MqueueApiTest, MqueueApiTest_0011, Function | MediumTest | Level2)
333 {
334 int ret;
335 mqd_t mq;
336 const char *sendBuf = "hello world";
337 char recvBuf[MAX_SIZE] = { 0 };
338 struct timespec ts;
339 struct mq_attr attr;
340 attr.mq_flags = 0;
341 attr.mq_maxmsg = 10;
342 attr.mq_msgsize = MAX_SIZE;
343 attr.mq_curmsgs = 0;
344
345 clock_gettime(CLOCK_REALTIME, &ts);
346 ts.tv_sec += 2;
347
348 mq = syscall(__NR_mq_open, QUEUE_NAME, O_CREAT | O_RDWR, 0644, &attr);
349 EXPECT_TRUE(mq > 0);
350
351 ret = syscall(__NR_mq_timedsend, mq, sendBuf, strlen(sendBuf) + 1, 0, &ts);
352 EXPECT_EQ(ret, 0);
353
354 errno = 0;
355 int bytesRead = syscall(__NR_mq_timedreceive, mq, recvBuf, MAX_SIZE, nullptr, &ts);
356 EXPECT_TRUE(bytesRead > 0);
357
358 ret = memcmp(sendBuf, recvBuf, strlen(sendBuf));
359 EXPECT_EQ(ret, 0);
360
361 ret = syscall(__NR_mq_unlink, QUEUE_NAME);
362 EXPECT_EQ(ret, 0);
363 }
364