Skip to content

Commit

Permalink
Add ck_skip() and ck_skip_msg(...) macros
Browse files Browse the repository at this point in the history
* `ck_skip()` aborts the tests and marks it as skipped
* `ck_skip_msg(...)` does the same with a custom printf message
* `_ck_skip()` is exposed as a symbol
  • Loading branch information
jbboehr committed Jun 12, 2020
1 parent 20bf5f3 commit 1e7029d
Show file tree
Hide file tree
Showing 17 changed files with 204 additions and 58 deletions.
34 changes: 29 additions & 5 deletions src/check.c
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,10 @@ void _mark_point(const char *file, int line)
send_loc_info(file, line);
}

void _ck_assert_failed(const char *file, int line, const char *expr, ...)
#if HAVE_FORK
CK_ATTRIBUTE_NORETURN
#endif
static void _assert_failed(const char *file, int line, int wasskipped, const char *expr, va_list apo)
{
const char *msg;
va_list ap;
Expand All @@ -371,7 +374,11 @@ void _ck_assert_failed(const char *file, int line, const char *expr, ...)

send_loc_info(file, line);

va_start(ap, expr);
#if defined(va_copy)
va_copy(ap, apo);
#else
ap = apo;
#endif
msg = (const char *)va_arg(ap, char *);

/*
Expand All @@ -389,7 +396,7 @@ void _ck_assert_failed(const char *file, int line, const char *expr, ...)
}

va_end(ap);
send_failure_info(to_send);
send_failure_info(to_send, wasskipped);
if(cur_fork_status() == CK_FORK)
{
#if defined(HAVE_FORK) && HAVE_FORK==1
Expand All @@ -402,6 +409,22 @@ void _ck_assert_failed(const char *file, int line, const char *expr, ...)
}
}

void _ck_assert_failed(const char *file, int line, const char *expr, ...)
{
va_list ap;
va_start(ap, expr);
_assert_failed(file, line, 0, expr, ap);
va_end(ap);
}

void _ck_skip(const char *file, int line, const char *expr, ...)
{
va_list ap;
va_start(ap, expr);
_assert_failed(file, line, 1, expr, ap);
va_end(ap);
}

SRunner *srunner_create(Suite * s)
{
SRunner *sr = (SRunner *)emalloc(sizeof(SRunner)); /* freed in srunner_free */
Expand All @@ -410,7 +433,7 @@ SRunner *srunner_create(Suite * s)
if(s != NULL)
check_list_add_end(sr->slst, s);
sr->stats = (TestStats *)emalloc(sizeof(TestStats)); /* freed in srunner_free */
sr->stats->n_checked = sr->stats->n_failed = sr->stats->n_errors = 0;
sr->stats->n_checked = sr->stats->n_failed = sr->stats->n_errors = sr->stats->n_skipped = 0;
sr->resultlst = check_list_create();
sr->log_fname = NULL;
sr->xml_fname = NULL;
Expand Down Expand Up @@ -514,7 +537,7 @@ TestResult **srunner_results(SRunner * sr)

static int non_pass(int val)
{
return val != CK_PASS;
return val != CK_PASS && val != CK_SKIP;
}

TestResult *tr_create(void)
Expand All @@ -536,6 +559,7 @@ static void tr_init(TestResult * tr)
tr->tcname = NULL;
tr->tname = NULL;
tr->duration = -1;
tr->wasskipped = 0;
}

void tr_free(TestResult * tr)
Expand Down
33 changes: 27 additions & 6 deletions src/check.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -489,20 +489,25 @@ static void __testname ## _fn (int _i CK_ATTRIBUTE_UNUSED)
#define fail ck_abort_msg

/*
* This is called whenever an assertion fails.
* Note that it only has the noreturn modifier when
* using fork. If fork is unavailable, the function
* calls longjmp() when a test assertion fails. Marking
* the function as noreturn causes gcc to make assumptions
* These are called whenever an assertion fails or a test is skipped.
* Note that they only have the noreturn modifier when
* using fork. If fork is unavailable, the functions
* call longjmp() when a test assertion fails. Marking
* the functions as noreturn causes gcc to make assumptions
* which are not valid, as longjmp() is like a return.
*/
#if @HAVE_FORK@
CK_DLL_EXP void CK_EXPORT _ck_assert_failed(const char *file, int line,
const char *expr,
...) CK_ATTRIBUTE_NORETURN;
CK_DLL_EXP void CK_EXPORT _ck_skip(const char *file, int line,
const char *expr,
...) CK_ATTRIBUTE_NORETURN;
#else
CK_DLL_EXP void CK_EXPORT _ck_assert_failed(const char *file, int line,
const char *expr, ...);
CK_DLL_EXP void CK_EXPORT _ck_skip(const char *file, int line,
const char *expr, ...);
#endif

