Added Resillance to SegFaults by forking tests

A child process is created which runs the test operation. It then
returns the exit status if exited properly and termination signal if
not.

A Termination signal of (11) corresponds to a segfault so keep that in
mind.
This commit is contained in:
xavi 2025-12-21 15:26:29 -08:00
parent a490341129
commit 3677b50fe1

View File

@ -1,8 +1,12 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
// printf Formating // printf Formating
#define X_RED "\x1B[31m" #define X_RED "\x1B[31m"
#define X_GREEN "\x1B[32m" #define X_GREEN "\x1B[32m"
#define X_YELLOW "\x1B[33m"
#define X_RST "\x1B[0m" #define X_RST "\x1B[0m"
// TEST FRAMEWORK STRUCT // TEST FRAMEWORK STRUCT
@ -29,6 +33,7 @@ static testnode* ptr = NULL;
if (head == NULL){\ if (head == NULL){\
head = &UNIT##node;\ head = &UNIT##node;\
tail = head;\ tail = head;\
return; \
}\ }\
ptr = tail;\ ptr = tail;\
tail = &UNIT##node;\ tail = &UNIT##node;\
@ -36,6 +41,9 @@ static testnode* ptr = NULL;
}\ }\
static int UNIT(void) static int UNIT(void)
// ASSERT MACRO
#define ASSERT()
// DEFINE TESTS // DEFINE TESTS
TEST(fail){ TEST(fail){
return -1; return -1;
@ -44,34 +52,68 @@ TEST(fail){
TEST(success){ TEST(success){
return 0; return 0;
} }
TEST(segfault){
int* x = NULL;
int y = *x;
}
// END OF TEST DEFINITIONS // END OF TEST DEFINITIONS
int main(){ int main(){
int total_tests = 0; int total_tests = 0;
int errors = 0; int errors = 0;
int status;
ptr = head; ptr = head;
while (ptr != NULL){ while (ptr != NULL){
total_tests++; total_tests++;
if(!ptr->op()){ pid_t cpid = fork();
printf("%s[PASS]%s ", X_GREEN, X_RST); if (cpid < 0){
} perror("fork");
else{ exit(EXIT_FAILURE);
printf("%s[FAIL]%s ", X_RED, X_RST);
errors++;
} }
printf("%s\n", ptr->name); if (cpid == 0){
int rc = ptr->op();
_exit(rc);
}else{
if (waitpid(cpid, &status, 0) < 0){
perror("waitpid");
exit(EXIT_FAILURE);
}
}
if (WIFEXITED(status)){
int rc = WEXITSTATUS(status);
if (rc == 0) {
printf("%s[PASS]%s ", X_GREEN, X_RST);
printf("%s", ptr->name);
}
else{
printf("%s[FAIL]%s ", X_RED, X_RST);
printf("%s ", ptr->name);
printf("- Exit Code %s(%d)%s", X_YELLOW, rc, X_RST);
errors++;
}
}else if (WIFSIGNALED(status)){
printf("%s[FAIL]%s ", X_RED, X_RST);
printf("%s ", ptr->name);
printf("- Termination Signal %s(%d)%s", X_YELLOW, WTERMSIG(status), X_RST);
errors++;
}
printf("\n");
ptr = ptr->next; ptr = ptr->next;
} }
printf("Tests completed with %s%d PASS%s", X_GREEN, total_tests - errors, X_RST); printf("Tests completed with %s%d PASS%s", X_GREEN, total_tests - errors, X_RST);
printf(" and %s%d FAIL%s\n", X_RED, errors, X_RST); printf(" and %s%d FAIL%s\n", X_RED, errors, X_RST);
if (errors > 0){
return 1;
}
return 0; return 0;
} }