]> git.ozlabs.org Git - ccan/blobdiff - ccan/rune/test/run.c
rune: new module to implement runes.
[ccan] / ccan / rune / test / run.c
diff --git a/ccan/rune/test/run.c b/ccan/rune/test/run.c
new file mode 100644 (file)
index 0000000..6cf33a3
--- /dev/null
@@ -0,0 +1,127 @@
+#include <ccan/rune/rune.c>
+#include <ccan/rune/coding.c>
+#include <ccan/tal/grab_file/grab_file.h>
+#include <ccan/tal/str/str.h>
+#include <ccan/tap/tap.h>
+
+static const char *check(const tal_t *ctx,
+                        const struct rune *rune,
+                        const struct rune_altern *alt,
+                        char **parts)
+{
+       const char *val = NULL;
+
+       for (size_t i = 1; parts[i]; i++) {
+               if (strstarts(parts[i], alt->fieldname)
+                   && parts[i][strlen(alt->fieldname)] == '=')
+                       val = parts[i] + strlen(alt->fieldname) + 1;
+       }
+
+       /* If it's an integer, hand it like that */
+       if (val) {
+               char *endp;
+               s64 v = strtol(val, &endp, 10);
+               if (*endp == '\0' && endp != val)
+                       return rune_alt_single(ctx, alt, NULL, &v);
+       }
+
+       return rune_alt_single(ctx, alt, val, NULL);
+}
+
+int main(void)
+{
+       char *vecs;
+       char **lines;
+       static const u8 secret_zero[16];
+       struct rune *mr;
+
+       /* Test vector rune uses all-zero secret */
+       mr = rune_new(NULL, secret_zero, sizeof(secret_zero), NULL); 
+
+       /* Python runes library generates test vectors */
+       vecs = grab_file(mr, "test/test_vectors.csv");
+       assert(vecs);
+       lines = tal_strsplit(mr, take(vecs), "\n", STR_NO_EMPTY);
+
+       plan_tests(343);
+
+       for (size_t i = 0; lines[i]; i++) {
+               struct rune *rune1, *rune2;
+               char **parts;
+
+               parts = tal_strsplit(lines, lines[i], ",", STR_EMPTY_OK);
+               if (streq(parts[0], "VALID")) {
+                       diag("test %s %s", parts[0], parts[1]);
+                       rune1 = rune_from_string(parts, parts[2]);
+                       ok1(rune1);
+                       rune2 = rune_from_base64(parts, parts[3]);
+                       ok1(rune2);
+                       ok1(rune_eq(rune1, rune2));
+                       ok1(streq(rune_to_string(parts, rune2), parts[2]));
+                       ok1(streq(rune_to_base64(parts, rune1), parts[3]));
+                       ok1(rune_is_derived_anyversion(mr, rune1) == NULL);
+                       ok1(rune_is_derived_anyversion(mr, rune2) == NULL);
+
+                       if (parts[4]) {
+                               if (parts[5])
+                                       ok1(streq(rune1->version, parts[5]));
+                               ok1(streq(rune1->unique_id, parts[4]));
+                       } else {
+                               ok1(!rune1->version);
+                               ok1(!rune1->unique_id);
+                       }
+                       mr->version = NULL;
+               } else if (streq(parts[0], "DERIVE")) {
+                       struct rune_restr *restr;
+                       diag("test %s %s", parts[0], parts[1]);
+                       rune1 = rune_from_base64(parts, parts[2]);
+                       ok1(rune1);
+                       rune2 = rune_from_base64(parts, parts[3]);
+                       ok1(rune2);
+                       ok1(rune_is_derived_anyversion(mr, rune1) == NULL);
+                       ok1(rune_is_derived_anyversion(mr, rune2) == NULL);
+                       ok1(rune_is_derived_anyversion(rune1, rune2) == NULL);
+
+                       restr = rune_restr_new(NULL);
+                       for (size_t i = 4; parts[i]; i+=3) {
+                               struct rune_altern *alt;
+                               alt = rune_altern_new(NULL,
+                                                     parts[i],
+                                                     parts[i+1][0],
+                                                     parts[i+2]);
+                               rune_restr_add_altern(restr, take(alt));
+                       }
+                       rune_add_restr(rune1, take(restr));
+                       ok1(rune_eq(rune1, rune2));
+               } else if (streq(parts[0], "MALFORMED")) {
+                       diag("test %s %s", parts[0], parts[1]);
+                       rune1 = rune_from_string(parts, parts[2]);
+                       ok1(!rune1);
+                       rune2 = rune_from_base64(parts, parts[3]);
+                       ok1(!rune2);
+               } else if (streq(parts[0], "BAD DERIVATION")) {
+                       diag("test %s %s", parts[0], parts[1]);
+                       rune1 = rune_from_string(parts, parts[2]);
+                       ok1(rune1);
+                       rune2 = rune_from_base64(parts, parts[3]);
+                       ok1(rune2);
+                       ok1(rune_eq(rune1, rune2));
+                       ok1(rune_is_derived(mr, rune1) != NULL);
+                       ok1(rune_is_derived(mr, rune2) != NULL);
+               } else {
+                       const char *err;
+                       diag("test %s", parts[0]);
+                       err = rune_test(parts, mr, rune1, check, parts);
+                       if (streq(parts[0], "PASS")) {
+                               ok1(!err);
+                       } else {
+                               assert(streq(parts[0], "FAIL"));
+                               ok1(err);
+                       }
+               }
+       }
+
+       tal_free(mr);
+       /* This exits depending on whether all tests passed */
+       return exit_status();
+}