nx_probe_test.nx source
↩ module page · 99 lines · 4243 B
1// nx_probe_test.nx -- smoke for nx_probe SA-1 MVP.
2//
3// Exercises:
4// - canary tamper-detect (pre + post)
5// - endianness witness on qemu-riscv64 (little-endian)
6// - pointer-width witness (64 on RV64)
7// - page-size witness (>= 4096 on Linux RV64)
8// - mono-clock witness (works + non-zero resolution)
9// - mmap + write smoke
10// - ISA-family compiled-target witness (RV64 under default --target asm)
11// - FALSIFICATION GATE: synthetic wrong claim must produce
12// falsification_count >= 1 with correct first_falsified_field tag
13//
14// SA-1 verification gate per NISHI_SELF_ASSEMBLY_ROADMAP.md ยง8.
15
16import "nx_syscalls.nx"
17import "nx_probe.nx"
18
19func main() -> i64 {
20 // ----- 1. Allocate + check initial canaries -----
21 let r: *NxProbeRecord = nx_probe_new()
22 if (r as i64) == 0 { return 1 }
23 if r.canary_pre != NX_PROBE_CANARY_PRE { return 2 }
24 if r.canary_post != NX_PROBE_CANARY_POST { return 3 }
25 if r.schema_version != NX_PROBE_SCHEMA_VERSION { return 4 }
26
27 // ----- 2. Run probe with NO claims (UNKNOWN claims = no falsification) -----
28 let rc: i64 = nx_probe_run(r)
29 if rc != 0 { return 5 } // canary-tamper post-run = fatal
30
31 // ----- 3. Witness expectations on qemu-riscv64 -----
32 // ISA family: RV64 (default --target asm).
33 if r.actual_isa_family != NX_ISA_RV64 { return 6 }
34
35 // Endianness: little (RV64 + x86_64 are little).
36 if r.actual_endianness != NX_ENDIAN_LITTLE { return 7 }
37
38 // Pointer width: 64 bits on RV64.
39 if r.actual_pointer_width_bits != 64 { return 8 }
40
41 // Page size: Linux default 4096; some kernels run with 16384 or 65536.
42 // Smoke gate accepts any of the canonical Linux page sizes.
43 if r.actual_page_size_bytes < 4096 { return 9 }
44
45 // mmap + write must work on a healthy substrate run.
46 if r.actual_mmap_works != 1 { return 10 }
47 if r.actual_write_works != 1 { return 11 }
48
49 // Mono clock: present + non-zero delta witnessed.
50 if r.actual_mono_clock_works != 1 { return 12 }
51 if r.actual_mono_clock_resolution_ns <= 0 { return 13 }
52
53 // No claims set -> no falsifications.
54 if r.falsification_count != 0 { return 14 }
55 if r.first_falsified_field != NX_PROBE_FIELD_NONE { return 15 }
56
57 // ----- 4. FALSIFICATION GATE -----
58 // Allocate a second probe record; assert a deliberately-wrong
59 // pointer-width claim (32 bits when the actual hardware is 64).
60 // The probe MUST detect this and increment falsification_count.
61 let r2: *NxProbeRecord = nx_probe_new()
62 r2.claim_pointer_width_bits = 32 // WRONG on RV64
63 let rc2: i64 = nx_probe_run(r2)
64 if rc2 != 0 { return 16 }
65 if r2.falsification_count < 1 { return 17 }
66 if r2.first_falsified_field != NX_PROBE_FIELD_POINTER_WIDTH { return 18 }
67 if r2.actual_pointer_width_bits != 64 { return 19 } // truth survives the claim
68
69 // ----- 5. Compound falsification -----
70 // Set both a wrong endianness AND a wrong ISA family claim.
71 // Count must be >= 2; first_falsified_field stamps the
72 // first-encountered (ISA_FAMILY is checked before ENDIANNESS).
73 let r3: *NxProbeRecord = nx_probe_new()
74 r3.claim_isa_family = NX_ISA_X86_64 // WRONG on RV64 target
75 r3.claim_endianness = NX_ENDIAN_BIG // WRONG on RV64 little
76 let rc3: i64 = nx_probe_run(r3)
77 if rc3 != 0 { return 20 }
78 if r3.falsification_count < 2 { return 21 }
79 if r3.first_falsified_field != NX_PROBE_FIELD_ISA_FAMILY { return 22 }
80
81 // ----- 6. Honest claim must NOT falsify -----
82 // Set claims that MATCH the truth; falsification_count must stay 0.
83 let r4: *NxProbeRecord = nx_probe_new()
84 r4.claim_isa_family = NX_ISA_RV64
85 r4.claim_endianness = NX_ENDIAN_LITTLE
86 r4.claim_pointer_width_bits = 64
87 let rc4: i64 = nx_probe_run(r4)
88 if rc4 != 0 { return 23 }
89 if r4.falsification_count != 0 { return 24 }
90 if r4.first_falsified_field != NX_PROBE_FIELD_NONE { return 25 }
91
92 // ----- 7. Sealed-enum validity gate -----
93 if nx_isa_family_is_valid(r.actual_isa_family) != 1 { return 26 }
94 if nx_isa_family_is_valid(-1) != 0 { return 27 }
95 if nx_isa_family_is_valid(NX_ISA_N) != 0 { return 28 }
96 if nx_isa_family_is_valid(NX_ISA_N + 1) != 0 { return 29 }
97
98 return 0
99}