code wiki / (root) / nx_moonraker_ready_check_test.nx

nx_moonraker_ready_check_test.nx source

↩ module page · 92 lines · 3926 B

1// nx_moonraker_ready_check_test.nx -- ready-state classifier tests 2// (offline; classify_body verified against canned response bodies) 3// + loopback fork test against fake Moonraker returning ready JSON. 4// 5// Closed-form invariants: 6// (a) "{\"result\":{\"state\":\"ready\"}}" -> NX_READY_OK 7// (b) "{\"result\":{\"state\":\"shutdown\"}}" -> NX_READY_NOT_READY 8// (c) "{\"result\":{\"state\":\"error\"}}" -> NX_READY_NOT_READY 9// (d) Body with no "state" field -> NX_READY_BAD_RESPONSE 10// (e) Loose form with space: "\"state\": \"ready\"" -> NX_READY_OK 11// (f) Loopback fork: fake Moonraker returns 200 + ready JSON -> 12// ready check returns NX_READY_OK 13// (g) Verdict names non-NULL for all verdicts. 14// 15// expect_exit: 0 16// license_tier: ORIGINAL 17 18import "nx_syscalls.nx" 19import "nx_tls13_io.nx" 20import "nx_moonraker_client.nx" 21import "nx_moonraker_io.nx" 22import "nx_moonraker_ready_check.nx" 23 24const TEST_PORT: i64 = 18449 25 26func body_len(s: *u8) -> i64 { 27 var i: i64 = 0 28 while s[i] != 0 { i = i + 1 } 29 return i 30} 31 32func main() -> i64 { 33 // --- (a)(b)(c)(d)(e) Offline body classification --- 34 let b_ready: *u8 = "{\"result\":{\"state\":\"ready\",\"hostname\":\"qidi\"}}" 35 let b_shutdown: *u8 = "{\"result\":{\"state\":\"shutdown\",\"reason\":\"err\"}}" 36 let b_error: *u8 = "{\"result\":{\"state\":\"error\"}}" 37 let b_nostate: *u8 = "{\"result\":{\"hostname\":\"qidi\"}}" 38 let b_loose: *u8 = "{\"result\": {\"state\": \"ready\"}}" 39 40 if nx_ready_classify_body(b_ready, body_len(b_ready)) != NX_READY_OK { return 10 } 41 if nx_ready_classify_body(b_shutdown, body_len(b_shutdown)) != NX_READY_NOT_READY { return 11 } 42 if nx_ready_classify_body(b_error, body_len(b_error)) != NX_READY_NOT_READY { return 12 } 43 if nx_ready_classify_body(b_nostate, body_len(b_nostate)) != NX_READY_BAD_RESPONSE { return 13 } 44 if nx_ready_classify_body(b_loose, body_len(b_loose)) != NX_READY_OK { return 14 } 45 46 // --- (f) Loopback fork test --- 47 let listen_fd: i64 = tcp_listen_loopback(TEST_PORT) 48 if listen_fd < 0 { return 20 } 49 let pid: i64 = sys_fork() 50 if pid < 0 { return 21 } 51 52 if pid == 0 { 53 // Child: query loopback 54 var spin: i64 = 0 55 while spin < 50000 { spin = spin + 1 } 56 let scratch: *u8 = sys_mmap(4096) 57 let resp: *u8 = sys_mmap(4096) 58 let host: *u8 = "127.0.0.1:18449" 59 let v: i64 = nx_moonraker_ready_check_loopback(TEST_PORT, 60 host, 15, 61 0 as *u8, 0, 62 scratch, 4096, 63 resp, 4096) 64 if v != NX_READY_OK { sys_exit(30 + v) } 65 sys_exit(0) 66 } 67 68 // Parent: serve canned 200 OK with ready state 69 let cfd: i64 = sys_accept(listen_fd) 70 if cfd < 0 { return 22 } 71 let req_buf: *u8 = sys_mmap(4096) 72 let n_req: i64 = sys_read(cfd, req_buf, 4096) 73 if n_req <= 0 { return 23 } 74 75 // Canned response: HTTP 200 with ready-state JSON body. 76 // Body: {"result":{"state":"ready"}} (29 bytes) 77 let resp: *u8 = "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nContent-Length: 29\r\nConnection: close\r\n\r\n{\"result\":{\"state\":\"ready\"}}" 78 var rl: i64 = 0 79 while resp[rl] != 0 { rl = rl + 1 } 80 let n_w: i64 = sys_write(cfd, resp, rl) 81 if n_w != rl { return 24 } 82 sys_close(cfd) 83 sys_close(listen_fd) 84 85 // --- (g) Verdict names --- 86 if (nx_ready_verdict_name(NX_READY_OK) as i64) == 0 { return 80 } 87 if (nx_ready_verdict_name(NX_READY_NOT_READY) as i64) == 0 { return 81 } 88 if (nx_ready_verdict_name(NX_READY_BAD_RESPONSE) as i64) == 0 { return 82 } 89 if (nx_ready_verdict_name(NX_READY_NETWORK_ERR) as i64) == 0 { return 83 } 90 91 return 0 92}