==> tests/cache.c <==1/* The cache's names, its atomic store and load, and eviction oldest first (the Rust's
2 * engine_config_and_cache_eviction, the cache half). */
3#define _XOPEN_SOURCE 700
4#include "mesh/check.h"
5#include "mesh/exec_wasm_cache.h"
6
7#include <stdio.h>
8#include <stdlib.h>
9#include <string.h>
10#include <sys/stat.h>
11#include <time.h>
12#include <unistd.h>
13
14int main(void) {
15 char dir[] = "/tmp/meshd-wasm-cache-XXXXXX";
16 CHECK(mkdtemp(dir) != NULL);
17 char nested[256];
18 snprintf(nested, sizeof nested, "%s/a/b", dir);
19 char *err = NULL;
20 CHECK(mesh_wasm_cache_dir(nested, &err));
21 const uint8_t wasm[] = {0, 'a', 's', 'm', 1, 0, 0, 0};
22 char *p = mesh_wasm_cache_path(nested, wasm, sizeof wasm, 0x1234);
23 CHECK(strstr(p, "-0000000000001234.cwasm") != NULL);
24 CHECK_U(strlen(strrchr(p, '/') + 1), 16 + 1 + 16 + 6);
25 uint8_t blob[1000];
26 memset(blob, 7, sizeof blob);
27 CHECK(mesh_wasm_cache_store(p, blob, sizeof blob, &err));
28 uint8_t *back;
29 size_t n;
30 CHECK(mesh_wasm_cache_load(p, &back, &n));
31 CHECK_U(n, sizeof blob);
32 CHECK(memcmp(back, blob, n) == 0);
33 free(back);
34 /* A newer file; over the cap by one byte: the oldest (the module) goes, the newest stays. */
35 struct timespec ms20 = {0, 20000000};
36 nanosleep(&ms20, NULL);
37 char newer[512];
38 snprintf(newer, sizeof newer, "%s/new.cwasm", nested);
39 uint8_t big[4096] = {0};
40 CHECK(mesh_wasm_cache_store(newer, big, sizeof big, &err));
41 CHECK_U(mesh_wasm_cache_evict(nested, sizeof blob + sizeof big - 1, NULL), 1);
42 struct stat st;
43 CHECK(stat(p, &st) != 0);
44 CHECK(stat(newer, &st) == 0);
45 /* Under the cap: nothing goes. */
46 CHECK_U(mesh_wasm_cache_evict(nested, 1u << 20, NULL), 0);
47 /* A file where the directory should be. */
48 char file[512];
49 snprintf(file, sizeof file, "%s/file", dir);
50 FILE *f = fopen(file, "w");
51 fclose(f);
52 CHECK(!mesh_wasm_cache_dir(file, &err));
53 CHECK(err && strncmp(err, "--wasm-cache ", 13) == 0);
54 free(err);
55 remove(newer);
56 remove(file);
57 char sub[512];
58 snprintf(sub, sizeof sub, "%s/a", dir);
59 rmdir(nested);
60 rmdir(sub);
61 rmdir(dir);
62 free(p);
63 return mesh_check_done();
64}