skip to content
==> tests/golden.c <==
1/* 5696 manifests against the Rust: every program.toml of alpha-rust-mesh, the
2 * Rust's own test cases, and systematic mutations of every key (one case per
3 * distinct verdict).  For each, tests/data/manifests.rust holds what the Rust
4 * printed: "ERR <message>" or "OK <fnv of {:?}> <fnv of the entry> <fnv of the
5 * extension> <threads> <smem> <native>" plus the place parts. */
6#include "mesh/check.h"
7#include "mesh/manifest_encode.h"
8
9#include "mesh/abi/fnv.h"
10
11#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
14
15static char *slurp(const char *path, size_t *n) {
16    FILE *f = fopen(path, "rb");
17    if (!f) {
18        perror(path);
19        exit(1);
20    }
21    mesh_text t = {0};
22    char buf[65536];
23    size_t k;
24    while ((k = fread(buf, 1, sizeof buf, f)) > 0) mesh_text_putn(&t, buf, k);
25    fclose(f);
26    *n = t.len;
27    return mesh_text_take(&t);
28}
29
30static void regions(mesh_text *t, const mesh_manifest_region *r, size_t n) {
31    mesh_text_putc(t, '[');
32    for (size_t i = 0; i < n; i++) mesh_text_printf(t, "%s(%u, %u)", i ? ", " : "", (unsigned)r[i].off, (unsigned)r[i].len);
33    mesh_text_putc(t, ']');
34}
35
36static char *verdict(const char *in, size_t n) {
37    mesh_manifest m;
38    char *err = NULL;
39    mesh_text t = {0};
40    if (!mesh_manifest_parse(in, n, &m, &err)) {
41        mesh_text_printf(&t, "ERR %s", err);
42        free(err);
43        return mesh_text_take(&t);
44    }
45    mesh_text d = {0};
46    mesh_manifest_debug(&d, &m);
47    mesh_image im = {0x100000, 5, UINT64_C(0x1122334455667788), 40, 9000, 6, 1};
48    uint8_t e[MESH_PT_BYTES], x[MESH_PX_BYTES];
49    mesh_manifest_encode_entry(&m, &im, e);
50    mesh_manifest_encode_ext(&m, x);
51    mesh_text_printf(&t, "OK %016llx %016llx %016llx %u %u %s",
52                     (unsigned long long)mesh_fnv1a64((const uint8_t *)mesh_text_str(&d), d.len),
53                     (unsigned long long)mesh_fnv1a64(e, sizeof e), (unsigned long long)mesh_fnv1a64(x, sizeof x),
54                     (unsigned)mesh_manifest_threads(&m), (unsigned)mesh_manifest_smem(&m), mesh_manifest_native(&m) ? "true" : "false");
55    if (m.place) {
56        const mesh_manifest_place *p = m.place;
57        mesh_text_printf(&t, " place %zu %u %zu", mesh_manifest_place_state_bytes(p), (unsigned)mesh_manifest_place_out_bytes(p),
58                         mesh_manifest_place_part_bytes(p));
59        mesh_manifest_region *r = mesh_alloc(p->nout * sizeof *r);
60        for (uint32_t b = 0; b < p->fanout; b++) {
61            mesh_text_putc(&t, ' ');
62            mesh_manifest_place_part(p, b, r);
63            regions(&t, r, p->nout);
64            mesh_manifest_place_part_in_buffer(p, b, r);
65            regions(&t, r, p->nout);
66        }
67        free(r);
68    }
69    /* A copy is the same manifest. */
70    mesh_manifest c;
71    mesh_manifest_copy(&c, &m);
72    mesh_text d2 = {0};
73    mesh_manifest_debug(&d2, &c);
74    CHECK_S(mesh_text_str(&d2), mesh_text_str(&d));
75    mesh_text_free(&d2);
76    mesh_manifest_free(&c);
77    if (getenv("MESH_GOLDEN_DEBUG")) fprintf(stderr, "%s\n", mesh_text_str(&d));
78    mesh_text_free(&d);
79    mesh_manifest_free(&m);
80    return mesh_text_take(&t);
81}
82
83int main(void) {
84    size_t ni, ne;
85    char *ins = slurp("tests/data/manifests.in", &ni);
86    char *exp = slurp("tests/data/manifests.rust", &ne);
87    size_t cases = 0, bad = 0;
88    const char *ip = ins, *ep = exp;
89    for (;;) {
90        const char *isep = memchr(ip, '\x1e', (size_t)(ins + ni - ip));
91        size_t ilen = isep ? (size_t)(isep - ip) : (size_t)(ins + ni - ip);
92        const char *nl = memchr(ep, '\n', (size_t)(exp + ne - ep));
93        if (!nl) break;
94        char *want = mesh_strndup(ep, (size_t)(nl - ep));
95        char *got = verdict(ip, ilen);
96        cases++;
97        if (!CHECK(strcmp(got, want) == 0) && ++bad <= 25) {
98            mesh_text qt = {0};
99            mesh_text_debug_str(&qt, ip, ilen);
100            char *q = mesh_text_take(&qt);
101            fprintf(stderr, "case %zu: %s\n  rust: %s\n  c:    %s\n", cases - 1, q, want, got);
102            free(q);
103        }
104        free(want);
105        free(got);
106        ep = nl + 1;
107        if (!isep) break;
108        ip = isep + 1;
109    }
110    CHECK_U(cases, 5696);
111    printf("%zu manifests, %zu differ\n", cases, bad);
112    free(ins);
113    free(exp);
114    return mesh_check_done();
115}