ccanlint: add ccanlint section to _info
authorRusty Russell <rusty@rustcorp.com.au>
Wed, 17 Nov 2010 09:59:13 +0000 (20:29 +1030)
committerRusty Russell <rusty@rustcorp.com.au>
Wed, 17 Nov 2010 09:59:13 +0000 (20:29 +1030)
This supersedes the previous Fails: section, into a more general set of
lines of form:

      <testname> <option>...

With the special <option> "FAIL" to mean we know we fail this test.
We accept options to valgrind-tests; in particular tdb2 wants
--partial-loads-ok=yes passed to valgrind.

ccan/tdb/_info
ccan/tdb2/_info
tools/ccanlint/ccanlint.c
tools/ccanlint/ccanlint.h
tools/ccanlint/tests/run_tests_valgrind.c

index 27436713e2a8ae6c8fca629133622a22ace1c0c6..51dcab5e7c2e7a42ad63d53e46e1720075aa3b2c 100644 (file)
@@ -65,7 +65,9 @@
  *
  * License: LGPLv3 (or later)
  *
- * Fails: valgrind-tests // valgrind breaks fcntl locks.
+ * Ccanlint:
+ *     // valgrind breaks fcntl locks.
+ *     valgrind-tests FAIL
  */
 int main(int argc, char *argv[])
 {
index ddb362022e3b1990f33675f6a823d2cccf373c24..53dd1ce2d53baacf39e8764c97a5d0bf95ec6ff4 100644 (file)
@@ -64,8 +64,9 @@
  *
  * License: LGPLv3 (or later)
  *
- * Fails:
- *     valgrind-tests // hash needs --partial-loads-ok=yes.
+ * Ccanlint:
+ *     // hash fails because it accesses data in 4 byte quantities for speed.
+ *     valgrind-tests --partial-loads-ok=yes
  */
 int main(int argc, char *argv[])
 {
index d09f68da19dc94932f4ba05d09a44d550e121608..e70eca1b342f58e418df333be223b1be0c123d5c 100644 (file)
@@ -344,24 +344,64 @@ static char *list_tests(void *arg)
        exit(0);
 }
 
-static char *strip(const void *ctx, const char *line)
+/* Remove empty lines. */
+static char **collapse(char **lines, unsigned int *nump)
 {
-       line += strcspn(line, IDENT_CHARS "-");
-       return talloc_strndup(ctx, line, strspn(line, IDENT_CHARS "-"));
+       unsigned int i, j;
+       for (i = j = 0; lines[i]; i++) {
+               if (lines[i][0])
+                       lines[j++] = lines[i];
+       }
+       if (nump)
+               *nump = j;
+       return lines;
 }
 
-static void add_info_fails(struct ccan_file *info)
+static void add_info_options(struct ccan_file *info, bool mark_fails)
 {
        struct doc_section *d;
        unsigned int i;
+       struct ccanlint *test;
 
        list_for_each(get_ccan_file_docs(info), d, list) {
-               if (!streq(d->type, "fails"))
+               if (!streq(d->type, "ccanlint"))
                        continue;
 
-               for (i = 0; i < d->num_lines; i++)
-                       btree_insert(info_exclude, strip(info, d->lines[i]));
-               break;
+               for (i = 0; i < d->num_lines; i++) {
+                       char **words = collapse(strsplit(d, d->lines[i], " \t",
+                                                        NULL), NULL);
+                       if (!words[0])
+                               continue;
+
+                       if (strncmp(words[0], "//", 2) == 0)
+                               continue;
+
+                       test = find_test(words[0]);
+                       if (!test) {
+                               warnx("%s: unknown ccanlint test '%s'",
+                                     info->fullname, words[0]);
+                               continue;
+                       }
+
+                       if (!words[1]) {
+                               warnx("%s: no argument to test '%s'",
+                                     info->fullname, words[0]);
+                               continue;
+                       }
+
+                       /* Known failure? */
+                       if (strcasecmp(words[1], "FAIL") == 0) {
+                               if (mark_fails)
+                                       btree_insert(info_exclude, words[0]);
+                       } else {
+                               if (!test->takes_options)
+                                       warnx("%s: %s doesn't take options",
+                                             info->fullname, words[0]);
+                               /* Copy line exactly into options. */
+                               test->options = strstr(d->lines[i], words[0])
+                                       + strlen(words[0]);
+                       }
+               }
        }
 }
 
@@ -469,9 +509,8 @@ int main(int argc, char *argv[])
                }
        }
 
-       /* --target overrides _info excludes */
-       if (!target)
-               add_info_fails(m->info_file);
+       /* --target overrides known FAIL from _info */
+       add_info_options(m->info_file, !target);
 
        while ((i = get_next_test(&normal_tests)) != NULL)
                run_test(i, summary, &score, &total_score, m);
index 41a569fab89c8fd906d6951fe635e14e9dae6c97..f5f7b51d8bbb89078d83fa82aa356c305856da70 100644 (file)
@@ -82,6 +82,11 @@ struct ccanlint {
        /* Can we do something about it? (NULL if not) */
        void (*handle)(struct manifest *m, struct score *score);
 
+       /* Options from _info. */
+       char *options;
+       /* If not set, we'll give an error if they try to set options. */
+       bool takes_options;
+
        /* Internal use fields: */
        /* Who depends on us? */
        struct list_head dependencies;
index 7ab67dbcd83f7550bf4b84a141c480fcc0c9a60a..310e89710829893aa15044870691ff4256408d19 100644 (file)
@@ -42,11 +42,12 @@ static void do_run_tests_vg(struct manifest *m,
                list_for_each(list, i, list) {
                        score->total++;
                        if (run_command(score, timeleft, &cmdout,
-                                       "valgrind -q --error-exitcode=100 %s",
+                                       "valgrind -q --error-exitcode=100%s %s",
+                                       run_tests_vg.options ?
+                                       run_tests_vg.options : "",
                                        i->compiled)) {
                                score->score++;
                        } else {
-                               score->error = "Running under valgrind";
                                score_file_error(score, i, 0, cmdout);
                        }
                }
@@ -79,7 +80,8 @@ struct ccanlint run_tests_vg = {
        .name = "Module's run and api tests succeed under valgrind",
        .can_run = can_run_vg,
        .check = do_run_tests_vg,
-       .handle = run_under_debugger_vg
+       .handle = run_under_debugger_vg,
+       .takes_options = true
 };
 
 REGISTER_TEST(run_tests_vg, &run_tests, NULL);