1570af302Sopenharmony_ci/* 2570af302Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd. 3570af302Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4570af302Sopenharmony_ci * you may not use this file except in compliance with the License. 5570af302Sopenharmony_ci * You may obtain a copy of the License at 6570af302Sopenharmony_ci * 7570af302Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8570af302Sopenharmony_ci * 9570af302Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10570af302Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11570af302Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12570af302Sopenharmony_ci * See the License for the specific language governing permissions and 13570af302Sopenharmony_ci * limitations under the License. 14570af302Sopenharmony_ci */ 15570af302Sopenharmony_ci 16570af302Sopenharmony_ci#include <info/fatal_message.h> 17570af302Sopenharmony_ci 18570af302Sopenharmony_ci#include <errno.h> 19570af302Sopenharmony_ci#include <stdio.h> 20570af302Sopenharmony_ci#include <stdlib.h> 21570af302Sopenharmony_ci#include <string.h> 22570af302Sopenharmony_ci#include <test.h> 23570af302Sopenharmony_ci#include <pthread.h> 24570af302Sopenharmony_ci#include <unistd.h> 25570af302Sopenharmony_ci#include <sys/wait.h> 26570af302Sopenharmony_ci 27570af302Sopenharmony_ci#define EXPECT_TRUE(c) \ 28570af302Sopenharmony_ci do \ 29570af302Sopenharmony_ci { \ 30570af302Sopenharmony_ci if (!(c)) \ 31570af302Sopenharmony_ci t_error("[%s] failed\n"); \ 32570af302Sopenharmony_ci } while (0) 33570af302Sopenharmony_ci 34570af302Sopenharmony_ci#define FORK(fpid) \ 35570af302Sopenharmony_ci do \ 36570af302Sopenharmony_ci { \ 37570af302Sopenharmony_ci if (fpid < 0) { \ 38570af302Sopenharmony_ci t_error("error in fork!");\ 39570af302Sopenharmony_ci } \ 40570af302Sopenharmony_ci } while (0) 41570af302Sopenharmony_ci 42570af302Sopenharmony_citypedef void (*TEST_FUN)(void); 43570af302Sopenharmony_cistatic const int WAIT_TIME = 1; 44570af302Sopenharmony_ci 45570af302Sopenharmony_ci/** 46570af302Sopenharmony_ci * @tc.name : get_fatal_message 47570af302Sopenharmony_ci * @tc.desc : Test the function of get_fatal_message. 48570af302Sopenharmony_ci * @tc.level : Level 0 49570af302Sopenharmony_ci */ 50570af302Sopenharmony_cistatic void fatal_message_0010(void) 51570af302Sopenharmony_ci{ 52570af302Sopenharmony_ci fatal_msg_t *fatal_message = get_fatal_message(); 53570af302Sopenharmony_ci EXPECT_TRUE(fatal_message == NULL); 54570af302Sopenharmony_ci} 55570af302Sopenharmony_ci 56570af302Sopenharmony_ci/** 57570af302Sopenharmony_ci * @tc.name : set_fatal_message 58570af302Sopenharmony_ci * @tc.desc : Test the function of set_fatal_message. 59570af302Sopenharmony_ci * @tc.level : Level 0 60570af302Sopenharmony_ci */ 61570af302Sopenharmony_cistatic void fatal_message_0020(void) 62570af302Sopenharmony_ci{ 63570af302Sopenharmony_ci const char msg[1024] = {"abcdefghijklmnopqrstuvwxyz1234567890"}; 64570af302Sopenharmony_ci fatal_msg_t *fatal_message = NULL; 65570af302Sopenharmony_ci 66570af302Sopenharmony_ci int childRet = 0; 67570af302Sopenharmony_ci int pidParent = 0; 68570af302Sopenharmony_ci int pidChild = 0; 69570af302Sopenharmony_ci 70570af302Sopenharmony_ci pid_t fpid; 71570af302Sopenharmony_ci fpid = fork(); 72570af302Sopenharmony_ci FORK(fpid); 73570af302Sopenharmony_ci if (fpid == 0) { 74570af302Sopenharmony_ci pidChild = getpid(); 75570af302Sopenharmony_ci set_fatal_message(msg); 76570af302Sopenharmony_ci fatal_message = get_fatal_message(); 77570af302Sopenharmony_ci EXPECT_TRUE(strcmp(fatal_message->msg, msg) == 0); 78570af302Sopenharmony_ci exit(0); 79570af302Sopenharmony_ci } 80570af302Sopenharmony_ci waitpid(fpid, &childRet, 0); 81570af302Sopenharmony_ci EXPECT_TRUE(childRet == 0); 82570af302Sopenharmony_ci} 83570af302Sopenharmony_ci 84570af302Sopenharmony_ci/** 85570af302Sopenharmony_ci * @tc.name : set_fatal_message 86570af302Sopenharmony_ci * @tc.desc : Test the multiple processes of set_fatal_message. 87570af302Sopenharmony_ci * @tc.level : Level 0 88570af302Sopenharmony_ci */ 89570af302Sopenharmony_cistatic void fatal_message_0030(void) 90570af302Sopenharmony_ci{ 91570af302Sopenharmony_ci fatal_msg_t *fatal_message = NULL; 92570af302Sopenharmony_ci 93570af302Sopenharmony_ci const char msgChild[1024] = {"msgChild"}; 94570af302Sopenharmony_ci const char msgParent[1024] = {"msgParent"}; 95570af302Sopenharmony_ci 96570af302Sopenharmony_ci int childRet = 0; 97570af302Sopenharmony_ci int pidChild = 0; 98570af302Sopenharmony_ci int pidParent = 0; 99570af302Sopenharmony_ci int pidCParent = 0; 100570af302Sopenharmony_ci int pidCChild = 0; 101570af302Sopenharmony_ci 102570af302Sopenharmony_ci pid_t fpid; 103570af302Sopenharmony_ci 104570af302Sopenharmony_ci // start process 105570af302Sopenharmony_ci fpid = fork(); 106570af302Sopenharmony_ci FORK(fpid); 107570af302Sopenharmony_ci if (fpid == 0) { 108570af302Sopenharmony_ci pidChild = getpid(); 109570af302Sopenharmony_ci } else { 110570af302Sopenharmony_ci pidParent = getpid(); 111570af302Sopenharmony_ci pid_t fpidChild; 112570af302Sopenharmony_ci 113570af302Sopenharmony_ci // start process again 114570af302Sopenharmony_ci fpidChild = fork(); 115570af302Sopenharmony_ci if (fpidChild < 0) { 116570af302Sopenharmony_ci t_printf("error in fork!"); 117570af302Sopenharmony_ci } else if (fpidChild == 0) { 118570af302Sopenharmony_ci pidCChild = getpid(); 119570af302Sopenharmony_ci set_fatal_message(msgParent); 120570af302Sopenharmony_ci fatal_message = get_fatal_message(); 121570af302Sopenharmony_ci EXPECT_TRUE(strcmp(fatal_message->msg, msgParent) == 0); 122570af302Sopenharmony_ci exit(0); 123570af302Sopenharmony_ci } else { 124570af302Sopenharmony_ci pidCParent = getpid(); 125570af302Sopenharmony_ci set_fatal_message(msgChild); 126570af302Sopenharmony_ci fatal_message = get_fatal_message(); 127570af302Sopenharmony_ci EXPECT_TRUE(strcmp(fatal_message->msg, msgChild) == 0); 128570af302Sopenharmony_ci waitpid(fpidChild, &childRet, 0); 129570af302Sopenharmony_ci EXPECT_TRUE(childRet == 0); 130570af302Sopenharmony_ci } 131570af302Sopenharmony_ci } 132570af302Sopenharmony_ci} 133570af302Sopenharmony_ci 134570af302Sopenharmony_ci/** 135570af302Sopenharmony_ci * @tc.name : set_fatal_message 136570af302Sopenharmony_ci * @tc.desc : Test the multiple processes of set_fatal_message, 137570af302Sopenharmony_ci* One of the threads crashed. 138570af302Sopenharmony_ci * @tc.level : Level 0 139570af302Sopenharmony_ci */ 140570af302Sopenharmony_cistatic void fatal_message_0040(void) 141570af302Sopenharmony_ci{ 142570af302Sopenharmony_ci fatal_msg_t *fatal_message = NULL; 143570af302Sopenharmony_ci 144570af302Sopenharmony_ci const char msgChild[1024] = {"msgChild004"}; 145570af302Sopenharmony_ci const char msgParent[1024] = {"msgParent004"}; 146570af302Sopenharmony_ci 147570af302Sopenharmony_ci int childRet = 0; 148570af302Sopenharmony_ci int pidChild = 0; 149570af302Sopenharmony_ci int pidParent = 0; 150570af302Sopenharmony_ci int pidCParent = 0; 151570af302Sopenharmony_ci int pidCChild = 0; 152570af302Sopenharmony_ci 153570af302Sopenharmony_ci pid_t fpid; 154570af302Sopenharmony_ci 155570af302Sopenharmony_ci // start process 156570af302Sopenharmony_ci fpid = fork(); 157570af302Sopenharmony_ci FORK(fpid); 158570af302Sopenharmony_ci if (fpid == 0) { 159570af302Sopenharmony_ci pidChild = getpid(); 160570af302Sopenharmony_ci } else { 161570af302Sopenharmony_ci pidParent = getpid(); 162570af302Sopenharmony_ci pid_t fpidChild; 163570af302Sopenharmony_ci 164570af302Sopenharmony_ci // start process again 165570af302Sopenharmony_ci fpidChild = fork(); 166570af302Sopenharmony_ci if (fpidChild < 0) { 167570af302Sopenharmony_ci t_printf("error in fork!"); 168570af302Sopenharmony_ci } else if (fpidChild == 0) { 169570af302Sopenharmony_ci pidCChild = getpid(); 170570af302Sopenharmony_ci char *str = NULL; 171570af302Sopenharmony_ci str[0] = 0; 172570af302Sopenharmony_ci // Process crash. Unable to continue calling the set_fatal_message interface 173570af302Sopenharmony_ci } else { 174570af302Sopenharmony_ci pidCParent = getpid(); 175570af302Sopenharmony_ci set_fatal_message(msgParent); 176570af302Sopenharmony_ci fatal_message = get_fatal_message(); 177570af302Sopenharmony_ci EXPECT_TRUE(strcmp(fatal_message->msg, msgParent) == 0); 178570af302Sopenharmony_ci waitpid(fpidChild, &childRet, 0); 179570af302Sopenharmony_ci EXPECT_TRUE(childRet != 0); 180570af302Sopenharmony_ci } 181570af302Sopenharmony_ci } 182570af302Sopenharmony_ci} 183570af302Sopenharmony_ci 184570af302Sopenharmony_civoid *ThreadFun1(void *arg) 185570af302Sopenharmony_ci{ 186570af302Sopenharmony_ci if (arg == NULL) { 187570af302Sopenharmony_ci t_printf("ThreadFun1 arg is NULL"); 188570af302Sopenharmony_ci } 189570af302Sopenharmony_ci fatal_msg_t *fatal_message = get_fatal_message(); 190570af302Sopenharmony_ci EXPECT_TRUE(strcmp(fatal_message->msg, (char *)arg) == 0); 191570af302Sopenharmony_ci pthread_exit("ThreadFun1 Exit"); 192570af302Sopenharmony_ci} 193570af302Sopenharmony_ci 194570af302Sopenharmony_civoid *ThreadFun2(void *arg) 195570af302Sopenharmony_ci{ 196570af302Sopenharmony_ci if (arg == NULL) { 197570af302Sopenharmony_ci t_printf("ThreadFun2 arg is NULL"); 198570af302Sopenharmony_ci } 199570af302Sopenharmony_ci fatal_msg_t *fatal_message = get_fatal_message(); 200570af302Sopenharmony_ci EXPECT_TRUE(strcmp(fatal_message->msg, (char *)arg) == 0); 201570af302Sopenharmony_ci pthread_exit("ThreadFun2 Exit"); 202570af302Sopenharmony_ci} 203570af302Sopenharmony_ci 204570af302Sopenharmony_ci/** 205570af302Sopenharmony_ci * @tc.name : set_fatal_message 206570af302Sopenharmony_ci * @tc.desc : Test the multithreading of set_fatal_message. 207570af302Sopenharmony_ci * @tc.level : Level 0 208570af302Sopenharmony_ci */ 209570af302Sopenharmony_cistatic void fatal_message_0050(void) 210570af302Sopenharmony_ci{ 211570af302Sopenharmony_ci const char msgThread[1024] = {"msgThread"}; 212570af302Sopenharmony_ci int res; 213570af302Sopenharmony_ci pthread_t fatalMessageThread1, fatalMessageThread2; 214570af302Sopenharmony_ci 215570af302Sopenharmony_ci set_fatal_message(msgThread); 216570af302Sopenharmony_ci res = pthread_create(&fatalMessageThread1, NULL, ThreadFun1, (void *)msgThread); 217570af302Sopenharmony_ci if (res != 0) { 218570af302Sopenharmony_ci t_printf("pthread_create1 error."); 219570af302Sopenharmony_ci } 220570af302Sopenharmony_ci sleep(WAIT_TIME); 221570af302Sopenharmony_ci 222570af302Sopenharmony_ci res = pthread_create(&fatalMessageThread2, NULL, ThreadFun2, (void *)msgThread); 223570af302Sopenharmony_ci if (res != 0) { 224570af302Sopenharmony_ci t_printf("pthread_create2 error."); 225570af302Sopenharmony_ci } 226570af302Sopenharmony_ci pthread_join(fatalMessageThread1, NULL); 227570af302Sopenharmony_ci pthread_join(fatalMessageThread2, NULL); 228570af302Sopenharmony_ci} 229570af302Sopenharmony_ci 230570af302Sopenharmony_ci/** 231570af302Sopenharmony_ci * @tc.name : set_fatal_message 232570af302Sopenharmony_ci * @tc.desc : Test the function of null message. 233570af302Sopenharmony_ci * @tc.level : Level 0 234570af302Sopenharmony_ci */ 235570af302Sopenharmony_cistatic void fatal_message_0060(void) 236570af302Sopenharmony_ci{ 237570af302Sopenharmony_ci const char* msg = NULL; 238570af302Sopenharmony_ci fatal_msg_t *fatal_message = NULL; 239570af302Sopenharmony_ci 240570af302Sopenharmony_ci int pidChild = 0; 241570af302Sopenharmony_ci 242570af302Sopenharmony_ci pid_t fpid; 243570af302Sopenharmony_ci fpid = fork(); 244570af302Sopenharmony_ci FORK(fpid); 245570af302Sopenharmony_ci if (fpid == 0) { 246570af302Sopenharmony_ci pidChild = getpid(); 247570af302Sopenharmony_ci set_fatal_message(msg); 248570af302Sopenharmony_ci fatal_message = get_fatal_message(); 249570af302Sopenharmony_ci EXPECT_TRUE(fatal_message == NULL); 250570af302Sopenharmony_ci exit(pidChild); 251570af302Sopenharmony_ci } 252570af302Sopenharmony_ci} 253570af302Sopenharmony_ci 254570af302Sopenharmony_ci/** 255570af302Sopenharmony_ci * @tc.name : set_fatal_message 256570af302Sopenharmony_ci * @tc.desc : Test the function of multi call set_fatal_message. 257570af302Sopenharmony_ci * @tc.level : Level 0 258570af302Sopenharmony_ci */ 259570af302Sopenharmony_cistatic void fatal_message_0070(void) 260570af302Sopenharmony_ci{ 261570af302Sopenharmony_ci const char msg[1024] = {"abcdefghijklmnopqrstuvwxyz1234567890"}; 262570af302Sopenharmony_ci const char msg1[1024] = {"abcdefghijklmnopqr"}; 263570af302Sopenharmony_ci fatal_msg_t *fatal_message = NULL; 264570af302Sopenharmony_ci 265570af302Sopenharmony_ci int pidParent = 0; 266570af302Sopenharmony_ci int pidChild = 0; 267570af302Sopenharmony_ci 268570af302Sopenharmony_ci pid_t fpid; 269570af302Sopenharmony_ci fpid = fork(); 270570af302Sopenharmony_ci if (fpid < 0) { 271570af302Sopenharmony_ci t_printf("error in fork!"); 272570af302Sopenharmony_ci } else if (fpid == 0) { 273570af302Sopenharmony_ci pidChild = getpid(); 274570af302Sopenharmony_ci set_fatal_message(msg); 275570af302Sopenharmony_ci fatal_message = get_fatal_message(); 276570af302Sopenharmony_ci EXPECT_TRUE(strcmp(fatal_message->msg, msg) == 0); 277570af302Sopenharmony_ci 278570af302Sopenharmony_ci set_fatal_message(msg1); 279570af302Sopenharmony_ci fatal_message = get_fatal_message(); 280570af302Sopenharmony_ci EXPECT_TRUE(strcmp(fatal_message->msg, msg) == 0); 281570af302Sopenharmony_ci 282570af302Sopenharmony_ci exit(pidChild); 283570af302Sopenharmony_ci } 284570af302Sopenharmony_ci} 285570af302Sopenharmony_ci 286570af302Sopenharmony_ci 287570af302Sopenharmony_ciTEST_FUN G_Fun_Array[] = { 288570af302Sopenharmony_ci fatal_message_0010, 289570af302Sopenharmony_ci fatal_message_0020, 290570af302Sopenharmony_ci fatal_message_0030, 291570af302Sopenharmony_ci fatal_message_0040, 292570af302Sopenharmony_ci fatal_message_0050, 293570af302Sopenharmony_ci fatal_message_0060, 294570af302Sopenharmony_ci fatal_message_0070 295570af302Sopenharmony_ci}; 296570af302Sopenharmony_ci 297570af302Sopenharmony_ciint main(void) 298570af302Sopenharmony_ci{ 299570af302Sopenharmony_ci int childPid, childRet; 300570af302Sopenharmony_ci int num = sizeof(G_Fun_Array) / sizeof(TEST_FUN); 301570af302Sopenharmony_ci for (int pos = 0; pos < num; ++pos) { 302570af302Sopenharmony_ci // Run each function in a new process to 303570af302Sopenharmony_ci // keep the initial state of fatal_message. 304570af302Sopenharmony_ci if ((childPid = fork()) == 0) { 305570af302Sopenharmony_ci G_Fun_Array[pos](); 306570af302Sopenharmony_ci exit(0); 307570af302Sopenharmony_ci } 308570af302Sopenharmony_ci waitpid(childPid, &childRet, 0); 309570af302Sopenharmony_ci EXPECT_TRUE(childRet == 0); 310570af302Sopenharmony_ci } 311570af302Sopenharmony_ci 312570af302Sopenharmony_ci return t_status; 313570af302Sopenharmony_ci} 314