/**
Expand Down Expand Up @@ -553,6 +558,21 @@ CK_DLL_EXP void CK_EXPORT _ck_assert_failed(const char *file, int line,
*/
#define ck_abort_msg(...) _ck_assert_failed(__FILE__, __LINE__, "Failed" , ## __VA_ARGS__, NULL)

/**
* Unconditionally mark the test as skipped
*
* @note Once called, the remaining of the test is aborted
*/
#define ck_skip() ck_skip_msg(NULL)
/**
* Unconditionally mark the test as skipped; print a message
*
* @param ... message to print (in printf format)
*
* @note Once called, the remaining of the test is aborted
*/
#define ck_skip_msg(...) _ck_skip(__FILE__, __LINE__, "Skipped" , ## __VA_ARGS__, NULL)

/* Signed and unsigned integer comparison macros with improved output compared to ck_assert(). */
/* OP may be any comparison operator. */
#define _ck_assert_int(X, OP, Y) do { \
Expand Down Expand Up @@ -1812,8 +1832,9 @@ enum test_result
CK_TEST_RESULT_INVALID, /**< Default value; should not encounter this */
CK_PASS, /**< Test passed */
CK_FAILURE, /**< Test completed but failed */
CK_ERROR /**< Test failed to complete
CK_ERROR, /**< Test failed to complete
(unexpected signal or non-zero early exit) */
CK_SKIP /**< Test marked as skipped */
};

/**
Expand Down
2 changes: 2 additions & 0 deletions src/check_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ typedef struct TestStats
int n_checked;
int n_failed;
int n_errors;
int n_skipped;
} TestStats;

struct TestResult
Expand All @@ -85,6 +86,7 @@ struct TestResult
const char *tcname; /* Test case that generated the result */
const char *tname; /* Test that generated the result */
char *msg; /* Failure message */
int wasskipped; /* Whether the test was skipped */
};

TestResult *tr_create(void);
Expand Down
9 changes: 6 additions & 3 deletions src/check_log.c
Original file line number Diff line number Diff line change
Expand Up @@ -370,9 +370,9 @@ void tap_lfun(SRunner * sr CK_ATTRIBUTE_UNUSED, FILE * file,
/* Print the test result to the tap file */
num_tests_run += 1;
tr = (TestResult *)obj;
fprintf(file, "%s %d - %s:%s:%s: %s\n",
tr->rtype == CK_PASS ? "ok" : "not ok", num_tests_run,
tr->file, tr->tcname, tr->tname, tr->msg);
fprintf(file, "%s %d - %s:%s:%s: %s%s\n",
tr->rtype == CK_PASS || tr->rtype == CK_SKIP ? "ok" : "not ok", num_tests_run,
tr->file, tr->tcname, tr->tname, tr->rtype == CK_SKIP ? "# skip " : "", tr->msg);
fflush(file);
break;
default:
Expand Down Expand Up @@ -430,6 +430,9 @@ void subunit_lfun(SRunner * sr, FILE * file, enum print_output printmode,
case CK_ERROR:
subunit_test_error(name, msg);
break;
case CK_SKIP:
subunit_test_skip(name, msg);
break;
case CK_TEST_RESULT_INVALID:
default:
eprintf("Bad result type in subunit_lfun", __FILE__,
Expand Down
4 changes: 3 additions & 1 deletion src/check_msg.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,12 @@ static FILE *get_pipe(void)
return NULL;
}

void send_failure_info(const char *msg)
void send_failure_info(const char *msg, int wasskipped)
{
FailMsg fmsg;

fmsg.msg = strdup(msg);
fmsg.wasskipped = wasskipped;
ppack(get_pipe(), CK_MSG_FAIL, (CheckMsg *) & fmsg);
free(fmsg.msg);
}
Expand Down Expand Up @@ -184,6 +185,7 @@ static TestResult *construct_test_result(RcvMsg * rmsg, int waserror)
tr->ctx = rmsg->lastctx;
}

tr->wasskipped = rmsg->wasskipped;
tr->msg = rmsg->msg;
rmsg->msg = NULL;
tr_set_loc_by_ctx(tr, tr->ctx, rmsg);
Expand Down
2 changes: 1 addition & 1 deletion src/check_msg.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

/* Functions implementing messaging during test runs */

void send_failure_info(const char *msg);
void send_failure_info(const char *msg, int wasskipped);
void send_loc_info(const char *file, int line);
void send_ctx_info(enum ck_result_ctx ctx);
void send_duration_info(int duration);
Expand Down
6 changes: 5 additions & 1 deletion src/check_pack.c
Original file line number Diff line number Diff line change
Expand Up @@ -328,17 +328,19 @@ static size_t pack_fail(char **buf, FailMsg * fmsg)
char *ptr;
size_t len;

len = 4 + 4 + (fmsg->msg ? strlen(fmsg->msg) : 0);
len = 4 + 4 + 4 + (fmsg->msg ? strlen(fmsg->msg) : 0);
*buf = ptr = (char *)emalloc(len);

pack_type(&ptr, CK_MSG_FAIL);
pack_int(&ptr, fmsg->wasskipped);
pack_str(&ptr, fmsg->msg);

return len;
}

