From 01fed651097a90ef9365ce6c2f16da2970a5444e Mon Sep 17 00:00:00 2001 From: Andy Zhou Date: Mon, 31 Mar 2014 13:38:04 -0700 Subject: [PATCH] unit-test: Improve ovstest user interface Improve help output. Running without argument now exit with an error message and an error code. Simplify OVSTEST_REGISTER() since not all test programs uses sub_commands. Signed-off-by: Andy Zhou Acked-by: Ben Pfaff --- tests/ovstest.c | 59 ++++++++++++++++++++++++++++++++--------------- tests/ovstest.h | 37 +++++++++++++---------------- tests/test-heap.c | 2 +- 3 files changed, 57 insertions(+), 41 deletions(-) diff --git a/tests/ovstest.c b/tests/ovstest.c index b8f5bfa3f..dbb4555da 100644 --- a/tests/ovstest.c +++ b/tests/ovstest.c @@ -22,6 +22,7 @@ #include #include "command-line.h" #include "ovstest.h" +#include "dynamic-string.h" #include "util.h" static struct command *commands = NULL; @@ -43,45 +44,60 @@ add_command(struct command *cmd) n_commands++; } +#define OVSTEST_USAGE \ +"TEST [TESTARGS] where 'TEST' is a string, 'TESTARGS' are optional \n"\ +"arguments of the TEST" + +static void +flush_help_string(struct ds *ds) +{ + if (ds->length > 2 ) { + ds->length -= 2; + printf ("%s\n", ds_cstr(ds)); + ds_clear(ds); + } +} + static void -list(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) +help(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) { const struct command *p; + struct ds test_names = DS_EMPTY_INITIALIZER; + const int linesize = 70; + + printf("%s: the big test executable\n" + "usage: %s TEST [TESTARGS]\n" + "where TEST is one of the following. \n\n", + program_name, program_name); for(p = commands; p->name != NULL; p++) { - printf("%s, %d, %d\n", p->name,p->min_args, p->max_args); + if (*p->name != '-') { /* Skip internal commands */ + ds_put_format(&test_names, "%s, ", p->name); + if ((test_names.length) >= linesize) { + flush_help_string(&test_names); + } + } } + flush_help_string(&test_names); + ds_destroy(&test_names); } static void add_top_level_commands(void) { - struct command help_cmd = {"--help", 0, 0, list}; + struct command help_cmd = {"--help", 0, 0, help}; add_command(&help_cmd); } void -ovstest_register(const char *test_name, ovstest_func f, - const struct command *sub_commands) +ovstest_register(const char *test_name, ovstest_func f) { struct command test_cmd; - int max_args = 0; - - if (sub_commands) { - const struct command *p; - - for(p = sub_commands; p->name != NULL; p++) { - if (p->max_args > max_args) { - max_args = p->max_args; - } - } - } - max_args++; /* adding in the sub program */ test_cmd.name = test_name; - test_cmd.min_args = 1; - test_cmd.max_args = max_args; + test_cmd.min_args = 0; + test_cmd.max_args = INT_MAX; test_cmd.handler = f; add_command(&test_cmd); @@ -100,6 +116,11 @@ main(int argc, char *argv[]) { set_program_name(argv[0]); + if (argc < 2) { + ovs_fatal(0, "expect test program to be specified; " + "use --help for usage"); + } + add_top_level_commands(); if (argc > 1) { run_command(argc - 1, argv + 1, commands); diff --git a/tests/ovstest.h b/tests/ovstest.h index 6d10a5de8..b4aad1b3a 100644 --- a/tests/ovstest.h +++ b/tests/ovstest.h @@ -17,6 +17,8 @@ #ifndef OVSTEST_H #define OVSTEST_H +#include "compiler.h" + /* Overview * ======== * @@ -29,33 +31,31 @@ * the number of test programs, linking will be done only once to produce * ovstest. * - * With ovs-test, each test programs now becomes a sub program of ovstest. + * With ovstest, each test programs now becomes a sub program of ovstest. * For example, 'mytest' program, can now be invoked as 'ovs mytest'. * * 'ovstest --help' will list all test programs can be invoked. * - * The Usage comment section below documents how a new test program can - * be added to ovs-test. + * The 'Usage' section below documents how to add a new sub program + * to ovstest using OVSTEST_REIGSTER macros. */ typedef void (*ovstest_func)(int argc, char *argv[]); - -void -ovstest_register(const char *test_name, ovstest_func f, - const struct command * sub_commands); +void ovstest_register(const char *test_name, ovstest_func f); /* Usage * ===== * - * For each test sub program, its 'main' program should be named as + * For each sub test program, its 'main' program should be named as * '_main()'. * - * OVSTEST_REGISTER register the sub program with ovs-test top level - * command line parser. is expected as argv[1] when invoking - * ovs-test. + * The 'main' programs should be registered with ovstest as a sub program. + * OVSTEST_REGISTER(name, function) + * + * 'name' will be name of the test program. It is expected as argv[1] when + * invoking with ovstest. * - * In case the test program has sub commands, its command array can be - * passed in as . Otherwise, NULL can be used instead. + * 'function' is the 'main' program mentioned above. * * Example: * ---------- @@ -69,16 +69,11 @@ ovstest_register(const char *test_name, ovstest_func f, * .... * } * - * // The last parameter is NULL in case my-test.c does - * // not have sub commands. Otherwise, its command - * // array can replace the NULL here. - * - * OVSTEST_REGISTER("my-test", my_test_main, NULL); + * OVSTEST_REGISTER("my-test", my_test_main); */ - -#define OVSTEST_REGISTER(name, function, sub_commands) \ +#define OVSTEST_REGISTER(name, function) \ OVS_CONSTRUCTOR(register_##function) { \ - ovstest_register(name, function, sub_commands); \ + ovstest_register(name, function); \ } #endif diff --git a/tests/test-heap.c b/tests/test-heap.c index 3e0940ca6..3a0afa5fa 100644 --- a/tests/test-heap.c +++ b/tests/test-heap.c @@ -485,4 +485,4 @@ test_heap_main(int argc, char *argv[]) run_command(argc - 1, argv + 1, commands); } -OVSTEST_REGISTER("test-heap", test_heap_main, commands); +OVSTEST_REGISTER("test-heap", test_heap_main); -- 2.43.0