code wiki / (root) / nx_websocket_stream_test.nx

nx_websocket_stream_test.nx source

↩ module page · 169 lines · 6562 B

1// nx_websocket_stream_test.nx -- KAT for the streaming WebSocket framer. 2// 3// Uses sys_pipe2 to create a loopback fd pair (write end = "client", 4// read end = our nx_ws_read_frame_from_fd reader). Drives canonical 5// RFC 6455 frame bytes through and asserts the parsed result. 6// 7// Tests: 8// T1: short unmasked text frame (server -> client direction simulated) 9// T2: client-masked "Hello" frame (RFC 6455 §5.7 wire vector) gets 10// unmasked in place during read 11// T3: extended 16-bit length (1000 bytes payload) 12// T4: send-to-fd round-trip: nx_ws_send_text -> read back through 13// a fresh pipe -> parse and verify 14// T5: nx_ws_send_close round-trip 15// 16// expect_exit: 0 17// license_tier: ORIGINAL 18 19import "nx_syscalls.nx" 20import "nx_websocket_frame.nx" 21import "nx_websocket_stream.nx" 22 23func main() -> i64 { 24 // ---- T1: unmasked text frame ---- 25 let fds1: *i32 = sys_mmap(16) as *i32 26 if sys_pipe2(fds1 as *i64, 0) < 0 { return 1 } 27 let rfd1: i64 = fds1[0] as i64 28 let wfd1: i64 = fds1[1] as i64 29 30 let f1bytes: *u8 = sys_mmap(16) 31 f1bytes[0] = 0x81; f1bytes[1] = 0x05 32 f1bytes[2] = 0x48; f1bytes[3] = 0x65; f1bytes[4] = 0x6C 33 f1bytes[5] = 0x6C; f1bytes[6] = 0x6F 34 if sys_write(wfd1, f1bytes, 7) != 7 { return 2 } 35 sys_close(wfd1) // EOF after frame so read can settle 36 37 let buf1: *u8 = sys_mmap(64) 38 let f1_raw: *u8 = sys_mmap(128) 39 let f1: *WsFrame = f1_raw as *WsFrame 40 let v1: i64 = nx_ws_read_frame_from_fd(rfd1, buf1, 64, f1) 41 sys_close(rfd1) 42 if v1 != NX_WSS_OK { return 3 } 43 if f1.opcode != WS_OP_TEXT { return 4 } 44 if f1.payload_len != 5 { return 5 } 45 if buf1[f1.payload_off] != 0x48 as u8 { return 6 } // 'H' 46 if buf1[f1.payload_off + 4] != 0x6F as u8 { return 7 } // 'o' 47 48 // ---- T2: masked client "Hello" (RFC 6455 §5.7) -- unmasked in place ---- 49 let fds2: *i32 = sys_mmap(16) as *i32 50 if sys_pipe2(fds2 as *i64, 0) < 0 { return 10 } 51 let rfd2: i64 = fds2[0] as i64 52 let wfd2: i64 = fds2[1] as i64 53 54 let f2bytes: *u8 = sys_mmap(16) 55 f2bytes[0] = 0x81; f2bytes[1] = 0x85 56 f2bytes[2] = 0x37; f2bytes[3] = 0xFA; f2bytes[4] = 0x21; f2bytes[5] = 0x3D 57 f2bytes[6] = 0x7F; f2bytes[7] = 0x9F; f2bytes[8] = 0x4D 58 f2bytes[9] = 0x51; f2bytes[10] = 0x58 59 if sys_write(wfd2, f2bytes, 11) != 11 { return 11 } 60 sys_close(wfd2) 61 62 let buf2: *u8 = sys_mmap(64) 63 let f2_raw: *u8 = sys_mmap(128) 64 let f2: *WsFrame = f2_raw as *WsFrame 65 let v2: i64 = nx_ws_read_frame_from_fd(rfd2, buf2, 64, f2) 66 sys_close(rfd2) 67 if v2 != NX_WSS_OK { return 12 } 68 if f2.masked != 1 { return 13 } 69 if f2.payload_len != 5 { return 14 } 70 // Read-from-fd unmasks in place -- buf2 should now show "Hello" 71 if buf2[f2.payload_off] != 0x48 as u8 { return 15 } 72 if buf2[f2.payload_off + 1] != 0x65 as u8 { return 16 } 73 if buf2[f2.payload_off + 2] != 0x6C as u8 { return 17 } 74 if buf2[f2.payload_off + 3] != 0x6C as u8 { return 18 } 75 if buf2[f2.payload_off + 4] != 0x6F as u8 { return 19 } 76 77 // ---- T3: extended 16-bit length frame (1000 bytes) ---- 78 let fds3: *i32 = sys_mmap(16) as *i32 79 if sys_pipe2(fds3 as *i64, 0) < 0 { return 20 } 80 let rfd3: i64 = fds3[0] as i64 81 let wfd3: i64 = fds3[1] as i64 82 83 let f3bytes: *u8 = sys_mmap(2048) 84 f3bytes[0] = 0x82; f3bytes[1] = 126 // binary FIN + extlen sentinel 85 f3bytes[2] = 0x03; f3bytes[3] = 0xE8 // 1000 in BE 86 var i: i64 = 0 87 while i < 1000 { 88 f3bytes[4 + i] = (i & 0xFF) as u8 89 i = i + 1 90 } 91 if sys_write(wfd3, f3bytes, 1004) != 1004 { return 21 } 92 sys_close(wfd3) 93 94 let buf3: *u8 = sys_mmap(2048) 95 let f3_raw: *u8 = sys_mmap(128) 96 let f3: *WsFrame = f3_raw as *WsFrame 97 let v3: i64 = nx_ws_read_frame_from_fd(rfd3, buf3, 2048, f3) 98 sys_close(rfd3) 99 if v3 != NX_WSS_OK { return 22 } 100 if f3.opcode != WS_OP_BINARY { return 23 } 101 if f3.payload_len != 1000 { return 24 } 102 if buf3[f3.payload_off] != 0x00 as u8 { return 25 } 103 if buf3[f3.payload_off + 999] != 0xE7 as u8 { return 26 } // (999 & 0xFF) 104 105 // ---- T4: send-to-fd round-trip -- send_text writes a parseable frame ---- 106 let fds4: *i32 = sys_mmap(16) as *i32 107 if sys_pipe2(fds4 as *i64, 0) < 0 { return 30 } 108 let rfd4: i64 = fds4[0] as i64 109 let wfd4: i64 = fds4[1] as i64 110 111 let txt: *u8 = "ping" as *u8 112 let sv: i64 = nx_ws_send_text(wfd4, txt, 4) 113 sys_close(wfd4) 114 if sv != NX_WSS_OK { return 31 } 115 116 let buf4: *u8 = sys_mmap(64) 117 let f4_raw: *u8 = sys_mmap(128) 118 let f4: *WsFrame = f4_raw as *WsFrame 119 let v4: i64 = nx_ws_read_frame_from_fd(rfd4, buf4, 64, f4) 120 sys_close(rfd4) 121 if v4 != NX_WSS_OK { return 32 } 122 if f4.opcode != WS_OP_TEXT { return 33 } 123 if f4.fin != 1 { return 34 } 124 if f4.masked != 0 { return 35 } // server frames MUST NOT be masked 125 if f4.payload_len != 4 { return 36 } 126 if buf4[f4.payload_off] != 0x70 as u8 { return 37 } // 'p' 127 if buf4[f4.payload_off + 3] != 0x67 as u8 { return 38 } // 'g' 128 129 // ---- T5: send_close with status code 1000 (normal closure) ---- 130 let fds5: *i32 = sys_mmap(16) as *i32 131 if sys_pipe2(fds5 as *i64, 0) < 0 { return 40 } 132 let rfd5: i64 = fds5[0] as i64 133 let wfd5: i64 = fds5[1] as i64 134 135 let svc: i64 = nx_ws_send_close(wfd5, 1000) 136 sys_close(wfd5) 137 if svc != NX_WSS_OK { return 41 } 138 139 let buf5: *u8 = sys_mmap(64) 140 let f5_raw: *u8 = sys_mmap(128) 141 let f5: *WsFrame = f5_raw as *WsFrame 142 let v5: i64 = nx_ws_read_frame_from_fd(rfd5, buf5, 64, f5) 143 sys_close(rfd5) 144 if v5 != NX_WSS_OK { return 42 } 145 if f5.opcode != WS_OP_CLOSE { return 43 } 146 if f5.payload_len != 2 { return 44 } 147 // status code 1000 = 0x03E8 big-endian 148 if buf5[f5.payload_off] != 0x03 as u8 { return 45 } 149 if buf5[f5.payload_off + 1] != 0xE8 as u8 { return 46 } 150 151 // ---- T6: EOF before any bytes returns NX_WSS_EOF (clean close) ---- 152 let fds6: *i32 = sys_mmap(16) as *i32 153 if sys_pipe2(fds6 as *i64, 0) < 0 { return 50 } 154 let rfd6: i64 = fds6[0] as i64 155 sys_close(fds6[1] as i64) // close write end immediately 156 157 let buf6: *u8 = sys_mmap(64) 158 let f6_raw: *u8 = sys_mmap(128) 159 let f6: *WsFrame = f6_raw as *WsFrame 160 let v6: i64 = nx_ws_read_frame_from_fd(rfd6, buf6, 64, f6) 161 sys_close(rfd6) 162 if v6 != NX_WSS_EOF { return 51 } 163 164 // "PASS\n" 165 let ok: *u8 = sys_mmap(8) 166 ok[0]=80; ok[1]=65; ok[2]=83; ok[3]=83; ok[4]=10 167 sys_write(1, ok, 5) 168 return 0 169}