use std::fs;
use std::path::PathBuf;
use std::process::{Command, Output};
use std::sync::atomic::{AtomicU64, Ordering};
static NEXT_FIXTURE: AtomicU64 = AtomicU64::new(0);
struct Fixture {
root: PathBuf,
}
impl Fixture {
fn new(label: &str) -> Self {
let ordinal = NEXT_FIXTURE.fetch_add(1, Ordering::Relaxed);
let root = std::env::temp_dir().join(format!(
"noxid-wo24-qa5-{label}-{}-{ordinal}",
std::process::id()
));
fs::create_dir_all(root.join("server/queues")).expect("create queue fixture");
fs::write(
root.join("Noxid.toml"),
"[app]\ntitle = \"WO-24 QA round 5\"\n",
)
.expect("write project manifest");
fs::write(root.join("package.json"), "{\"type\":\"module\"}\n").expect("write ESM marker");
fs::write(
root.join("server/host.js"),
"export const queues = Object.freeze({});\n",
)
.expect("write inert host");
Self { root }
}
fn write(&self, relative: &str, contents: &str) {
let path = self.root.join(relative);
if let Some(parent) = path.parent() {
fs::create_dir_all(parent).expect("create fixture parent");
}
fs::write(path, contents).expect("write fixture file");
}
fn build(&self) -> Output {
Command::new(env!("CARGO_BIN_EXE_noxid"))
.args(["build", ".", "--out-dir", "dist"])
.current_dir(&self.root)
.output()
.expect("build queue fixture")
}
fn run_node(&self, name: &str, source: &str) -> Output {
self.write(&format!("dist/{name}.mjs"), source);
Command::new("node")
.arg(format!("{name}.mjs"))
.current_dir(self.root.join("dist"))
.env_remove("DATABASE_URL")
.output()
.expect("execute generated queue runtime")
}
fn run_node_with_database(&self, name: &str, source: &str) -> Output {
self.write(&format!("dist/{name}.mjs"), source);
Command::new("node")
.arg(format!("{name}.mjs"))
.current_dir(self.root.join("dist"))
.env("DATABASE_URL", "postgres://qa.invalid/noxid")
.output()
.expect("execute generated queue runtime with fake database")
}
}
impl Drop for Fixture {
fn drop(&mut self) {
let _ = fs::remove_dir_all(&self.root);
}
}
fn output_text(output: &Output) -> String {
format!(
"stdout:\n{}\nstderr:\n{}",
String::from_utf8_lossy(&output.stdout),
String::from_utf8_lossy(&output.stderr)
)
}
fn assert_success(output: &Output, context: &str) {
assert!(
output.status.success(),
"{context}:\n{}",
output_text(output)
);
}
fn write_probe_queue(fixture: &Fixture) {
fixture.write(
"server/queues/Probe.nox",
"queue Probe { payload {} retry: 0 backoff: 1s }\n",
);
}
#[test]
fn qa_round5_work_once_rejects_undeclared_options_and_non_string_identities() {
let fixture = Fixture::new("work-once-options");
write_probe_queue(&fixture);
assert_success(&fixture.build(), "build work-once option fixture");
let node = fixture.run_node(
"work-once-options",
r#"import { workQueueOnce } from "./server/handler.js";
async function code(options) {
try { await workQueueOnce(options); } catch (error) { return error?.code ?? error?.name; }
return null;
}
const cases = [
["valid declared options", { queue: "Probe", worker: "qa", now: "2028-02-29T12:00:00Z" }, "QUEUE_DATABASE_URL_REQUIRED"],
["numeric queue", { queue: 7, worker: "qa", now: "2028-02-29T12:00:00Z" }, "QUEUE_CLOCK_INVALID"],
["object worker", { queue: "Probe", worker: {}, now: "2028-02-29T12:00:00Z" }, "QUEUE_CLOCK_INVALID"],
["timer option belongs to loop", { queue: "Probe", setTimeout() {} }, "QUEUE_CLOCK_INVALID"],
["poll option belongs to loop", { queue: "Probe", pollIntervalMs: 10 }, "QUEUE_CLOCK_INVALID"],
["error hook belongs to loop", { queue: "Probe", onError() {} }, "QUEUE_CLOCK_INVALID"],
["undeclared field", { queue: "Probe", authority: true }, "QUEUE_CLOCK_INVALID"],
];
const failures = [];
for (const [label, options, expected] of cases) {
const observed = await code(options);
if (observed !== expected) failures.push(`${label}: expected ${expected}, saw ${observed}`);
}
if (failures.length > 0) throw new Error(failures.join("; "));
"#,
);
assert_success(
&node,
"enforce workQueueOnce's declared typed option surface",
);
}
#[test]
fn qa_round5_start_worker_validates_identity_and_clock_before_polling() {
let fixture = Fixture::new("start-worker-scalars");
write_probe_queue(&fixture);
assert_success(&fixture.build(), "build start-worker scalar fixture");
let node = fixture.run_node(
"start-worker-scalars",
r#"import { startQueueWorker } from "./server/handler.js";
async function code(options) {
let worker;
try { worker = startQueueWorker(options); } catch (error) { return error?.code ?? error?.name; }
try { await worker.stop(); } catch (error) { return `late:${error?.code ?? error?.name}`; }
return "accepted";
}
const quiet = () => {};
const cases = [
["numeric queue", { queue: 7, onError: quiet }, "QUEUE_CLOCK_INVALID"],
["object worker", { queue: "Probe", worker: {}, onError: quiet }, "QUEUE_CLOCK_INVALID"],
["invalid fixed clock", { queue: "Probe", now: "2026-02-31T12:00:00Z", onError: quiet }, "QUEUE_CLOCK_INVALID"],
["object inheriting from Date is not genuine", { queue: "Probe", now: Object.create(new Date("2028-02-29T12:00:00Z")), onError: quiet }, "QUEUE_CLOCK_INVALID"],
];
const failures = [];
for (const [label, options, expected] of cases) {
const observed = await code(options);
if (observed !== expected) failures.push(`${label}: expected ${expected}, saw ${observed}`);
}
if (failures.length > 0) throw new Error(failures.join("; "));
"#,
);
assert_success(
&node,
"validate startQueueWorker identity and clock before its first poll",
);
}
#[test]
fn qa_round5_start_worker_rejects_invalid_timer_hooks_and_poll_intervals() {
let fixture = Fixture::new("worker-loop-options");
write_probe_queue(&fixture);
assert_success(&fixture.build(), "build worker-loop option fixture");
let node = fixture.run_node(
"worker-loop-options",
r#"import { startQueueWorker } from "./server/handler.js";
async function code(options) {
let worker;
try { worker = startQueueWorker(options); } catch (error) { return error?.code ?? error?.name; }
try { await worker.stop(); } catch (error) { return `late:${error?.code ?? error?.name}`; }
return "accepted";
}
const quiet = () => {};
const timer = () => 1;
const clear = () => {};
const cases = [
["non-callable setTimeout", { setTimeout: 1, clearTimeout: clear, onError: quiet }, "QUEUE_CLOCK_INVALID"],
["non-callable clearTimeout", { setTimeout: timer, clearTimeout: {}, onError: quiet }, "QUEUE_CLOCK_INVALID"],
["non-callable onError", { onError: "ignore" }, "QUEUE_CLOCK_INVALID"],
["zero interval", { pollIntervalMs: 0, onError: quiet }, "QUEUE_CLOCK_INVALID"],
["negative interval", { pollIntervalMs: -1, onError: quiet }, "QUEUE_CLOCK_INVALID"],
["fractional interval", { pollIntervalMs: 1.5, onError: quiet }, "QUEUE_CLOCK_INVALID"],
["infinite interval", { pollIntervalMs: Infinity, onError: quiet }, "QUEUE_CLOCK_INVALID"],
["string interval", { pollIntervalMs: "17", onError: quiet }, "QUEUE_CLOCK_INVALID"],
];
const failures = [];
for (const [label, options, expected] of cases) {
const observed = await code(options);
if (observed !== expected) failures.push(`${label}: expected ${expected}, saw ${observed}`);
}
if (failures.length > 0) throw new Error(failures.join("; "));
"#,
);
assert_success(
&node,
"validate worker timers, callback hooks, and positive integer polling",
);
}
#[test]
fn qa_round5_on_error_can_stop_its_worker_without_deadlock_or_timer_leak() {
let fixture = Fixture::new("on-error-stop");
write_probe_queue(&fixture);
assert_success(&fixture.build(), "build onError disposal fixture");
let node = fixture.run_node(
"on-error-stop",
r#"import { startQueueWorker } from "./server/handler.js";
const timers = new Map();
let nextTimer = 0;
let errorCode = null;
let stoppedFromError = false;
let worker;
worker = startQueueWorker({
pollIntervalMs: 11,
setTimeout(callback, delay) { const id = ++nextTimer; timers.set(id, { callback, delay }); return id; },
clearTimeout(id) { timers.delete(id); },
async onError(error) {
errorCode = error?.code;
await worker.stop();
stoppedFromError = true;
},
});
for (let turn = 0; turn < 8 && !stoppedFromError; turn += 1) {
await new Promise((resolve) => setImmediate(resolve));
}
if (errorCode !== "QUEUE_DATABASE_URL_REQUIRED") throw new Error(`unexpected worker error ${errorCode}`);
if (!stoppedFromError) throw new Error("onError awaiting worker.stop() deadlocked");
if (timers.size !== 0) throw new Error(`onError stop leaked ${timers.size} timer(s)`);
await worker.stop();
"#,
);
assert_success(
&node,
"allow an error callback to dispose the worker that invoked it",
);
}
#[test]
fn qa_round5_recursive_map_result_sparse_arrays_and_dates_replay_at_enqueue() {
let fixture = Fixture::new("recursive-payload-replay");
fixture.write(
"server/queues/Probe.nox",
r#"type Envelope {
at: Date
values: Array<Optional<Int>>
next: Optional<Envelope>
}
queue Probe {
payload { entries: Map<String, Result<Envelope, Array<Date>>> }
retry: 1
backoff: 1s
}
"#,
);
assert_success(&fixture.build(), "build recursive payload replay fixture");
let node = fixture.run_node(
"recursive-payload-replay",
r#"import { enqueue } from "./server/handler.js";
async function code(entries) {
try { await enqueue("Probe", { entries }); } catch (error) { return error?.code ?? error?.name; }
return null;
}
const sparseOptional = new Array(3);
sparseOptional[1] = 7;
const validEnvelope = { at: "2000-02-29T23:59:59.999Z", values: sparseOptional, next: null };
const cyclicEnvelope = { at: "2000-02-29T23:59:59Z", values: [], next: null };
cyclicEnvelope.next = cyclicEnvelope;
const sparseDates = new Array(1);
const cases = [
["valid recursive wrappers", { safe: { tag: "Ok", value: validEnvelope }, dates: { tag: "Err", value: ["2028-02-29T12:00:00Z"] } }, "QUEUE_DATABASE_URL_REQUIRED"],
["reserved proto", JSON.parse('{"__proto__":{"tag":"Ok","value":{"at":"2000-02-29T00:00:00Z","values":[],"next":null}}}'), "QUEUE_PAYLOAD_TYPE"],
["reserved constructor", { constructor: { tag: "Ok", value: validEnvelope } }, "QUEUE_PAYLOAD_TYPE"],
["reserved prototype", { prototype: { tag: "Ok", value: validEnvelope } }, "QUEUE_PAYLOAD_TYPE"],
["invalid named Date", { bad: { tag: "Ok", value: { at: "2100-02-29T00:00:00Z", values: [], next: null } } }, "QUEUE_PAYLOAD_TYPE"],
["invalid Result Date", { bad: { tag: "Err", value: ["2028-02-29T12:00:00+00:00"] } }, "QUEUE_PAYLOAD_TYPE"],
["non-optional sparse Date", { bad: { tag: "Err", value: sparseDates } }, "QUEUE_PAYLOAD_TYPE"],
["recursive named cycle", { bad: { tag: "Ok", value: cyclicEnvelope } }, "QUEUE_PAYLOAD_TYPE"],
["genuine Date payload", { bad: { tag: "Ok", value: { at: new Date("2000-02-29T00:00:00Z"), values: [], next: null } } }, "QUEUE_PAYLOAD_TYPE"],
];
const failures = [];
for (const [label, entries, expected] of cases) {
const observed = await code(entries);
if (observed !== expected) failures.push(`${label}: expected ${expected}, saw ${observed}`);
}
if (failures.length > 0) throw new Error(failures.join("; "));
"#,
);
assert_success(
&node,
"replay recursive Map/Result, sparse-array, and Date payload boundaries",
);
}
#[test]
fn qa_round5_fake_claim_refuses_reserved_maps_and_recursive_date_drift() {
let fixture = Fixture::new("claim-payload-replay");
fixture.write(
"server/queues/Probe.nox",
r#"type Envelope { at: Date values: Array<Optional<Int>> }
queue Probe {
payload { entries: Map<String, Result<Envelope, Array<Date>>> }
retry: 0
backoff: 1s
}
"#,
);
fixture.write(
"server/host.js",
r#"export const queues = Object.freeze({
"queue:Probe": async () => { globalThis.__qaHandlerCalls += 1; return "handled"; },
});
"#,
);
assert_success(&fixture.build(), "build fake-claim payload replay fixture");
fixture.write(
"dist/node_modules/postgres/package.json",
"{\"type\":\"module\",\"exports\":\"./index.js\"}\n",
);
fixture.write(
"dist/node_modules/postgres/index.js",
r#"export default function postgres() {
const sql = async (strings) => {
const query = strings.join("?");
globalThis.__qaQueries.push(query);
if (query.includes("SELECT id, queue, payload")) return [globalThis.__qaRows.shift()];
return [];
};
sql.unsafe = async (query) => { globalThis.__qaQueries.push(query); return []; };
sql.begin = async (callback) => callback(sql);
sql.end = async () => {};
sql.json = (value) => value;
return sql;
}
"#,
);
let node = fixture.run_node_with_database(
"claim-payload-replay",
r#"globalThis.__qaQueries = [];
globalThis.__qaHandlerCalls = 0;
const envelope = { at: "2000-02-29T00:00:00Z", values: [] };
globalThis.__qaRows = [
{ id: "reserved-proto", queue: "Probe", principal: null, attempts: 0, run_at: new Date("2026-08-30T12:00:00Z"), payload: { entries: JSON.parse('{"__proto__":{"tag":"Ok","value":{"at":"2000-02-29T00:00:00Z","values":[]}}}') } },
{ id: "reserved-constructor", queue: "Probe", principal: null, attempts: 0, run_at: new Date("2026-08-30T12:00:00Z"), payload: { entries: { constructor: { tag: "Ok", value: envelope } } } },
{ id: "reserved-prototype", queue: "Probe", principal: null, attempts: 0, run_at: new Date("2026-08-30T12:00:00Z"), payload: { entries: { prototype: { tag: "Ok", value: envelope } } } },
{ id: "nested-date", queue: "Probe", principal: null, attempts: 0, run_at: new Date("2026-08-30T12:00:00Z"), payload: { entries: { unsafe: { tag: "Err", value: ["2100-02-29T00:00:00Z"] } } } },
];
const { workQueueOnce, closeQueueDatabase } = await import("./server/handler.js");
const failures = [];
for (const expectedId of ["reserved-proto", "reserved-constructor", "reserved-prototype", "nested-date"]) {
let failure;
try { await workQueueOnce({ queue: "Probe", worker: "qa", now: "2026-08-30T12:00:00Z" }); }
catch (error) { failure = error; }
if (failure?.code !== "QUEUE_PAYLOAD_DRIFT" || failure?.jobId !== expectedId) failures.push(`${expectedId}: saw ${failure?.code}/${failure?.jobId}`);
}
if (globalThis.__qaHandlerCalls !== 0) failures.push(`drift reached handler ${globalThis.__qaHandlerCalls} time(s)`);
const driftUpdates = globalThis.__qaQueries.filter((query) => query.includes("last_error = 'QUEUE_PAYLOAD_DRIFT'"));
if (driftUpdates.length !== 4) failures.push(`expected four drift updates, saw ${driftUpdates.length}`);
if (globalThis.__qaQueries.some((query) => query.includes("state = 'running'"))) failures.push("drifted claim entered running state");
await closeQueueDatabase();
if (failures.length > 0) throw new Error(failures.join("; "));
"#,
);
assert_success(
&node,
"refuse reserved Map keys and recursive Date drift on fake claims",
);
}