aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tests/CMakeLists.txt10
-rw-r--r--tests/convey.c329
-rw-r--r--tests/convey.h194
-rw-r--r--tests/convey_test.c145
4 files changed, 397 insertions, 281 deletions
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 7dd74d8a..357ea402 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -35,6 +35,16 @@ if (NNG_TESTS)
add_definitions (-pthread)
endif()
+ # convey tests -- verify the test framework works!
+ add_executable(convey_test convey_test.c convey.c)
+ if (CMAKE_THREAD_LIBS_INIT)
+ target_link_libraries (convey_test "${CMAKE_THREAD_LIBS_INIT}")
+ endif()
+ add_test (NAME convey_test COMMAND convey_test
+ -v -d -p ENV_TEST=ON -p ANOTHERNAME -p AGAIN=yes extra)
+ set_tests_properties( convey_test PROPERTIES TIMEOUT 2)
+ list (APPEND all_tests convey_test)
+
set (TEST_PORT 12100)
macro (add_nng_test NAME TIMEOUT)
list (APPEND all_tests ${NAME})
diff --git a/tests/convey.c b/tests/convey.c
index 2d2b1f03..2cb4e367 100644
--- a/tests/convey.c
+++ b/tests/convey.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 Garrett D'Amore <garrett@damore.org>
+ * Copyright 2017 Garrett D'Amore <garrett@damore.org>
*
* This software is supplied under the terms of the MIT License, a
* copy of which should be located in the distribution where this
@@ -29,12 +29,12 @@
* only added late -- like in 2010. Specifically uint32_t and uint64_t).
*/
-#include <stddef.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdint.h>
#include <setjmp.h>
#include <stdarg.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
@@ -42,11 +42,11 @@
#else
-#include <time.h>
-#include <locale.h>
#include <langinfo.h>
-#include <unistd.h>
+#include <locale.h>
#include <sys/time.h>
+#include <time.h>
+#include <unistd.h>
#ifndef CONVEY_NO_THREADS
#include <pthread.h>
@@ -76,81 +76,81 @@
* a scope not expressed to user code, these rules are relaxed.
*/
-static const char *convey_sym_pass = ".";
-static const char *convey_sym_skip = "?";
-static const char *convey_sym_fail = "X";
+static const char *convey_sym_pass = ".";
+static const char *convey_sym_skip = "?";
+static const char *convey_sym_fail = "X";
static const char *convey_sym_fatal = "!";
-static const char *convey_nocolor = "";
-static const char *convey_green = "";
-static const char *convey_red = "";
-static const char *convey_yellow = "";
-
-static int convey_debug = 0;
-static int convey_verbose = 0;
-static int convey_nassert = 0;
-static int convey_nskip = 0;
+static const char *convey_nocolor = "";
+static const char *convey_green = "";
+static const char *convey_red = "";
+static const char *convey_yellow = "";
+
+static int convey_debug = 0;
+static int convey_verbose = 0;
+static int convey_nassert = 0;
+static int convey_nskip = 0;
static const char *convey_assert_color = "";
#if defined(_WIN32)
-static WORD convey_defattr;
+static WORD convey_defattr;
static HANDLE convey_console;
#endif
-#define CONVEY_EXIT_OK 0
-#define CONVEY_EXIT_USAGE 1
-#define CONVEY_EXIT_FAIL 2
-#define CONVEY_EXIT_FATAL 3
-#define CONVEY_EXIT_NOMEM 4
+#define CONVEY_EXIT_OK 0
+#define CONVEY_EXIT_USAGE 1
+#define CONVEY_EXIT_FAIL 2
+#define CONVEY_EXIT_FATAL 3
+#define CONVEY_EXIT_NOMEM 4
struct convey_timer {
- uint64_t timer_base;
- uint64_t timer_count;
- uint64_t timer_rate;
- int timer_running;
+ uint64_t timer_base;
+ uint64_t timer_count;
+ uint64_t timer_rate;
+ int timer_running;
};
struct convey_log {
- char * log_buf;
- size_t log_size;
- size_t log_length;
+ char * log_buf;
+ size_t log_size;
+ size_t log_length;
};
struct convey_ctx {
- char ctx_name[256];
- struct convey_ctx * ctx_parent;
- struct convey_ctx * ctx_root; /* the root node on the list */
- struct convey_ctx * ctx_next; /* root list only, cleanup */
- int ctx_level;
- int ctx_done;
- int ctx_started;
- jmp_buf * ctx_jmp;
- int ctx_fatal;
- int ctx_fail;
- int ctx_skip;
- int ctx_printed;
- struct convey_timer ctx_timer;
- struct convey_log * ctx_errlog;
- struct convey_log * ctx_faillog;
- struct convey_log * ctx_dbglog;
+ char ctx_name[256];
+ struct convey_ctx * ctx_parent;
+ struct convey_ctx * ctx_root; /* the root node on the list */
+ struct convey_ctx * ctx_next; /* root list only, cleanup */
+ int ctx_level;
+ int ctx_done;
+ int ctx_started;
+ jmp_buf * ctx_jmp;
+ int ctx_fatal;
+ int ctx_fail;
+ int ctx_skip;
+ int ctx_printed;
+ struct convey_timer ctx_timer;
+ struct convey_log * ctx_errlog;
+ struct convey_log * ctx_faillog;
+ struct convey_log * ctx_dbglog;
};
-static void convey_print_result(struct convey_ctx *);
-static void convey_init_timer(struct convey_timer *);
-static void convey_start_timer(struct convey_timer *);
-static void convey_stop_timer(struct convey_timer *);
-static void convey_read_timer(struct convey_timer *, int *, int *);
-static void convey_init_term(void);
-static int convey_tls_init(void);
+static void convey_print_result(struct convey_ctx *);
+static void convey_init_timer(struct convey_timer *);
+static void convey_start_timer(struct convey_timer *);
+static void convey_stop_timer(struct convey_timer *);
+static void convey_read_timer(struct convey_timer *, int *, int *);
+static void convey_init_term(void);
+static int convey_tls_init(void);
static void *convey_tls_get(void);
-static int convey_tls_set(void *);
+static int convey_tls_set(void *);
static struct convey_ctx *convey_get_ctx(void);
static void convey_vlogf(struct convey_log *, const char *, va_list, int);
static void convey_logf(struct convey_log *, const char *, ...);
static void convey_log_emit(struct convey_log *, const char *, const char *);
static void convey_log_free(struct convey_log *);
static struct convey_log *convey_log_alloc(void);
-static char *convey_nextline(char **);
-static void convey_emit_color(const char *);
+static char * convey_nextline(char **);
+static void convey_emit_color(const char *);
/*
* convey_emit_color just changes the output text to the color
@@ -165,8 +165,8 @@ convey_emit_color(const char *color)
WORD attr;
attr = convey_defattr &
- ~(FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_RED|
- FOREGROUND_INTENSITY);
+ ~(FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED |
+ FOREGROUND_INTENSITY);
if (color == convey_nocolor) {
attr = convey_defattr;
@@ -190,7 +190,6 @@ convey_emit_color(const char *color)
#endif
}
-
/*
* convey_print_result prints the test results. It prints more information
* in convey_verbose mode. Note that its possible for assertion checks done at
@@ -207,15 +206,16 @@ convey_print_result(struct convey_ctx *t)
int secs, usecs;
if (t->ctx_root == t) {
- convey_stop_timer(&t->ctx_timer); /* This is idempotent */
+ convey_stop_timer(&t->ctx_timer); /* This is idempotent */
convey_read_timer(&t->ctx_timer, &secs, &usecs);
(void) convey_logf(t->ctx_dbglog, "Test %s: %s (%d.%02ds)\n",
- t->ctx_fatal ? "FATAL" :
- t->ctx_fail ? "FAIL" :
- t->ctx_skip ? "PASS (with SKIPs)" :
- "PASS", t->ctx_name, secs, usecs / 10000);
+ t->ctx_fatal ? "FATAL"
+ : t->ctx_fail
+ ? "FAIL"
+ : t->ctx_skip ? "PASS (with SKIPs)" : "PASS",
+ t->ctx_name, secs, usecs / 10000);
if (convey_verbose) {
(void) puts("");
@@ -229,20 +229,21 @@ convey_print_result(struct convey_ctx *t)
(void) puts("");
(void) puts("");
convey_emit_color(convey_assert_color);
- (void) printf("%d assertions thus far", convey_nassert);
+ (void) printf(
+ "%d assertions thus far", convey_nassert);
convey_emit_color(convey_nocolor);
if (convey_nskip) {
(void) fputs(" ", stdout);
convey_emit_color(convey_yellow);
- (void) fputs("(one or more sections skipped)",
- stdout);
+ (void) fputs(
+ "(one or more sections skipped)", stdout);
convey_emit_color(convey_nocolor);
}
(void) printf("\n\n--- %s: %s (%d.%02ds)\n",
- t->ctx_fatal ? "FATAL" :
- t->ctx_fail ? "FAIL" :
- "PASS", t->ctx_name, secs, usecs / 10000);
+ t->ctx_fatal ? "FATAL"
+ : t->ctx_fail ? "FAIL" : "PASS",
+ t->ctx_name, secs, usecs / 10000);
}
/* Remove the context, because we cannot reenter here */
@@ -256,13 +257,12 @@ convey_print_result(struct convey_ctx *t)
convey_log_free(t->ctx_errlog);
}
t = t->ctx_next;
- memset(freeit, 0, sizeof (*freeit));
+ memset(freeit, 0, sizeof(*freeit));
free(freeit);
}
}
}
-
/*
* conveyStart is called when the context starts, before any call to
* setjmp is made. If the context isn't initialized already, that is
@@ -282,37 +282,37 @@ conveyStart(conveyScope *scope, const char *name)
if ((t = scope->cs_data) != NULL) {
if (t->ctx_done) {
convey_print_result(t);
- return (1); /* all done, skip */
+ return (1); /* all done, skip */
}
- return (0); /* continue onward */
+ return (0); /* continue onward */
}
- scope->cs_data = (t = calloc(1, sizeof (struct convey_ctx)));
+ scope->cs_data = (t = calloc(1, sizeof(struct convey_ctx)));
if (t == NULL) {
goto allocfail;
}
t->ctx_jmp = &scope->cs_jmp;
- (void) snprintf(t->ctx_name, sizeof (t->ctx_name)-1, "%s", name);
+ (void) snprintf(t->ctx_name, sizeof(t->ctx_name) - 1, "%s", name);
+
if (parent != NULL) {
t->ctx_parent = parent;
- t->ctx_root = t->ctx_parent->ctx_root;
- t->ctx_level = t->ctx_parent->ctx_level + 1;
+ t->ctx_root = t->ctx_parent->ctx_root;
+ t->ctx_level = t->ctx_parent->ctx_level + 1;
/* unified logging against the root context */
- t->ctx_dbglog = t->ctx_root->ctx_dbglog;
- t->ctx_faillog = t->ctx_root->ctx_faillog;
- t->ctx_errlog = t->ctx_root->ctx_errlog;
- t->ctx_next = t->ctx_root->ctx_next;
+ t->ctx_dbglog = t->ctx_root->ctx_dbglog;
+ t->ctx_faillog = t->ctx_root->ctx_faillog;
+ t->ctx_errlog = t->ctx_root->ctx_errlog;
+ t->ctx_next = t->ctx_root->ctx_next;
t->ctx_root->ctx_next = t;
} else {
t->ctx_parent = t;
- t->ctx_root = t;
+ t->ctx_root = t;
if (((t->ctx_errlog = convey_log_alloc()) == NULL) ||
((t->ctx_faillog = convey_log_alloc()) == NULL) ||
((t->ctx_dbglog = convey_log_alloc()) == NULL)) {
goto allocfail;
}
- convey_logf(t->ctx_dbglog,
- "Test Started: %s\n", t->ctx_name);
+ convey_logf(t->ctx_dbglog, "Test Started: %s\n", t->ctx_name);
}
return (0);
@@ -330,7 +330,6 @@ allocfail:
return (1);
}
-
/*
* conveyLoop is called right after setjmp. If unwind is true it indicates
* that setjmp returned true, and we are unwinding the stack. In that case
@@ -344,7 +343,7 @@ int
conveyLoop(conveyScope *scope, int unwind)
{
struct convey_ctx *t;
- int i;
+ int i;
if ((t = scope->cs_data) == NULL) {
return (1);
@@ -382,7 +381,6 @@ conveyLoop(conveyScope *scope, int unwind)
return (0);
}
-
void
conveyFinish(conveyScope *scope, int *rvp)
{
@@ -407,12 +405,11 @@ conveyFinish(conveyScope *scope, int *rvp)
longjmp(*t->ctx_jmp, 1);
}
-
void
conveySkip(const char *file, int line, const char *fmt, ...)
{
- va_list ap;
- struct convey_ctx *t = convey_get_ctx();
+ va_list ap;
+ struct convey_ctx *t = convey_get_ctx();
struct convey_log *dlog = t->ctx_dbglog;
if (convey_verbose) {
@@ -420,17 +417,15 @@ conveySkip(const char *file, int line, const char *fmt, ...)
(void) fputs(convey_sym_skip, stdout);
convey_emit_color(convey_nocolor);
}
- convey_logf(dlog, "* %s (%s:%d) (Skip): ",
- t->ctx_name, file, line);
+ convey_logf(dlog, "* %s (%s:%d) (Skip): ", t->ctx_name, file, line);
va_start(ap, fmt);
convey_vlogf(dlog, fmt, ap, 1);
va_end(ap);
- t->ctx_done = 1; /* This forces an end */
+ t->ctx_done = 1; /* This forces an end */
convey_nskip++;
longjmp(*t->ctx_jmp, 1);
}
-
void
conveyAssertFail(const char *cond, const char *file, int line)
{
@@ -447,18 +442,16 @@ conveyAssertFail(const char *cond, const char *file, int line)
}
convey_assert_color = convey_yellow;
t->ctx_fail++;
- t->ctx_done = 1; /* This forces an end */
- convey_logf(t->ctx_faillog, "* %s (Assertion Failed)\n",
- t->ctx_name);
+ t->ctx_done = 1; /* This forces an end */
+ convey_logf(t->ctx_faillog, "* Assertion Failed (%s)\n", t->ctx_name);
convey_logf(t->ctx_faillog, "File: %s\n", file);
convey_logf(t->ctx_faillog, "Line: %d\n", line);
convey_logf(t->ctx_faillog, "Test: %s\n\n", cond);
- convey_logf(t->ctx_dbglog, "* %s (%s:%d) (FAILED): %s\n",
- t->ctx_name, file, line, cond);
+ convey_logf(t->ctx_dbglog, "* %s (%s:%d) (FAILED): %s\n", t->ctx_name,
+ file, line, cond);
longjmp(*t->ctx_jmp, 1);
}
-
void
conveyAssertPass(const char *cond, const char *file, int line)
{
@@ -470,11 +463,10 @@ conveyAssertPass(const char *cond, const char *file, int line)
(void) fputs(convey_sym_pass, stdout);
convey_emit_color(convey_nocolor);
}
- convey_logf(t->ctx_dbglog, "* %s (%s:%d) (Passed): %s\n",
- t->ctx_name, file, line, cond);
+ convey_logf(t->ctx_dbglog, "* %s (%s:%d) (Passed): %s\n", t->ctx_name,
+ file, line, cond);
}
-
void
conveyAssertSkip(const char *cond, const char *file, int line)
{
@@ -486,11 +478,10 @@ conveyAssertSkip(const char *cond, const char *file, int line)
(void) fputs(convey_sym_pass, stdout);
convey_emit_color(convey_nocolor);
}
- convey_logf(t->ctx_dbglog, "* %s (%s:%d) (Skip): %s\n",
- t->ctx_name, file, line, cond);
+ convey_logf(t->ctx_dbglog, "* %s (%s:%d) (Skip): %s\n", t->ctx_name,
+ file, line, cond);
}
-
/*
* Performance counters. Really we just want to start and stop timers, to
* measure elapsed time in usec.
@@ -498,10 +489,9 @@ conveyAssertSkip(const char *cond, const char *file, int line)
static void
convey_init_timer(struct convey_timer *pc)
{
- memset(pc, 0, sizeof (*pc));
+ memset(pc, 0, sizeof(*pc));
}
-
static void
convey_start_timer(struct convey_timer *pc)
{
@@ -515,7 +505,7 @@ convey_start_timer(struct convey_timer *pc)
pc->timer_base = pcnt.QuadPart;
pc->timer_rate = pfreq.QuadPart;
#elif defined(CLOCK_MONOTONIC) && !defined(CONVEY_USE_GETTIMEOFDAY)
- uint64_t usecs;
+ uint64_t usecs;
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
@@ -533,7 +523,6 @@ convey_start_timer(struct convey_timer *pc)
pc->timer_running = 1;
}
-
static void
convey_stop_timer(struct convey_timer *pc)
{
@@ -546,7 +535,7 @@ convey_stop_timer(struct convey_timer *pc)
QueryPerformanceCounter(&pcnt);
pc->timer_count += (pcnt.QuadPart - pc->timer_base);
#elif defined(CLOCK_MONOTONIC) && !defined(CONVEY_USE_GETTIMEOFDAY)
- uint64_t ns;
+ uint64_t ns;
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
@@ -554,7 +543,7 @@ convey_stop_timer(struct convey_timer *pc)
ns += ts.tv_nsec;
pc->timer_count += (ns - pc->timer_base);
#else
- uint64_t us;
+ uint64_t us;
struct timeval tv;
gettimeofday(&tv, NULL);
@@ -565,14 +554,13 @@ convey_stop_timer(struct convey_timer *pc)
} while (0);
}
-
static void
convey_read_timer(struct convey_timer *pc, int *secp, int *usecp)
{
uint64_t delta, rate, sec, usec;
delta = pc->timer_count;
- rate = pc->timer_rate;
+ rate = pc->timer_rate;
sec = delta / rate;
delta -= (sec * rate);
@@ -591,10 +579,10 @@ convey_read_timer(struct convey_timer *pc, int *secp, int *usecp)
}
}
-
/*
* Thread-specific data. Pthreads uses one way, Win32 another. If you
- * lack threads, just #define CONVEY_NO_THREADS. C11 thread support is pending.
+ * lack threads, just #define CONVEY_NO_THREADS. C11 thread support is
+ * pending.
*/
#ifdef CONVEY_NO_THREADS
@@ -606,7 +594,6 @@ convey_tls_init(void)
return (0);
}
-
static int
convey_tls_set(void *v)
{
@@ -614,14 +601,12 @@ convey_tls_set(void *v)
return (0);
}
-
static void *
convey_tls_get(void)
{
return (convey_tls_key);
}
-
#elif defined(_WIN32)
static DWORD convey_tls_key;
@@ -635,7 +620,6 @@ convey_tls_init(void)
return (0);
}
-
static int
convey_tls_set(void *v)
{
@@ -645,14 +629,12 @@ convey_tls_set(void *v)
return (0);
}
-
static void *
convey_tls_get(void)
{
return ((void *) TlsGetValue(convey_tls_key));
}
-
#else
pthread_key_t convey_tls_key;
@@ -666,7 +648,6 @@ convey_tls_init(void)
return (0);
}
-
static int
convey_tls_set(void *v)
{
@@ -676,14 +657,12 @@ convey_tls_set(void *v)
return (0);
}
-
static void *
convey_tls_get(void)
{
return (pthread_getspecific(convey_tls_key));
}
-
#endif
static struct convey_ctx *
@@ -692,7 +671,6 @@ convey_get_ctx(void)
return (convey_tls_get());
}
-
/*
* Log stuff.
*/
@@ -702,14 +680,14 @@ convey_vlogf(struct convey_log *log, const char *fmt, va_list va, int addnl)
/* Grow the log buffer if we need to */
while ((log->log_size - log->log_length) < 256) {
size_t newsz = log->log_size + 2000;
- char *ptr = malloc(newsz);
+ char * ptr = malloc(newsz);
if (ptr == NULL) {
return;
}
memcpy(ptr, log->log_buf, log->log_length);
memset(ptr + log->log_length, 0, newsz - log->log_length);
free(log->log_buf);
- log->log_buf = ptr;
+ log->log_buf = ptr;
log->log_size = newsz;
}
@@ -717,12 +695,11 @@ convey_vlogf(struct convey_log *log, const char *fmt, va_list va, int addnl)
(void) vsnprintf(log->log_buf + log->log_length,
log->log_size - (log->log_length + 2), fmt, va);
log->log_length += strlen(log->log_buf + log->log_length);
- if (addnl && (log->log_buf[log->log_length-1] != '\n')) {
+ if (addnl && (log->log_buf[log->log_length - 1] != '\n')) {
log->log_buf[log->log_length++] = '\n';
}
}
-
static void
convey_logf(struct convey_log *log, const char *fmt, ...)
{
@@ -733,7 +710,6 @@ convey_logf(struct convey_log *log, const char *fmt, ...)
va_end(va);
}
-
static void
convey_log_emit(struct convey_log *log, const char *header, const char *color)
{
@@ -758,7 +734,6 @@ convey_log_emit(struct convey_log *log, const char *header, const char *color)
}
}
-
static void
convey_log_free(struct convey_log *log)
{
@@ -770,14 +745,12 @@ convey_log_free(struct convey_log *log)
}
}
-
static struct convey_log *
convey_log_alloc(void)
{
- return (calloc(1, sizeof (struct convey_log)));
+ return (calloc(1, sizeof(struct convey_log)));
}
-
/*
* ConveyInit initializes some common global stuff. Call it from main(),
* if you don't use the framework provided main.
@@ -797,21 +770,19 @@ ConveyInit(void)
return (0);
}
-
void
ConveySetVerbose(void)
{
convey_verbose = 1;
}
-
void
conveyFail(const char *file, int line, const char *fmt, ...)
{
- struct convey_ctx *t = convey_get_ctx();
+ struct convey_ctx *t = convey_get_ctx();
struct convey_log *flog = t->ctx_faillog;
struct convey_log *dlog = t->ctx_dbglog;
- va_list ap;
+ va_list ap;
convey_logf(dlog, "* %s (%s:%d) (Failed): ", t->ctx_name, file, line);
va_start(ap, fmt);
@@ -831,18 +802,17 @@ conveyFail(const char *file, int line, const char *fmt, ...)
}
convey_assert_color = convey_yellow;
t->ctx_fail++;
- t->ctx_done = 1; /* This forces an end */
+ t->ctx_done = 1; /* This forces an end */
longjmp(*t->ctx_jmp, 1);
}
-
void
conveyError(const char *file, int line, const char *fmt, ...)
{
- struct convey_ctx *t = convey_get_ctx();
+ struct convey_ctx *t = convey_get_ctx();
struct convey_log *flog = t->ctx_errlog;
struct convey_log *dlog = t->ctx_dbglog;
- va_list ap;
+ va_list ap;
convey_logf(dlog, "* %s (%s:%d) (Error): ", t->ctx_name, file, line);
va_start(ap, fmt);
@@ -862,16 +832,15 @@ conveyError(const char *file, int line, const char *fmt, ...)
}
convey_assert_color = convey_red;
t->ctx_fail++;
- t->ctx_done = 1; /* This forces an end */
+ t->ctx_done = 1; /* This forces an end */
longjmp(*t->ctx_jmp, 1);
}
-
void
conveyPrintf(const char *file, int line, const char *fmt, ...)
{
- va_list ap;
- struct convey_ctx *t = convey_get_ctx();
+ va_list ap;
+ struct convey_ctx *t = convey_get_ctx();
struct convey_log *dlog = t->ctx_dbglog;
convey_logf(dlog, "* %s (%s:%d) (Debug): ", t->ctx_name, file, line);
@@ -880,7 +849,6 @@ conveyPrintf(const char *file, int line, const char *fmt, ...)
va_end(ap);
}
-
extern int conveyMainImpl(void);
static void
@@ -895,10 +863,10 @@ convey_init_term(void)
(void) setlocale(LC_ALL, "");
codeset = nl_langinfo(CODESET);
if ((codeset != NULL) && (strcmp(codeset, "UTF-8") == 0)) {
- convey_sym_pass = "✔";
- convey_sym_fail = "✘";
+ convey_sym_pass = "✔";
+ convey_sym_fail = "✘";
convey_sym_fatal = "🔥";
- convey_sym_skip = "⚠";
+ convey_sym_skip = "⚠";
}
term = getenv("TERM");
if (!isatty(fileno(stdin))) {
@@ -916,28 +884,26 @@ convey_init_term(void)
// Values probably don't matter, just need to be
// different!
convey_nocolor = "\033[0m";
- convey_green = "\033[32m";
- convey_yellow = "\033[33m";
- convey_red = "\033[31m";
+ convey_green = "\033[32m";
+ convey_yellow = "\033[33m";
+ convey_red = "\033[31m";
}
term = getenv("TERM");
#endif
-
if (term != NULL) {
if ((strstr(term, "xterm") != NULL) ||
(strstr(term, "ansi") != NULL) ||
(strstr(term, "color") != NULL)) {
convey_nocolor = "\033[0m";
- convey_green = "\033[32m";
- convey_yellow = "\033[33m";
- convey_red = "\033[31m";
+ convey_green = "\033[32m";
+ convey_yellow = "\033[33m";
+ convey_red = "\033[31m";
}
}
convey_assert_color = convey_green;
}
-
/*
* This function exists because strtok isn't safe, and strtok_r and
* strsep are not universally available. Its like strsep, but only does
@@ -949,14 +915,14 @@ convey_nextline(char **next)
{
char *line = *next;
char *nl;
- char c;
+ char c;
if (line == NULL) {
return (NULL);
}
for (nl = line; (c = (*nl)) != '\0'; nl++) {
if (c == '\n') {
- *nl = '\0';
+ *nl = '\0';
*next = nl + 1;
return (line);
}
@@ -975,9 +941,9 @@ convey_nextline(char **next)
static struct convey_env {
struct convey_env *next;
- const char *name;
- char *value;
-} *convey_environment;
+ const char * name;
+ char * value;
+} * convey_environment;
static struct convey_env *
conveyFindEnv(const char *name)
@@ -1008,14 +974,14 @@ conveyPutEnv(const char *name, char *value)
struct convey_env *env;
if ((env = conveyFindEnv(name)) == NULL) {
- env = malloc(sizeof (*env));
+ env = malloc(sizeof(*env));
if (env == NULL) {
return (-1);
}
- env->next = convey_environment;
+ env->next = convey_environment;
convey_environment = env;
}
- env->name = name;
+ env->name = name;
env->value = value;
return (0);
}
@@ -1023,17 +989,15 @@ conveyPutEnv(const char *name, char *value)
int
conveyMain(int argc, char **argv)
{
- int i;
- const char *status;
- const char *prog;
+ int i;
+ const char * status;
+ const char * prog = "<unknown>";
struct convey_timer pc;
- int secs, usecs;
- struct convey_env *env;
+ int secs, usecs;
+ struct convey_env * env;
if ((argc > 0) && (argv[0] != NULL)) {
prog = argv[0];
- } else {
- prog = "<unknown>";
}
/*
@@ -1054,11 +1018,11 @@ conveyMain(int argc, char **argv)
}
if ((strcmp(argv[i], "-p") == 0) && ((i + 1) < argc)) {
char *delim;
- if ((delim = strchr(argv[i+1], '=')) != NULL) {
+ if ((delim = strchr(argv[i + 1], '=')) != NULL) {
*delim = '\0';
- conveyPutEnv(argv[i+1], delim+1);
+ conveyPutEnv(argv[i + 1], delim + 1);
} else {
- conveyPutEnv(argv[i+1], "");
+ conveyPutEnv(argv[i + 1], "");
}
i++;
continue;
@@ -1099,7 +1063,8 @@ conveyMain(int argc, char **argv)
}
convey_read_timer(&pc, &secs, &usecs);
- (void) printf("%-8s%-52s%4d.%03ds\n", status, prog, secs, usecs / 1000);
+ (void) printf(
+ "%-8s%-52s%4d.%03ds\n", status, prog, secs, usecs / 1000);
while ((env = convey_environment) != NULL) {
convey_environment = env->next;
free(env);
diff --git a/tests/convey.h b/tests/convey.h
index d367cfcc..59445059 100644
--- a/tests/convey.h
+++ b/tests/convey.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 Garrett D'Amore <garrett@damore.org>
+ * Copyright 2017 Garrett D'Amore <garrett@damore.org>
*
* This software is supplied under the terms of the MIT License, a
* copy of which should be located in the distribution where this
@@ -9,13 +9,13 @@
#ifndef CONVEY_H
-#define CONVEY_H
+#define CONVEY_H
-#include <stddef.h>
-#include <stdlib.h>
-#include <stdio.h>
#include <setjmp.h>
#include <stdarg.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
/*
* This test framework allows one to write tests as a form of assertion,
@@ -72,16 +72,16 @@
*/
typedef struct {
jmp_buf cs_jmp;
- void *cs_data;
+ void * cs_data;
} conveyScope;
/* These functions are not for use by tests -- they are used internally. */
-extern int conveyStart(conveyScope *, const char *);
-extern int conveyLoop(conveyScope *, int);
-extern void conveyFinish(conveyScope *, int *);
-extern int conveyMain(int, char **);
+extern int conveyStart(conveyScope *, const char *);
+extern int conveyLoop(conveyScope *, int);
+extern void conveyFinish(conveyScope *, int *);
+extern int conveyMain(int, char **);
extern char *conveyGetEnv(const char *);
-extern int conveyPutEnv(const char *, char *);
+extern int conveyPutEnv(const char *, char *);
extern void conveyAssertPass(const char *, const char *, int);
extern void conveyAssertSkip(const char *, const char *, int);
@@ -97,29 +97,29 @@ extern void conveyPrintf(const char *, int, const char *, ...);
* and for the code block to be inlined. Becuase this inlines user
* code, we have to be *very* careful with symbol names.
*/
-#define conveyRun(convey_name, convey_code, convey_resultp) \
- do { \
- static conveyScope convey_scope; \
- int convey_unwind; \
- int convey_break = 0; \
- if (conveyStart(&convey_scope, convey_name) != 0) { \
- break; \
- } \
- convey_unwind = setjmp(convey_scope.cs_jmp); \
- if (conveyLoop(&convey_scope, convey_unwind) != 0) { \
- break; \
- } \
- do { \
- convey_code \
- } while (0); \
- if (convey_break) { \
- break; \
- } \
- conveyFinish(&convey_scope, convey_resultp); \
+#define conveyRun(convey_name, convey_code, convey_resultp) \
+ do { \
+ static conveyScope convey_scope; \
+ int convey_unwind; \
+ int convey_break = 0; \
+ if (conveyStart(&convey_scope, convey_name) != 0) { \
+ break; \
+ } \
+ convey_unwind = setjmp(convey_scope.cs_jmp); \
+ if (conveyLoop(&convey_scope, convey_unwind) != 0) { \
+ break; \
+ } \
+ do { \
+ convey_code \
+ } while (0); \
+ if (convey_break) { \
+ break; \
+ } \
+ conveyFinish(&convey_scope, convey_resultp); \
} while (0);
/*
- * ConveyRset establishes a reset for the current scope. This code will
+ * ConveyReset establishes a reset for the current scope. This code will
* be executed every time the current scope is unwinding. This means that
* the code will be executed each time a child convey exits. It is also
* going to be executed once more, for the final pass, which doesn't actually
@@ -139,16 +139,16 @@ extern void conveyPrintf(const char *, int, const char *, ...);
* override a prior reset. Normally you should avoid this, and just
* use lower level convey blocks.
*/
-#define ConveyReset(convey_reset_code) \
- convey_unwind = setjmp(convey_scope.cs_jmp); \
- if (convey_unwind) { \
- do { \
- convey_reset_code \
- } while (0); \
- } \
- if (conveyLoop(&convey_scope, convey_unwind) != 0) { \
- convey_break = 1; \
- break; \
+#define ConveyReset(convey_reset_code) \
+ convey_unwind = setjmp(convey_scope.cs_jmp); \
+ if (convey_unwind) { \
+ do { \
+ convey_reset_code \
+ } while (0); \
+ } \
+ if (conveyLoop(&convey_scope, convey_unwind) != 0) { \
+ convey_break = 1; \
+ break; \
}
/*
@@ -157,17 +157,16 @@ extern void conveyPrintf(const char *, int, const char *, ...);
* sets up the program, parses options, and then executes the tests nested
* within it.
*/
-#define ConveyMain(code) \
- static int convey_main_rv; \
- int conveyMainImpl(void) { \
- do { \
- code \
- } while (0); \
- return (convey_main_rv); \
- } \
- int main(int argc, char **argv) { \
- return (conveyMain(argc, argv)); \
- }
+#define ConveyMain(code) \
+ static int convey_main_rv; \
+ int conveyMainImpl(void) \
+ { \
+ do { \
+ code \
+ } while (0); \
+ return (convey_main_rv); \
+ } \
+ int main(int argc, char **argv) { return (conveyMain(argc, argv)); }
/*
* ConveyGetEnv is used to get environment variables, which can be
@@ -177,20 +176,20 @@ extern void conveyPrintf(const char *, int, const char *, ...);
/*
* ConveyPutEnv is used to change environment variables. This is not
- * thread safe!
+ * thread safe!
*/
#define ConveyPutEnv(name, value) conveyPutEnv(name, value)
/*
* ConveyTest creates a top-level test instance, which can contain multiple
* Convey blocks.
*/
-#define ConveyTest(name, code) \
- do { \
- int convey_rv; \
- conveyRun(name, code, &convey_rv); \
- if (convey_rv > convey_main_rv) { \
- convey_main_rv = convey_rv; \
- }; \
+#define ConveyTest(name, code) \
+ do { \
+ int convey_rv; \
+ conveyRun(name, code, &convey_rv); \
+ if (convey_rv > convey_main_rv) { \
+ convey_main_rv = convey_rv; \
+ }; \
} while (0);
/*
@@ -200,8 +199,7 @@ extern void conveyPrintf(const char *, int, const char *, ...);
* is the same as using Main with just a single Test embedded, but saves
* some typing and probably a level of indentation.
*/
-#define ConveyTestMain(name, code) \
- ConveyMain(ConveyTest(name, code))
+#define ConveyTestMain(name, code) ConveyMain(ConveyTest(name, code))
/*
* EXPERIMENTAL:
@@ -220,28 +218,28 @@ extern void conveyPrintf(const char *, int, const char *, ...);
* Block takes the place of both Main() and Test(). It is to be hoped
* that you will not need this.
*/
-#define ConveyBlock(name, code, resultp) conveyRun(name, code, resultp)
+#define ConveyBlock(name, code, resultp) conveyRun(name, code, resultp)
/*
* ConveyAssert and ConveySo allow you to run assertions.
*/
-#define ConveyAssert(truth) \
- do { \
- if (!(truth)) { \
- conveyAssertFail(#truth, __FILE__, __LINE__); \
- } else { \
- conveyAssertPass(#truth, __FILE__, __LINE__); \
- } \
+#define ConveyAssert(truth) \
+ do { \
+ if (!(truth)) { \
+ conveyAssertFail(#truth, __FILE__, __LINE__); \
+ } else { \
+ conveyAssertPass(#truth, __FILE__, __LINE__); \
+ } \
} while (0)
-#define ConveySo(truth) ConveyAssert(truth)
+#define ConveySo(truth) ConveyAssert(truth)
/*
* Convey(name, <code>) starts a convey context, with <code> as
* the body. The <code> is its scope, and may be called repeatedly
* within the body of a loop.
*/
-#define Convey(name, code) conveyRun(name, code, NULL)
+#define Convey(name, code) conveyRun(name, code, NULL)
/*
* ConveySkip() just stops processing of the rest of the current context,
@@ -254,33 +252,31 @@ extern void conveyPrintf(const char *, int, const char *, ...);
* format specifiers.
*/
#ifdef CONVEY_NO_VARIADICS
-#define ConveySkip(reason) conveySkip(__FILE__, __LINE__, reason)
-#define ConveyFail(reason) conveyFail(__FILE__, __LINE__, reason)
-#define ConveyError(reason) conveyError(__FILE__, __LINE__, reason)
-#define ConveyPrintf(reason) conveyPrintf(__FILE__, __LINE__, reason)
+#define ConveySkip(reason) conveySkip(__FILE__, __LINE__, reason)
+#define ConveyFail(reason) conveyFail(__FILE__, __LINE__, reason)
+#define ConveyError(reason) conveyError(__FILE__, __LINE__, reason)
+#define ConveyPrintf(reason) conveyPrintf(__FILE__, __LINE__, reason)
#else
-#define ConveySkip(...) conveySkip(__FILE__, __LINE__, __VA_ARGS__)
-#define ConveyFail(...) conveyFail(__FILE__, __LINE__, __VA_ARGS__)
-#define ConveyError(...) conveyError(__FILE__, __LINE__, __VA_ARGS__)
-#define ConveyPrintf(...) conveyPrintf(__FILE__, __LINE__, __VA_ARGS__)
+#define ConveySkip(...) conveySkip(__FILE__, __LINE__, __VA_ARGS__)
+#define ConveyFail(...) conveyFail(__FILE__, __LINE__, __VA_ARGS__)
+#define ConveyError(...) conveyError(__FILE__, __LINE__, __VA_ARGS__)
+#define ConveyPrintf(...) conveyPrintf(__FILE__, __LINE__, __VA_ARGS__)
#endif
/*
* ConveySkipSo() is used to skip processing of a single assertion.
* Further processing in the same context continues.
*/
-#define ConveySkipAssert(truth) \
- conveyAssertSkip(truth, __FILE__, __LINE__)
-#define ConveySkipSo(truth) ConveySkipAssert(truth)
+#define ConveySkipAssert(truth) conveyAssertSkip(#truth, __FILE__, __LINE__)
+#define ConveySkipSo(truth) ConveySkipAssert(truth)
/*
* ConveySkipConvey() is used to skip a convey context. This is intended
* to permit changing "Convey", to "SkipConvey". This is logged,
* and the current convey context continues processing.
*/
-#define ConveySkipConvey(name, code) \
- Convey(name, ConveySkip("Skipped"))
-
+#define ConveySkipConvey(name, code) \
+ conveyRun(name, ConveySkip("Skipped");, NULL)
/*
* ConveyInit sets up initial things required for testing. If you don't
@@ -313,18 +309,18 @@ extern void ConveySetVerbose(void);
*/
#ifndef CONVEY_NAMESPACE_CLEAN
-#define TestMain ConveyTestMain
-#define Test ConveyTest
-#define Main ConveyMain
-#define So ConveySo
-#define Skip ConveySkip
-#define Fail ConveyFail
-#define Error ConveyError
-#define SkipConvey ConveySkipConvey
-#define SkipSo ConveySkipSo
-#define Reset ConveyReset
-#define Printf ConveyPrintf
+#define TestMain ConveyTestMain
+#define Test ConveyTest
+#define Main ConveyMain
+#define So ConveySo
+#define Skip ConveySkip
+#define Fail ConveyFail
+#define Error ConveyError
+#define SkipConvey ConveySkipConvey
+#define SkipSo ConveySkipSo
+#define Reset ConveyReset
+#define Printf ConveyPrintf
-#endif /* CONVEY_NAMESPACE_CLEAN */
+#endif /* CONVEY_NAMESPACE_CLEAN */
-#endif /* CONVEY_H */
+#endif /* CONVEY_H */
diff --git a/tests/convey_test.c b/tests/convey_test.c
new file mode 100644
index 00000000..0970e664
--- /dev/null
+++ b/tests/convey_test.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2017 Garrett D'Amore <garrett@damore.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/*
+ * This file is intended to test the framework. It also demonstrates
+ * some of the capabilities.
+ */
+
+#include "convey.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+Main({
+
+ /*
+ * The ordering test demonstrates the execution order.
+ * At the end of each inner Convey, we roll back up the stack
+ * to the root, and then start over, bypassing Convey blocks
+ * that have already completed. Note that if a Convey block
+ * is the last thing in an enclosing Convey, we will make
+ * one more pass all the way through until we bypass that last
+ * item and can close the outer Convey.
+ */
+ Test("Ordering", {
+ /*
+ * The buffer has to be static because don't want to clear
+ * it with each new pass -- that would defeat our tests!
+ * Note that it starts zeroed (C standard).
+ */
+ static char buffer[32];
+ static int bufidx;
+
+ Convey("A runs first", { buffer[bufidx++] = 'A'; });
+ Printf("Bufidx is now %d", 1);
+ buffer[bufidx++] = '1';
+
+ Convey("B runs after A", {
+
+ So(strlen(buffer) > 0);
+ So(buffer[bufidx - 1] == '1');
+ buffer[bufidx++] = 'B';
+
+ Convey("C runs inside B", {
+ So(buffer[bufidx - 1] == 'B');
+ buffer[bufidx++] = 'C';
+ });
+ });
+
+ Convey("D runs afer A, B, C.", {
+ So(buffer[bufidx - 1] == '1');
+ buffer[bufidx++] = 'D';
+ });
+
+ buffer[bufidx++] = '2';
+
+ Convey("E is last", {
+ So(buffer[bufidx - 1] == '2');
+ buffer[bufidx++] = 'E';
+ });
+
+ So(strcmp(buffer, "A1BC1B1D12E12") == 0);
+ });
+
+ Test("Skipping works", {
+ int skipped = 0;
+ SkipConvey("ConveySkip works.", { So(skipped = 0); });
+ Convey("Assertion skipping works.", { SkipSo(skipped == 1); });
+ });
+
+ Test("Reset", {
+ static int x;
+
+ Convey("Initialize X to a non-zero value", {
+ So(x == 0);
+ x = 1;
+ So(x == 1);
+ });
+
+ Reset({ x = 20; });
+
+ Convey("Verify that reset did not get called", {
+ So(x == 1);
+ x = 5;
+ So(x == 5);
+ });
+
+ Convey("But now it did", { So(x == 20); });
+ });
+
+ /* save the current status so we can override */
+ int oldrv = convey_main_rv;
+ Test("Failures work", {
+ Convey("Assertion failure works",
+ { Convey("Injected failure", { So(1 == 0); }); });
+
+ Convey("ConveyFail works", { ConveyFail("forced failure"); });
+
+ Convey("ConveyError works", { ConveyError("forced error"); });
+ });
+
+ /* Override the result variable to reset failure. */
+ convey_main_rv = oldrv;
+
+ Test("Environment works", {
+ Convey("PATH environment", {
+ So(ConveyGetEnv("PATH") != NULL);
+ So(strlen(ConveyGetEnv("PATH")) != 0);
+ });
+ Convey("Command line args work", {
+ char *v1 = ConveyGetEnv("ANOTHERNAME");
+ char *v2 = ConveyGetEnv("AGAIN");
+ if (ConveyGetEnv("NAMETEST") == NULL) {
+ SkipSo(v1 != NULL);
+ SkipSo(v2 != NULL);
+ SkipSo(strcmp(v1, "") == 0);
+ SkipSo(strcmp(v2, "YES") == 0);
+ } else {
+ So(v1 != NULL);
+ So(v2 != NULL);
+ So(strcmp(v1, "") == 0);
+ So(strcmp(v2, "YES") == 0);
+ }
+ })
+ });
+})