code wiki / (root) / nx_netscope_heal_test.nx

nx_netscope_heal_test.nx source

↩ module page · 87 lines · 4346 B

1// nx_netscope_heal_test.nx -- 1:1 KAT for the rung-3 self-healing decision 2// core (nx_netscope_heal.nx). Deterministic fault-injection (synthetic 3// probe matrices, NO live link): inject a bad/best cell, assert the agent 4// selects the correct resolver + the heal action + reason. Proves the 5// Happy-Eyeballs correctness gate (fast WRONG answer never wins), the 6// fail-over, the anti-flap hysteresis, owned-domain hairpin demotion, and 7// the safe give-up. 8// 9// expect_exit: 0 10// license_tier: ORIGINAL 11 12import "nx_netscope_heal.nx" 13 14func hset(cells: *ProbeCell, idx: i64, verdict: i64, ipv4: i64, rfc1918: i64, lat: i64) -> i64 { 15 let c: *ProbeCell = ((cells as i64) + idx * NXNS_PROBECELL_BYTES) as *ProbeCell 16 c.server_ip = 0; c.host_idx = 0; c.verdict = verdict; c.rcode = 0 17 c.ancount = 0; c.ipv4_packed = ipv4; c.latency_ms = lat; c.is_rfc1918 = rfc1918 18 return 0 19} 20 21func main() -> i64 { 22 let lan: i64 = (192 << 24) | (168 << 16) | (8 << 8) | 240 23 let pub: i64 = (75 << 24) | (28 << 16) | (18 << 8) | 94 24 let cells: *ProbeCell = sys_mmap(4 * NXNS_PROBECELL_BYTES) as *ProbeCell 25 let servers: *i64 = sys_mmap(2 * 8) as *i64 26 servers[0] = (192 << 24) | (168 << 16) | (1 << 8) | 254 // incumbent (ATT) 27 servers[1] = (192 << 24) | (168 << 16) | (8 << 8) | 1 // backup (GL) 28 let d: *HealDecision = sys_mmap(HEAL_DECISION_BYTES) as *HealDecision 29 30 // ---- T1: incumbent(0) TIMED OUT, backup(1) correct -> SWITCH (fail over) ---- 31 hset(cells, 0, NXNS_TIMEOUT, 0, 0, 800) 32 hset(cells, 1, NXNS_OK_A, lan, 1, 5) 33 heal_decide(cells, 2, 1, 0, 1, 0, HEAL_BAND_MS, d) 34 if d.action != HEAL_SWITCH { return 1 } 35 if d.target_idx != 1 { return 2 } 36 if d.reason != HEAL_R_INCUMBENT_FAILED { return 3 } 37 38 // ---- T2: CORRECTNESS over SPEED -- a fast NXDOMAIN must NOT beat a 39 // slower correct answer (the Happy-Eyeballs correctness gate) ---- 40 hset(cells, 0, NXNS_NXDOMAIN, 0, 0, 1) // fast but WRONG 41 hset(cells, 1, NXNS_OK_A, lan, 1, 50) // slower but CORRECT 42 if heal_select_best(cells, 2, 1, 0, 1) != 1 { return 4 } 43 44 // ---- T3: incumbent already best (small diff) -> KEEP (no needless switch) ---- 45 hset(cells, 0, NXNS_OK_A, lan, 1, 10) 46 hset(cells, 1, NXNS_OK_A, lan, 1, 12) 47 heal_decide(cells, 2, 1, 0, 1, 0, HEAL_BAND_MS, d) 48 if d.action != HEAL_KEEP { return 5 } 49 if d.target_idx != 0 { return 6 } 50 51 // ---- T4: HYSTERESIS -- within band = KEEP; beyond band = SWITCH(better) ---- 52 hset(cells, 0, NXNS_OK_A, lan, 1, 30) 53 hset(cells, 1, NXNS_OK_A, lan, 1, 25) // 5ms gain < band(20) -> no flap 54 heal_decide(cells, 2, 1, 0, 1, 0, HEAL_BAND_MS, d) 55 if d.action != HEAL_KEEP { return 7 } 56 hset(cells, 1, NXNS_OK_A, lan, 1, 5) // 25ms gain > band -> switch 57 heal_decide(cells, 2, 1, 0, 1, 0, HEAL_BAND_MS, d) 58 if d.action != HEAL_SWITCH { return 8 } 59 if d.reason != HEAL_R_BETTER_FOUND { return 9 } 60 61 // ---- T5: everything failing -> GIVE UP safely ---- 62 hset(cells, 0, NXNS_TIMEOUT, 0, 0, 800) 63 hset(cells, 1, NXNS_SERVFAIL, 0, 0, 30) 64 heal_decide(cells, 2, 1, 0, 1, 0, HEAL_BAND_MS, d) 65 if d.action != HEAL_GIVEUP { return 10 } 66 if d.reason != HEAL_R_NO_CANDIDATE { return 11 } 67 68 // ---- T6: owned-domain HAIRPIN demotion -- a PUBLIC answer to an owned 69 // name is not a valid heal target (require_private=1) ---- 70 hset(cells, 0, NXNS_OK_A, pub, 0, 3) // fast, but PUBLIC (hairpin) 71 hset(cells, 1, NXNS_TIMEOUT, 0, 0, 800) 72 if heal_select_best(cells, 2, 1, 0, 1) != (0 - 1) { return 12 } // none eligible (owned) 73 if heal_select_best(cells, 2, 1, 0, 0) != 0 { return 13 } // general domain: public ok 74 75 sys_write(1, "T1-T6 self-heal decisions OK (failover, correctness>speed, keep, hysteresis, giveup, hairpin)\n", 92) 76 77 // ---- render the easy-for-anyone HEAL action (the fail-over case) ---- 78 sys_write(1, "\n=== rendered: self-heal action ===\n", 36) 79 let name: *u8 = "nishifamily.com" as *u8 80 hset(cells, 0, NXNS_TIMEOUT, 0, 0, 800) 81 hset(cells, 1, NXNS_OK_A, lan, 1, 5) 82 heal_decide(cells, 2, 1, 0, 1, 0, HEAL_BAND_MS, d) 83 heal_render(d, servers, name, 15) 84 85 sys_write(1, "\nNETSCOPE SELF-HEAL KAT PASS (goal-directed best-correct selection + safe heal decision)\n", 89) 86 return 0 87}