==> 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}