src/test/test.c
branchnew-transport
changeset 168 a58ad50911fc
parent 167 0d2d8ca879d8
child 188 6fd4706a4180
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/test/test.c	Mon May 04 20:55:04 2009 +0300
@@ -0,0 +1,160 @@
+#include "test.h"
+
+#include "../sock.h"
+
+#include <getopt.h>
+
+/**
+ * The global state
+ */
+struct test_ctx _test_ctx;
+
+/**
+ * Setup the global sock_stream state
+ */
+static struct event_base* setup_sock (void)
+{
+    struct event_base *ev_base;
+    struct error_info err;
+
+    assert((ev_base = event_base_new()));
+    assert_success(sock_init(ev_base, &err));
+
+    return ev_base;
+}
+
+/**
+ * Command-line option codes
+ */
+enum option_code {
+    OPT_HELP            = 'h',
+    OPT_DEBUG           = 'd',
+    OPT_QUIET           = 'q',
+    OPT_LIST            = 'l',
+    
+    /** Options without short names */
+    _OPT_EXT_BEGIN      = 0x00ff,
+};
+
+/**
+ * Command-line option definitions
+ */
+static struct option options[] = {
+    {"help",            0,  NULL,   OPT_HELP        },
+    {"debug",           0,  NULL,   OPT_DEBUG       },
+    {"quiet",           0,  NULL,   OPT_QUIET       },
+    {"list",            0,  NULL,   OPT_LIST        },
+    {0,                 0,  0,      0               },
+};
+
+/**
+ * Display --help output on stdout
+ */
+static void usage (const char *exe) 
+{
+    printf("Usage: %s [OPTIONS]\n", exe);
+    printf("\n");
+    printf(" --help / -h            display this message\n");
+    printf(" --debug / -d           display DEBUG log messages\n");
+    printf(" --quiet / -q           supress INFO log messages\n");
+    printf(" --list / -l            list all tests\n");
+}
+
+/**
+ * Output the given list of tests on stdout
+ */
+static void list_tests (const struct test *tests)
+{
+    const struct test *test;
+    
+    printf("Available tests:\n");
+
+    for (test = tests; test->name; test++) {
+        printf("\t%s\n", test->name);
+    }
+}
+
+/**
+ * Run the given NULL-terminated list of tests, optionally filtering against the given filter.
+ *
+ * Returns the number of tests run, which may be zero.
+ */
+static size_t run_tests (const struct test tests[], const char *filter)
+{
+    size_t test_count = 0;
+    const struct test *test;
+
+    // run each test in turn
+    for (test = tests; test->name; test++) {
+        // filter out if given
+        if ((filter && strcmp(test->name, filter)) || (!filter && test->optional))
+            continue;
+
+        log_info("Running test: %s", test->name);
+        
+        // count and run
+        test_count++;
+        test->func();
+    }
+    
+    return test_count;
+}
+
+int main (int argc, char **argv)
+{
+    int opt, option_index;
+    const char *filter = NULL;
+
+    size_t test_count;
+
+    // parse options
+    while ((opt = getopt_long(argc, argv, "hdql", options, &option_index)) != -1) {
+        switch (opt) {
+            case OPT_HELP:
+                usage(argv[0]);
+                exit(EXIT_SUCCESS);
+            
+            case OPT_DEBUG:
+                set_log_level(LOG_DEBUG);
+                break;
+
+            case OPT_QUIET:
+                set_log_level(LOG_WARN);
+                break;
+           
+            case OPT_LIST:
+                list_tests(_tests);
+                exit(EXIT_SUCCESS);
+
+            case '?':
+                usage(argv[0]);
+                exit(EXIT_FAILURE);
+        }
+    }
+
+    // parse positional arguments
+    if (optind < argc) {
+        if (optind == argc - 1) {
+            // filter
+            filter = argv[optind];
+            
+            log_info("only running tests: %s", filter);
+        } else {
+            FATAL("too many arguments");
+        }
+    }
+
+    // setup the sockets stuff
+    _test_ctx.ev_base = setup_sock();
+
+    // run tests
+    if ((test_count = run_tests(_tests, filter)) == 0)
+        FATAL("no tests run");
+    
+    // log
+    log_info("done, ran %zu tests", test_count);
+    
+    // ok
+    return EXIT_SUCCESS;
+}
+