nx_iot_local_wiz_test.nx source
↩ module page · 213 lines · 10313 B
1// nx_iot_local_wiz_test.nx -- in-memory smoke for the WiZ JSON-over-
2// UDP kind generator.
3//
4// Coverage:
5// - sealed-enum verdict validity gate
6// - itoa: 0, single digit, multi-digit, max-ish (255)
7// - atoi: digit, multi-digit, terminator stops parse
8// - byte-pattern find: present + absent + at-edge
9// - setPilot RGB + dimming payload bytes + length
10// - setPilot state on/off payload
11// - setPilot sceneId payload
12// - getPilot probe length + first/last bytes
13// - parse_pilot against a canned getPilot reply: state true,
14// r/g/b/dimming/sceneId all extracted
15// - parse_pilot: missing "result" -> NO_RESULT
16// - parse_pilot: malformed (too short) -> BUF_TOO_SMALL
17//
18// expect_exit: 0
19//
20// license_tier: ORIGINAL
21
22import "nx_syscalls_x86_64.nx"
23import "nx_iot_local_wiz.nx"
24
25func main() -> i64 {
26 // ---- Verdict gate ----------------------------------------------
27 if nx_iot_wiz_verdict_is_valid(NX_IOT_WIZ_VERDICT_UNKNOWN) != 1 { return 1 }
28 if nx_iot_wiz_verdict_is_valid(NX_IOT_WIZ_VERDICT_OK) != 1 { return 2 }
29 if nx_iot_wiz_verdict_is_valid(NX_IOT_WIZ_VERDICT_BUF_TOO_SMALL) != 1 { return 3 }
30 if nx_iot_wiz_verdict_is_valid(NX_IOT_WIZ_VERDICT_NO_RESULT) != 1 { return 4 }
31 if nx_iot_wiz_verdict_is_valid(NX_IOT_WIZ_VERDICT_KEY_NOT_FOUND) != 1 { return 5 }
32 if nx_iot_wiz_verdict_is_valid(NX_IOT_WIZ_VERDICT_BAD_VALUE) != 1 { return 6 }
33 if nx_iot_wiz_verdict_is_valid(NX_IOT_WIZ_VERDICT_BAD_ARG) != 1 { return 7 }
34 if nx_iot_wiz_verdict_is_valid(NX_IOT_WIZ_VERDICT_N) != 0 { return 8 }
35
36 // ---- itoa ------------------------------------------------------
37 let buf: *u8 = sys_mmap(32)
38 if nx_iot_wiz_itoa(buf, 0) != 1 { return 10 }
39 if buf[0] != 0x30 { return 11 }
40 if nx_iot_wiz_itoa(buf, 7) != 1 { return 12 }
41 if buf[0] != 0x37 { return 13 }
42 if nx_iot_wiz_itoa(buf, 42) != 2 { return 14 }
43 if buf[0] != 0x34 { return 15 }
44 if buf[1] != 0x32 { return 16 }
45 if nx_iot_wiz_itoa(buf, 255) != 3 { return 17 }
46 if buf[0] != 0x32 { return 18 }
47 if buf[1] != 0x35 { return 19 }
48 if buf[2] != 0x35 { return 20 }
49
50 // ---- atoi ------------------------------------------------------
51 let abuf: *u8 = sys_mmap(16)
52 abuf[0] = 0x31; abuf[1] = 0x32; abuf[2] = 0x33 // "123"
53 abuf[3] = 0x2C // "," -- terminator
54 let used: *i64 = sys_mmap(8) as *i64
55 let v: i64 = nx_iot_wiz_atoi(abuf, 4, 0, used)
56 if v != 123 { return 30 }
57 if used[0] != 3 { return 31 }
58
59 // Non-digit at start
60 abuf[0] = 0x41 // 'A'
61 let v2: i64 = nx_iot_wiz_atoi(abuf, 4, 0, used)
62 if v2 != 0 { return 32 }
63 if used[0] != 0 { return 33 }
64
65 // ---- find: present + absent -----------------------------------
66 let hay: *u8 = sys_mmap(16)
67 hay[0]=0x48; hay[1]=0x65; hay[2]=0x6C; hay[3]=0x6C; hay[4]=0x6F // "Hello"
68 let needle: *u8 = sys_mmap(8)
69 needle[0]=0x6C; needle[1]=0x6C // "ll"
70 if nx_iot_wiz_find(hay, 5, needle, 2) != 2 { return 40 }
71 needle[0]=0x77 // "w"
72 if nx_iot_wiz_find(hay, 5, needle, 1) != -1 { return 41 }
73 // Empty pattern returns 0
74 if nx_iot_wiz_find(hay, 5, needle, 0) != 0 { return 42 }
75 // Pattern longer than haystack
76 if nx_iot_wiz_find(hay, 2, needle, 5) != -1 { return 43 }
77
78 // ---- setPilot RGB + dimming payload ---------------------------
79 let p: *u8 = sys_mmap(128)
80 let pn: i64 = nx_iot_wiz_build_set_rgb(p, 128, 255, 0, 128, 80)
81 if pn < 50 { return 50 }
82 if p[0] != 0x7B { return 51 } // {
83 if p[pn - 1] != 0x7D { return 52 } // }
84 if p[pn - 2] != 0x7D { return 53 } // }}
85 // Should contain "setPilot"
86 let kw: *u8 = sys_mmap(16)
87 kw[0]=0x73; kw[1]=0x65; kw[2]=0x74; kw[3]=0x50
88 kw[4]=0x69; kw[5]=0x6C; kw[6]=0x6F; kw[7]=0x74
89 if nx_iot_wiz_find(p, pn, kw, 8) < 0 { return 54 }
90 // Should contain the literal "255"
91 let two55: *u8 = sys_mmap(8)
92 two55[0]=0x32; two55[1]=0x35; two55[2]=0x35
93 if nx_iot_wiz_find(p, pn, two55, 3) < 0 { return 55 }
94 // Should contain "dimming":80
95 let dimv: *u8 = sys_mmap(16)
96 dimv[0]=0x64; dimv[1]=0x69; dimv[2]=0x6D; dimv[3]=0x6D
97 dimv[4]=0x69; dimv[5]=0x6E; dimv[6]=0x67
98 if nx_iot_wiz_find(p, pn, dimv, 7) < 0 { return 56 }
99
100 // ---- setPilot state on/off ------------------------------------
101 let sp: *u8 = sys_mmap(128)
102 let spn: i64 = nx_iot_wiz_build_set_state(sp, 128, 1)
103 if spn < 40 { return 60 }
104 // Should contain "true"
105 let tru: *u8 = sys_mmap(8)
106 tru[0]=0x74; tru[1]=0x72; tru[2]=0x75; tru[3]=0x65
107 if nx_iot_wiz_find(sp, spn, tru, 4) < 0 { return 61 }
108 let spn_off: i64 = nx_iot_wiz_build_set_state(sp, 128, 0)
109 let fal: *u8 = sys_mmap(8)
110 fal[0]=0x66; fal[1]=0x61; fal[2]=0x6C; fal[3]=0x73; fal[4]=0x65
111 if nx_iot_wiz_find(sp, spn_off, fal, 5) < 0 { return 62 }
112
113 // ---- setPilot sceneId -----------------------------------------
114 let sc: *u8 = sys_mmap(128)
115 let scn: i64 = nx_iot_wiz_build_set_scene(sc, 128, 12)
116 let scnk: *u8 = sys_mmap(16)
117 scnk[0]=0x73; scnk[1]=0x63; scnk[2]=0x65; scnk[3]=0x6E
118 scnk[4]=0x65; scnk[5]=0x49; scnk[6]=0x64
119 if nx_iot_wiz_find(sc, scn, scnk, 7) < 0 { return 70 }
120 let twelve: *u8 = sys_mmap(8)
121 twelve[0]=0x31; twelve[1]=0x32
122 if nx_iot_wiz_find(sc, scn, twelve, 2) < 0 { return 71 }
123
124 // ---- getPilot probe -------------------------------------------
125 let g: *u8 = sys_mmap(64)
126 let gn: i64 = nx_iot_wiz_build_get_pilot(g, 64)
127 if gn != 33 { return 80 }
128 if g[0] != 0x7B { return 81 }
129 if g[32] != 0x7D { return 82 }
130 let get: *u8 = sys_mmap(16)
131 get[0]=0x67; get[1]=0x65; get[2]=0x74; get[3]=0x50
132 get[4]=0x69; get[5]=0x6C; get[6]=0x6F; get[7]=0x74
133 if nx_iot_wiz_find(g, gn, get, 8) < 0 { return 83 }
134
135 // ---- parse_pilot against canned reply -------------------------
136 // Reply (typical real WiZ getPilot response shape):
137 // {"method":"getPilot","env":"pro","result":{"mac":"a8bb...",
138 // "rssi":-56,"state":true,"sceneId":0,"r":255,"g":128,"b":64,
139 // "dimming":80,"temp":2700,"src":""}}
140 //
141 // Build it byte-by-byte. Full string is large; we use a smaller
142 // representative subset with the keys we extract.
143 //
144 // Subset: '{"result":{"state":true,"r":255,"g":128,"b":64,"dimming":80,"sceneId":12,"temp":2700}}'
145 let rep: *u8 = sys_mmap(256)
146 var i: i64 = 0
147 rep[i]=0x7B;i=i+1 // {
148 rep[i]=0x22;i=i+1; rep[i]=0x72;i=i+1; rep[i]=0x65;i=i+1
149 rep[i]=0x73;i=i+1; rep[i]=0x75;i=i+1; rep[i]=0x6C;i=i+1
150 rep[i]=0x74;i=i+1; rep[i]=0x22;i=i+1; rep[i]=0x3A;i=i+1 // "result":
151 rep[i]=0x7B;i=i+1 // {
152 rep[i]=0x22;i=i+1; rep[i]=0x73;i=i+1; rep[i]=0x74;i=i+1
153 rep[i]=0x61;i=i+1; rep[i]=0x74;i=i+1; rep[i]=0x65;i=i+1
154 rep[i]=0x22;i=i+1; rep[i]=0x3A;i=i+1 // "state":
155 rep[i]=0x74;i=i+1; rep[i]=0x72;i=i+1; rep[i]=0x75;i=i+1; rep[i]=0x65;i=i+1 // true
156 rep[i]=0x2C;i=i+1 // ,
157 rep[i]=0x22;i=i+1; rep[i]=0x72;i=i+1; rep[i]=0x22;i=i+1; rep[i]=0x3A;i=i+1 // "r":
158 rep[i]=0x32;i=i+1; rep[i]=0x35;i=i+1; rep[i]=0x35;i=i+1 // 255
159 rep[i]=0x2C;i=i+1 // ,
160 rep[i]=0x22;i=i+1; rep[i]=0x67;i=i+1; rep[i]=0x22;i=i+1; rep[i]=0x3A;i=i+1 // "g":
161 rep[i]=0x31;i=i+1; rep[i]=0x32;i=i+1; rep[i]=0x38;i=i+1 // 128
162 rep[i]=0x2C;i=i+1 // ,
163 rep[i]=0x22;i=i+1; rep[i]=0x62;i=i+1; rep[i]=0x22;i=i+1; rep[i]=0x3A;i=i+1 // "b":
164 rep[i]=0x36;i=i+1; rep[i]=0x34;i=i+1 // 64
165 rep[i]=0x2C;i=i+1
166 rep[i]=0x22;i=i+1; rep[i]=0x64;i=i+1; rep[i]=0x69;i=i+1; rep[i]=0x6D;i=i+1
167 rep[i]=0x6D;i=i+1; rep[i]=0x69;i=i+1; rep[i]=0x6E;i=i+1; rep[i]=0x67;i=i+1
168 rep[i]=0x22;i=i+1; rep[i]=0x3A;i=i+1 // "dimming":
169 rep[i]=0x38;i=i+1; rep[i]=0x30;i=i+1 // 80
170 rep[i]=0x2C;i=i+1
171 rep[i]=0x22;i=i+1; rep[i]=0x73;i=i+1; rep[i]=0x63;i=i+1; rep[i]=0x65;i=i+1
172 rep[i]=0x6E;i=i+1; rep[i]=0x65;i=i+1; rep[i]=0x49;i=i+1; rep[i]=0x64;i=i+1
173 rep[i]=0x22;i=i+1; rep[i]=0x3A;i=i+1 // "sceneId":
174 rep[i]=0x31;i=i+1; rep[i]=0x32;i=i+1 // 12
175 rep[i]=0x2C;i=i+1
176 rep[i]=0x22;i=i+1; rep[i]=0x74;i=i+1; rep[i]=0x65;i=i+1; rep[i]=0x6D;i=i+1
177 rep[i]=0x70;i=i+1; rep[i]=0x22;i=i+1; rep[i]=0x3A;i=i+1 // "temp":
178 rep[i]=0x32;i=i+1; rep[i]=0x37;i=i+1; rep[i]=0x30;i=i+1; rep[i]=0x30;i=i+1 // 2700
179 rep[i]=0x7D;i=i+1; rep[i]=0x7D;i=i+1
180 let rep_len: i64 = i
181
182 let pilot: *IotWizPilot = sys_mmap(80) as *IotWizPilot
183 let pv: *i64 = sys_mmap(8) as *i64
184 let pr: i64 = nx_iot_wiz_parse_pilot(rep, rep_len, pilot, pv)
185 if pr != 0 { return 100 }
186 if pv[0] != NX_IOT_WIZ_VERDICT_OK { return 101 }
187 if pilot.state != 1 { return 102 }
188 if pilot.r != 255 { return 103 }
189 if pilot.g != 128 { return 104 }
190 if pilot.b != 64 { return 105 }
191 if pilot.dimming != 80 { return 106 }
192 if pilot.scene_id != 12 { return 107 }
193 if pilot.temp_k != 2700 { return 108 }
194
195 // ---- parse_pilot: no "result" key -----------------------------
196 let nores: *u8 = sys_mmap(64)
197 nores[0]=0x7B; nores[1]=0x22; nores[2]=0x6F; nores[3]=0x6B
198 nores[4]=0x22; nores[5]=0x3A; nores[6]=0x31; nores[7]=0x7D
199 nores[8]=0x20; nores[9]=0x20; nores[10]=0x20; nores[11]=0x20
200 nores[12]=0x20; nores[13]=0x20; nores[14]=0x20; nores[15]=0x20
201 let nr: i64 = nx_iot_wiz_parse_pilot(nores, 16, pilot, pv)
202 if nr != -1 { return 110 }
203 if pv[0] != NX_IOT_WIZ_VERDICT_NO_RESULT { return 111 }
204
205 // ---- parse_pilot: too short ----------------------------------
206 let ts: *u8 = sys_mmap(16)
207 ts[0]=0x7B; ts[1]=0x7D
208 let tsr: i64 = nx_iot_wiz_parse_pilot(ts, 2, pilot, pv)
209 if tsr != -1 { return 120 }
210 if pv[0] != NX_IOT_WIZ_VERDICT_BUF_TOO_SMALL { return 121 }
211
212 return 0
213}