static void upack_fail(char **buf, FailMsg * fmsg)
{
fmsg->wasskipped = upack_int(buf);
fmsg->msg = upack_str(buf);
}

Expand Down Expand Up @@ -431,6 +433,7 @@ static size_t get_result(char *buf, RcvMsg * rmsg)
{
rmsg->msg = strdup(fmsg->msg);
rmsg->failctx = rmsg->lastctx;
rmsg->wasskipped = fmsg->wasskipped;
}
else
{
Expand Down Expand Up @@ -471,6 +474,7 @@ static RcvMsg *rcvmsg_create(void)
rmsg->failctx = CK_CTX_INVALID;
rmsg->msg = NULL;
rmsg->duration = -1;
rmsg->wasskipped = 0;
reset_rcv_test(rmsg);
reset_rcv_fixture(rmsg);
return rmsg;
Expand Down
2 changes: 2 additions & 0 deletions src/check_pack.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ typedef struct LocMsg
typedef struct FailMsg
{
char *msg;
int wasskipped;
} FailMsg;

typedef struct DurationMsg
Expand All @@ -70,6 +71,7 @@ typedef struct RcvMsg
int test_line;
char *msg;
int duration;
int wasskipped;
} RcvMsg;

void rcvmsg_free(RcvMsg * rmsg);
Expand Down
3 changes: 3 additions & 0 deletions src/check_print.c
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,9 @@ void tr_xmlprint(FILE * file, TestResult * tr,
case CK_ERROR:
snprintf(result, sizeof(result), "%s", "error");
break;
case CK_SKIP:
snprintf(result, sizeof(result), "%s", "skipped");
break;
case CK_TEST_RESULT_INVALID:
default:
abort();
Expand Down
10 changes: 6 additions & 4 deletions src/check_run.c
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,8 @@ static void srunner_add_failure(SRunner * sr, TestResult * tr)
sr->stats->n_failed++;
else if(tr->rtype == CK_ERROR)
sr->stats->n_errors++;
if(tr->rtype == CK_SKIP)
sr->stats->n_skipped++;

}

Expand Down Expand Up @@ -460,7 +462,7 @@ static void set_nofork_info(TestResult * tr)
}
else
{
tr->rtype = CK_FAILURE;
tr->rtype = tr->wasskipped ? CK_SKIP : CK_FAILURE;
}
}

Expand Down Expand Up @@ -639,7 +641,7 @@ static void set_fork_info(TestResult * tr, int status, int signal_expected,
}
else
{
tr->rtype = CK_FAILURE;
tr->rtype = tr->wasskipped ? CK_SKIP : CK_FAILURE;
}
}
}
Expand All @@ -654,11 +656,11 @@ static void set_fork_info(TestResult * tr, int status, int signal_expected,
tr->msg = exit_msg(exit_status);
if(exit_status == allowed_exit_value)
{
tr->rtype = CK_FAILURE; /* normal exit status */
tr->rtype = tr->wasskipped ? CK_SKIP : CK_FAILURE; /* normal exit status */
}
else
{
tr->rtype = CK_FAILURE; /* early exit */
tr->rtype = tr->wasskipped ? CK_SKIP : CK_FAILURE; /* early exit */
}
}
}
Expand Down
18 changes: 13 additions & 5 deletions src/check_str.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,15 @@ char *sr_stat_str(SRunner * sr)

ts = sr->stats;

str = ck_strdup_printf("%d%%: Checks: %d, Failures: %d, Errors: %d",
percent_passed(ts), ts->n_checked, ts->n_failed,
ts->n_errors);
if (ts->n_skipped <= 0) {
str = ck_strdup_printf("%d%%: Checks: %d, Failures: %d, Errors: %d",
percent_passed(ts), ts->n_checked, ts->n_failed,
ts->n_errors);
} else {
str = ck_strdup_printf("%d%%: Checks: %d, Failures: %d, Errors: %d, Skipped: %d",
percent_passed(ts), ts->n_checked, ts->n_failed,
ts->n_errors, ts->n_skipped);
}

return str;
}
Expand Down Expand Up @@ -114,6 +120,8 @@ static const char *tr_type_str(TestResult * tr)
return "F";
if(tr->rtype == CK_ERROR)
return "E";
if(tr->rtype == CK_SKIP)
return "K";
return NULL;
}
return "S";
Expand All @@ -125,6 +133,6 @@ static int percent_passed(TestStats * t)
return 100;
if(t->n_checked == 0)
return 0;
return (int)((float)(t->n_checked - (t->n_failed + t->n_errors)) /
(float)t->n_checked * 100);
return (int)((float)(t->n_checked - t->n_skipped - (t->n_failed + t->n_errors)) /
(float)(t->n_checked - t->n_skipped) * 100);
}
Loading

0 comments on commit 1e7029d

Please sign in to comment.