Commit 46c5812f authored by Chris Müller's avatar Chris Müller

redirect assertion output in a seperate file and uses this content later for a...

redirect assertion output in a seperate file and uses this content later for a compact summary. Compute statistical values (tests, failures, segfaults, timeouts, skips)
parent fd5c9e1c
#include "unittest.h"
#include "standard.h"
#include "unix_colors.h"
#include <sys/signal.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
......@@ -12,38 +14,44 @@
static int monitor_testprocess(pid_t worker_pid, unsigned int timeout);
static void print_testprocess_status(const char* desc, int return_code, suseconds_t time);
static void print_verbose_testprocess_status(const char* desc, int return_code, suseconds_t time);
static void print_testprocess_status(int return_code);
static void print_usage(FILE* stream, const char* programm, int exit_code);
#define COLOR(condition, color, string) (condition ? color string CRY_NORMAL : string)
// Current Errorfile
const char* ErrorFile = 0;
static char* Testlog = 0;
// Options
static int Colors = 0;
static int Repeat = 1;
static int Verbose = 0;
static const char* Filter = 0;
static struct option option[] = {
static struct option Option[] = {
{"help", no_argument, 0, 'h'},
{"colors", no_argument, 0, 'c'},
{"verbose", no_argument, 0, 'v'},
{"repeat", optional_argument, 0, 'r'},
{"filter", optional_argument, 0, 'f'}
};
// Statistics
static int TestCaseNumber = 0;
static int SegFaultNumber = 0;
static int SegfaultNumber = 0;
static int TimeoutNumber = 0;
static int FailureNumber = 0;
static int SkippedNumber = 0;
void
cry_unittest_initialize(int argc, char** argv)
{
int ch = 0;
time_t current_time = time(0);
struct tm* time_struct = localtime(&current_time);
while( (ch = getopt_long(argc, argv, "hcr:f:", option, 0)) != -1 ) {
while( (ch = getopt_long(argc, argv, "vhcr:f:", Option, 0)) != -1 ) {
switch(ch) {
case 'h':
print_usage(stdout, argv[0], EXIT_SUCCESS);
......@@ -56,6 +64,9 @@ cry_unittest_initialize(int argc, char** argv)
case 'f':
Filter = optarg;
break;
case 'v':
Verbose = 1;
break;
case '?':
print_usage(stderr, argv[0], EXIT_FAILURE);
default:
......@@ -63,9 +74,14 @@ cry_unittest_initialize(int argc, char** argv)
}
}
printf(":: colors %s, repeat %d, filter %s ::\n", Colors ? "ON" : "OFF", Repeat, Filter ? Filter : "OFF");
}
printf(":: colors %s, repeat %d, filter %s ::\n\n", Colors ? "ON" : "OFF", Repeat, Filter ? Filter : "OFF");
if(Testlog == 0) {
Testlog = cry_calloc(char, 64);
strftime(Testlog, 64, "%Y%m%d_%H%M%S.testlog", time_struct);
}
}
void
print_usage(FILE* stream, const char* programm, int exit_code)
......@@ -74,11 +90,36 @@ print_usage(FILE* stream, const char* programm, int exit_code)
fprintf(stream,
" -h --help Display this usage information for your testcase.\n"
" -c --colors Enable color support for test output.\n"
" -v --verbose Show more details about the testing progress.\n"
" -r --repeat INT Set number of repeats for each testcase.\n"
" -f --filter REGEX Set a regular expression filter for all testcases.\n");
exit(exit_code);
}
void cry_unittest_finalize(void)
{
int Failures = SegfaultNumber + TimeoutNumber + FailureNumber;
FILE* log = fopen(Testlog, "r");
char buffer[128];
if(!Verbose)
printf("\n\n");
else
printf("\n");
printf("%d tests, %d skipped, %d failures, %d segfaults, %d timeouts\n\n", TestCaseNumber, SkippedNumber, Failures, SegfaultNumber, TimeoutNumber);
while(log != 0 && !feof(log)) {
if(fgets(buffer, 128, log) != 0)
printf(COLOR(Colors, CRY_RED, "%s"), buffer);
}
printf("\n");
fclose(log);
cry_free(Testlog);
}
void
cry_unittest_run(const char* desc, cry_modulechecker handler, const_pointer data, unsigned int timeout)
......@@ -98,12 +139,21 @@ cry_unittest_run(const char* desc, cry_modulechecker handler, const_pointer data
time_t diff_s = end.tv_sec - start.tv_sec;
suseconds_t diff_ms = end.tv_usec - start.tv_usec;
print_testprocess_status(desc, status, diff_s * 1000000L + diff_ms);
if(Verbose)
print_verbose_testprocess_status(desc, status, diff_s * 1000000L + diff_ms);
else
print_testprocess_status(status);
} else {
// Process for running test case
freopen(Testlog, "w+", stderr);
freopen("/dev/null", "w", stdout);
handler(data);
fclose(stderr);
fclose(stdout);
exit(EXIT_SUCCESS);
}
}
......@@ -137,7 +187,7 @@ monitor_testprocess(pid_t worker_pid, unsigned int timeout)
void
print_testprocess_status(const char* desc, int return_code, suseconds_t time)
print_verbose_testprocess_status(const char* desc, int return_code, suseconds_t time)
{
char buffer[128];
......@@ -145,15 +195,38 @@ print_testprocess_status(const char* desc, int return_code, suseconds_t time)
printf("%-50s ", buffer);
if(return_code == SIGINT)
TestCaseNumber++;
if(return_code == SIGINT) {
printf(COLOR(Colors, CRY_RED, "TIMEOUT"));
else if(WIFEXITED(return_code))
printf(COLOR(Colors, CRY_GREEN, "OK"));
else if(WCOREDUMP(return_code))
TimeoutNumber++;
} else if(WIFEXITED(return_code)) {
printf(COLOR(Colors, CRY_GREEN, "OK"));
} else if(WCOREDUMP(return_code)) {
printf(COLOR(Colors, CRY_RED, "SEGFAULT"));
else
SegfaultNumber++;
} else {
printf(COLOR(Colors, CRY_RED, "FAIL (%d)"), return_code);
FailureNumber++;
}
printf("\n");
}
void
print_testprocess_status(int return_code)
{
TestCaseNumber++;
if(return_code == SIGINT) {
printf(COLOR(Colors, CRY_RED, "T"));
TimeoutNumber++;
} else if(WIFEXITED(return_code)) {
printf(COLOR(Colors, CRY_GREEN, "."));
} else if(WCOREDUMP(return_code)) {
printf(COLOR(Colors, CRY_RED, "S"));
} else {
printf(COLOR(Colors, CRY_RED, "F"));
FailureNumber++;
}
}
......@@ -9,4 +9,6 @@ void cry_unittest_run(const char* desc, cry_modulechecker handler, const_pointer
void cry_unittest_initialize(int argc, char** argv);
void cry_unittest_finalize(void);
#endif // CRYSTAL_UNITTEST_H
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment