aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt89
-rw-r--r--tests/CMakeLists.txt56
-rw-r--r--tests/demo.c33
-rw-r--r--tests/test.c86
-rw-r--r--tests/test.h176
5 files changed, 353 insertions, 87 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d94ecd26..d41a5b2b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -205,6 +205,8 @@ endif ()
add_subdirectory (src)
+add_subdirectory (tests)
+
# Build the tools
if (NNG_ENABLE_NNGCAT)
@@ -305,93 +307,6 @@ if (NNG_ENABLE_DOC)
endif ()
-# Build unit tests.
-
-if (NNG_TESTS)
-
- enable_testing ()
- set (all_tests "")
-
- set (TEST_PORT 12100)
- macro (add_libnng_test NAME TIMEOUT)
- list (APPEND all_tests ${NAME})
- add_executable (${NAME} tests/${NAME}.c)
- target_link_libraries (${NAME} ${PROJECT_NAME})
- add_test (NAME ${NAME} COMMAND ${NAME} ${TEST_PORT})
- set_tests_properties (${NAME} PROPERTIES TIMEOUT ${TIMEOUT})
- math (EXPR TEST_PORT "${TEST_PORT}+10")
- endmacro (add_libnng_test)
-
- # Transport tests.
- #add_libnng_test (inproc 5)
- #add_libnng_test (inproc_shutdown 5)
- #add_libnng_test (ipc 5)
- #add_libnng_test (ipc_shutdown 30)
- #add_libnng_test (ipc_stress 5)
- #add_libnng_test (tcp 5)
- #add_libnng_test (tcp_shutdown 120)
- #add_libnng_test (ws 5)
-
- # Protocol tests.
- #add_libnng_test (pair 5)
- #add_libnng_test (pubsub 5)
- #add_libnng_test (reqrep 5)
- #add_libnng_test (pipeline 5)
- #add_libnng_test (survey 5)
- #add_libnng_test (bus 5)
-
- # Feature tests.
- #add_libnng_test (async_shutdown 30)
- #add_libnng_test (block 5)
- #add_libnng_test (term 5)
- #add_libnng_test (timeo 5)
- #add_libnng_test (iovec 5)
- #add_libnng_test (msg 5)
- #add_libnng_test (prio 5)
- #add_libnng_test (poll 5)
- #add_libnng_test (device 5)
- #add_libnng_test (device4 5)
- #add_libnng_test (device5 5)
- #add_libnng_test (device6 5)
- #add_libnng_test (device7 30)
- #add_libnng_test (emfile 5)
- #add_libnng_test (domain 5)
- #add_libnng_test (trie 5)
- #add_libnng_test (list 5)
- #add_libnng_test (hash 5)
- #add_libnng_test (stats 5)
- #add_libnng_test (symbol 5)
- #add_libnng_test (separation 5)
- #add_libnng_test (zerocopy 5)
- #add_libnng_test (shutdown 5)
- #add_libnng_test (cmsg 5)
- #add_libnng_test (bug328 5)
- #add_libnng_test (bug777 5)
- #add_libnng_test (ws_async_shutdown 5)
- #add_libnng_test (reqttl 10)
- #add_libnng_test (surveyttl 10)
-
- # Platform-specific tests
- #if (WIN32)
- # add_libnng_test (win_sec_attr 5)
- #endif()
-
- # Build the performance tests.
-
- macro (add_libnng_perf NAME)
- add_executable (${NAME} perf/${NAME}.c)
- target_link_libraries (${NAME} ${PROJECT_NAME})
- endmacro (add_libnng_perf)
-
- #add_libnng_perf (inproc_lat)
- #add_libnng_perf (inproc_thr)
- #add_libnng_perf (local_lat)
- #add_libnng_perf (remote_lat)
- #add_libnng_perf (local_thr)
- #add_libnng_perf (remote_thr)
-
-endif ()
-
install (TARGETS LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
install (TARGETS ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
install (FILES src/nng.h DESTINATION include/nng)
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
new file mode 100644
index 00000000..1d8bcad5
--- /dev/null
+++ b/tests/CMakeLists.txt
@@ -0,0 +1,56 @@
+#
+# Copyright (c) 2012 Martin Sustrik All rights reserved.
+# Copyright (c) 2013 GoPivotal, Inc. All rights reserved.
+# Copyright (c) 2015-2016 Jack R. Dunaway. All rights reserved.
+# Copyright 2016 Garrett D'Amore <garrett@damore.org>
+# Copyright 2016 Franklin "Snaipe" Mathieu <franklinmathieu@gmail.com>
+#
+# 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.
+#
+
+# Build unit tests.
+
+if (NNG_TESTS)
+
+ enable_testing ()
+ set (all_tests "")
+
+ set (TEST_PORT 12100)
+ macro (add_nng_test NAME TIMEOUT)
+ list (APPEND all_tests ${NAME})
+ add_executable (${NAME} ${NAME}.c test.c)
+ target_link_libraries (${NAME} ${PROJECT_NAME})
+ add_test (NAME ${NAME} COMMAND ${NAME} ${TEST_PORT})
+ set_tests_properties (${NAME} PROPERTIES TIMEOUT ${TIMEOUT})
+ math (EXPR TEST_PORT "${TEST_PORT}+10")
+ endmacro (add_nng_test)
+
+ macro (add_nng_perf NAME)
+ add_executable (${NAME} perf/${NAME}.c)
+ target_link_libraries (${NAME} ${PROJECT_NAME})
+ endmacro (add_nng_perf)
+
+else ()
+ macro (add_nng_test NAME TIMEOUT)
+ endmacro (add_nng_test)
+ macro (add_nng_perf NAME)
+ endmacro (add_nng_perf)
+endif ()
+
+add_nng_test(demo 5)
diff --git a/tests/demo.c b/tests/demo.c
new file mode 100644
index 00000000..2b874b9e
--- /dev/null
+++ b/tests/demo.c
@@ -0,0 +1,33 @@
+#include <stdio.h>
+#include "test.h"
+
+test_main("Things work", {
+ int x;
+ int y;
+ x = 1;
+ y = 2;
+ test_convey("X is one", {
+ test_assert(x == 1);
+ });
+ test_convey("Y is two", {
+ test_so(y == 2);
+ y = 3;
+ test_so(y == 3);
+ });
+
+test_convey("Bounce", {
+ test_convey("Arithmetic", {
+ test_so(y == 2);
+ test_convey("Addition", {
+ test_so(x + y == 3);
+ test_so(x + y + y == 5);
+ y = 5;
+ test_so(x + y == 6);
+ });
+ test_convey("Subtraction", {
+ test_so(x - y == -1);
+ test_so(y - x == 1);
+ });
+ });
+});
+})
diff --git a/tests/test.c b/tests/test.c
new file mode 100644
index 00000000..2a881307
--- /dev/null
+++ b/tests/test.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2016 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.
+ */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <setjmp.h>
+#include <stdarg.h>
+
+#include "test.h"
+
+test_ctx_t *T_C = NULL;
+
+void
+test_ctx_print_start(test_ctx_t *ctx)
+{
+ int i;
+ if (ctx->T_printed) {
+ return;
+ }
+ ctx->T_printed = 1;
+ if (ctx->T_root) {
+ printf("\n=== RUN: %s\n", ctx->T_name);
+ } else {
+ printf("\n");
+ for (i = 0; i < ctx->T_level; i++) {
+ printf(" ");
+ }
+ printf("%s ", ctx->T_name);
+ fflush(stdout);
+ }
+}
+
+void
+test_ctx_print_result(test_ctx_t *ctx)
+{
+ if (ctx->T_root) {
+ printf("\n\n--- %s: %s\n",
+ ctx->T_fatal ? "FATAL" :
+ ctx->T_fail ? "FAIL" :
+ ctx->T_skip ? "SKIP" :
+ "PASS", ctx->T_name);
+ }
+}
+
+void
+test_ctx_log(test_ctx_t ctx, const char *fmt, ...)
+{
+}
+
+void
+test_ctx_fatal(test_ctx_t *ctx, const char *fmt, ...)
+{
+ va_list va;
+ va_start(va, fmt);
+ printf("FATALITY: ");
+ vprintf(fmt, va);
+ printf("\n");
+}
+
+extern int test_main_impl(void);
+
+int
+main(int argc, char **argv)
+{
+ test_main_impl();
+} \ No newline at end of file
diff --git a/tests/test.h b/tests/test.h
new file mode 100644
index 00000000..3be760b2
--- /dev/null
+++ b/tests/test.h
@@ -0,0 +1,176 @@
+
+/*
+ * Copyright 2016 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.
+ */
+
+#ifndef TESTS_TEST_H
+
+#define TESTS_TEST_H
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <setjmp.h>
+#include <stdarg.h>
+
+/*
+ * This test framework allows one to write tests as a form of assertion,
+ * giving simpler and more readable test logic.
+ *
+ * The test framework provides a main() function.
+ *
+ * To use this call the test_main() macro, and embed test_convey() references.
+ * These can be nested, and after each convey the entire stack is popped so
+ * that execution can continue from the beginning, giving each test section
+ * the same environment.
+ *
+ * There are assertion macros too, which don't roll back the stack, but which
+ * do update the test state.
+ *
+ * Here's a sample file:
+ *
+ * test_main("Integer Tests", {
+ * int x = 1; int y = 2;
+ * test_convey("Addition works", func() {
+ * test_so(y == 2);
+ * test_so(y + x == 3);
+ * test_so(x + y == 3);
+ * test_convey("Even big numbers", func() {
+ * y = 100;
+ * test_so(x + y == 101);
+ * });
+ * test_convey("Notice y is still 2 in this context", func() {
+ * test_so(y == 2);
+ * });
+ * });
+ * })
+ *
+ * There are other macros, but this is a work in progress. The inspiration
+ * for this is from GoConvey -- github.com/smartystreets/goconvey - but this
+ * is a version for C programs.
+ */
+
+typedef struct test_ctx {
+ const char *T_name;
+ jmp_buf T_jmp;
+ void (*T_cleanup_fn)(void *);
+ void *T_cleanup_arg;
+ int T_fail;
+ int T_fatal;
+ int T_skip;
+ int T_asserts;
+ int T_good;
+ int T_bad;
+ int T_done;
+ int T_root;
+ int T_level;
+ int T_printed;
+ struct test_ctx *T_parent;
+} test_ctx_t;
+
+extern test_ctx_t *T_C;
+
+#define test_ctx_do(T_xparent, T_xname, T_xcode) \
+do { \
+ static test_ctx_t T_ctx; \
+ T_ctx.T_name = T_xname; \
+ T_ctx.T_parent = T_xparent; \
+ if (T_xparent != NULL) { \
+ T_ctx.T_level = T_xparent->T_level + 1; \
+ T_ctx.T_root = 0; \
+ } else { \
+ T_ctx.T_root = 1; \
+ T_ctx.T_level = 0; \
+ } \
+ if (T_ctx.T_done) { \
+ test_ctx_print_result(&T_ctx); \
+ break; \
+ } \
+ if (setjmp(T_ctx.T_jmp) != 0) { \
+ if (T_ctx.T_cleanup_fn != NULL) { \
+ T_ctx.T_cleanup_fn(T_ctx.T_cleanup_arg); \
+ } \
+ if (!T_ctx.T_root) { \
+ longjmp(T_ctx.T_parent->T_jmp, 1); \
+ } \
+ if (T_ctx.T_done) { \
+ test_ctx_print_result(&T_ctx); \
+ break; \
+ } \
+ } \
+ test_ctx_print_start(&T_ctx); \
+ do { \
+ T_C = &T_ctx; \
+ { T_xcode } \
+ T_ctx.T_done = 1; \
+ } while (0); \
+ longjmp(T_ctx.T_jmp, 1); \
+} while (0);
+
+#define test_main(name, code) \
+int test_main_impl(void) { \
+ static test_ctx_t ctx; \
+ test_ctx_t *T_null = NULL; \
+ ctx.T_root = 1; \
+ test_ctx_t *T_xctx = &ctx; \
+ test_ctx_do(T_null, name, code); \
+ return (ctx.T_fatal ? 2 : ctx.T_fail ? 1 : 0); \
+}
+
+#define test_ctx_convey(T_xparent, T_xname, T_xcode) \
+{ \
+ test_ctx_do( T_xparent, T_xname, T_xcode); \
+}
+
+#define test_convey(T_xname, T_xcode) test_ctx_convey(T_C, T_xname, T_xcode)
+
+
+#define test_ctx_assert(T_xctx, T_cond) \
+ if (!(T_cond)) { \
+ T_xctx->T_bad++; \
+ test_ctx_fatal(T_xctx, "%s: %d: Assertion failed: %s", \
+ __FILE__, __LINE__, #T_cond); \
+ } else { \
+ printf("."); \
+ T_xctx->T_good++; \
+ }
+
+#define test_assert(T_cond) test_ctx_assert(T_C, T_cond)
+
+#define test_ctx_so(T_xctx, T_cond) \
+ if (!(T_cond)) { \
+ printf("X"); \
+ T_xctx->T_bad++; \
+ } else { \
+ printf("."); \
+ T_xctx->T_good++; \
+ }
+
+#define test_so(T_cond) test_ctx_so(T_C, T_cond)
+
+#define test_assert(T_cond) test_ctx_assert(T_C, T_cond)
+
+extern void test_ctx_print_start(test_ctx_t *);
+extern void test_ctx_print_result(test_ctx_t *);
+extern void test_ctx_fatal(test_ctx_t *ctx, const char *fmt, ...);
+extern int test_main_impl(void);
+
+#endif /* TEST_TEST_H */