1 /*
2 * Copyright (c) 2021 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 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <stdlib.h>
19 #include <limits.h>
20 #include <sys/shm.h>
21 #include <assert.h>
22 #include <unistd.h>
23 #include <gtest/gtest.h>
24 #include "utils.h"
25 #include "mt_utils.h"
26 #include "log.h"
27 #include "KernelConstants.h"
28
29 using namespace testing::ext;
30
31 class ProcessTest : public::testing::Test {
32 };
33
34 /**
35 * @tc.number SUB_KERNEL_PROCESS_LINE_BIGEXIT_0100
36 * @tc.name Basic test about _Exit
37 * @tc.desc [C- SOFTWARE -0200]
38 */
HWTEST_F(ProcessTest, testLineBigExit, Function | MediumTest | Level2)39 HWTEST_F(ProcessTest, testLineBigExit, Function | MediumTest | Level2)
40 {
41 int exitCode;
42 pid_t pid;
43 int reInt[4] = {0, 1, 100, 255};
44
45 for (int i = 0; i < sizeof(reInt) / sizeof(int); i++) {
46 pid = fork();
47 ASSERT_TRUE(pid >= 0) << "> parent: fork errno = " << errno;
48 if (pid == 0) {
49 _Exit(reInt[i]);
50 }
51 Msleep(50);
52 exitCode = 0;
53 ASSERT_EQ(CheckProcStatus(pid, &exitCode, 0), 1);
54 ASSERT_EQ(exitCode, reInt[i]);
55 }
56 }
57
58 /**
59 * @tc.number SUB_KERNEL_PROCESS_LINE_BIGEXIT_0200
60 * @tc.name Test _Exit about IO flush
61 * @tc.desc [C- SOFTWARE -0200]
62 */
HWTEST_F(ProcessTest, testLineBigExitFlush, Function | MediumTest | Level3)63 HWTEST_F(ProcessTest, testLineBigExitFlush, Function | MediumTest | Level3)
64 {
65 const char* testFile = "TEST_FILE.txt";
66 char writeBuf[] = "this is a file";
67 char readBuf[20] = {0};
68 pid_t pid;
69
70 pid = fork();
71 ASSERT_TRUE(pid >= 0) << "> parent: fork errno = " << errno;
72 if (pid == 0) {
73
74 // write
75 FILE *fp = fopen(testFile, "w+");
76 if (fp == nullptr) {
77 LOG("> child fopen errno = %d", errno);
78 _Exit(1);
79 }
80 fwrite(writeBuf, sizeof(writeBuf), 1, fp);
81 _Exit(0);
82 }
83
84 WaitProcExitedOK(pid);
85
86 // read
87 FILE *fp = fopen(testFile, "r+");
88 ASSERT_NE(fp, nullptr) << "> fopen errno = " << errno;
89 EXPECT_EQ(fread(readBuf, sizeof(writeBuf), 1, fp), 0);
90 EXPECT_STRNE(writeBuf, readBuf) << "> writeBuf = " << writeBuf\
91 << "\n> readBuf = " << readBuf;
92 EXPECT_NE(fclose(fp), -1) << "> fclose errno =" <<errno;
93 remove(testFile);
94 }
95
96 int g_shmid0;
97
AtexitCallback0(void)98 void AtexitCallback0(void)
99 {
100 LOG("> AtexitCallback0");
101 pid_t *shared = (int*)shmat(g_shmid0, nullptr, 0);
102 if (shared == (void *)-1) {
103 LOG("> AtexitCallback0 shmat errno = %d", errno);
104 _Exit(1);
105 }
106 *shared = getppid();
107 if ((shmdt(shared)) == -1) {
108 LOG("> AtexitCallback0 shmdt errno = %d", errno);
109 _Exit(1);
110 }
111 LOG("> 333");
112 }
113
114 /**
115 * @tc.number SUB_KERNEL_PROCESS_LINE_BIGEXIT_0300
116 * @tc.name Test _Exit about call functions registered with atexit
117 * @tc.desc [C- SOFTWARE -0200]
118 */
HWTEST_F(ProcessTest, testLineBigExitAtexit, Function | MediumTest | Level3)119 HWTEST_F(ProcessTest, testLineBigExitAtexit, Function | MediumTest | Level3)
120 {
121 const int memSize = 1024;
122 g_shmid0 = shmget(IPC_PRIVATE, memSize, 0666 | IPC_CREAT);
123 ASSERT_NE(g_shmid0, -1) << "> parent: shmid errno = " << errno;
124 pid_t pid = fork();
125 ASSERT_TRUE(pid >= 0) << "> parent: fork errno = " << errno;
126 if (pid == 0) {
127 Msleep(20);
128 if (atexit(AtexitCallback0) != 0) {
129 _Exit(1);
130 }
131 LOG("> 222");
132 _Exit(0);
133 }
134 pid_t *shared = (int*)shmat(g_shmid0, nullptr, 0);
135 LOG("> 111");
136 WaitProcExitedOK(pid);
137 LOG("> 444");
138 ASSERT_NE(shared, (void*)-1) << "> shmat errno = " << errno;
139 EXPECT_NE(*shared, getpid());
140 ASSERT_NE(shmdt(shared), -1) << "> parent: shmdt errno = " << errno;
141 ASSERT_NE(shmctl(g_shmid0, IPC_RMID, nullptr), -1) << "> shmctl : IPC_RMID : errno = " << errno;
142 }
143
144 /**
145 * @tc.number SUB_KERNEL_PROCESS_LINE_EXIT_0100
146 * @tc.name Basic test about _exit
147 * @tc.desc [C- SOFTWARE -0200]
148 */
HWTEST_F(ProcessTest, testLineExit, Function | MediumTest | Level2)149 HWTEST_F(ProcessTest, testLineExit, Function | MediumTest | Level2)
150 {
151 int exitCode;
152 pid_t pid;
153 int reInt[4] = {0, 1, 100, 255};
154
155 for (int i = 0; i < sizeof(reInt) / sizeof(int); i++) {
156 pid = fork();
157 ASSERT_TRUE(pid >= 0) << "> parent: fork errno = " << errno;
158 if (pid == 0) {
159 _exit(reInt[i]);
160 }
161 Msleep(50);
162 exitCode = 0;
163 ASSERT_EQ(CheckProcStatus(pid, &exitCode, 0), 1);
164 ASSERT_EQ(exitCode, reInt[i]);
165 }
166 }
167
168 /**
169 * @tc.number SUB_KERNEL_PROCESS_LINE_EXIT_0200
170 * @tc.name Test _exit about IO flush
171 * @tc.desc [C- SOFTWARE -0200]
172 */
HWTEST_F(ProcessTest, testLineExitFlush, Function | MediumTest | Level3)173 HWTEST_F(ProcessTest, testLineExitFlush, Function | MediumTest | Level3)
174 {
175 const char* testFile = "TEST_FILE.txt";
176 char writeBuf[] = "this is a file";
177 char readBuf[20] = {0};
178 pid_t pid;
179
180 pid = fork();
181 ASSERT_TRUE(pid >= 0) << "> parent: fork errno = " << errno;
182 if (pid == 0) {
183
184 // write
185 FILE *fp = fopen(testFile, "w+");
186 if (fp == nullptr) {
187 LOG("> child fopen errno = %d", errno);
188 _exit(1);
189 }
190 fwrite(writeBuf, sizeof(writeBuf), 1, fp);
191 _exit(0);
192 }
193
194 WaitProcExitedOK(pid);
195
196 // read
197 FILE *fp = fopen(testFile, "r+");
198 ASSERT_NE(fp, nullptr) << "> fopen errno = " << errno;
199 EXPECT_EQ(fread(readBuf, sizeof(writeBuf), 1, fp), 0);
200 EXPECT_STRNE(writeBuf, readBuf) << "> writeBuf = " << writeBuf\
201 << "\n> readBuf = " << readBuf;
202 EXPECT_NE(fclose(fp), -1) << "> fclose errno =" <<errno;
203 remove(testFile);
204 }
205
206 int g_shmid1;
207
AtexitCallback1(void)208 void AtexitCallback1(void)
209 {
210 LOG("> AtexitCallback0");
211 pid_t *shared = (int*)shmat(g_shmid1, nullptr, 0);
212 if (shared == (void *)-1) {
213 LOG("> AtexitCallback0 shmat errno = %d", errno);
214 _exit(1);
215 }
216 *shared = getppid();
217 if ((shmdt(shared)) == -1) {
218 LOG("> AtexitCallback0 shmdt errno = %d", errno);
219 _exit(1);
220 }
221 LOG("> 333");
222 }
223
224 /**
225 * @tc.number SUB_KERNEL_PROCESS_LINE_EXIT_0300
226 * @tc.name Test _exit about call functions registered with atexit
227 * @tc.desc [C- SOFTWARE -0200]
228 */
HWTEST_F(ProcessTest, testLineExitAtexit, Function | MediumTest | Level3)229 HWTEST_F(ProcessTest, testLineExitAtexit, Function | MediumTest | Level3)
230 {
231 const int memSize = 1024;
232 g_shmid1 = shmget(IPC_PRIVATE, memSize, 0666 | IPC_CREAT);
233 ASSERT_NE(g_shmid1, -1) << "> parent: shmid errno = " << errno;
234 pid_t pid = fork();
235 ASSERT_TRUE(pid >= 0) << "> parent: fork errno = " << errno;
236 if (pid == 0) {
237 Msleep(20);
238 if (atexit(AtexitCallback1) != 0) {
239 _exit(1);
240 }
241 LOG("> 222");
242 _exit(0);
243 }
244 pid_t *shared = (int*)shmat(g_shmid1, nullptr, 0);
245 LOG("> 111");
246 WaitProcExitedOK(pid);
247 LOG("> 444");
248 ASSERT_NE(shared, (void*)-1) << "> shmat errno = " << errno;
249 EXPECT_NE(*shared, getpid());
250 ASSERT_NE(shmdt(shared), -1) << "> parent: shmdt errno = " << errno;
251 ASSERT_NE(shmctl(g_shmid1, IPC_RMID, nullptr), -1) << "> shmctl : IPC_RMID : errno = " << errno;
252 }
253
254 /**
255 * @tc.number SUB_KERNEL_PROCESS_EXIT_0100
256 * @tc.name Basic test about exit
257 * @tc.desc [C- SOFTWARE -0200]
258 */
HWTEST_F(ProcessTest, testExit, Function | MediumTest | Level2)259 HWTEST_F(ProcessTest, testExit, Function | MediumTest | Level2)
260 {
261 int exitCode;
262 pid_t pid;
263 int reInt[4] = {0, 1, 100, 255};
264
265 for (int i = 0; i < sizeof(reInt) / sizeof(int); i++) {
266 pid = fork();
267 ASSERT_TRUE(pid >= 0) << "> parent: fork errno = " << errno;
268 if (pid == 0) {
269 exit(reInt[i]);
270 }
271 Msleep(50);
272 exitCode = 0;
273 ASSERT_EQ(CheckProcStatus(pid, &exitCode, 0), 1);
274 ASSERT_EQ(exitCode, reInt[i]);
275 }
276 }
277 /**
278 * @tc.number SUB_KERNEL_PROCESS_ASSERT_0100
279 * @tc.name Basic test about assert true
280 * @tc.desc [C- SOFTWARE -0200]
281 */
HWTEST_F(ProcessTest, testAssertTrue, Function | MediumTest | Level3)282 HWTEST_F(ProcessTest, testAssertTrue, Function | MediumTest | Level3)
283 {
284 pid_t pid = fork();
285 ASSERT_TRUE(pid >= 0) << "> parent: fork errno = " << errno;
286 if (pid == 0) {
287 assert(true);
288 exit(0);
289 }
290 Msleep(50);
291 WaitProcExitedOK(pid);
292 }
293
FunctionAssertFalse(void)294 int FunctionAssertFalse(void)
295 {
296 pid_t pid = fork();
297 if (pid < 0) {
298 LOG("> fork errno = %d", errno);
299 return 0;
300 } else if (pid == 0) {
301 assert(false);
302 LOG("> child not stop");
303 exit(0);
304 }
305 Msleep(50);
306 int exitCode = 0;
307 int reInt = CheckProcStatus(pid, &exitCode, 0);
308 if ((reInt == 2) && (exitCode == SIGABRT)) {
309 LOG("> Success");
310 return 1;
311 }
312 LOG("> Fail");
313 return 0;
314 }
315
316 /**
317 * @tc.number SUB_KERNEL_PROCESS_ASSERT_0200
318 * @tc.name Basic test about assert false
319 * @tc.desc [C- SOFTWARE -0200]
320 */
HWTEST_F(ProcessTest, testAssertFalse, Function | MediumTest | Level3)321 HWTEST_F(ProcessTest, testAssertFalse, Function | MediumTest | Level3)
322 {
323 pid_t pid = fork();
324 ASSERT_TRUE(pid >= 0) << "> parent: fork errno = " << errno;
325 if (pid == 0) {
326 assert(false);
327 LOG("> child not stop");
328 exit(0);
329 }
330 Msleep(50);
331 int exitCode = 0;
332 ASSERT_EQ(CheckProcStatus(pid, &exitCode, 0), 2);
333 ASSERT_EQ(exitCode, SIGABRT);
334 }
335
336 int g_shmid;
337
AtexitCallback(void)338 void AtexitCallback(void)
339 {
340 LOG("> AtexitCallback");
341 pid_t *shared = (int*)shmat(g_shmid, nullptr, 0);
342 if (shared == (void *)-1) {
343 LOG("> AtexitCallback shmat errno = %d", errno);
344 exit(1);
345 }
346 *shared = getppid();
347 if ((shmdt(shared)) == -1) {
348 LOG("> AtexitCallback shmdt errno = %d", errno);
349 exit(1);
350 }
351 }
352
353 /**
354 * @tc.number SUB_KERNEL_PROCESS_ATEXIT_0100
355 * @tc.name Basic test about atexit
356 * @tc.desc [C- SOFTWARE -0200]
357 */
HWTEST_F(ProcessTest, testAtexit, Function | MediumTest | Level3)358 HWTEST_F(ProcessTest, testAtexit, Function | MediumTest | Level3)
359 {
360 const int memSize = 1024;
361 g_shmid = shmget(IPC_PRIVATE, memSize, 0666 | IPC_CREAT);
362 ASSERT_NE(g_shmid, -1) << "> parent: shmid errno = " << errno;
363 pid_t pid = fork();
364 ASSERT_TRUE(pid >= 0) << "> parent: fork errno = " << errno;
365 if (pid == 0) {
366 Msleep(20);
367 if (atexit(AtexitCallback) != 0) {
368 LOG("> atexit errno = %d", errno);
369 exit(1);
370 }
371 exit(0);
372 }
373 pid_t *shared = (int*)shmat(g_shmid, nullptr, 0);
374
375 WaitProcExitedOK(pid);
376 ASSERT_NE(shared, (void*)-1) << "> shmat errno = " << errno;
377 EXPECT_EQ(*shared, getpid());
378 ASSERT_NE(shmdt(shared), -1) << "> parent: shmdt errno = " << errno;
379 ASSERT_NE(shmctl(g_shmid, IPC_RMID, nullptr), -1) << "> shmctl : IPC_RMID : errno = " << errno;
380 }
381
382 /**
383 * @tc.number SUB_KERNEL_PROCESS_WAIT_0100
384 * @tc.name test wait return
385 * @tc.desc [C- SOFTWARE -0200]
386 */
HWTEST_F(ProcessTest, testWaitReturn, Function | MediumTest | Level3)387 HWTEST_F(ProcessTest, testWaitReturn, Function | MediumTest | Level3)
388 {
389 InitGlobalVariable();
390 pid_t pid = fork();
391 ASSERT_TRUE(pid >= 0) << "> fork errno = " << errno;
392 if (pid == 0) {
393 int myPid = (int)getpid();
394 LOG("> child pid = %d", myPid);
395 SetGlobalVariable(myPid);
396 exit(0);
397 }
398 Msleep(20);
399 int pidChild = (int)wait(nullptr);
400 LOG("> pidChild = %d", pidChild);
401 int expectPid = GetGlobalVariable();
402 EXPECT_EQ(pidChild, expectPid);
403 DeleteGlobalVariable();
404 }
405
406
407 /**
408 * @tc.number SUB_KERNEL_PROCESS_WAIT_0200
409 * @tc.name test wait parameter
410 * @tc.desc [C- SOFTWARE -0200]
411 */
HWTEST_F(ProcessTest, testWaitTest, Function | MediumTest | Level3)412 HWTEST_F(ProcessTest, testWaitTest, Function | MediumTest | Level3)
413 {
414 int childReturn = GetRandom(256) - 1;
415 LOG("> childReturn = %d", childReturn);
416
417 pid_t pid = fork();
418 ASSERT_TRUE(pid >= 0) << "> fork errno = " << errno;
419 if (pid == 0) {
420 exit(childReturn);
421 }
422 Msleep(20);
423 int status = 0;
424 int pidChild = (int)wait(&status);
425 EXPECT_NE(pidChild, -1);
426 EXPECT_TRUE(WIFEXITED(status));
427 EXPECT_EQ(WEXITSTATUS(status), childReturn);
428 }
429
430 /**
431 * @tc.number SUB_KERNEL_PROCESS_WAIT_0300
432 * @tc.name test wait killed by SIGABRT
433 * @tc.desc [C- SOFTWARE -0200]
434 */
HWTEST_F(ProcessTest, testWaitKilled, Function | MediumTest | Level3)435 HWTEST_F(ProcessTest, testWaitKilled, Function | MediumTest | Level3)
436 {
437 pid_t pid = fork();
438 ASSERT_TRUE(pid >= 0) << "> fork errno = " << errno;
439 if (pid == 0) {
440 Msleep(40);
441 exit(0);
442 }
443 Msleep(20);
444 kill(pid, SIGABRT);
445 int status = 0;
446 int pidChild = (int)wait(&status);
447 EXPECT_NE(pidChild, -1);
448 EXPECT_TRUE(WIFSIGNALED(status));
449 EXPECT_EQ(WTERMSIG(status), SIGABRT);
450 }
451
452 /**
453 * @tc.number SUB_KERNEL_PROCESS_WAITPID_0100
454 * @tc.name waitpid basic test
455 * @tc.desc [C- SOFTWARE -0200]
456 */
HWTEST_F(ProcessTest, testWaitPidBasic, Function | MediumTest | Level3)457 HWTEST_F(ProcessTest, testWaitPidBasic, Function | MediumTest | Level3)
458 {
459 int childReturn = GetRandom(128) - 1;
460 LOG("> childReturn = %d", childReturn);
461
462 pid_t pid = fork();
463 ASSERT_TRUE(pid >= 0) << "> fork errno = " << errno;
464 if (pid == 0) {
465 exit(childReturn);
466 }
467 Msleep(20);
468 int status = 0;
469 int pidChild = (int)waitpid(pid, &status, 0);
470 EXPECT_NE(pidChild, -1);
471 EXPECT_TRUE(WIFEXITED(status));
472 EXPECT_EQ(WEXITSTATUS(status), childReturn);
473 }
474
475 /**
476 * @tc.number SUB_KERNEL_PROCESS_WAITPID_0200
477 * @tc.name test waitpid with WNOHANG
478 * @tc.desc [C- SOFTWARE -0200]
479 */
HWTEST_F(ProcessTest, testWaitPidTest, Function | MediumTest | Level3)480 HWTEST_F(ProcessTest, testWaitPidTest, Function | MediumTest | Level3)
481 {
482 InitGlobalVariable();
483 SetGlobalVariable(1);
484 pid_t pid = fork();
485 ASSERT_TRUE(pid >= 0) << "> fork errno = " << errno;
486 if (pid == 0) {
487 Msleep(50);
488 SetGlobalVariable(2);
489 exit(0);
490 }
491 Msleep(20);
492 int status = 0;
493 int pidChild = (int)waitpid(pid, &status, WNOHANG);
494 int expectPid = GetGlobalVariable();
495 EXPECT_EQ(expectPid, 1);
496 EXPECT_EQ(pidChild, 0);
497 Msleep(50);
498 WaitProcExitedOK(pid);
499 DeleteGlobalVariable();
500 }
501