lib misc+ww tests: hand-main plumbing -> assert (@test conversion B7)

toktest documents the per-row signalled pinpoint loss.
This commit is contained in:
2026-06-10 18:52:53 +09:00
parent eb891f4007
commit 3e2bf0612e
8 changed files with 797 additions and 858 deletions

View File

@@ -18,19 +18,6 @@ package temp_test;
import os;
import temp;
// Direct exit(2) binding rather than mixing `use io;` and `use os;` —
// they share read/write/close names under the driver's flat-scope
// concat (task #7). We don't need lib/io here at all (raw fd ops
// via os.read/os.write/os.close suffice), but the binding shape
// mirrors memio/getopt for parity.
fn doexit(code: i32) void = { os.exit(code); };
// signalled — bumped by main before each test so a failing exit
// code pinpoints the offending case.
let signalled: i32 = 0;
fn fail() void = { doexit(signalled + 10); };
fn streq(a: str, b: str) bool = {
if (a.len != b.len) { return false; };
let i: i32 = 0;
@@ -58,16 +45,16 @@ fn streq(a: str, b: str) bool = {
let p: str;
match (temp.named(&fd, &p, "/tmp", temp.mode.RDWR, 384i32)) { // 0o600
case void => {};
case let e: os.oserror => fail();
case let e: os.oserror => abort();
};
if (fd < 0) { fail(); };
if (p.len < 10) { fail(); }; // at minimum "/tmp/temp.<1 hex>"
assert(!(fd < 0));
assert(!(p.len < 10)); // at minimum "/tmp/temp.<1 hex>"
// Path bytes must start with "/tmp/temp." and live in temp's
// static buffer (NUL-terminated for syscall handoff).
if (p[0] != 47u8) { fail(); }; // '/'
if (!streq(strslice(p, 0, 10), "/tmp/temp.")) { fail(); };
if (p.ptr[p.len] != 0u8) { fail(); };
assert(!(p[0] != 47u8)); // '/'
assert(!(!streq(strslice(p, 0, 10), "/tmp/temp.")));
assert(!(p.ptr[p.len] != 0u8));
// Build fill payload, write it, lseek to 0, read it back.
let wbuf: [64]u8;
@@ -75,11 +62,11 @@ fn streq(a: str, b: str) bool = {
for (k < sz[i]) { wbuf[k] = fill[i]; k += 1; };
if (sz[i] > 0) {
let wr: i64 = os.write(fd, &wbuf[0], sz[i]: u64);
if (wr != sz[i]: i64) { fail(); };
assert(!(wr != sz[i]: i64));
};
let r: i64 = os.lseek(fd, 0i64, os.whence.SET);
if (r != 0i64) { fail(); };
assert(!(r != 0i64));
let rbuf: [64]u8;
let z: i32 = 0;
@@ -87,22 +74,22 @@ fn streq(a: str, b: str) bool = {
let rd: i64 = 0i64;
if (sz[i] > 0) {
rd = os.read(fd, &rbuf[0], sz[i]: u64);
if (rd != sz[i]: i64) { fail(); };
assert(!(rd != sz[i]: i64));
};
let k2: i32 = 0;
for (k2 < sz[i]) {
if (rbuf[k2] != fill[i]) { fail(); };
assert(!(rbuf[k2] != fill[i]));
k2 += 1;
};
// File exists pre-cleanup.
if (os.access(p, 0i32) != 0) { fail(); };
assert(!(os.access(p, 0i32) != 0));
if (os.close(fd) != 0) { fail(); };
if (os.remove(p) != 0) { fail(); };
assert(!(os.close(fd) != 0));
assert(!(os.remove(p) != 0));
// Cleanup landed.
if (os.access(p, 0i32) == 0) { fail(); };
assert(!(os.access(p, 0i32) == 0));
i += 1;
};
@@ -127,7 +114,7 @@ fn strslice(p: str, lo: i32, hi: i32) str = {
let p1: str;
match (temp.named(&fd1, &p1, "/tmp", temp.mode.WRITE, 384i32)) {
case void => {};
case let e: os.oserror => fail();
case let e: os.oserror => abort();
};
// Snapshot p1's bytes BEFORE the second call clobbers the buffer,
@@ -146,22 +133,22 @@ fn strslice(p: str, lo: i32, hi: i32) str = {
let p2: str;
match (temp.named(&fd2, &p2, "/tmp", temp.mode.WRITE, 384i32)) {
case void => {};
case let e: os.oserror => fail();
case let e: os.oserror => abort();
};
// Same buffer (Hare docs: "overwritten on subsequent calls"),
// distinct path bytes (random suffix differs).
if (p1.ptr != p2.ptr) { fail(); };
if (streq(strslice(p2, 0, p2.len), psnap)) { fail(); };
assert(!(p1.ptr != p2.ptr));
assert(!(streq(strslice(p2, 0, p2.len), psnap)));
// Both fds are distinct.
if (fd1 == fd2) { fail(); };
assert(!(fd1 == fd2));
if (os.close(fd2) != 0) { fail(); };
if (os.remove(p2) != 0) { fail(); };
assert(!(os.close(fd2) != 0));
assert(!(os.remove(p2) != 0));
if (os.close(fd1) != 0) { fail(); };
if (os.remove(psnap) != 0) { fail(); };
assert(!(os.close(fd1) != 0));
assert(!(os.remove(psnap) != 0));
};
// NOTE: temp.file() has no test of its own. The function is a thin
@@ -184,12 +171,12 @@ fn strslice(p: str, lo: i32, hi: i32) str = {
let i: i32 = 0;
for (i < 2) {
let d: str = temp.dir();
if (d.len < 6) { fail(); };
if (!streq(strslice(d, 0, 5), "/tmp/")) { fail(); };
if (d.ptr[d.len] != 0u8) { fail(); };
assert(!(d.len < 6));
assert(!(!streq(strslice(d, 0, 5), "/tmp/")));
assert(!(d.ptr[d.len] != 0u8));
// Dir exists.
if (os.access(d, 0i32) != 0) { fail(); };
assert(!(os.access(d, 0i32) != 0));
// Snapshot the dir path into a local NUL-terminated buffer:
// the os.* path entrypoints now copy through lib/os.pathbuf
@@ -217,21 +204,21 @@ fn strslice(p: str, lo: i32, hi: i32) str = {
cview.ptr = &cbuf[0]; cview.len = off;
let cflags: os.flag = os.flag.WRONLY | os.flag.CREATE | os.flag.EXCL;
let fd: i32 = os.open(cview, cflags, 384i32);
if (fd < 0) { fail(); };
assert(!(fd < 0));
let payload: [3]u8;
payload[0] = 88u8; payload[1] = 89u8; payload[2] = 90u8; // "XYZ"
let wr: i64 = os.write(fd, &payload[0], 3u64);
if (wr != 3i64) { fail(); };
if (os.close(fd) != 0) { fail(); };
if (os.remove(cview) != 0) { fail(); };
assert(!(wr != 3i64));
assert(!(os.close(fd) != 0));
assert(!(os.remove(cview) != 0));
};
// Rmdir uses dview (more robust if the static buffer were
// touched between dir() and here).
if (os.rmdir(dview) != 0) { fail(); };
assert(!(os.rmdir(dview) != 0));
// Cleanup landed.
if (os.access(dview, 0i32) == 0) { fail(); };
assert(!(os.access(dview, 0i32) == 0));
i += 1;
};
@@ -252,18 +239,18 @@ fn strslice(p: str, lo: i32, hi: i32) str = {
dsnap.len = snaplen;
let d2: str = temp.dir();
if (d1.ptr != d2.ptr) { fail(); }; // same static buffer
if (streq(strslice(d2, 0, d2.len), dsnap)) { fail(); };
assert(!(d1.ptr != d2.ptr)); // same static buffer
assert(!(streq(strslice(d2, 0, d2.len), dsnap)));
// Cleanup both, using snap for d1's old contents.
if (os.rmdir(d2) != 0) { fail(); };
if (os.rmdir(dsnap) != 0) { fail(); };
assert(!(os.rmdir(d2) != 0));
assert(!(os.rmdir(dsnap) != 0));
};
export fn main() i32 = {
signalled = 1; namedroundtrip();
signalled = 2; namedoverwrite();
signalled = 3; dirlifecycle();
signalled = 4; diruniqueness();
namedroundtrip();
namedoverwrite();
dirlifecycle();
diruniqueness();
return 0;
};