e7738de6d2
CI / Deep Native Runtime Cases (1/6) (push) Has been skipped
CI / Native Preflight (push) Failing after 1s
CI / Native Runtime Cases (1/2) (push) Failing after 0s
CI / Native Runtime Cases (2/2) (push) Failing after 1s
CI / Native Metadata Reports (push) Failing after 0s
CI / Native Direct Backend Artifacts (push) Failing after 0s
CI / Native Sanitizer Smoke (push) Failing after 1s
CI / Command Contract Snapshots (push) Failing after 1s
CI / Deep Conformance Suite (push) Has been skipped
CI / Graph Build Perf (push) Failing after 1s
CI / Deep Native Preflight (push) Has been skipped
CI / Deep Native Runtime Cases (2/6) (push) Has been skipped
CI / Deep Native Runtime Cases (3/6) (push) Has been skipped
CI / Conformance Suite (push) Failing after 1s
CI / Workspace Checks (push) Failing after 0s
CI / Deep Native Runtime Cases (5/6) (push) Has been skipped
CI / Deep Native Runtime Cases (6/6) (push) Has been skipped
CI / Deep Native Runtime Cases (4/6) (push) Has been skipped
CI / Deep Graph Build Perf (push) Has been skipped
149 lines
5.1 KiB
TypeScript
Executable File
149 lines
5.1 KiB
TypeScript
Executable File
#!/usr/bin/env -S node --experimental-strip-types --disable-warning=ExperimentalWarning
|
|
import assert from "node:assert/strict";
|
|
import { execFile } from "node:child_process";
|
|
import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
|
|
import { join } from "node:path";
|
|
import { promisify } from "node:util";
|
|
|
|
const execFileAsync = promisify(execFile);
|
|
|
|
const root = process.cwd();
|
|
const tempDir = await mkdtemp("/tmp/zero-fs-runtime-");
|
|
const src = join(tempDir, "fs-runtime-smoke.c");
|
|
const exe = join(tempDir, "fs-runtime-smoke");
|
|
const input = join(tempDir, "input.txt");
|
|
const large = join(tempDir, "large.bin");
|
|
const nestedDir = join(tempDir, "nested");
|
|
const missing = join(tempDir, "missing.txt");
|
|
|
|
const harness = String.raw`
|
|
#include "zero_runtime.h"
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
static ZeroByteView bytes(const char *text) {
|
|
return (ZeroByteView){(const unsigned char *)text, strlen(text)};
|
|
}
|
|
|
|
static ZeroMutByteView mut_bytes(unsigned char *ptr, size_t len) {
|
|
return (ZeroMutByteView){ptr, len};
|
|
}
|
|
|
|
static int fail(const char *name) {
|
|
fprintf(stderr, "fs runtime smoke failed: %s\n", name);
|
|
return 1;
|
|
}
|
|
|
|
static int expect_true(int ok, const char *name) {
|
|
return ok ? 0 : fail(name);
|
|
}
|
|
|
|
static int expect_none(ZeroMaybeUsize result, const char *name) {
|
|
return expect_true(result.has == 0 && result.value == 0, name);
|
|
}
|
|
|
|
static int expect_small_read(const char *path) {
|
|
unsigned char buffer[64];
|
|
memset(buffer, 0, sizeof(buffer));
|
|
ZeroMaybeUsize result = zero_fs_read_bytes(bytes(path), mut_bytes(buffer, sizeof(buffer)));
|
|
return expect_true(
|
|
result.has == 1 &&
|
|
result.value == 14 &&
|
|
memcmp(buffer, "hello runtime\n", 14) == 0 &&
|
|
buffer[14] == 0,
|
|
"read regular file"
|
|
);
|
|
}
|
|
|
|
static int expect_partial_read(const char *path) {
|
|
unsigned char buffer[5];
|
|
memset(buffer, 0, sizeof(buffer));
|
|
ZeroMaybeUsize result = zero_fs_read_bytes(bytes(path), mut_bytes(buffer, sizeof(buffer)));
|
|
return expect_true(
|
|
result.has == 1 &&
|
|
result.value == 14 &&
|
|
memcmp(buffer, "hello", sizeof(buffer)) == 0,
|
|
"read partial buffer reports total size"
|
|
);
|
|
}
|
|
|
|
static int expect_zero_len_read(const char *path) {
|
|
unsigned char buffer[1] = {0xaa};
|
|
ZeroMaybeUsize result = zero_fs_read_bytes(bytes(path), mut_bytes(buffer, 0));
|
|
return expect_true(result.has == 1 && result.value == 14 && buffer[0] == 0xaa, "read zero-length buffer reports total size");
|
|
}
|
|
|
|
static int expect_large_read(const char *path) {
|
|
const size_t len = 1048576u + 17u;
|
|
unsigned char *buffer = (unsigned char *)malloc(len);
|
|
if (!buffer) return fail("allocate large read buffer");
|
|
memset(buffer, 0, len);
|
|
ZeroMaybeUsize result = zero_fs_read_bytes(bytes(path), mut_bytes(buffer, len));
|
|
int ok = result.has == 1 && result.value == len;
|
|
for (size_t i = 0; ok && i < len; i++) {
|
|
ok = buffer[i] == 'z';
|
|
}
|
|
free(buffer);
|
|
return expect_true(ok, "read large file");
|
|
}
|
|
|
|
static int expect_rejected_inputs(const char *directory, const char *missing) {
|
|
unsigned char buffer[16];
|
|
memset(buffer, 0, sizeof(buffer));
|
|
|
|
int status = 0;
|
|
status |= expect_none(zero_fs_read_bytes(bytes(directory), mut_bytes(buffer, sizeof(buffer))), "reject directory");
|
|
status |= expect_none(zero_fs_read_bytes(bytes(missing), mut_bytes(buffer, sizeof(buffer))), "reject missing file");
|
|
status |= expect_none(zero_fs_read_bytes((ZeroByteView){NULL, 1}, mut_bytes(buffer, sizeof(buffer))), "reject null path");
|
|
status |= expect_none(zero_fs_read_bytes((ZeroByteView){(const unsigned char *)"", 0}, mut_bytes(buffer, sizeof(buffer))), "reject empty path");
|
|
status |= expect_none(zero_fs_read_bytes(bytes(missing), (ZeroMutByteView){NULL, sizeof(buffer)}), "reject null buffer");
|
|
status |= expect_none(zero_fs_read_bytes(bytes(missing), (ZeroMutByteView){NULL, 0}), "reject null zero-length buffer");
|
|
|
|
char long_path[4097];
|
|
memset(long_path, 'a', 4096);
|
|
long_path[4096] = '\0';
|
|
status |= expect_none(
|
|
zero_fs_read_bytes((ZeroByteView){(const unsigned char *)long_path, 4096}, mut_bytes(buffer, sizeof(buffer))),
|
|
"reject path at runtime limit"
|
|
);
|
|
return status;
|
|
}
|
|
|
|
int main(int argc, char **argv) {
|
|
if (argc != 5) return fail("expected input, large, directory, and missing paths");
|
|
int status = 0;
|
|
status |= expect_small_read(argv[1]);
|
|
status |= expect_partial_read(argv[1]);
|
|
status |= expect_zero_len_read(argv[1]);
|
|
status |= expect_large_read(argv[2]);
|
|
status |= expect_rejected_inputs(argv[3], argv[4]);
|
|
return status;
|
|
}
|
|
`;
|
|
|
|
try {
|
|
await mkdir(nestedDir);
|
|
await writeFile(input, "hello runtime\n");
|
|
await writeFile(large, Buffer.alloc(1048576 + 17, "z"));
|
|
await writeFile(src, harness);
|
|
await execFileAsync("cc", [
|
|
"-std=c11",
|
|
"-Wall",
|
|
"-Wextra",
|
|
"-Wpedantic",
|
|
"-Inative/zero-c/include",
|
|
"native/zero-c/runtime/zero_runtime.c",
|
|
src,
|
|
"-o",
|
|
exe,
|
|
], { cwd: root });
|
|
const { stdout, stderr } = await execFileAsync(exe, [input, large, nestedDir, missing], { timeout: 5000 });
|
|
assert.equal(stderr, "");
|
|
assert.equal(stdout, "");
|
|
console.log("fs runtime smoke ok");
|
|
} finally {
|
|
await rm(tempDir, { recursive: true, force: true });
|
|
}
|