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 9efed3a..5398d38 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 330866d..85f68a3 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 876fc64..cf27739 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 d2b22ac..8b53013 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 4c0b6bb..0768bc6 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 2118964..a0b5966 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 d902a98..854f4bc 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 656901e..28f581c 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 b61d0ba..72df8ca 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 fc88b1b..5c7a9ec 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 6444fc1..a614adb 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 974967b..a5c8252 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 071c715..b404aef 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 46998d5..930b412 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 16a07ae..2fd87a8 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 17e4207..aed2293 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 e9d7cf5..6ed1767 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 2191f80..6312a0a 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 e5d2102..f5bf5b9 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