X-Git-Url: https://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=tools%2Fccanlint%2Ftests%2Frun-coverage.c;h=886aebd54424b9019eb212eca4a91e649c799dd7;hp=9e9769907b90b3ed3649d6d680d23ae86c3d3814;hb=a8e0cfb1b02bd89850540f60232fc52fb0a11500;hpb=982539059656e4bbe6684e281140b3bb723deaa8 diff --git a/tools/ccanlint/tests/run-coverage.c b/tools/ccanlint/tests/run-coverage.c index 9e976990..886aebd5 100644 --- a/tools/ccanlint/tests/run-coverage.c +++ b/tools/ccanlint/tests/run-coverage.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -18,7 +19,7 @@ struct coverage_result { float uncovered; const char *what; - const char *output; + char *output; }; static bool find_source_file(struct manifest *m, const char *filename) @@ -38,17 +39,19 @@ static bool find_source_file(struct manifest *m, const char *filename) /* FIXME: Don't know how stable this is. Read cov files directly? */ static void analyze_coverage(struct manifest *m, - struct coverage_result *res, const char *output) + struct coverage_result *res, const char *output, + bool full_gcov) { char **lines = strsplit(res, output, "\n", NULL); float covered_lines = 0.0; unsigned int i, total_lines = 0; bool lines_matter = false; - /* FIXME: We assume GCOV mentions all files! + /* Output looks like: File '../../../ccan/tdb2/private.h' Lines executed:0.00% of 8 + /home/ccan/ccan/tdb2/test/run-simple-delete.c:creating 'run-simple-delete.c.gcov' File '../../../ccan/tdb2/tdb.c' Lines executed:0.00% of 450 @@ -71,13 +74,38 @@ static void analyze_coverage(struct manifest *m, errx(1, "Could not parse line '%s'", lines[i]); total_lines += of; covered_lines += ex / 100.0 * of; + } else if (full_gcov && strstr(lines[i], ":creating '")) { + char *file, *filename, *apostrophe; + apostrophe = strchr(lines[i], '\''); + filename = apostrophe + 1; + apostrophe = strchr(filename, '\''); + *apostrophe = '\0'; + if (lines_matter) { + file = grab_file(res, filename, NULL); + if (!file) { + res->what = talloc_asprintf(res, + "Reading %s", + filename); + res->output = talloc_strdup(res, + strerror(errno)); + return; + } + res->output = talloc_append_string(res->output, + file); + } + if (tools_verbose) + printf("Unlinking %s", filename); + unlink(filename); } } - /* Nothing covered? */ - if (total_lines == 0) + /* Nothing covered? We can't tell if there's a source file which + * was never executed, or there really is no code to execute, so + * assume the latter: this test deserves no score. */ + if (total_lines == 0) { res->uncovered = 1.0; - else + run_coverage_tests.total_score = 0; + } else res->uncovered = 1.0 - covered_lines / total_lines; } @@ -88,24 +116,18 @@ static void *do_run_coverage_tests(struct manifest *m, struct coverage_result *res; struct ccan_file *i; char *cmdout; - char *olddir; char *covcmd; bool ok; - - /* We run tests in the module directory, so any paths - * referenced can all be module-local. */ - olddir = talloc_getcwd(m); - if (!olddir) - err(1, "Could not save cwd"); - if (chdir(m->dir) != 0) - err(1, "Could not chdir to %s", m->dir); + bool full_gcov = (verbose > 1); res = talloc(m, struct coverage_result); res->what = NULL; + res->output = talloc_strdup(res, ""); res->uncovered = 1.0; /* This tells gcov where we put those .gcno files. */ - covcmd = talloc_asprintf(m, "gcov -n -o %s", + covcmd = talloc_asprintf(m, "gcov %s -o %s", + full_gcov ? "" : "-n", talloc_dirname(res, m->info_file->compiled)); /* Run them all. */ @@ -116,7 +138,7 @@ static void *do_run_coverage_tests(struct manifest *m, res->output = talloc_steal(res, cmdout); return res; } - covcmd = talloc_asprintf_append(covcmd, " %s", i->name); + covcmd = talloc_asprintf_append(covcmd, " %s", i->fullname); } list_for_each(&m->api_tests, i, list) { @@ -126,7 +148,7 @@ static void *do_run_coverage_tests(struct manifest *m, res->output = talloc_steal(res, cmdout); return res; } - covcmd = talloc_asprintf_append(covcmd, " %s", i->name); + covcmd = talloc_asprintf_append(covcmd, " %s", i->fullname); } /* Now run gcov: we want output even if it succeeds. */ @@ -137,7 +159,8 @@ static void *do_run_coverage_tests(struct manifest *m, return res; } - analyze_coverage(m, res, cmdout); + analyze_coverage(m, res, cmdout, full_gcov); + return res; } @@ -161,12 +184,20 @@ static const char *describe_run_coverage_tests(struct manifest *m, void *check_result) { struct coverage_result *res = check_result; + bool full_gcov = (verbose > 1); + char *ret; if (res->what) return talloc_asprintf(m, "%s: %s", res->what, res->output); - return talloc_asprintf(m, "Tests achieved %0.2f%% coverage", - (1.0 - res->uncovered) * 100); + if (!verbose) + return NULL; + + ret = talloc_asprintf(m, "Tests achieved %0.2f%% coverage", + (1.0 - res->uncovered) * 100); + if (full_gcov) + ret = talloc_asprintf_append(ret, "\n%s", res->output); + return ret; } struct ccanlint run_coverage_tests = {