• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <info/fatal_message.h>
17 
18 #include <errno.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <test.h>
23 #include <pthread.h>
24 #include <unistd.h>
25 #include <sys/wait.h>
26 
27 #define EXPECT_TRUE(c)                \
28     do                                \
29     {                                 \
30         if (!(c))                     \
31             t_error("[%s] failed\n"); \
32     } while (0)
33 
34 #define FORK(fpid)                    \
35     do                                \
36     {                                 \
37         if (fpid < 0) {               \
38             t_error("error in fork!");\
39         }                             \
40     } while (0)
41 
42 typedef void (*TEST_FUN)(void);
43 static const int WAIT_TIME = 1;
44 
45 /**
46  * @tc.name      : get_fatal_message
47  * @tc.desc      : Test the function of get_fatal_message.
48  * @tc.level     : Level 0
49  */
fatal_message_0010(void)50 static void fatal_message_0010(void)
51 {
52     fatal_msg_t *fatal_message = get_fatal_message();
53     EXPECT_TRUE(fatal_message == NULL);
54 }
55 
56 /**
57  * @tc.name      : set_fatal_message
58  * @tc.desc      : Test the function of set_fatal_message.
59  * @tc.level     : Level 0
60  */
fatal_message_0020(void)61 static void fatal_message_0020(void)
62 {
63     const char msg[1024] = {"abcdefghijklmnopqrstuvwxyz1234567890"};
64     fatal_msg_t *fatal_message = NULL;
65 
66     int childRet = 0;
67     int pidParent = 0;
68     int pidChild = 0;
69 
70     pid_t fpid;
71     fpid = fork();
72     FORK(fpid);
73     if (fpid == 0) {
74         pidChild = getpid();
75         set_fatal_message(msg);
76         fatal_message = get_fatal_message();
77         EXPECT_TRUE(strcmp(fatal_message->msg, msg) == 0);
78         exit(0);
79     }
80     waitpid(fpid, &childRet, 0);
81     EXPECT_TRUE(childRet == 0);
82 }
83 
84 /**
85  * @tc.name      : set_fatal_message
86  * @tc.desc      : Test the multiple processes of set_fatal_message.
87  * @tc.level     : Level 0
88  */
fatal_message_0030(void)89 static void fatal_message_0030(void)
90 {
91     fatal_msg_t *fatal_message = NULL;
92 
93     const char msgChild[1024] = {"msgChild"};
94     const char msgParent[1024] = {"msgParent"};
95 
96     int childRet = 0;
97     int pidChild = 0;
98     int pidParent = 0;
99     int pidCParent = 0;
100     int pidCChild = 0;
101 
102     pid_t fpid;
103 
104     // start process
105     fpid = fork();
106     FORK(fpid);
107     if (fpid == 0) {
108         pidChild = getpid();
109     } else {
110         pidParent = getpid();
111         pid_t fpidChild;
112 
113         // start process again
114         fpidChild = fork();
115         if (fpidChild < 0) {
116             t_printf("error in fork!");
117         } else if (fpidChild == 0) {
118             pidCChild = getpid();
119             set_fatal_message(msgParent);
120             fatal_message = get_fatal_message();
121             EXPECT_TRUE(strcmp(fatal_message->msg, msgParent) == 0);
122             exit(0);
123         } else {
124             pidCParent = getpid();
125             set_fatal_message(msgChild);
126             fatal_message = get_fatal_message();
127             EXPECT_TRUE(strcmp(fatal_message->msg, msgChild) == 0);
128             waitpid(fpidChild, &childRet, 0);
129             EXPECT_TRUE(childRet == 0);
130         }
131     }
132 }
133 
134 /**
135  * @tc.name      : set_fatal_message
136  * @tc.desc      : Test the multiple processes of set_fatal_message,
137 *                  One of the threads crashed.
138  * @tc.level     : Level 0
139  */
fatal_message_0040(void)140 static void fatal_message_0040(void)
141 {
142     fatal_msg_t *fatal_message = NULL;
143 
144     const char msgChild[1024] = {"msgChild004"};
145     const char msgParent[1024] = {"msgParent004"};
146 
147     int childRet = 0;
148     int pidChild = 0;
149     int pidParent = 0;
150     int pidCParent = 0;
151     int pidCChild = 0;
152 
153     pid_t fpid;
154 
155     // start process
156     fpid = fork();
157     FORK(fpid);
158     if (fpid == 0) {
159         pidChild = getpid();
160     } else {
161         pidParent = getpid();
162         pid_t fpidChild;
163 
164         // start process again
165         fpidChild = fork();
166         if (fpidChild < 0) {
167             t_printf("error in fork!");
168         } else if (fpidChild == 0) {
169             pidCChild = getpid();
170             char *str = NULL;
171             str[0] = 0;
172             // Process crash. Unable to continue calling the set_fatal_message interface
173         } else {
174             pidCParent = getpid();
175             set_fatal_message(msgParent);
176             fatal_message = get_fatal_message();
177             EXPECT_TRUE(strcmp(fatal_message->msg, msgParent) == 0);
178             waitpid(fpidChild, &childRet, 0);
179             EXPECT_TRUE(childRet != 0);
180         }
181     }
182 }
183 
ThreadFun1(void * arg)184 void *ThreadFun1(void *arg)
185 {
186     if (arg == NULL) {
187         t_printf("ThreadFun1 arg is NULL");
188     }
189     fatal_msg_t *fatal_message = get_fatal_message();
190     EXPECT_TRUE(strcmp(fatal_message->msg, (char *)arg) == 0);
191     pthread_exit("ThreadFun1 Exit");
192 }
193 
ThreadFun2(void * arg)194 void *ThreadFun2(void *arg)
195 {
196     if (arg == NULL) {
197         t_printf("ThreadFun2 arg is NULL");
198     }
199     fatal_msg_t *fatal_message = get_fatal_message();
200     EXPECT_TRUE(strcmp(fatal_message->msg, (char *)arg) == 0);
201     pthread_exit("ThreadFun2 Exit");
202 }
203 
204 /**
205  * @tc.name      : set_fatal_message
206  * @tc.desc      : Test the multithreading of set_fatal_message.
207  * @tc.level     : Level 0
208  */
fatal_message_0050(void)209 static void fatal_message_0050(void)
210 {
211     const char msgThread[1024] = {"msgThread"};
212     int res;
213     pthread_t fatalMessageThread1, fatalMessageThread2;
214 
215     set_fatal_message(msgThread);
216     res = pthread_create(&fatalMessageThread1, NULL, ThreadFun1, (void *)msgThread);
217     if (res != 0) {
218         t_printf("pthread_create1 error.");
219     }
220     sleep(WAIT_TIME);
221 
222     res = pthread_create(&fatalMessageThread2, NULL, ThreadFun2, (void *)msgThread);
223     if (res != 0) {
224         t_printf("pthread_create2 error.");
225     }
226     pthread_join(fatalMessageThread1, NULL);
227     pthread_join(fatalMessageThread2, NULL);
228 }
229 
230 /**
231  * @tc.name      : set_fatal_message
232  * @tc.desc      : Test the function of null message.
233  * @tc.level     : Level 0
234  */
fatal_message_0060(void)235 static void fatal_message_0060(void)
236 {
237     const char* msg = NULL;
238     fatal_msg_t *fatal_message = NULL;
239 
240     int pidChild = 0;
241 
242     pid_t fpid;
243     fpid = fork();
244     FORK(fpid);
245     if (fpid == 0) {
246         pidChild = getpid();
247         set_fatal_message(msg);
248         fatal_message = get_fatal_message();
249         EXPECT_TRUE(fatal_message == NULL);
250         exit(pidChild);
251     }
252 }
253 
254 /**
255  * @tc.name      : set_fatal_message
256  * @tc.desc      : Test the function of multi call set_fatal_message.
257  * @tc.level     : Level 0
258  */
fatal_message_0070(void)259 static void fatal_message_0070(void)
260 {
261     const char msg[1024] = {"abcdefghijklmnopqrstuvwxyz1234567890"};
262     const char msg1[1024] = {"abcdefghijklmnopqr"};
263     fatal_msg_t *fatal_message = NULL;
264 
265     int pidParent = 0;
266     int pidChild = 0;
267 
268     pid_t fpid;
269     fpid = fork();
270     if (fpid < 0) {
271         t_printf("error in fork!");
272     } else if (fpid == 0) {
273         pidChild = getpid();
274         set_fatal_message(msg);
275         fatal_message = get_fatal_message();
276         EXPECT_TRUE(strcmp(fatal_message->msg, msg) == 0);
277 
278         set_fatal_message(msg1);
279         fatal_message = get_fatal_message();
280         EXPECT_TRUE(strcmp(fatal_message->msg, msg) == 0);
281 
282         exit(pidChild);
283     }
284 }
285 
286 
287 TEST_FUN G_Fun_Array[] = {
288     fatal_message_0010,
289     fatal_message_0020,
290     fatal_message_0030,
291     fatal_message_0040,
292     fatal_message_0050,
293     fatal_message_0060,
294     fatal_message_0070
295 };
296 
main(void)297 int main(void)
298 {
299     int childPid, childRet;
300     int num = sizeof(G_Fun_Array) / sizeof(TEST_FUN);
301     for (int pos = 0; pos < num; ++pos) {
302         // Run each function in a new process to
303         // keep the initial state of fatal_message.
304         if ((childPid = fork()) == 0) {
305             G_Fun_Array[pos]();
306             exit(0);
307         }
308         waitpid(childPid, &childRet, 0);
309         EXPECT_TRUE(childRet == 0);
310     }
311 
312     return t_status;
313 }
314