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:
parent
a490341129
commit
3677b50fe1
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user