Commit f952b88b authored by Rusty Russell's avatar Rusty Russell

From: Joseph Adams <joeyadams3.14159@gmail.com>

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.
parent 7b877620
...@@ -9,6 +9,7 @@ CORE_OBJS := tools/ccanlint/ccanlint.o \ ...@@ -9,6 +9,7 @@ CORE_OBJS := tools/ccanlint/ccanlint.o \
tools/tools.o \ tools/tools.o \
tools/compile.o \ tools/compile.o \
ccan/str_talloc/str_talloc.o ccan/grab_file/grab_file.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/talloc/talloc.o ccan/noerr/noerr.o \
ccan/read_write_all/read_write_all.o ccan/read_write_all/read_write_all.o
......
...@@ -26,6 +26,9 @@ ...@@ -26,6 +26,9 @@
#include <string.h> #include <string.h>
#include <err.h> #include <err.h>
#include <ctype.h> #include <ctype.h>
#include <ccan/btree/btree.h>
#include <ccan/str/str.h>
#include <ccan/str_talloc/str_talloc.h>
#include <ccan/talloc/talloc.h> #include <ccan/talloc/talloc.h>
static unsigned int verbose = 0; static unsigned int verbose = 0;
...@@ -33,6 +36,7 @@ static LIST_HEAD(compulsory_tests); ...@@ -33,6 +36,7 @@ static LIST_HEAD(compulsory_tests);
static LIST_HEAD(normal_tests); static LIST_HEAD(normal_tests);
static LIST_HEAD(finished_tests); static LIST_HEAD(finished_tests);
bool safe_mode = false; bool safe_mode = false;
static struct btree *exclude;
static void usage(const char *name) static void usage(const char *name)
{ {
...@@ -40,7 +44,9 @@ static void usage(const char *name) ...@@ -40,7 +44,9 @@ static void usage(const char *name)
" -v: verbose mode\n" " -v: verbose mode\n"
" -s: simply give one line summary\n" " -s: simply give one line summary\n"
" -d: use this directory instead of the current one\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); name);
exit(1); exit(1);
} }
...@@ -73,6 +79,9 @@ bool ask(const char *question) ...@@ -73,6 +79,9 @@ bool ask(const char *question)
static const char *should_skip(struct manifest *m, struct ccanlint *i) 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) if (i->skip_fail)
return "dependency failed"; return "dependency failed";
...@@ -212,6 +221,7 @@ static inline struct ccanlint *get_next_test(struct list_head *test) ...@@ -212,6 +221,7 @@ static inline struct ccanlint *get_next_test(struct list_head *test)
static void init_tests(void) static void init_tests(void)
{ {
const struct ccanlint *i; const struct ccanlint *i;
struct btree *keys, *names;
#undef REGISTER_TEST #undef REGISTER_TEST
#define REGISTER_TEST(name, ...) register_test(&normal_tests, &name, __VA_ARGS__) #define REGISTER_TEST(name, ...) register_test(&normal_tests, &name, __VA_ARGS__)
...@@ -220,6 +230,25 @@ static void init_tests(void) ...@@ -220,6 +230,25 @@ static void init_tests(void)
#define REGISTER_TEST(name, ...) register_test(&compulsory_tests, &name, __VA_ARGS__) #define REGISTER_TEST(name, ...) register_test(&compulsory_tests, &name, __VA_ARGS__)
#include "generated-compulsory-tests" #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) if (!verbose)
return; return;
...@@ -246,6 +275,37 @@ static void init_tests(void) ...@@ -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 main(int argc, char *argv[])
{ {
int c; int c;
...@@ -255,9 +315,11 @@ int main(int argc, char *argv[]) ...@@ -255,9 +315,11 @@ int main(int argc, char *argv[])
struct ccanlint *i; struct ccanlint *i;
const char *prefix = "", *dir = "."; const char *prefix = "", *dir = ".";
exclude = btree_new(btree_strcmp);
/* I'd love to use long options, but that's not standard. */ /* I'd love to use long options, but that's not standard. */
/* FIXME: getopt_long ccan package? */ /* FIXME: getopt_long ccan package? */
while ((c = getopt(argc, argv, "sd:vn")) != -1) { while ((c = getopt(argc, argv, "sd:vnlx:")) != -1) {
switch (c) { switch (c) {
case 'd': case 'd':
dir = optarg; dir = optarg;
...@@ -265,6 +327,8 @@ int main(int argc, char *argv[]) ...@@ -265,6 +327,8 @@ int main(int argc, char *argv[])
optarg), optarg),
": "); ": ");
break; break;
case 'l':
list_tests();
case 's': case 's':
summary = true; summary = true;
break; break;
...@@ -274,6 +338,12 @@ int main(int argc, char *argv[]) ...@@ -274,6 +338,12 @@ int main(int argc, char *argv[])
case 'n': case 'n':
safe_mode = true; safe_mode = true;
break; 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: default:
usage(argv[0]); usage(argv[0]);
} }
......
...@@ -40,6 +40,9 @@ struct manifest *get_manifest(const void *ctx, const char *dir); ...@@ -40,6 +40,9 @@ struct manifest *get_manifest(const void *ctx, const char *dir);
struct ccanlint { struct ccanlint {
struct list_node list; struct list_node list;
/* More concise unique name of test. */
const char *key;
/* Unique name of test */ /* Unique name of test */
const char *name; const char *name;
......
...@@ -62,6 +62,7 @@ static const char *describe_build(struct manifest *m, void *check_result) ...@@ -62,6 +62,7 @@ static const char *describe_build(struct manifest *m, void *check_result)
} }
struct ccanlint build = { struct ccanlint build = {
.key = "build",
.name = "Module can be built", .name = "Module can be built",
.total_score = 1, .total_score = 1,
.check = do_build, .check = do_build,
......
...@@ -50,6 +50,7 @@ static const char *describe_objs_build(struct manifest *m, void *check_result) ...@@ -50,6 +50,7 @@ static const char *describe_objs_build(struct manifest *m, void *check_result)
} }
struct ccanlint build_objs = { struct ccanlint build_objs = {
.key = "build-objs",
.name = "Module object files can be built", .name = "Module object files can be built",
.check = check_objs_build, .check = check_objs_build,
.describe = describe_objs_build, .describe = describe_objs_build,
......
...@@ -84,6 +84,7 @@ static const char *describe_use_build(struct manifest *m, void *check_result) ...@@ -84,6 +84,7 @@ static const char *describe_use_build(struct manifest *m, void *check_result)
} }
struct ccanlint check_build = { struct ccanlint check_build = {
.key = "check-build",
.name = "Module can be used", .name = "Module can be used",
.total_score = 1, .total_score = 1,
.check = check_use_build, .check = check_use_build,
......
...@@ -83,6 +83,7 @@ static const char *describe_depends_built(struct manifest *m, ...@@ -83,6 +83,7 @@ static const char *describe_depends_built(struct manifest *m,
} }
struct ccanlint depends_built = { struct ccanlint depends_built = {
.key = "depends-built",
.name = "CCAN dependencies are built", .name = "CCAN dependencies are built",
.total_score = 1, .total_score = 1,
.check = check_depends_built, .check = check_depends_built,
......
...@@ -66,6 +66,7 @@ static const char *describe_depends_exist(struct manifest *m, ...@@ -66,6 +66,7 @@ static const char *describe_depends_exist(struct manifest *m,
} }
struct ccanlint depends_exist = { struct ccanlint depends_exist = {
.key = "depends-exist",
.name = "CCAN dependencies are present", .name = "CCAN dependencies are present",
.total_score = 1, .total_score = 1,
.check = check_depends_exist, .check = check_depends_exist,
......
...@@ -57,6 +57,7 @@ static const char *describe_includes_build(struct manifest *m, ...@@ -57,6 +57,7 @@ static const char *describe_includes_build(struct manifest *m,
} }
struct ccanlint includes_build = { struct ccanlint includes_build = {
.key = "include-main",
.name = "Can compile against main header", .name = "Can compile against main header",
.total_score = 1, .total_score = 1,
.check = check_includes_build, .check = check_includes_build,
......
...@@ -56,6 +56,7 @@ static const char *describe_compile_test_helpers(struct manifest *m, ...@@ -56,6 +56,7 @@ static const char *describe_compile_test_helpers(struct manifest *m,
} }
struct ccanlint compile_test_helpers = { struct ccanlint compile_test_helpers = {
.key = "compile-helpers",
.name = "Compiling test helper files", .name = "Compiling test helper files",
.total_score = 1, .total_score = 1,
.check = do_compile_test_helpers, .check = do_compile_test_helpers,
......
...@@ -182,6 +182,7 @@ static const char *describe_compile_tests(struct manifest *m, ...@@ -182,6 +182,7 @@ static const char *describe_compile_tests(struct manifest *m,
} }
struct ccanlint compile_tests = { struct ccanlint compile_tests = {
.key = "compile",
.name = "Compile tests succeed", .name = "Compile tests succeed",
.score = score_compile_tests, .score = score_compile_tests,
.check = do_compile_tests, .check = do_compile_tests,
......
...@@ -71,6 +71,7 @@ static void create_info_template(struct manifest *m, void *check_result) ...@@ -71,6 +71,7 @@ static void create_info_template(struct manifest *m, void *check_result)
} }
struct ccanlint has_info = { struct ccanlint has_info = {
.key = "info",
.name = "Has _info file", .name = "Has _info file",
.check = check_has_info, .check = check_has_info,
.describe = describe_has_info, .describe = describe_has_info,
......
...@@ -35,6 +35,7 @@ static const char *describe_has_main_header(struct manifest *m, ...@@ -35,6 +35,7 @@ static const char *describe_has_main_header(struct manifest *m,
} }
struct ccanlint has_main_header = { struct ccanlint has_main_header = {
.key = "has-main-header",
.name = "No main header file", .name = "No main header file",
.check = check_has_main_header, .check = check_has_main_header,
.describe = describe_has_main_header, .describe = describe_has_main_header,
......
...@@ -124,6 +124,7 @@ static void handle_no_tests(struct manifest *m, void *check_result) ...@@ -124,6 +124,7 @@ static void handle_no_tests(struct manifest *m, void *check_result)
} }
struct ccanlint has_tests = { struct ccanlint has_tests = {
.key = "has-tests",
.name = "Has tests", .name = "Has tests",
.check = check_has_tests, .check = check_has_tests,
.describe = describe_has_tests, .describe = describe_has_tests,
......
...@@ -124,6 +124,7 @@ static void run_under_debugger(struct manifest *m, void *check_result) ...@@ -124,6 +124,7 @@ static void run_under_debugger(struct manifest *m, void *check_result)
} }
struct ccanlint run_tests = { struct ccanlint run_tests = {
.key = "run",
.name = "run and api tests run successfully", .name = "run and api tests run successfully",
.score = score_run_tests, .score = score_run_tests,
.check = do_run_tests, .check = do_run_tests,
......
...@@ -123,6 +123,7 @@ static unsigned int has_info_documentation_score(struct manifest *m, ...@@ -123,6 +123,7 @@ static unsigned int has_info_documentation_score(struct manifest *m,
} }
struct ccanlint has_info_documentation = { struct ccanlint has_info_documentation = {
.key = "info-documentation",
.name = "Documentation in _info file", .name = "Documentation in _info file",
.total_score = 3, .total_score = 3,
.score = has_info_documentation_score, .score = has_info_documentation_score,
......
...@@ -132,6 +132,7 @@ static const char *describe_idempotent(struct manifest *m, void *check_result) ...@@ -132,6 +132,7 @@ static const char *describe_idempotent(struct manifest *m, void *check_result)
} }
struct ccanlint idempotent = { struct ccanlint idempotent = {
.key = "idempotent",
.name = "Headers are #ifndef/#define idempotent wrapped", .name = "Headers are #ifndef/#define idempotent wrapped",
.total_score = 1, .total_score = 1,
.check = check_idempotent, .check = check_idempotent,
......
...@@ -127,6 +127,7 @@ static void run_under_debugger_vg(struct manifest *m, void *check_result) ...@@ -127,6 +127,7 @@ static void run_under_debugger_vg(struct manifest *m, void *check_result)
} }
struct ccanlint run_tests_vg = { struct ccanlint run_tests_vg = {
.key = "valgrind",
.name = "run and api tests under valgrind", .name = "run and api tests under valgrind",
.score = score_run_tests_vg, .score = score_run_tests_vg,
.check = do_run_tests_vg, .check = do_run_tests_vg,
......
...@@ -40,6 +40,7 @@ static const char *describe_trailing_whitespace(struct manifest *m, ...@@ -40,6 +40,7 @@ static const char *describe_trailing_whitespace(struct manifest *m,
} }
struct ccanlint trailing_whitespace = { struct ccanlint trailing_whitespace = {
.key = "trailing-whitespace",
.name = "No lines with unnecessary trailing whitespace", .name = "No lines with unnecessary trailing whitespace",
.total_score = 1, .total_score = 1,
.check = check_trailing_whitespace, .check = check_trailing_whitespace,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment