Skip to content

Commit

Permalink
Merge pull request #101 from pks-t/pks-clar-abort
Browse files Browse the repository at this point in the history
Handle failures more consistently via `clar_abort()`
  • Loading branch information
ethomson authored Sep 20, 2024
2 parents 94461c1 + eaefd95 commit 9007d48
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 46 deletions.
78 changes: 47 additions & 31 deletions clar.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
* This file is part of clar, distributed under the ISC license.
* For full terms see the included COPYING file.
*/
#include <assert.h>

#include <errno.h>
#include <setjmp.h>
#include <stdlib.h>
#include <stdio.h>
Expand Down Expand Up @@ -183,11 +184,12 @@ static void clar_print_shutdown(int test_count, int suite_count, int error_count
static void clar_print_error(int num, const struct clar_report *report, const struct clar_error *error);
static void clar_print_ontest(const char *suite_name, const char *test_name, int test_number, enum cl_test_status failed);
static void clar_print_onsuite(const char *suite_name, int suite_index);
static void clar_print_onabortv(const char *msg, va_list argp);
static void clar_print_onabort(const char *msg, ...);

/* From clar_sandbox.c */
static void clar_unsandbox(void);
static int clar_sandbox(void);
static void clar_sandbox(void);

/* From summary.h */
static struct clar_summary *clar_summary_init(const char *filename);
Expand All @@ -206,6 +208,15 @@ static int clar_summary_shutdown(struct clar_summary *fp);
_clar.trace_payload); \
} while (0)

static void clar_abort(const char *msg, ...)
{
va_list argp;
va_start(argp, msg);
clar_print_onabortv(msg, argp);
va_end(argp);
exit(-1);
}

void cl_trace_register(cl_trace_cb *cb, void *payload)
{
_clar.pfn_trace_cb = cb;
Expand Down Expand Up @@ -372,7 +383,8 @@ clar_run_suite(const struct clar_suite *suite, const char *filter)

_clar.active_test = test[i].name;

report = calloc(1, sizeof(struct clar_report));
if ((report = calloc(1, sizeof(*report))) == NULL)
clar_abort("Failed to allocate report.\n");
report->suite = _clar.active_suite;
report->test = _clar.active_test;
report->test_number = _clar.tests_ran;
Expand Down Expand Up @@ -465,9 +477,10 @@ clar_parse_args(int argc, char **argv)

switch (action) {
case 's': {
struct clar_explicit *explicit =
calloc(1, sizeof(struct clar_explicit));
assert(explicit);
struct clar_explicit *explicit;

if ((explicit = calloc(1, sizeof(*explicit))) == NULL)
clar_abort("Failed to allocate explicit test.\n");

explicit->suite_idx = j;
explicit->filter = argument;
Expand All @@ -491,10 +504,8 @@ clar_parse_args(int argc, char **argv)
}
}

if (!found) {
clar_print_onabort("No suite matching '%s' found.\n", argument);
exit(-1);
}
if (!found)
clar_abort("No suite matching '%s' found.\n", argument);
break;
}

Expand Down Expand Up @@ -526,11 +537,17 @@ clar_parse_args(int argc, char **argv)
case 'r':
_clar.write_summary = 1;
free(_clar.summary_filename);
_clar.summary_filename = *(argument + 2) ? strdup(argument + 2) : NULL;
if (*(argument + 2)) {
if ((_clar.summary_filename = strdup(argument + 2)) == NULL)
clar_abort("Failed to allocate summary filename.\n");
} else {
_clar.summary_filename = NULL;
}
break;

default:
assert(!"Unexpected commandline argument!");
clar_abort("Unexpected commandline argument '%s'.\n",
argument[1]);
}
}
}
Expand All @@ -552,22 +569,18 @@ clar_test_init(int argc, char **argv)
if (!_clar.summary_filename &&
(summary_env = getenv("CLAR_SUMMARY")) != NULL) {
_clar.write_summary = 1;
_clar.summary_filename = strdup(summary_env);
if ((_clar.summary_filename = strdup(summary_env)) == NULL)
clar_abort("Failed to allocate summary filename.\n");
}

if (_clar.write_summary && !_clar.summary_filename)
_clar.summary_filename = strdup("summary.xml");
if ((_clar.summary_filename = strdup("summary.xml")) == NULL)
clar_abort("Failed to allocate summary filename.\n");

