code wiki / (root) / nx_queries_merge_gate.nx

nx_queries_merge_gate.nx source

↩ module page · 76 lines · 4658 B

1// nx_queries_merge_gate.nx -- the referee for nx_queries_merge_lib: a three-file union is row-aligned and space-joined, 2// CRLF inputs merge without their CR, a mismatched id is REFUSED naming the row and input, a row-count mismatch is 3// REFUSED naming the input, and a killed run leaves no half file (the write is tmp + rename). Fixtures live in 4// /tmp/nx_queries_merge_gate/ (fixture-ratchet law), truncate-written at setup so the gate is idempotent. 5// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0 6import "nx_queries_merge_lib.nx" 7import "nx_gate_verdict.nx" 8 9const QG_DIR: *u8 = "/tmp/nx_queries_merge_gate" as *u8 10const QG_A: *u8 = "/tmp/nx_queries_merge_gate/a.tsv" as *u8 11const QG_B: *u8 = "/tmp/nx_queries_merge_gate/b.tsv" as *u8 12const QG_C: *u8 = "/tmp/nx_queries_merge_gate/c.tsv" as *u8 13const QG_D: *u8 = "/tmp/nx_queries_merge_gate/d.tsv" as *u8 14const QG_E: *u8 = "/tmp/nx_queries_merge_gate/e.tsv" as *u8 15const QG_OUT: *u8 = "/tmp/nx_queries_merge_gate/out.tsv" as *u8 16const QG_OUT2: *u8 = "/tmp/nx_queries_merge_gate/out2.tsv" as *u8 17const QG_MODE_DIR: i64 = 493 18const QG_IN3: i64 = 3 19const QG_IN2: i64 = 2 20 21func qg_write(p: *u8, s: *u8) -> i64 { let fd: i64 = sys_openat_wr(p, QM_FILE_MODE); if fd < 0 { return 0 - 1 } qm_write_all(fd, s, qm_slen(s)); sys_close(fd); return 0 } 22func qg_exists(p: *u8) -> i64 { let fd: i64 = sys_openat_rd(p); if fd < 0 { return 0 } sys_close(fd); return 1 } 23func qg_read_eq(p: *u8, want: *u8) -> i64 { 24 let ln: *i64 = sys_mmap(16) as *i64 25 let b: *u8 = sys_read_file(p, ln) 26 if (b as i64) == 0 { return 0 } 27 if ln[0] != qm_slen(want) { return 0 } 28 var i: i64 = 0 29 while i < ln[0] { if b[i] != want[i] { return 0 } i = i + 1 } 30 return 1 31} 32 33func main(argc: i64, argv: *i64) -> i64 { 34 let ctr: *i64 = gv_ctr() 35 gv_head("nx_queries_merge_gate -- row-aligned union of query files, refusals named" as *u8) 36 sys_mkdir(QG_DIR, QG_MODE_DIR) 37 qg_write(QG_A, "q1\tA one\nq2\tA two\n" as *u8) 38 // b carries CRLF line ends: the merge must drop the CR 39 let bcr: *u8 = sys_mmap(64) 40 var bo: i64 = qm_cat(bcr, 0, "q1\tB one" as *u8); bcr[bo] = QM_CR as u8; bo = bo + 1; bcr[bo] = QM_NL as u8; bo = bo + 1 41 bo = qm_cat(bcr, bo, "q2\tB two" as *u8); bcr[bo] = QM_CR as u8; bo = bo + 1; bcr[bo] = QM_NL as u8; bo = bo + 1 42 bcr[bo] = 0 as u8 43 qg_write(QG_B, bcr) 44 qg_write(QG_C, "q1\tC one\nq2\tC two" as *u8) // no trailing newline: still two rows 45 qg_write(QG_D, "q1\tD one\nq3\tD three\n" as *u8) 46 qg_write(QG_E, "q1\tE one\n" as *u8) 47 sys_unlinkat(QG_OUT); sys_unlinkat(QG_OUT2) 48 let st: *i64 = sys_mmap(QM_ST_SLOTS * QM_I64) as *i64 49 let ins: *i64 = sys_mmap(QG_IN3 * QM_I64) as *i64 50 ins[0] = QG_A as i64; ins[1] = QG_B as i64; ins[2] = QG_C as i64 51 let rc: i64 = qm_merge(QG_OUT, ins, QG_IN3, st) 52 gv_check_eq("T1 three aligned files merge (exit 0)" as *u8, rc, QM_EXIT_OK, ctr) 53 gv_check_eq("T1a two rows" as *u8, st[0], 2, ctr) 54 gv_check("T1b the union is id TAB text1 SPACE text2 SPACE text3 per row, CR dropped, trailing newline added" as *u8, qg_read_eq(QG_OUT, "q1\tA one B one C one\nq2\tA two B two C two\n" as *u8), ctr) 55 gv_check("T1c no tmp file left behind" as *u8, (qg_exists("/tmp/nx_queries_merge_gate/out.tsv.tmp" as *u8) == 0) as i64, ctr) 56 let mb: i64 = st[1] // banked before the refusal teeth reuse st 57 // ---- refusals ---- 58 let ins2: *i64 = sys_mmap(QG_IN2 * QM_I64) as *i64 59 ins2[0] = QG_A as i64; ins2[1] = QG_D as i64 60 let rc2: i64 = qm_merge(QG_OUT2, ins2, QG_IN2, st) 61 gv_check_eq("T2 neg-control a mismatched id is REFUSED" as *u8, rc2, QM_EXIT_REFUSED, ctr) 62 gv_check_eq("T2a ... naming the row (2)" as *u8, st[2], 2, ctr) 63 gv_check_eq("T2b ... and the input (1)" as *u8, st[3], 1, ctr) 64 gv_check("T2c a refused merge writes NO output" as *u8, (qg_exists(QG_OUT2) == 0) as i64, ctr) 65 ins2[1] = QG_E as i64 66 let rc3: i64 = qm_merge(QG_OUT2, ins2, QG_IN2, st) 67 gv_check_eq("T3 neg-control a row-count mismatch is REFUSED" as *u8, rc3, QM_EXIT_REFUSED, ctr) 68 gv_check_eq("T3a ... naming the input (1) with its rows (1)" as *u8, st[3] * 10 + st[4], 11, ctr) 69 gv_check_eq("T3b ... and the reference row count (2)" as *u8, st[0], 2, ctr) 70 ins2[1] = "/tmp/nx_queries_merge_gate/absent.tsv" as i64 71 gv_check_eq("T4 neg-control a missing input is IO, not a merge" as *u8, qm_merge(QG_OUT2, ins2, QG_IN2, st), QM_EXIT_IO, ctr) 72 gv_kv("merged_bytes" as *u8, mb) 73 let rcv: i64 = gv_verdict("QUERIES-MERGE-GATE" as *u8, ctr, "the union is row-aligned and every misalignment is refused by name" as *u8) 74 sys_exit(rcv) 75 return rcv 76}