nx_fio_region_gate.nx source
↩ module page · 578 lines · 46175 B
1import "nx_fio.nx"
2import "nx_resource_arbiter.nx"
3import "nx_file_install.nx"
4import "_hdl_build/nx_mgmt_data.nx"
5import "_hdl_build/nx_mgmt_api.nx"
6import "_hdl_build/nx_hostctl.nx"
7import "nx_gate_verdict.nx"
8static frg_plan: *i64
9const FRG_CASES: *u8="real-file-open-size\nrange-selection\nbounded-first-read\nbounded-final-read-closes\nclosed-read-is-eof\nidempotent-close\ninvalid-range-retains-session\ninvalid-buffer-retains-session\nfull-file-stream-by-caller-capacity\nmissing-file-cause\npremature-eof-counts-and-closes\npathname-replacement-retains-open-file\nsparse-offset-beyond-signed32\n"
10func frg_check(name: *u8,ok: i64,count: *i64) -> i64 { return gv_plan_check(frg_plan,name,ok,count) }
11func frg_len(s: *u8) -> i64 { var n: i64=0;while s[n]!=(0 as u8) { n=n+1 };return n }
12func frg_file(path: *u8,data: *u8,n: i64) -> i64 {
13 let fd: i64=sys_openat_wr(path,0x180);if fd<0 { return fd }
14 let result: *NxFileWriteResult=sys_mmap(__size_of(NxFileWriteResult)) as *NxFileWriteResult
15 let rc: i64=fio_write_sync_fd(fd,data,n,result)
16 sys_munmap(result as *u8,__size_of(NxFileWriteResult));return rc
17}
18func frg_prepare_checks() -> i64 {
19 let c: *i64=gv_ctr()
20 let r: *NxFilePrepareResult=sys_mmap(__size_of(NxFilePrepareResult)) as *NxFilePrepareResult
21 let scratch: *u8=sys_mmap(3)
22 let bytes: *u8="candidate bytes cross several chunks"
23 let n: i64=frg_len(bytes)
24 if frg_file("prepare-source",bytes,n)!=0 { return 3 }
25 let rc: i64=fio_prepare_copy("prepare-source","prepared",0x180,scratch,3,r)
26 gv_check("bounded preparation persists complete candidate",rc==0 && r.copied==n && r.created==1 && r.durable==1 && r.source_close==0 && r.destination_close==0,c)
27 let read: *NxFileReadRegion=sys_mmap(__size_of(NxFileReadRegion)) as *NxFileReadRegion
28 fio_region_init(read);let opened: i64=fio_region_open("prepared",read)
29 let buf: *u8=sys_mmap(n+1);let got: i64=fio_region_next(read,buf,n+1)
30 var same: i64=(opened==0 && got==n) as i64;var i: i64=0
31 while i<got { if buf[i]!=bytes[i] { same=0 };i=i+1 }
32 gv_check("prepared bytes exactly match source",same,c)
33 let exists: i64=fio_prepare_copy("prepare-source","prepared",0x180,scratch,3,r)
34 gv_check("existing candidate refused without overwrite",exists==FIO_EEXIST && r.created==0 && r.copied==0 && r.durable==0,c)
35 fio_region_open("prepared",read);let again: i64=fio_region_next(read,buf,n+1)
36 same=(again==n) as i64;i=0
37 while i<again { if buf[i]!=bytes[i] { same=0 };i=i+1 }
38 gv_check("refusal preserves every existing byte",same,c)
39 let missing: i64=fio_prepare_copy("missing-source","uncreated",0x180,scratch,3,r)
40 gv_check("source failure never creates candidate",missing<0 && r.created==0 && r.copied==0 && fio_exists("uncreated")==0,c)
41 let noDir: i64=fio_prepare_copy("prepare-source","missing-directory/candidate",0x180,scratch,3,r)
42 gv_check("destination failure closes source",noDir<0 && r.created==0 && r.source_close==0 && r.durable==0,c)
43 gv_check("invalid buffer refuses before creation",fio_prepare_copy("prepare-source","invalid-candidate",0x180,scratch,0,r)==FIO_EINVAL && r.created==0,c)
44 fio_region_close(read)
45 sys_munmap(read as *u8,__size_of(NxFileReadRegion));sys_munmap(buf,n+1)
46 sys_munmap(scratch,3);sys_munmap(r as *u8,__size_of(NxFilePrepareResult))
47 return gv_verdict("FIO-PREPARE-GATE",c,"real files; preparation only, not publication or power-loss qualification")
48}
49
50func frg_equals(path: *u8,expected: *u8) -> i64 {
51 let n: i64=frg_len(expected)
52 let r: *NxFileReadRegion=sys_mmap(__size_of(NxFileReadRegion)) as *NxFileReadRegion
53 let b: *u8=sys_mmap(n+1);fio_region_init(r)
54 let opened: i64=fio_region_open(path,r)
55 let got: i64=fio_region_next(r,b,n+1)
56 var same: i64=(opened==0 && r.total==n && got==n) as i64
57 var i: i64=0;while i<got { if b[i]!=expected[i] { same=0 };i=i+1 }
58 fio_region_close(r);sys_munmap(r as *u8,__size_of(NxFileReadRegion));sys_munmap(b,n+1);return same
59}
60func frg_replace_checks() -> i64 {
61 let c: *i64=gv_ctr()
62 let out: *NxFileReplaceResult=sys_mmap(__size_of(NxFileReplaceResult)) as *NxFileReplaceResult
63 let buf: *u8=sys_mmap(3)
64 let old: *u8="original-live";let fresh: *u8="replacement-live"
65 if frg_file("replace-live",old,frg_len(old))!=0 { return 3 }
66 if frg_file("replace-source",fresh,frg_len(fresh))!=0 { return 3 }
67 let held: *NxFileReadRegion=sys_mmap(__size_of(NxFileReadRegion)) as *NxFileReadRegion
68 fio_region_init(held)
69 if fio_region_open("replace-live",held)!=0 { return 3 }
70 let rc: i64=fio_replace_with_backup("replace-source","replace-live","replace-candidate","replace-bank",0x180,buf,3,out)
71 gv_check("replacement prepares bank before durable publication",rc==0 && out.backup.durable==1 && out.candidate.durable==1 && out.publication.visible==1 && out.publication.durable==1,c)
72 gv_check("live contains complete replacement",frg_equals("replace-live",fresh),c)
73 gv_check("history retains complete previous content",frg_equals("replace-bank",old),c)
74 gv_check("source artifact remains available",frg_equals("replace-source",fresh),c)
75 let heldbuf: *u8=sys_mmap(frg_len(old)+1)
76 let got: i64=fio_region_next(held,heldbuf,frg_len(old)+1)
77 var same: i64=(got==frg_len(old)) as i64;var i: i64=0
78 while i<got { if heldbuf[i]!=old[i] { same=0 };i=i+1 }
79 gv_check("existing reader retains original inode after replacement",same,c)
80 let conflict: i64=fio_replace_with_backup("replace-source","replace-live","replace-candidate-2","replace-bank",0x180,buf,3,out)
81 gv_check("existing history refuses publication",conflict==FIO_EEXIST && out.publication.visible==0 && out.backup.created==0,c)
82 gv_check("history conflict preserves live and history",frg_equals("replace-live",fresh)==1 && frg_equals("replace-bank",old)==1,c)
83 let missing: i64=fio_replace_with_backup("missing-source","replace-live","replace-candidate-3","replace-bank-3",0x180,buf,3,out)
84 gv_check("missing replacement never changes live",missing<0 && out.publication.visible==0 && out.backup.created==0 && frg_equals("replace-live",fresh)==1,c)
85 let pub: *NxFilePublishResult=sys_mmap(__size_of(NxFilePublishResult)) as *NxFilePublishResult
86 let noCandidate: i64=fio_publish_candidate("missing-candidate","replace-live",pub)
87 gv_check("failed rename is not reported visible or durable",noCandidate<0 && pub.visible==0 && pub.durable==0 && frg_equals("replace-live",fresh)==1,c)
88 let rollback: i64=fio_replace_with_backup("replace-bank","replace-live","rollback-candidate","rollback-bank",0x180,buf,3,out)
89 gv_check("rollback uses same operation and preserves both generations",rollback==0 && frg_equals("replace-live",old)==1 && frg_equals("replace-bank",old)==1 && frg_equals("rollback-bank",fresh)==1,c)
90
91 let wanted_new: *u8=sys_mmap(32);let wanted_old: *u8=sys_mmap(32)
92 sha256_digest(fresh,frg_len(fresh),wanted_new);sha256_digest(old,frg_len(old),wanted_old)
93 let absent_identity: i64=fio_replace_verified("replace-source","replace-live","identity-absent","identity-bank-absent",0x180,buf,3,0 as *u8,wanted_old,out)
94 gv_check("verified replacement requires both expected digests",absent_identity==FIO_EINVAL && out.candidate.created==0 && out.publication.visible==0,c)
95 let wrong_new: i64=fio_replace_verified("replace-source","replace-live","identity-bad-new","identity-bank-new",0x180,buf,3,wanted_old,wanted_old,out)
96 gv_check("wrong candidate digest blocks before backup or publication",wrong_new==FIO_EBADMSG && out.backup.created==0 && out.publication.visible==0 && frg_equals("replace-live",old)==1,c)
97 let wrong_old: i64=fio_replace_verified("replace-source","replace-live","identity-bad-old","identity-bank-old",0x180,buf,3,wanted_new,wanted_new,out)
98 gv_check("changed live digest blocks publication and retains history",wrong_old==FIO_EBADMSG && out.backup.durable==1 && out.publication.visible==0 && frg_equals("replace-live",old)==1 && frg_equals("identity-bank-old",old)==1,c)
99 let matched: i64=fio_replace_verified("replace-source","replace-live","identity-matched","identity-bank-matched",0x180,buf,3,wanted_new,wanted_old,out)
100 gv_check("both expected identities permit complete replacement",matched==0 && out.publication.durable==1 && frg_equals("replace-live",fresh)==1 && frg_equals("identity-bank-matched",old)==1,c)
101 sys_munmap(wanted_new,32);sys_munmap(wanted_old,32)
102
103 fio_region_close(held);sys_munmap(held as *u8,__size_of(NxFileReadRegion));sys_munmap(heldbuf,frg_len(old)+1)
104 sys_munmap(pub as *u8,__size_of(NxFilePublishResult));sys_munmap(buf,3);sys_munmap(out as *u8,__size_of(NxFileReplaceResult))
105 return gv_verdict("FIO-REPLACE-GATE",c,"real replacement, retained history, reader continuity and rollback; crash recovery not qualified")
106}
107
108func frg_lock_checks() -> i64 {
109 let c: *i64=gv_ctr()
110 let plan: *i64=gv_plan_new("target-lock-acquired\nheld-target-refuses-before-copy\nindependent-target-admitted\nchild-cannot-acquire-parent-target\nrelease-is-idempotent\nreplacement-after-release\nreplacement-releases-ownership\n")
111 let held: *NxFileTargetLock=sys_mmap(__size_of(NxFileTargetLock)) as *NxFileTargetLock
112 let other: *NxFileTargetLock=sys_mmap(__size_of(NxFileTargetLock)) as *NxFileTargetLock
113 let out: *NxFileReplaceResult=sys_mmap(__size_of(NxFileReplaceResult)) as *NxFileReplaceResult
114 let buf: *u8=sys_mmap(3)
115 fio_target_lock_init(held);fio_target_lock_init(other)
116 if frg_file("locked-live","OLD",3)!=0 || frg_file("locked-source","NEW",3)!=0 { return 3 }
117 let acquired: i64=fio_target_lock_acquire("locked-live",held)
118 gv_plan_check(plan,"target-lock-acquired",acquired==0 && held.fd>=0,c)
119 if acquired!=0 { return gv_verdict("FIO-LOCK-GATE",c,"lock acquisition failed; no contention test launched") }
120 let conflict: i64=fio_replace_with_backup("locked-source","locked-live","locked-candidate","locked-bank",MODE_0600,buf,3,out)
121 gv_plan_check(plan,"held-target-refuses-before-copy",conflict==(0-11) && out.candidate.created==0 && out.backup.created==0 && out.publication.visible==0 && out.lock.fd<0 && frg_equals("locked-live","OLD")==1,c)
122 let independent: i64=fio_target_lock_acquire("independent-live",other)
123 gv_plan_check(plan,"independent-target-admitted",independent==0 && other.fd>=0,c)
124 fio_target_lock_release(other)
125 let pid: i64=sys_fork()
126 if pid==0 {
127 // Close this inherited reference only: LOCK_UN would unlock the parent's
128 // shared open-file-description and invalidate the contention experiment.
129 sys_close(held.fd);held.fd=0-1
130 let child_rc: i64=fio_target_lock_acquire("locked-live",other)
131 fio_target_lock_release(other)
132 if child_rc==(0-11) { sys_exit(0) };sys_exit(1);return 1
133 }
134 var child_ok: i64=0
135 if pid>0 {
136 let status: *i64=sys_mmap(__size_of(i64)) as *i64
137 var waited: i64=sys_wait4(pid,status,0)
138 while waited==FIO_EINTR { waited=sys_wait4(pid,status,0) }
139 child_ok=(waited==pid && wait_term_signal(status[0])==0 && wait_exit_code(status[0])==0) as i64
140 sys_munmap(status as *u8,__size_of(i64))
141 }
142 gv_plan_check(plan,"child-cannot-acquire-parent-target",child_ok,c)
143 let released: i64=fio_target_lock_release(held)
144 gv_plan_check(plan,"release-is-idempotent",released==0 && held.fd<0 && fio_target_lock_release(held)==0,c)
145 let installed: i64=fio_replace_with_backup("locked-source","locked-live","locked-candidate","locked-bank",MODE_0600,buf,3,out)
146 gv_plan_check(plan,"replacement-after-release",installed==0 && out.publication.durable==1 && frg_equals("locked-live","NEW")==1 && frg_equals("locked-bank","OLD")==1,c)
147 let next: i64=fio_target_lock_acquire("locked-live",other)
148 gv_plan_check(plan,"replacement-releases-ownership",out.lock.fd<0 && out.lock.unlock_code==0 && out.lock.close_code==0 && next==0,c)
149 fio_target_lock_release(other);fio_target_lock_release(held)
150 sys_munmap(held as *u8,__size_of(NxFileTargetLock));sys_munmap(other as *u8,__size_of(NxFileTargetLock))
151 sys_munmap(out as *u8,__size_of(NxFileReplaceResult));sys_munmap(buf,3)
152 gv_plan_finish(plan,c)
153 return gv_verdict("FIO-LOCK-GATE",c,"real process contention, independent targets and release; interrupted deployment reconciliation remains separate")
154}
155static frg_root: *u8
156func frg_absolute(name: *u8) -> *u8 {
157 let a: i64=frg_len(frg_root);let b: i64=frg_len(name)
158 let p: *u8=sys_mmap(a+b+2)
159 fi_copy(p,frg_root,a);p[a]=47 as u8;fi_copy(p+a+1,name,b+1);return p
160}
161func frg_install_receipt_checks(parsed: *NxInstallRequest,result: *NxRegisteredInstallResult) -> i64 {
162 let c: *i64=gv_ctr();let plan: *i64=gv_plan_new("measure-before-write\nundersize-preserves-destination\nexact-capacity-preserves-guard\nreceipt-retains-publication-state\nreceipt-escapes-path\nsigned-minimum-exact\n")
163 let writer: *NxInstallReceiptWriter=sys_mmap(__size_of(NxInstallReceiptWriter)) as *NxInstallReceiptWriter
164 let original: *u8=parsed.intent
165 parsed.intent="/fixture/quote\"slash\\line\n"
166 let required: i64=ma_install_receipt_emit(writer,200,0,parsed,result,0 as *u8,0)
167 gv_plan_check(plan,"measure-before-write",required>0 && writer.count==required && writer.code==0,c)
168 let buffer: *u8=sys_mmap(required+1);var i: i64=0
169 while i<=required { buffer[i]=90 as u8;i=i+1 }
170 let short: i64=ma_install_receipt_emit(writer,200,0,parsed,result,buffer,required-1)
171 var untouched: i64=1;i=0
172 while i<=required { if buffer[i]!=(90 as u8) { untouched=0 };i=i+1 }
173 gv_plan_check(plan,"undersize-preserves-destination",short==required && untouched==1,c)
174 let written: i64=ma_install_receipt_emit(writer,200,0,parsed,result,buffer,required)
175 gv_plan_check(plan,"exact-capacity-preserves-guard",written==required && buffer[required]==(90 as u8),c)
176 gv_plan_check(plan,"receipt-retains-publication-state",ma_find(buffer,written,"\"visible\":1")>=0 && ma_find(buffer,written,"\"durable\":1")>=0 && ma_find(buffer,written,"\"serving\":\"not-verified\"")>=0,c)
177 gv_plan_check(plan,"receipt-escapes-path",ma_find(buffer,written,"quote\\\"slash\\\\line\\u000a")>=0,c)
178 hc_puts("NX-INSTALL-RECEIPT ");sys_write(1,buffer,written);hc_puts("\n")
179 writer.bytes=buffer;writer.capacity=required;writer.count=0;writer.code=0
180 let minimum: i64=(0-1)<<(__size_of(i64)*8-1)
181 ma_ir_number(writer,minimum)
182 let expected: *u8="-9223372036854775808"
183 gv_plan_check(plan,"signed-minimum-exact",writer.code==0 && writer.count==fi_len(expected) && fi_same(buffer,expected,fi_len(expected))==1,c)
184 parsed.intent=original
185 sys_munmap(buffer,required+1);sys_munmap(writer as *u8,__size_of(NxInstallReceiptWriter))
186 gv_plan_finish(plan,c)
187 return gv_verdict("INSTALL-RECEIPT-GATE",c,"bounded JSON emission with exact size and signed integers; persistence and transport separate")
188}
189func frg_install_http_request(intent: *u8,digest: *u8) -> *u8 {
190 let head: *u8="POST /api/install HTTP/1.1\r\n\r\ntarget=fixture&intent="
191 let middle: *u8="&expect_intent_sha256=";let tail: *u8="&confirm=yes"
192 let total: i64=fi_len(head)+fi_len(intent)+fi_len(middle)+FI_DIGEST_BYTES*2+fi_len(tail)
193 let req: *u8=sys_mmap(total+1);var o: i64=0
194 fi_copy(req+o,head,fi_len(head));o=o+fi_len(head)
195 fi_copy(req+o,intent,fi_len(intent));o=o+fi_len(intent)
196 fi_copy(req+o,middle,fi_len(middle));o=o+fi_len(middle)
197 let digits: *u8="0123456789abcdef";var i: i64=0
198 while i<FI_DIGEST_BYTES { let value: i64=digest[i] as i64;req[o]=digits[value>>4];req[o+1]=digits[value&15];o=o+2;i=i+1 }
199 fi_copy(req+o,tail,fi_len(tail)+1);return req
200}
201func frg_install_http_checks(intent: *u8,intent_size: i64,intent_hash: *u8,rollback: *u8,rollback_size: i64,rollback_hash: *u8,registry_size: i64,live: *u8) -> i64 {
202 let c: *i64=gv_ctr()
203 let plan: *i64=gv_plan_new("unauthenticated-no-io\nreader-no-write\nmethod-refused\nroute-exact\nduplicate-field-refused\nmalformed-encoding-refused\nrequest-installs-approved-artifact\nrequest-replay-reconciles\nrequest-rolls-back\nrequest-cleanup\n")
204 let parsed: *NxInstallRequest=sys_mmap(__size_of(NxInstallRequest)) as *NxInstallRequest
205 let out: *NxRegisteredInstallResult=sys_mmap(__size_of(NxRegisteredInstallResult)) as *NxRegisteredInstallResult
206 ma_install_request_init(parsed);md_registered_install_init(out)
207 let scratch: *u8=sys_mmap(3);var req: *u8=frg_install_http_request(intent,intent_hash);let n: i64=fi_len(req)
208 let unauth: i64=ma_install_dispatch(req,n,0-1,"absent-registry",registry_size,intent_size,scratch,3,parsed,out)
209 gv_plan_check(plan,"unauthenticated-no-io",unauth==401 && (parsed.bytes as i64)==0 && out.install.replacement.publication.visible==0,c)
210 ma_install_request_close(parsed);md_registered_install_close(out)
211 let reader: i64=ma_install_dispatch(req,n,MA_LVL_READ,"absent-registry",registry_size,intent_size,scratch,3,parsed,out)
212 gv_plan_check(plan,"reader-no-write",reader==403 && (parsed.bytes as i64)==0 && out.install.replacement.publication.visible==0,c)
213 ma_install_request_close(parsed);md_registered_install_close(out)
214 let method: *u8="GET /api/install HTTP/1.1\r\n\r\n"
215 gv_plan_check(plan,"method-refused",ma_install_dispatch(method,fi_len(method),MA_LVL_ACT,"absent-registry",registry_size,intent_size,scratch,3,parsed,out)==405,c)
216 ma_install_request_close(parsed);md_registered_install_close(out)
217 let route: *u8="POST /api/install_extra HTTP/1.1\r\n\r\n"
218 gv_plan_check(plan,"route-exact",ma_install_dispatch(route,fi_len(route),MA_LVL_ACT,"absent-registry",registry_size,intent_size,scratch,3,parsed,out)==404,c)
219 ma_install_request_close(parsed);md_registered_install_close(out)
220 let suffix: *u8="&target=other";let dup: *u8=sys_mmap(n+fi_len(suffix)+1)
221 fi_copy(dup,req,n);fi_copy(dup+n,suffix,fi_len(suffix)+1)
222 let duplicate: i64=ma_install_dispatch(dup,n+fi_len(suffix),MA_LVL_ACT,"registered-install.conf",registry_size,intent_size,scratch,3,parsed,out)
223 gv_plan_check(plan,"duplicate-field-refused",duplicate==400 && (out.target.bytes as i64)==0 && frg_equals(live,"OLD")==1,c)
224 ma_install_request_close(parsed);md_registered_install_close(out);sys_munmap(dup,n+fi_len(suffix)+1)
225 let malformed: *u8="POST /api/install HTTP/1.1\r\n\r\ntarget=%QZ"
226 gv_plan_check(plan,"malformed-encoding-refused",ma_install_dispatch(malformed,fi_len(malformed),MA_LVL_ACT,"registered-install.conf",registry_size,intent_size,scratch,3,parsed,out)==400 && (out.target.bytes as i64)==0,c)
227 ma_install_request_close(parsed);md_registered_install_close(out)
228 let installed: i64=ma_install_dispatch(req,n,MA_LVL_ACT,"registered-install.conf",registry_size,intent_size,scratch,3,parsed,out)
229 gv_plan_check(plan,"request-installs-approved-artifact",installed==200 && out.install.replacement.publication.durable==1 && frg_equals(live,"NEW")==1,c)
230 ma_install_request_close(parsed);md_registered_install_close(out)
231 let replay: i64=ma_install_dispatch(req,n,MA_LVL_ACT,"registered-install.conf",registry_size,intent_size,scratch,3,parsed,out)
232 gv_plan_check(plan,"request-replay-reconciles",replay==200 && out.install.already_published==1,c)
233 ma_install_request_close(parsed);md_registered_install_close(out);sys_munmap(req,n+1)
234 req=frg_install_http_request(rollback,rollback_hash)
235 let restored: i64=ma_install_dispatch(req,fi_len(req),MA_LVL_ACT,"registered-install.conf",registry_size,rollback_size,scratch,3,parsed,out)
236 gv_plan_check(plan,"request-rolls-back",restored==200 && out.install.replacement.publication.durable==1 && frg_equals(live,"OLD")==1,c)
237 if frg_install_receipt_checks(parsed,out)!=0 { return 1 }
238 let closed: i64=ma_install_request_close(parsed);md_registered_install_close(out)
239 gv_plan_check(plan,"request-cleanup",closed==0 && ma_install_request_close(parsed)==0 && (parsed.bytes as i64)==0 && (parsed.digest as i64)==0,c)
240 sys_munmap(req,fi_len(req)+1);sys_munmap(scratch,3)
241 sys_munmap(parsed as *u8,__size_of(NxInstallRequest));sys_munmap(out as *u8,__size_of(NxRegisteredInstallResult))
242 gv_plan_finish(plan,c)
243 return gv_verdict("INSTALL-REQUEST-GATE",c,"actual request bytes and real file operations; supplied session levels, not cryptographic or live HTTP qualification")
244}
245func frg_registered_checks(intent: *u8,intent_size: i64,intent_hash: *u8,rollback: *u8,rollback_size: i64,live: *u8,bank: *u8,rollback_bank: *u8) -> i64 {
246 let plan: *i64=gv_plan_new("approval-required-before-resolution\nmissing-target-never-installs\nwrong-approval-never-installs\nregistered-install-publishes\nregistered-replay-reconciles\nregistered-rollback-preserves-generations\nresult-release-idempotent\n")
247 let c: *i64=gv_ctr()
248 let prefix: *u8="fixture 0 unused.new unused port:0 unused "
249 let suffix: *u8=" fixture\n"
250 let registry_size: i64=fi_len(prefix)+fi_len(live)+fi_len(suffix)
251 let row: *u8=sys_mmap(registry_size)
252 fi_copy(row,prefix,fi_len(prefix));fi_copy(row+fi_len(prefix),live,fi_len(live))
253 fi_copy(row+fi_len(prefix)+fi_len(live),suffix,fi_len(suffix))
254 if frg_file("registered-install.conf",row,registry_size)!=0 { return 3 }
255 sys_munmap(row,registry_size)
256 let out: *NxRegisteredInstallResult=sys_mmap(__size_of(NxRegisteredInstallResult)) as *NxRegisteredInstallResult
257 md_registered_install_init(out)
258 let scratch: *u8=sys_mmap(3)
259 let no_approval: i64=md_install_registered("registered-install.conf",registry_size,"fixture",7,intent,intent_size,0 as *u8,scratch,3,out)
260 gv_plan_check(plan,"approval-required-before-resolution",no_approval==FIO_EINVAL && (out.target.bytes as i64)==0 && out.install.replacement.publication.visible==0,c)
261 md_registered_install_close(out)
262 let absent: i64=md_install_registered("registered-install.conf",registry_size,"missing",7,intent,intent_size,intent_hash,scratch,3,out)
263 gv_plan_check(plan,"missing-target-never-installs",absent==FI_ENOENT && out.target.code==FI_ENOENT && out.install.replacement.lock.fd<0 && out.install.replacement.publication.visible==0,c)
264 md_registered_install_close(out)
265 let wrong: *u8=sys_mmap(FI_DIGEST_BYTES);sha256_digest("incorrect-approval",18,wrong)
266 let bad: i64=md_install_registered("registered-install.conf",registry_size,"fixture",7,intent,intent_size,wrong,scratch,3,out)
267 gv_plan_check(plan,"wrong-approval-never-installs",bad==FIO_EBADMSG && out.target.code==0 && out.install.code==FIO_EBADMSG && out.install.replacement.lock.fd<0 && out.install.replacement.publication.visible==0,c)
268 md_registered_install_close(out);sys_munmap(wrong,FI_DIGEST_BYTES)
269 // Restore only the owned test fixture to its predecessor; the approved source
270 // and retained old bank already exist from the preceding installation cases.
271 if frg_file(live,"OLD",3)!=0 { return 3 }
272 let installed: i64=md_install_registered("registered-install.conf",registry_size,"fixture",7,intent,intent_size,intent_hash,scratch,3,out)
273 gv_plan_check(plan,"registered-install-publishes",installed==0 && out.install.replacement.publication.durable==1 && frg_equals(live,"NEW")==1 && frg_equals(bank,"OLD")==1,c)
274 md_registered_install_close(out)
275 let replay: i64=md_install_registered("registered-install.conf",registry_size,"fixture",7,intent,intent_size,intent_hash,scratch,3,out)
276 gv_plan_check(plan,"registered-replay-reconciles",replay==0 && out.install.already_published==1 && out.install.replacement.publication.durable==1,c)
277 md_registered_install_close(out)
278 let p: *NxFileInstallPlan=sys_mmap(__size_of(NxFileInstallPlan)) as *NxFileInstallPlan
279 fi_plan_init(p);if fi_plan_read(rollback,rollback_size,p)!=0 { return 3 }
280 let rollback_hash: *u8=sys_mmap(FI_DIGEST_BYTES)
281 sha256_digest(p.bytes,p.length,rollback_hash);fi_plan_close(p)
282 sys_munmap(p as *u8,__size_of(NxFileInstallPlan))
283 let restored: i64=md_install_registered("registered-install.conf",registry_size,"fixture",7,rollback,rollback_size,rollback_hash,scratch,3,out)
284 gv_plan_check(plan,"registered-rollback-preserves-generations",restored==0 && out.install.replacement.publication.durable==1 && frg_equals(live,"OLD")==1 && frg_equals(bank,"OLD")==1 && frg_equals(rollback_bank,"NEW")==1,c)
285 let released: i64=md_registered_install_close(out)
286 gv_plan_check(plan,"result-release-idempotent",released==0 && md_registered_install_close(out)==0 && (out.target.live as i64)==0 && out.install.replacement.lock.fd<0,c)
287 if frg_install_http_checks(intent,intent_size,intent_hash,rollback,rollback_size,rollback_hash,registry_size,live)!=0 { return 1 }
288 sys_munmap(rollback_hash,FI_DIGEST_BYTES);sys_munmap(scratch,3)
289 sys_munmap(out as *u8,__size_of(NxRegisteredInstallResult));gv_plan_finish(plan,c)
290 return gv_verdict("REGISTERED-INSTALL-GATE",c,"registered target through bound installation and rollback; HTTP authorization and service restart separate")
291}
292func frg_install_checks() -> i64 {
293 let c: *i64=gv_ctr()
294 let plan: *i64=gv_plan_new("intent-exclusive-durable\nintent-reopens-recorded-identities\nintent-rejects-path-alias\nrecord-budget-enforced\nintent-corruption-refused\nrestart-after-preparation\nreplay-observes-published-without-recopy\nchanged-live-refuses-without-overwrite\ncorrupt-backup-preserves-visible-observation\nrollback-from-durable-intent\ncontroller-reconciles-intent\ncontroller-rejects-invalid-admission\ncontroller-rejects-malformed-decimal\ncontroller-installs-recorded-artifact\ncontroller-restores-recorded-history\nbinding-required-before-io\nwrong-intent-identity-refused\nwrong-authorized-target-refused\nmatched-binding-installs\nbound-replay-reconciles\n")
295 let source: *u8=frg_absolute("install-source");let live: *u8=frg_absolute("install-live")
296 let candidate: *u8=frg_absolute("install-candidate");let bank: *u8=frg_absolute("install-bank")
297 let intent: *u8=frg_absolute("install-intent")
298 let dhnew: *u8=sys_mmap(FI_DIGEST_BYTES);let dhold: *u8=sys_mmap(FI_DIGEST_BYTES)
299 sha256_digest("NEW",3,dhnew);sha256_digest("OLD",3,dhold)
300 let record_size: i64=FI_HEADER_BYTES+FI_DIGEST_BYTES+frg_len(source)+frg_len(live)+frg_len(candidate)+frg_len(bank)+FI_PATH_FIELDS
301 let w: *NxFileWriteResult=sys_mmap(__size_of(NxFileWriteResult)) as *NxFileWriteResult
302 let p: *NxFileInstallPlan=sys_mmap(__size_of(NxFileInstallPlan)) as *NxFileInstallPlan
303 fi_plan_init(p)
304 let made: i64=fi_plan_create(intent,source,live,candidate,bank,MODE_0600,dhnew,dhold,record_size,w)
305 let durable: i64=(made==0 && w.written==record_size) as i64
306 let duplicate: i64=fi_plan_create(intent,source,live,candidate,bank,MODE_0600,dhnew,dhold,record_size,w)
307 gv_plan_check(plan,"intent-exclusive-durable",durable==1 && duplicate==FIO_EEXIST,c)
308 let read: i64=fi_plan_read(intent,record_size,p)
309 gv_plan_check(plan,"intent-reopens-recorded-identities",read==0 && p.length==record_size && fi_same(p.expected_new,dhnew,FI_DIGEST_BYTES)==1 && fi_same(p.expected_old,dhold,FI_DIGEST_BYTES)==1 && fi_same(p.live,live,frg_len(live)+1)==1,c)
310 fi_plan_close(p)
311 gv_plan_check(plan,"intent-rejects-path-alias",fi_plan_create("invalid-intent",source,live,live,bank,MODE_0600,dhnew,dhold,record_size,w)==FIO_EINVAL,c)
312 gv_plan_check(plan,"record-budget-enforced",fi_plan_read(intent,record_size-1,p)==FIO_EINVAL && (p.bytes as i64)==0,c)
313 if fi_plan_read(intent,record_size,p)!=0 { return 3 }
314 p.bytes[FI_MAGIC_BYTES]=p.bytes[FI_MAGIC_BYTES] ^ (1 as u8)
315 if frg_file("install-corrupted-intent",p.bytes,p.length)!=0 { return 3 }
316 fi_plan_close(p)
317 gv_plan_check(plan,"intent-corruption-refused",fi_plan_read("install-corrupted-intent",record_size,p)==FIO_EBADMSG && (p.bytes as i64)==0,c)
318 if frg_file(source,"NEW",3)!=0 || frg_file(live,"OLD",3)!=0 { return 3 }
319 let buf: *u8=sys_mmap(3)
320 let child: i64=sys_fork()
321 if child==0 {
322 let prepared: *NxFilePrepareResult=sys_mmap(__size_of(NxFilePrepareResult)) as *NxFilePrepareResult
323 if fio_prepare_copy(source,candidate,MODE_0600,buf,3,prepared)!=0 { sys_exit(1) }
324 if fio_prepare_copy(live,bank,MODE_0600,buf,3,prepared)!=0 { sys_exit(1) }
325 // Exit before publication, discarding all process-local transaction state.
326 sys_exit(0);return 1
327 }
328 var child_ok: i64=0
329 if child>0 {
330 let status: *i64=sys_mmap(__size_of(i64)) as *i64
331 var waited: i64=sys_wait4(child,status,0)
332 while waited==FIO_EINTR { waited=sys_wait4(child,status,0) }
333 child_ok=(waited==child && wait_exit_code(status[0])==0 && wait_term_signal(status[0])==0) as i64
334 sys_munmap(status as *u8,__size_of(i64))
335 }
336 let out: *NxFileInstallResult=sys_mmap(__size_of(NxFileInstallResult)) as *NxFileInstallResult
337 let installed: i64=fi_install(intent,record_size,buf,3,out)
338 gv_plan_check(plan,"restart-after-preparation",child_ok==1 && installed==0 && out.replacement.publication.durable==1 && frg_equals(live,"NEW")==1 && frg_equals(bank,"OLD")==1,c)
339 if frg_file(source,"CHANGED SOURCE",14)!=0 { return 3 }
340 let replay: i64=fi_install(intent,record_size,buf,3,out)
341 gv_plan_check(plan,"replay-observes-published-without-recopy",replay==0 && out.already_published==1 && out.replacement.publication.durable==1 && frg_equals(live,"NEW")==1,c)
342 if frg_file(live,"OTHER",5)!=0 { return 3 }
343 let conflict: i64=fi_install(intent,record_size,buf,3,out)
344 gv_plan_check(plan,"changed-live-refuses-without-overwrite",conflict==FIO_EBADMSG && out.replacement.publication.visible==0 && frg_equals(live,"OTHER")==1 && frg_equals(bank,"OLD")==1,c)
345 if frg_file(live,"NEW",3)!=0 || frg_file(bank,"BAD",3)!=0 { return 3 }
346 let corrupt: i64=fi_install(intent,record_size,buf,3,out)
347 gv_plan_check(plan,"corrupt-backup-preserves-visible-observation",corrupt==FIO_EBADMSG && out.already_published==1 && out.replacement.publication.visible==1 && out.replacement.publication.durable==0 && frg_equals(bank,"BAD")==1,c)
348 if frg_file(bank,"OLD",3)!=0 { return 3 }
349 let rollback: *u8=frg_absolute("install-rollback-intent")
350 let rollback_candidate: *u8=frg_absolute("install-rollback-candidate")
351 let rollback_bank: *u8=frg_absolute("install-rollback-bank")
352 let rollback_size: i64=FI_HEADER_BYTES+FI_DIGEST_BYTES+frg_len(bank)+frg_len(live)+frg_len(rollback_candidate)+frg_len(rollback_bank)+FI_PATH_FIELDS
353 let stored: i64=fi_plan_create(rollback,bank,live,rollback_candidate,rollback_bank,MODE_0600,dhold,dhnew,rollback_size,w)
354 let restored: i64=fi_install(rollback,rollback_size,buf,3,out)
355 gv_plan_check(plan,"rollback-from-durable-intent",stored==0 && restored==0 && frg_equals(live,"OLD")==1 && frg_equals(bank,"OLD")==1 && frg_equals(rollback_bank,"NEW")==1,c)
356 gv_plan_check(plan,"controller-reconciles-intent",cmd_install_record(rollback,rollback_size,3)==0 && frg_equals(live,"OLD")==1,c)
357 gv_plan_check(plan,"controller-rejects-invalid-admission",cmd_install_record(intent,0,3)==2 && frg_equals(live,"OLD")==1,c)
358 gv_plan_check(plan,"controller-rejects-malformed-decimal",hc_install_allowance("9223372036854775808")==(0-1) && hc_install_allowance("563x")==(0-1) && hc_install_allowance("3")==3,c)
359 if frg_file(source,"NEW",3)!=0 { return 3 }
360 gv_plan_check(plan,"controller-installs-recorded-artifact",cmd_install_record(intent,record_size,3)==0 && frg_equals(live,"NEW")==1 && frg_equals(bank,"OLD")==1,c)
361 gv_plan_check(plan,"controller-restores-recorded-history",cmd_install_record(rollback,rollback_size,3)==0 && frg_equals(live,"OLD")==1 && frg_equals(rollback_bank,"NEW")==1,c)
362
363 let intent_hash: *u8=sys_mmap(FI_DIGEST_BYTES)
364 if fi_plan_read(intent,record_size,p)!=0 { return 3 }
365 sha256_digest(p.bytes,p.length,intent_hash);fi_plan_close(p)
366 let unbound: i64=fi_install_bound(intent,record_size,buf,3,live,0 as *u8,out)
367 gv_plan_check(plan,"binding-required-before-io",unbound==FIO_EINVAL && out.replacement.publication.visible==0 && out.replacement.lock.fd<0,c)
368 let wrong_intent: i64=fi_install_bound(intent,record_size,buf,3,live,dhnew,out)
369 gv_plan_check(plan,"wrong-intent-identity-refused",wrong_intent==FIO_EBADMSG && out.replacement.lock.fd<0 && out.replacement.candidate.created==0 && frg_equals(live,"OLD")==1,c)
370 let wrong_target: i64=fi_install_bound(intent,record_size,buf,3,source,intent_hash,out)
371 gv_plan_check(plan,"wrong-authorized-target-refused",wrong_target==FI_EACCES && out.replacement.lock.fd<0 && out.replacement.candidate.created==0 && frg_equals(live,"OLD")==1,c)
372 let bound: i64=fi_install_bound(intent,record_size,buf,3,live,intent_hash,out)
373 gv_plan_check(plan,"matched-binding-installs",bound==0 && out.replacement.publication.durable==1 && frg_equals(live,"NEW")==1 && frg_equals(bank,"OLD")==1,c)
374 let rebound: i64=fi_install_bound(intent,record_size,buf,3,live,intent_hash,out)
375 gv_plan_check(plan,"bound-replay-reconciles",rebound==0 && out.already_published==1 && out.replacement.publication.durable==1,c)
376 if frg_registered_checks(intent,record_size,intent_hash,rollback,rollback_size,live,bank,rollback_bank)!=0 { return 1 }
377 sys_munmap(intent_hash,FI_DIGEST_BYTES)
378 fi_plan_close(p)
379 sys_munmap(p as *u8,__size_of(NxFileInstallPlan));sys_munmap(w as *u8,__size_of(NxFileWriteResult))
380 sys_munmap(out as *u8,__size_of(NxFileInstallResult));sys_munmap(buf,3)
381 sys_munmap(dhnew,FI_DIGEST_BYTES);sys_munmap(dhold,FI_DIGEST_BYTES)
382 sys_munmap(source,frg_len(source)+1);sys_munmap(live,frg_len(live)+1)
383 sys_munmap(candidate,frg_len(candidate)+1);sys_munmap(bank,frg_len(bank)+1);sys_munmap(intent,frg_len(intent)+1)
384 sys_munmap(rollback,frg_len(rollback)+1);sys_munmap(rollback_candidate,frg_len(rollback_candidate)+1);sys_munmap(rollback_bank,frg_len(rollback_bank)+1)
385 gv_plan_finish(plan,c)
386 return gv_verdict("FIO-INSTALL-GATE",c,"durable intent and process restart reconciliation; no hardware power-cut or serving-health claim")
387}
388func frg_target_checks() -> i64 {
389 let cases: *u8="exact-owned-record\ncaller-storage-independent\nmissing-target-no-fallback\nduplicate-target-rejected\nlegacy-target-needs-live-binding\nextra-column-rejected\nnoncanonical-live-rejected\ncontrol-byte-rejected\nwhitespace-and-final-line\nlong-live-path-preserved\nfile-reader-owns-row\nfile-budget-refuses-without-record\nfile-absence-retains-cause\nclose-idempotent\n"
390 let plan: *i64=gv_plan_new(cases);let c: *i64=gv_ctr()
391 let r: *NxDeployTargetRecord=sys_mmap(__size_of(NxDeployTargetRecord)) as *NxDeployTargetRecord
392 md_target_init(r)
393 let row: *u8="beach 0 beach.new deploy port:8443 rollback /estate/beach beach"
394 let n: i64=frg_len(row);let snapshot: *u8=sys_mmap(n)
395 fi_copy(snapshot,row,n)
396 let resolved: i64=md_target_decode(snapshot,n,"beach",5,r)
397 gv_plan_check(plan,"exact-owned-record",resolved==0 && r.allocation==n+1 && fi_same(r.live,"/estate/beach",frg_len("/estate/beach")+1)==1 && r.line==1,c)
398 snapshot[0]=88 as u8
399 gv_plan_check(plan,"caller-storage-independent",resolved==0 && r.name[0]==(98 as u8),c)
400 md_target_close(r);sys_munmap(snapshot,n)
401 let missing: i64=md_target_decode(row,n,"sites",5,r)
402 gv_plan_check(plan,"missing-target-no-fallback",missing==FI_ENOENT && (r.bytes as i64)==0,c)
403 md_target_close(r)
404 let dup: *u8="beach 0 a b c d /one p\nbeach 0 a b c d /two p\n"
405 let ambiguous: i64=md_target_decode(dup,frg_len(dup),"beach",5,r)
406 gv_plan_check(plan,"duplicate-target-rejected",ambiguous==FIO_EEXIST && r.line==1 && r.conflicting_line==2 && (r.live as i64)==0,c)
407 md_target_close(r)
408 let legacy: *u8="beach 0 a b c d"
409 gv_plan_check(plan,"legacy-target-needs-live-binding",md_target_decode(legacy,frg_len(legacy),"beach",5,r)==FIO_EBADMSG && (r.live as i64)==0,c)
410 md_target_close(r)
411 let extra: *u8="beach 0 a b c d /one p unexpected"
412 gv_plan_check(plan,"extra-column-rejected",md_target_decode(extra,frg_len(extra),"beach",5,r)==FIO_EBADMSG && (r.bytes as i64)==0,c)
413 md_target_close(r)
414 let alias: *u8="beach 0 a b c d /estate/../other p"
415 gv_plan_check(plan,"noncanonical-live-rejected",md_target_decode(alias,frg_len(alias),"beach",5,r)==FIO_EBADMSG && (r.live as i64)==0,c)
416 md_target_close(r)
417 let corrupt: *u8=sys_mmap(n);fi_copy(corrupt,row,n);corrupt[n-1]=0 as u8
418 gv_plan_check(plan,"control-byte-rejected",md_target_decode(corrupt,n,"beach",5,r)==FIO_EBADMSG && (r.bytes as i64)==0,c)
419 md_target_close(r);sys_munmap(corrupt,n)
420 let spaced: *u8=" # comment\r\n\tbeach\t0 a b c d /one p \r"
421 let whitespace: i64=md_target_decode(spaced,frg_len(spaced),"beach",5,r)
422 gv_plan_check(plan,"whitespace-and-final-line",whitespace==0 && r.line==2 && fi_same(r.live,"/one",5)==1,c)
423 md_target_close(r)
424 // Regression at one byte beyond the legacy resolver's 512-byte destination.
425 let old_capacity: i64=512;let path_length: i64=old_capacity+1
426 let prefix: *u8="beach 0 a b c d ";let suffix: *u8=" p"
427 let long_n: i64=frg_len(prefix)+path_length+frg_len(suffix)
428 let long_row: *u8=sys_mmap(long_n)
429 fi_copy(long_row,prefix,frg_len(prefix));let path: *u8=long_row+frg_len(prefix)
430 path[0]=47 as u8;var i: i64=1
431 while i<path_length { path[i]=97 as u8;i=i+1 }
432 fi_copy(path+path_length,suffix,frg_len(suffix))
433 let long_rc: i64=md_target_decode(long_row,long_n,"beach",5,r)
434 gv_plan_check(plan,"long-live-path-preserved",long_rc==0 && fi_len(r.live)==path_length && fi_same(r.live,path,path_length)==1,c)
435 sys_munmap(long_row,long_n)
436 md_target_close(r)
437let real: *u8="target-registry"
438 if frg_file(real,row,n)!=0 { return 3 }
439 let file_rc: i64=md_target_read(real,n,"beach",5,r)
440 gv_plan_check(plan,"file-reader-owns-row",file_rc==0 && fi_same(r.live,"/estate/beach",13)==1,c)
441 md_target_close(r)
442 gv_plan_check(plan,"file-budget-refuses-without-record",md_target_read(real,n-1,"beach",5,r)==FIO_EINVAL && (r.bytes as i64)==0,c)
443 md_target_close(r)
444 gv_plan_check(plan,"file-absence-retains-cause",md_target_read("absent-target-registry",n,"beach",5,r)==FI_ENOENT && (r.bytes as i64)==0,c)
445 md_target_close(r)
446 let closed: i64=md_target_close(r)
447 gv_plan_check(plan,"close-idempotent",closed==0 && md_target_close(r)==0 && (r.bytes as i64)==0 && (r.live as i64)==0,c)
448 sys_munmap(r as *u8,__size_of(NxDeployTargetRecord))
449 gv_plan_finish(plan,c)
450 return gv_verdict("DEPLOY-TARGET-GATE",c,"owned snapshot selection and binding data; authenticated execution and parent-path ownership separate")
451}
452func frg_live_target_checks(path: *u8,budget: i64) -> i64 {
453 let plan: *i64=gv_plan_new("sites-binding\nmanagement-binding\ncontroller-binding\n")
454 let c: *i64=gv_ctr()
455 let r: *NxDeployTargetRecord=sys_mmap(__size_of(NxDeployTargetRecord)) as *NxDeployTargetRecord
456 md_target_init(r)
457 let sites: *u8="/volume1/homes/elderwesto/nishihost/sites.elf"
458 let mgmt: *u8="/volume1/homes/elderwesto/nishihost/nx_mgmt_api.elf"
459 let host: *u8="/volume1/homes/elderwesto/nishihost/nx_hostctl"
460 let a: i64=md_target_read(path,budget,"sites",5,r)
461 gv_plan_check(plan,"sites-binding",a==0 && fi_same(r.live,sites,fi_len(sites)+1)==1,c);md_target_close(r)
462 let b: i64=md_target_read(path,budget,"mgmtapi",7,r)
463 gv_plan_check(plan,"management-binding",b==0 && fi_same(r.live,mgmt,fi_len(mgmt)+1)==1,c);md_target_close(r)
464 let d: i64=md_target_read(path,budget,"hostctl",7,r)
465 gv_plan_check(plan,"controller-binding",d==0 && fi_same(r.live,host,fi_len(host)+1)==1,c);md_target_close(r)
466 sys_munmap(r as *u8,__size_of(NxDeployTargetRecord));gv_plan_finish(plan,c)
467 return gv_verdict("DEPLOY-LIVE-REGISTRY-GATE",c,"read-only current registry bindings; no activation or authorization claim")
468}
469func frg_arbiter_checks() -> i64 {
470 let c: *i64=gv_ctr()
471 let plan: *i64=gv_plan_new("invalid-capacity-no-allocation\nconstructor-covers-last-field\nnegative-budget-refused\nnegative-request-clears-output\nlarge-budget-share-no-overflow\nlarge-valid-grant\nreleased-slot-reused\nshare-rounding-cannot-overgrant\nnull-request-clears-output\npartial-grant-preserved\n")
472 let rejected: *NxResourceArbiter=nx_ra_new(NX_RA_SIZE_MAX)
473 gv_plan_check(plan,"invalid-capacity-no-allocation",(rejected as i64)==0 && (nx_ra_new(0) as i64)==0,c)
474 let a: *NxResourceArbiter=nx_ra_new(1)
475 if (a as i64)==0 { return 3 }
476 let last_end: i64=((&a.preemptions as *nx_int) as i64)-(a as i64)+__size_of(nx_int)
477 gv_plan_check(plan,"constructor-covers-last-field",NX_RA_BYTES>=last_end && a.capacity==1 && a.n_allocations==0,c)
478 let kind: nx_int=NX_RA_KIND_RAM_BYTES
479 gv_plan_check(plan,"negative-budget-refused",nx_ra_set_budget(a,kind,0-1)==NX_RA_V_INVALID && nx_ra_get_budget(a,kind)==0,c)
480 let granted: *i64=sys_mmap(__size_of(i64));granted[0]=1
481 gv_plan_check(plan,"negative-request-clears-output",nx_ra_request(a,1,kind,0-1,0,0,granted,0)==NX_RA_V_INVALID && granted[0]==0,c)
482 nx_ra_set_budget(a,kind,NX_RA_SIZE_MAX);nx_ra_set_max_share(a,kind,NX_RA_Q10_ONE/2)
483 let half: nx_size=NX_RA_SIZE_MAX/2
484 let denied: nx_int=nx_ra_request(a,1,kind,half+1,0,0,granted,0)
485 gv_plan_check(plan,"large-budget-share-no-overflow",denied==NX_RA_V_DENIED_MAX_SHARE && granted[0]==0 && nx_ra_total_held(a,kind)==0,c)
486 let allowed: nx_int=nx_ra_request(a,1,kind,half,0,0,granted,0)
487 gv_plan_check(plan,"large-valid-grant",allowed==NX_RA_V_GRANTED_FULL && granted[0]==half && nx_ra_total_held(a,kind)==half,c)
488 let released: nx_size=nx_ra_release(a,1,kind)
489 let again: nx_int=nx_ra_request(a,2,kind,half,0,0,granted,0)
490 gv_plan_check(plan,"released-slot-reused",released==half && again==NX_RA_V_GRANTED_FULL && a.n_allocations==1 && nx_ra_held_by_cell(a,1,kind)==0 && nx_ra_held_by_cell(a,2,kind)==half,c)
491 nx_ra_release(a,2,kind)
492 nx_ra_set_budget(a,kind,NX_RA_Q10_ONE+1);nx_ra_set_max_share(a,kind,1)
493 gv_plan_check(plan,"share-rounding-cannot-overgrant",nx_ra_request(a,1,kind,2,0,0,granted,0)==NX_RA_V_DENIED_MAX_SHARE && granted[0]==0,c)
494 granted[0]=1
495 gv_plan_check(plan,"null-request-clears-output",nx_ra_request(0 as *NxResourceArbiter,1,kind,1,0,0,granted,0)==NX_RA_V_NULL && granted[0]==0,c)
496 sys_munmap(a.allocations,a.capacity*NX_RA_A_BYTES);sys_munmap(a.budgets,NX_RA_KIND_N*__size_of(nx_size));sys_munmap(a.max_share_q10,NX_RA_KIND_N*__size_of(nx_int));sys_munmap(a as *u8,NX_RA_BYTES)
497 let b: *NxResourceArbiter=nx_ra_new(2);if (b as i64)==0 { return 3 }
498 let unit: nx_size=__size_of(NxAllocation)
499 nx_ra_set_budget(b,kind,unit*3);nx_ra_set_max_share(b,kind,NX_RA_Q10_ONE)
500 let first: nx_int=nx_ra_request(b,1,kind,unit*2,0,0,granted,0)
501 let second: nx_int=nx_ra_request(b,2,kind,unit*2,0,0,granted,0)
502 gv_plan_check(plan,"partial-grant-preserved",first==NX_RA_V_GRANTED_FULL && second==NX_RA_V_GRANTED_PARTIAL && granted[0]==unit && nx_ra_total_held(b,kind)==unit*3,c)
503 nx_ra_release(b,1,kind);nx_ra_release(b,2,kind)
504 sys_munmap(b.allocations,b.capacity*NX_RA_A_BYTES);sys_munmap(b.budgets,NX_RA_KIND_N*__size_of(nx_size));sys_munmap(b.max_share_q10,NX_RA_KIND_N*__size_of(nx_int));sys_munmap(b as *u8,NX_RA_BYTES)
505 sys_munmap(granted as *u8,__size_of(i64));gv_plan_finish(plan,c)
506 return gv_verdict("RESOURCE-ARBITER-GATE",c,"single-owner accounting, layout and arithmetic; no cross-process ownership or physical reclamation claim")
507}
508func main(argc: i64,argv: *i64) -> i64 {
509 if argc==4 {
510 if fi_len(argv[1] as *u8)!=8 || fi_same(argv[1] as *u8,"registry",8)==0 { return 2 }
511 return frg_live_target_checks(argv[2] as *u8,hc_install_allowance(argv[3] as *u8))
512 }
513 if argc!=2 { return 2 }
514 if sys_mkdir(argv[1] as *u8,0x1c0)!=0 { return 2 }
515 if sys_chdir(argv[1] as *u8)!=0 { return 2 }
516 frg_root=sys_mmap(SYS_PATH_MAX)
517 if sys_getcwd(frg_root,SYS_PATH_MAX)<=0 { return 3 }
518 if fi_path_valid(frg_root)==0 { return 3 }
519 if frg_arbiter_checks()!=0 { return 1 }
520 if frg_prepare_checks()!=0 { return 1 }
521 if frg_replace_checks()!=0 { return 1 }
522 if frg_lock_checks()!=0 { return 1 }
523 if frg_install_checks()!=0 { return 1 }
524 if frg_target_checks()!=0 { return 1 }
525 let count: *i64=gv_ctr();frg_plan=gv_plan_new(FRG_CASES)
526 let text: *u8="abcdefghijklmnopqrstuvwxyz";let size: i64=frg_len(text)
527 if frg_file("data",text,size)!=0 { return 3 }
528 let r: *NxFileReadRegion=sys_mmap(__size_of(NxFileReadRegion)) as *NxFileReadRegion
529 fio_region_init(r)
530 let opened: i64=fio_region_open("data",r)
531 frg_check("real-file-open-size",((opened==0)&&(r.total==size)&&(r.read_bytes==0)) as i64,count)
532 frg_check("range-selection",(fio_region_select(r,4,4)==0) as i64,count)
533 let buf: *u8=sys_mmap(size+1);buf[2]=77 as u8
534 let first: i64=fio_region_next(r,buf,2)
535 frg_check("bounded-first-read",((first==2)&&(buf[0]==(101 as u8))&&(buf[1]==(102 as u8))&&(buf[2]==(77 as u8))&&(r.read_bytes==2)&&(r.fd>=0)) as i64,count)
536 let final: i64=fio_region_next(r,buf,size)
537 frg_check("bounded-final-read-closes",((final==2)&&(buf[0]==(103 as u8))&&(buf[1]==(104 as u8))&&(r.read_bytes==4)&&(r.fd<0)&&(r.close_code==0)) as i64,count)
538 frg_check("closed-read-is-eof",(fio_region_next(r,buf,size)==0) as i64,count)
539 frg_check("idempotent-close",((fio_region_close(r)==0)&&(fio_region_close(r)==0)) as i64,count)
540 fio_region_open("data",r)
541 let oldfd: i64=r.fd
542 let invalid: i64=fio_region_select(r,size,1)
543 frg_check("invalid-range-retains-session",((invalid==FIO_EINVAL)&&(r.fd==oldfd)&&(r.start==0)&&(r.length==size)&&(r.read_bytes==0)) as i64,count)
544 frg_check("invalid-buffer-retains-session",((fio_region_next(r,buf,0)==FIO_EINVAL)&&(r.fd==oldfd)&&(r.read_bytes==0)) as i64,count)
545 var seen: i64=0;var correct: i64=1
546 while seen<size {
547 let n: i64=fio_region_next(r,buf,3)
548 if n<=0 { correct=0;break }
549 var i: i64=0;while i<n { if buf[i]!=text[seen+i] { correct=0 };i=i+1 };seen=seen+n
550 }
551 frg_check("full-file-stream-by-caller-capacity",((correct==1)&&(seen==size)&&(r.read_bytes==size)&&(r.fd<0)) as i64,count)
552 let missing: i64=fio_region_open("absent",r)
553 frg_check("missing-file-cause",((missing<0)&&(r.code==missing)&&(r.fd<0)) as i64,count)
554 fio_region_open("data",r)
555 if frg_file("data","abc",3)!=0 { return 3 }
556 let early: i64=fio_region_next(r,buf,size)
557 frg_check("premature-eof-counts-and-closes",((early==FIO_EIO)&&(r.read_bytes==3)&&(r.last_read==3)&&(r.fd<0)&&(r.close_code==0)) as i64,count)
558 if frg_file("data",text,size)!=0 { return 3 }
559 fio_region_open("data",r)
560 if sys_renameat("data","old-data")!=0 { return 3 }
561 if frg_file("data","NEW",3)!=0 { return 3 }
562 let kept: i64=fio_region_next(r,buf,size)
563 var same: i64=(kept==size) as i64;var j: i64=0;while j<kept { if buf[j]!=text[j] { same=0 };j=j+1 }
564 frg_check("pathname-replacement-retains-open-file",same,count)
565 let fd: i64=sys_openat_wr("sparse",0x180)
566 let offset: i64=1<<31
567 if sys_lseek(fd,offset,0)!=offset { sys_close(fd);return 3 }
568 if sys_write(fd,"NXANIM01",8)!=8 { sys_close(fd);return 3 };sys_close(fd)
569 fio_region_open("sparse",r)
570 let selected: i64=fio_region_select(r,offset,8)
571 let got: i64=fio_region_next(r,buf,size)
572 let expected: *u8="NXANIM01";var matches: i64=1;j=0;while j<8 { if buf[j]!=expected[j] { matches=0 };j=j+1 }
573 frg_check("sparse-offset-beyond-signed32",((selected==0)&&(got==8)&&(r.total==offset+8)&&(r.read_bytes==8)&&(matches==1)&&(r.fd<0)) as i64,count)
574 fio_region_close(r);sys_munmap(r as *u8,__size_of(NxFileReadRegion));sys_munmap(buf,size+1)
575 gv_plan_finish(frg_plan,count)
576 sys_munmap(frg_root,SYS_PATH_MAX)
577 return gv_verdict("FIO-REGION-GATE",count,"real files, bounded reads and ownership; HTTP integration separate")
578}