From f952b88b36e3803370825fb43385f1a42aa24b64 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Fri, 9 Apr 2010 10:58:21 +0930 Subject: [PATCH] From: Joseph Adams The ccanlint patch is rather intrusive. First, it adds a new field to all the ccanlint tests, "key". key is a shorter, still unique description of the test (e.g. "valgrind"). The names I chose as keys for all the tests are somewhat arbitrary and often don't reflect the name of the .c source file (because some of those names are just too darn long). Second, it adds two new options to ccanlint: -l: list tests ccanlint performs -x: exclude tests (e.g. -x trailing_whitespace,valgrind) It also adds a consistency check making sure all tests have unique keys and names. The primary goal of the ccanlint patch was so I could exclude the valgrind test, which takes a really long time for some modules (I think btree takes the longest, at around 2 minutes). I'm not sure I did it 100% correctly, so you'll want to review it first. --- tools/ccanlint/Makefile | 1 + tools/ccanlint/ccanlint.c | 74 ++++++++++++++++++- tools/ccanlint/ccanlint.h | 3 + tools/ccanlint/compulsory_tests/build.c | 1 + tools/ccanlint/compulsory_tests/build_objs.c | 1 + tools/ccanlint/compulsory_tests/check_build.c | 1 + .../compulsory_tests/check_depends_built.c | 1 + .../compulsory_tests/check_depends_exist.c | 1 + .../compulsory_tests/check_includes_build.c | 1 + .../compulsory_tests/compile_test_helpers.c | 1 + .../ccanlint/compulsory_tests/compile_tests.c | 1 + tools/ccanlint/compulsory_tests/has_info.c | 1 + .../compulsory_tests/has_main_header.c | 1 + tools/ccanlint/compulsory_tests/has_tests.c | 1 + tools/ccanlint/compulsory_tests/run_tests.c | 1 + tools/ccanlint/tests/has_info_documentation.c | 1 + tools/ccanlint/tests/idempotent.c | 1 + tools/ccanlint/tests/run_tests_valgrind.c | 1 + tools/ccanlint/tests/trailing_whitespace.c | 1 + 19 files changed, 92 insertions(+), 2 deletions(-) diff --git a/tools/ccanlint/Makefile b/tools/ccanlint/Makefile index 9efed3a5..5398d380 100644 --- a/tools/ccanlint/Makefile +++ b/tools/ccanlint/Makefile @@ -9,6 +9,7 @@ CORE_OBJS := tools/ccanlint/ccanlint.o \ tools/tools.o \ tools/compile.o \ ccan/str_talloc/str_talloc.o ccan/grab_file/grab_file.o \ + ccan/btree/btree.o \ ccan/talloc/talloc.o ccan/noerr/noerr.o \ ccan/read_write_all/read_write_all.o diff --git a/tools/ccanlint/ccanlint.c b/tools/ccanlint/ccanlint.c index 330866d1..85f68a3d 100644 --- a/tools/ccanlint/ccanlint.c +++ b/tools/ccanlint/ccanlint.c @@ -26,6 +26,9 @@ #include #include #include +#include +#include +#include #include static unsigned int verbose = 0; @@ -33,6 +36,7 @@ static LIST_HEAD(compulsory_tests); static LIST_HEAD(normal_tests); static LIST_HEAD(finished_tests); bool safe_mode = false; +static struct btree *exclude; static void usage(const char *name) { @@ -40,7 +44,9 @@ static void usage(const char *name) " -v: verbose mode\n" " -s: simply give one line summary\n" " -d: use this directory instead of the current one\n" - " -n: do not compile anything\n", + " -n: do not compile anything\n" + " -l: list tests ccanlint performs\n" + " -x: exclude tests (e.g. -x trailing_whitespace,valgrind)\n", name); exit(1); } @@ -73,6 +79,9 @@ bool ask(const char *question) static const char *should_skip(struct manifest *m, struct ccanlint *i) { + if (btree_lookup(exclude, i->key)) + return "excluded on command line"; + if (i->skip_fail) return "dependency failed"; @@ -212,6 +221,7 @@ static inline struct ccanlint *get_next_test(struct list_head *test) static void init_tests(void) { const struct ccanlint *i; + struct btree *keys, *names; #undef REGISTER_TEST #define REGISTER_TEST(name, ...) register_test(&normal_tests, &name, __VA_ARGS__) @@ -220,6 +230,25 @@ static void init_tests(void) #define REGISTER_TEST(name, ...) register_test(&compulsory_tests, &name, __VA_ARGS__) #include "generated-compulsory-tests" + /* Self-consistency check: make sure no two tests + have the same key or name. */ + keys = btree_new(btree_strcmp); + names = btree_new(btree_strcmp); + list_for_each(&compulsory_tests, i, list) { + if (!btree_insert(keys, i->key)) + errx(1, "BUG: Duplicate test key '%s'", i->key); + if (!btree_insert(keys, i->name)) + errx(1, "BUG: Duplicate test name '%s'", i->name); + } + list_for_each(&normal_tests, i, list) { + if (!btree_insert(keys, i->key)) + errx(1, "BUG: Duplicate test key '%s'", i->key); + if (!btree_insert(keys, i->name)) + errx(1, "BUG: Duplicate test name '%s'", i->name); + } + btree_delete(keys); + btree_delete(names); + if (!verbose) return; @@ -246,6 +275,37 @@ static void init_tests(void) } } +static void print_test(const struct ccanlint *i) +{ + int space = 25 - strlen(i->key); + + if (space >= 2) { + printf(" %s", i->key); + while (space--) + putchar(' '); + } else { + printf(" %s ", i->key); + } + + printf("%s\n", i->name); +} + +static void list_tests(void) +{ + const struct ccanlint *i; + + init_tests(); + + printf("Compulsory tests:\n"); + list_for_each(&compulsory_tests, i, list) + print_test(i); + printf("Normal tests:\n"); + list_for_each(&normal_tests, i, list) + print_test(i); + + exit(0); +} + int main(int argc, char *argv[]) { int c; @@ -254,10 +314,12 @@ int main(int argc, char *argv[]) struct manifest *m; struct ccanlint *i; const char *prefix = "", *dir = "."; + + exclude = btree_new(btree_strcmp); /* I'd love to use long options, but that's not standard. */ /* FIXME: getopt_long ccan package? */ - while ((c = getopt(argc, argv, "sd:vn")) != -1) { + while ((c = getopt(argc, argv, "sd:vnlx:")) != -1) { switch (c) { case 'd': dir = optarg; @@ -265,6 +327,8 @@ int main(int argc, char *argv[]) optarg), ": "); break; + case 'l': + list_tests(); case 's': summary = true; break; @@ -274,6 +338,12 @@ int main(int argc, char *argv[]) case 'n': safe_mode = true; break; + case 'x': { + char **exclude_strs = strsplit(NULL, optarg, ",", NULL); + size_t i; + for (i = 0; exclude_strs[i]; i++) + btree_insert(exclude, exclude_strs[i]); + } break; default: usage(argv[0]); } diff --git a/tools/ccanlint/ccanlint.h b/tools/ccanlint/ccanlint.h index 876fc64c..cf277393 100644 --- a/tools/ccanlint/ccanlint.h +++ b/tools/ccanlint/ccanlint.h @@ -40,6 +40,9 @@ struct manifest *get_manifest(const void *ctx, const char *dir); struct ccanlint { struct list_node list; + /* More concise unique name of test. */ + const char *key; + /* Unique name of test */ const char *name; diff --git a/tools/ccanlint/compulsory_tests/build.c b/tools/ccanlint/compulsory_tests/build.c index d2b22ac5..8b530131 100644 --- a/tools/ccanlint/compulsory_tests/build.c +++ b/tools/ccanlint/compulsory_tests/build.c @@ -62,6 +62,7 @@ static const char *describe_build(struct manifest *m, void *check_result) } struct ccanlint build = { + .key = "build", .name = "Module can be built", .total_score = 1, .check = do_build, diff --git a/tools/ccanlint/compulsory_tests/build_objs.c b/tools/ccanlint/compulsory_tests/build_objs.c index 4c0b6bba..0768bc6f 100644 --- a/tools/ccanlint/compulsory_tests/build_objs.c +++ b/tools/ccanlint/compulsory_tests/build_objs.c @@ -50,6 +50,7 @@ static const char *describe_objs_build(struct manifest *m, void *check_result) } struct ccanlint build_objs = { + .key = "build-objs", .name = "Module object files can be built", .check = check_objs_build, .describe = describe_objs_build, diff --git a/tools/ccanlint/compulsory_tests/check_build.c b/tools/ccanlint/compulsory_tests/check_build.c index 21189645..a0b59669 100644 --- a/tools/ccanlint/compulsory_tests/check_build.c +++ b/tools/ccanlint/compulsory_tests/check_build.c @@ -84,6 +84,7 @@ static const char *describe_use_build(struct manifest *m, void *check_result) } struct ccanlint check_build = { + .key = "check-build", .name = "Module can be used", .total_score = 1, .check = check_use_build, diff --git a/tools/ccanlint/compulsory_tests/check_depends_built.c b/tools/ccanlint/compulsory_tests/check_depends_built.c index d902a985..854f4bc8 100644 --- a/tools/ccanlint/compulsory_tests/check_depends_built.c +++ b/tools/ccanlint/compulsory_tests/check_depends_built.c @@ -83,6 +83,7 @@ static const char *describe_depends_built(struct manifest *m, } struct ccanlint depends_built = { + .key = "depends-built", .name = "CCAN dependencies are built", .total_score = 1, .check = check_depends_built, diff --git a/tools/ccanlint/compulsory_tests/check_depends_exist.c b/tools/ccanlint/compulsory_tests/check_depends_exist.c index 656901e7..28f581c5 100644 --- a/tools/ccanlint/compulsory_tests/check_depends_exist.c +++ b/tools/ccanlint/compulsory_tests/check_depends_exist.c @@ -66,6 +66,7 @@ static const char *describe_depends_exist(struct manifest *m, } struct ccanlint depends_exist = { + .key = "depends-exist", .name = "CCAN dependencies are present", .total_score = 1, .check = check_depends_exist, diff --git a/tools/ccanlint/compulsory_tests/check_includes_build.c b/tools/ccanlint/compulsory_tests/check_includes_build.c index b61d0baa..72df8ca8 100644 --- a/tools/ccanlint/compulsory_tests/check_includes_build.c +++ b/tools/ccanlint/compulsory_tests/check_includes_build.c @@ -57,6 +57,7 @@ static const char *describe_includes_build(struct manifest *m, } struct ccanlint includes_build = { + .key = "include-main", .name = "Can compile against main header", .total_score = 1, .check = check_includes_build, diff --git a/tools/ccanlint/compulsory_tests/compile_test_helpers.c b/tools/ccanlint/compulsory_tests/compile_test_helpers.c index fc88b1b0..5c7a9ec6 100644 --- a/tools/ccanlint/compulsory_tests/compile_test_helpers.c +++ b/tools/ccanlint/compulsory_tests/compile_test_helpers.c @@ -56,6 +56,7 @@ static const char *describe_compile_test_helpers(struct manifest *m, } struct ccanlint compile_test_helpers = { + .key = "compile-helpers", .name = "Compiling test helper files", .total_score = 1, .check = do_compile_test_helpers, diff --git a/tools/ccanlint/compulsory_tests/compile_tests.c b/tools/ccanlint/compulsory_tests/compile_tests.c index 6444fc17..a614adb3 100644 --- a/tools/ccanlint/compulsory_tests/compile_tests.c +++ b/tools/ccanlint/compulsory_tests/compile_tests.c @@ -182,6 +182,7 @@ static const char *describe_compile_tests(struct manifest *m, } struct ccanlint compile_tests = { + .key = "compile", .name = "Compile tests succeed", .score = score_compile_tests, .check = do_compile_tests, diff --git a/tools/ccanlint/compulsory_tests/has_info.c b/tools/ccanlint/compulsory_tests/has_info.c index 974967bf..a5c82526 100644 --- a/tools/ccanlint/compulsory_tests/has_info.c +++ b/tools/ccanlint/compulsory_tests/has_info.c @@ -71,6 +71,7 @@ static void create_info_template(struct manifest *m, void *check_result) } struct ccanlint has_info = { + .key = "info", .name = "Has _info file", .check = check_has_info, .describe = describe_has_info, diff --git a/tools/ccanlint/compulsory_tests/has_main_header.c b/tools/ccanlint/compulsory_tests/has_main_header.c index 071c7157..b404aef8 100644 --- a/tools/ccanlint/compulsory_tests/has_main_header.c +++ b/tools/ccanlint/compulsory_tests/has_main_header.c @@ -35,6 +35,7 @@ static const char *describe_has_main_header(struct manifest *m, } struct ccanlint has_main_header = { + .key = "has-main-header", .name = "No main header file", .check = check_has_main_header, .describe = describe_has_main_header, diff --git a/tools/ccanlint/compulsory_tests/has_tests.c b/tools/ccanlint/compulsory_tests/has_tests.c index 46998d58..930b4129 100644 --- a/tools/ccanlint/compulsory_tests/has_tests.c +++ b/tools/ccanlint/compulsory_tests/has_tests.c @@ -124,6 +124,7 @@ static void handle_no_tests(struct manifest *m, void *check_result) } struct ccanlint has_tests = { + .key = "has-tests", .name = "Has tests", .check = check_has_tests, .describe = describe_has_tests, diff --git a/tools/ccanlint/compulsory_tests/run_tests.c b/tools/ccanlint/compulsory_tests/run_tests.c index 16a07aee..2fd87a8c 100644 --- a/tools/ccanlint/compulsory_tests/run_tests.c +++ b/tools/ccanlint/compulsory_tests/run_tests.c @@ -124,6 +124,7 @@ static void run_under_debugger(struct manifest *m, void *check_result) } struct ccanlint run_tests = { + .key = "run", .name = "run and api tests run successfully", .score = score_run_tests, .check = do_run_tests, diff --git a/tools/ccanlint/tests/has_info_documentation.c b/tools/ccanlint/tests/has_info_documentation.c index 17e4207e..aed22934 100644 --- a/tools/ccanlint/tests/has_info_documentation.c +++ b/tools/ccanlint/tests/has_info_documentation.c @@ -123,6 +123,7 @@ static unsigned int has_info_documentation_score(struct manifest *m, } struct ccanlint has_info_documentation = { + .key = "info-documentation", .name = "Documentation in _info file", .total_score = 3, .score = has_info_documentation_score, diff --git a/tools/ccanlint/tests/idempotent.c b/tools/ccanlint/tests/idempotent.c index e9d7cf56..6ed17676 100644 --- a/tools/ccanlint/tests/idempotent.c +++ b/tools/ccanlint/tests/idempotent.c @@ -132,6 +132,7 @@ static const char *describe_idempotent(struct manifest *m, void *check_result) } struct ccanlint idempotent = { + .key = "idempotent", .name = "Headers are #ifndef/#define idempotent wrapped", .total_score = 1, .check = check_idempotent, diff --git a/tools/ccanlint/tests/run_tests_valgrind.c b/tools/ccanlint/tests/run_tests_valgrind.c index 2191f80e..6312a0a8 100644 --- a/tools/ccanlint/tests/run_tests_valgrind.c +++ b/tools/ccanlint/tests/run_tests_valgrind.c @@ -127,6 +127,7 @@ static void run_under_debugger_vg(struct manifest *m, void *check_result) } struct ccanlint run_tests_vg = { + .key = "valgrind", .name = "run and api tests under valgrind", .score = score_run_tests_vg, .check = do_run_tests_vg, diff --git a/tools/ccanlint/tests/trailing_whitespace.c b/tools/ccanlint/tests/trailing_whitespace.c index e5d2102e..f5bf5b9f 100644 --- a/tools/ccanlint/tests/trailing_whitespace.c +++ b/tools/ccanlint/tests/trailing_whitespace.c @@ -40,6 +40,7 @@ static const char *describe_trailing_whitespace(struct manifest *m, } struct ccanlint trailing_whitespace = { + .key = "trailing-whitespace", .name = "No lines with unnecessary trailing whitespace", .total_score = 1, .check = check_trailing_whitespace, -- 2.39.2