==> tests/hash.c <==1/* The identity of a small tree: the same as hashing "path\0content" in path
2 * order by hand; non-sources and .sexc folders ignored; any change moves it. */
3#include "mesh/check.h"
4#include "mesh/source_hash.h"
5#include "sha256_stream.h"
6
7#include <stdio.h>
8#include <stdlib.h>
9#include <sys/stat.h>
10#include <unistd.h>
11
12static char root[] = "/tmp/mesh-source-hash-XXXXXX";
13
14static void put(const char *rel, const char *text) {
15 char p[512];
16 snprintf(p, sizeof p, "%s/%s", root, rel);
17 FILE *f = fopen(p, "w");
18 fputs(text, f);
19 fclose(f);
20}
21
22int main(void) {
23 CHECK(mkdtemp(root) != NULL);
24 char d[512];
25 const char *mk[] = {"prog", "prog/src", "prog/.sexc", "lib", "lib/include"};
26 for (int i = 0; i < 5; i++) { snprintf(d, sizeof d, "%s/%s", root, mk[i]); mkdir(d, 0755); }
27 put("prog/program.toml", "name = \"p\"\n");
28 put("prog/src/a.c", "int a;\n");
29 put("prog/README.md", "ignored\n");
30 put("prog/.sexc/x.c", "ignored\n");
31 put("lib/include/b.h", "int b;\n");
32 put("lib/sexc.json", "{}\n");
33 const char *dirs[] = {"prog", "lib", "missing"};
34 char h[17];
35 CHECK(mesh_source_hash(root, dirs, 3, h));
36 /* By hand: lib/include/b.h, lib/sexc.json, prog/program.toml, prog/src/a.c. */
37 sha256_stream s;
38 sha256_stream_init(&s);
39 const char *files[4][2] = {{"lib/include/b.h", "int b;\n"}, {"lib/sexc.json", "{}\n"}, {"prog/program.toml", "name = \"p\"\n"}, {"prog/src/a.c", "int a;\n"}};
40 for (int i = 0; i < 4; i++) {
41 sha256_stream_update(&s, files[i][0], strlen(files[i][0]) + 1);
42 sha256_stream_update(&s, files[i][1], strlen(files[i][1]));
43 }
44 uint8_t dg[32];
45 char hex[65];
46 sha256_stream_final(&s, dg);
47 sha256_stream_hex(dg, hex);
48 hex[16] = 0;
49 CHECK_S(h, hex);
50 put("prog/src/a.c", "int a = 1;\n");
51 char h2[17];
52 CHECK(mesh_source_hash(root, dirs, 3, h2));
53 CHECK(strcmp(h, h2) != 0);
54 snprintf(d, sizeof d, "rm -rf %s", root);
55 CHECK(system(d) == 0);
56 return mesh_check_done();
57}