struct _fctchk_t
{
+ /* The name of the test this condition is in */
+ char name[FCT_MAX_LOG_LINE];
+
/* This string that represents the condition. */
char cndtn[FCT_MAX_LOG_LINE];
#define fctchk__lineno(_CHK_) ((_CHK_)->lineno)
#define fctchk__cndtn(_CHK_) ((_CHK_)->cndtn)
#define fctchk__msg(_CHK_) ((_CHK_)->msg)
+#define fctchk__name(_CHK_) ((_CHK_)->name)
static fctchk_t*
fctchk_new(int is_pass,
char const *cndtn,
+ char const *name,
char const *file,
int lineno,
char const *format,
return NULL;
}
+ fctstr_safe_cpy(chk->name, name ? name : "", FCT_MAX_LOG_LINE);
fctstr_safe_cpy(chk->cndtn, cndtn, FCT_MAX_LOG_LINE);
fctstr_safe_cpy(chk->file, file, FCT_MAX_LOG_LINE);
chk->lineno = lineno;
static void
fct_logger_record_failure(fctchk_t const* chk, fct_nlist_t* fail_list)
{
- /* For now we will truncate the string to some set amount, later
- we can work out a dynamic string object. */
- char *str = (char*)malloc(sizeof(char)*FCT_MAX_LOG_LINE);
- FCT_ASSERT( str != NULL );
- fct_snprintf(
- str,
- FCT_MAX_LOG_LINE,
- "%s(%d):\n %s",
- fctchk__file(chk),
- fctchk__lineno(chk),
- fctchk__msg(chk)
- );
- /* Append it to the listing ... */
- fct_nlist__append(fail_list, (void*)str);
+ fct_nlist__append(fail_list, (void *)chk);
}
static void
fct_logger_print_failures(fct_nlist_t const *fail_list)
{
+ const char *last_test = NULL;
puts(
"\n----------------------------------------------------------------------------\n"
);
- puts("FAILED TESTS\n\n");
- FCT_NLIST_FOREACH_BGN(char *, cndtn_str, fail_list)
+ puts("FAILED TESTS\n");
+ FCT_NLIST_FOREACH_BGN(fctchk_t const *, chk, fail_list)
{
- printf("%s\n", cndtn_str);
+ if (!last_test || strcmp(last_test, fctchk__name(chk))) {
+ printf("\n%s\n", fctchk__name(chk));
+ }
+ last_test = fctchk__name(chk);
+ printf(" %s(%d):\n %s\n",
+ fctchk__file(chk),
+ fctchk__lineno(chk),
+ fctchk__msg(chk));
}
FCT_NLIST_FOREACH_END();
{
fctchk_t *chk =NULL;
chk = fctchk_new(
+
is_pass,
condition,
+ fct_test__name(fct_xchk_test),
fct_xchk_file,
fct_xchk_lineno,
format,
*/
#define fst_check_string_not_equals fct_chk_neq_str
+/**
+ * Mark reference for time measure
+ */
+#define fst_time_mark() \
+ fst_time_start = switch_time_now();
+
+/**
+ * Check duration relative to test start, last marked time, or last check.
+ */
+#define fst_check_duration(duration_ms, precision_ms) \
+ { \
+ int actual_duration_ms = (int)((switch_time_now() - fst_time_start) / 1000); \
+ fct_xchk( \
+ abs((actual_duration_ms - duration_ms)) <= precision_ms, \
+ "fst_check_duration: %d != %d +/- %d", \
+ (actual_duration_ms), \
+ (duration_ms), \
+ (precision_ms) \
+ ); \
+ }
+
+/**
+ * Check if integer is in range
+ */
+#define fst_check_int_range(actual, expected, precision) \
+ fct_xchk( \
+ abs((val - expected)) <= precision, \
+ "fst_check_int_range: %d != %d +/- %d", \
+ (actual), \
+ (expected), \
+ (precision) \
+ );
+
+/**
+ * Check if double-precision number is in range
+ */
+#define fst_check_double_range(actual, expected, precision) \
+ fct_xchk( \
+ fabs((val - expected)) <= precision, \
+ "fst_check_double_range: %f != %f +/- %f", \
+ (actual), \
+ (expected), \
+ (precision) \
+ );
/**
* Define the beginning of a freeswitch core test driver. Only one per test application allowed.
{ \
switch_timer_t fst_timer = { 0 }; \
switch_memory_pool_t *fst_pool = NULL; \
- fst_init_core_and_modload(confdir, NULL);
+ fst_init_core_and_modload(confdir, NULL); \
+ switch_time_t fst_time_start = 0;
/**
* Define the end of a freeswitch core test driver.
FCT_SETUP_BGN() \
switch_core_new_memory_pool(&fst_pool); \
fst_requires(fst_pool != NULL); \
- fst_requires(switch_core_timer_init(&fst_timer, "soft", 20, 160, fst_pool) == SWITCH_STATUS_SUCCESS);
+ fst_requires(switch_core_timer_init(&fst_timer, "soft", 20, 160, fst_pool) == SWITCH_STATUS_SUCCESS); \
+ fst_time_mark();
/**
* Define the end of test suite setup.