if (_clar.write_summary &&
!(_clar.summary = clar_summary_init(_clar.summary_filename))) {
clar_print_onabort("Failed to open the summary file\n");
exit(-1);
}
if (_clar.write_summary)
_clar.summary = clar_summary_init(_clar.summary_filename);

if (clar_sandbox() < 0) {
clar_print_onabort("Failed to sandbox the test runner.\n");
exit(-1);
}
clar_sandbox();
}

int
Expand Down Expand Up @@ -601,10 +614,9 @@ clar_test_shutdown(void)

clar_unsandbox();

if (_clar.write_summary && clar_summary_shutdown(_clar.summary) < 0) {
clar_print_onabort("Failed to write the summary file\n");
exit(-1);
}
if (_clar.write_summary && clar_summary_shutdown(_clar.summary) < 0)
clar_abort("Failed to write the summary file '%s: %s.\n",
_clar.summary_filename, strerror(errno));

for (explicit = _clar.explicit; explicit; explicit = explicit_next) {
explicit_next = explicit->next;
Expand Down Expand Up @@ -635,7 +647,7 @@ static void abort_test(void)
{
if (!_clar.trampoline_enabled) {
clar_print_onabort(
"Fatal error: a cleanup method raised an exception.");
"Fatal error: a cleanup method raised an exception.\n");
clar_report_errors(_clar.last_report);
exit(-1);
}
Expand All @@ -659,7 +671,10 @@ void clar__fail(
const char *description,
int should_abort)
{
struct clar_error *error = calloc(1, sizeof(struct clar_error));
struct clar_error *error;

if ((error = calloc(1, sizeof(*error))) == NULL)
clar_abort("Failed to allocate error.\n");

if (_clar.last_report->errors == NULL)
_clar.last_report->errors = error;
Expand All @@ -674,8 +689,9 @@ void clar__fail(
error->line_number = line;
error->error_msg = error_msg;

if (description != NULL)
error->description = strdup(description);
if (description != NULL &&
(error->description = strdup(description)) == NULL)
clar_abort("Failed to allocate description.\n");

_clar.total_errors++;
_clar.last_report->status = CL_TEST_FAILURE;
Expand Down
7 changes: 6 additions & 1 deletion clar/print.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,10 +202,15 @@ static void clar_print_onsuite(const char *suite_name, int suite_index)
PRINT(onsuite, suite_name, suite_index);
}

static void clar_print_onabortv(const char *msg, va_list argp)
{
PRINT(onabort, msg, argp);
}

static void clar_print_onabort(const char *msg, ...)
{
va_list argp;
va_start(argp, msg);
PRINT(onabort, msg, argp);
clar_print_onabortv(msg, argp);
va_end(argp);
}
9 changes: 4 additions & 5 deletions clar/sandbox.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,15 +142,14 @@ static int build_sandbox_path(void)
return 0;
}

static int clar_sandbox(void)
static void clar_sandbox(void)
{
if (_clar_path[0] == '\0' && build_sandbox_path() < 0)
return -1;
clar_abort("Failed to build sandbox path.\n");

if (chdir(_clar_path) != 0)
return -1;

return 0;
clar_abort("Failed to change into sandbox directory '%s': %s.\n",
_clar_path, strerror(errno));
}

const char *clar_sandbox_path(void)
Expand Down
14 changes: 5 additions & 9 deletions clar/summary.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,16 +66,12 @@ struct clar_summary *clar_summary_init(const char *filename)
struct clar_summary *summary;
FILE *fp;

if ((fp = fopen(filename, "w")) == NULL) {
perror("fopen");
return NULL;
}
if ((fp = fopen(filename, "w")) == NULL)
clar_abort("Failed to open the summary file '%s': %s.\n",
filename, strerror(errno));

if ((summary = malloc(sizeof(struct clar_summary))) == NULL) {
perror("malloc");
fclose(fp);
return NULL;
}
if ((summary = malloc(sizeof(struct clar_summary))) == NULL)
clar_abort("Failed to allocate summary.\n");

summary->filename = filename;
summary->fp = fp;
Expand Down

0 comments on commit 9007d48

Please sign in to comment.