#include <sys/resource.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <err.h>
#include <libprop/proplib.h>
#include "parser.h"
#include "testcase.h"
#include "runlist.h"
#include <dfregress.h>
static int count_by_result[10];
static void
print_row(char c)
{
int i;
for (i = 0; i < 80; i++)
printf("%c", c);
printf("\n");
}
static void
print_header(void)
{
int i, j;
i = printf("Test case");
for (j = 60 - i; j > 0; j--)
printf(" ");
printf("Result\n");
print_row('-');
}
static char *get_arg_string(prop_dictionary_t testcase)
{
static char buf[2048];
const char **argv;
int i;
buf[0] = '\0';
argv = testcase_get_args(testcase);
for (i = 1; argv[i] != NULL; i++) {
strcat(buf, argv[i]);
if (argv[i+1] != NULL)
strcat(buf, " ");
}
return (i > 1) ? buf : NULL;
}
static void
print_summary(prop_array_t runlist)
{
float total_run;
float total_tests;
total_tests = 0.0 + prop_array_count(runlist);
total_run = 0.0 + total_tests - count_by_result[RESULT_BUILDFAIL] -
count_by_result[RESULT_PREFAIL] - count_by_result[RESULT_NOTRUN] -
count_by_result[RESULT_UNKNOWN];
printf("\n\n");
print_row('=');
printf("Summary:\n\n");
printf("Tests not built:\t%d\n", count_by_result[RESULT_BUILDFAIL]);
printf("Tests not run:\t\t%.0f\n", total_tests - total_run);
printf("Tests pre-failed:\t%d\n", count_by_result[RESULT_PREFAIL]);
printf("Tests post-failed:\t%d\n", count_by_result[RESULT_POSTFAIL]);
printf("Tests passed:\t\t%d\n", count_by_result[RESULT_PASS]);
printf("Tests failed:\t\t%d\n", count_by_result[RESULT_FAIL]);
printf("Tests crashed:\t\t%d\n", count_by_result[RESULT_SIGNALLED]);
printf("Tests timed out:\t%d\n", count_by_result[RESULT_TIMEOUT]);
printf("------\n");
printf("Run rate:\t\t%.2f\n", total_run/total_tests);
printf("Pass rate:\t\t%.2f\n", count_by_result[RESULT_PASS]/total_run);
}
static int
runlist_parse_summary(void *arg __unused, prop_dictionary_t testcase)
{
char *args;
int i, j;
++count_by_result[testcase_get_result(testcase)];
args = get_arg_string(testcase);
i = printf("%s", testcase_get_name(testcase));
if (args != NULL)
i+= printf(" (%s)", args);
for (j = 60 - i; j > 0; j--)
printf(" ");
printf("%s\n", testcase_get_result_desc(testcase));
return 0;
}
static int
runlist_parse_detail(void *arg __unused, prop_dictionary_t testcase)
{
char *args;
args = get_arg_string(testcase);
printf("\n");
print_row('=');
printf("Test: %s\n", testcase_get_name(testcase));
if (args != NULL)
printf("Command line arguments: %s\n", args);
printf("Type: %s\n", testcase_get_type_desc(testcase));
printf("Result: %s\n", testcase_get_result_desc(testcase));
switch (testcase_get_result(testcase)) {
case RESULT_FAIL:
printf("Exit code: %d\n", testcase_get_exit_value(testcase));
break;
case RESULT_SIGNALLED:
printf("Signal: %d\n", testcase_get_signal(testcase));
break;
}
print_row('-');
printf("driver sysbuf:\n%s\n", testcase_get_sys_buf(testcase));
print_row('-');
printf("build log:\n%s\n", testcase_get_build_buf(testcase));
print_row('-');
printf("'pre' log:\n%s\n", testcase_get_precmd_buf(testcase));
print_row('-');
printf("testcase stdout:\n%s\n", testcase_get_stdout_buf(testcase));
print_row('-');
printf("testcase stderr:\n%s\n", testcase_get_stderr_buf(testcase));
print_row('-');
printf("'post' log:\n%s\n", testcase_get_postcmd_buf(testcase));
print_row('-');
printf("cleanup log:\n%s\n", testcase_get_cleanup_buf(testcase));
return 0;
}
int
main(int argc, char *argv[])
{
if (argc != 2) {
fprintf(stderr, "Usage: dfr2text <foo.plist>\n");
exit(1);
}
prop_array_t runlist = runlist_load(argv[1]);
memset(count_by_result, 0, sizeof(count_by_result));
print_header();
runlist_iterate(runlist, runlist_parse_summary, runlist);
print_summary(runlist);
printf("\n\nDETAILED RESULTS:\n");
runlist_iterate(runlist, runlist_parse_detail, runlist);
return 0;
}