lib misc+ww tests: hand-main plumbing -> assert (@test conversion B7)
toktest documents the per-row signalled pinpoint loss.
This commit is contained in:
@@ -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;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user