code wiki / _hdl_build / nx_job_reservation_gate_t182.nx
nx_job_reservation_gate_t182.nx source
↩ module page · 43 lines · 3518 B
1import "nx_jobclaim_candidate_t182.nx"
2import "nx_gate_verdict.nx"
3import "nx_tool_exec_allow.nx"
4func main()->i64{
5 let c:*i64=gv_ctr();gv_head("Shared exclusive job reservation")
6 let dir:*u8=sys_mmap(JR_PATH);var d:i64=jr_cat(dir,0,"/tmp/nishi-job-reserve-t182-");d=jr_catnum(dir,d,sys_now_ms());dir[d]=0
7 if sys_mkdir(dir,MODE_0755)!=0{return 3}
8 let p:*u8=sys_mmap(JR_PATH);let line:*u8=sys_mmap(JR_LINE);let info:*i64=sys_mmap(32) as *i64
9 let base:i64=sys_now_realtime_sec();var i:i64=0
10 while i<180{
11 jr_mkpath(p,JR_PATH,dir,base+i,JR_EXT_CLAIM)
12 let fd:i64=sys_openat_exclusive(p,MODE_0644);if fd<0{return 3}
13 let mark:*u8="state=CLAIMED owner=fixture\n";let n:i64=jr_slen(mark)
14 if sys_write(fd,mark,n)!=n{return 3};sys_close(fd);i=i+1
15 }
16 let budget:i64=tea_reply_reserve_ms()
17 let start:i64=sys_now_ms()
18 let id:i64=jr_reserve(dir,base,start+budget,p,JR_PATH,line,JR_LINE,info)
19 gv_check("passes more than legacy100 occupied IDs",id==base+180,c)
20 gv_check("records exact collision count and ownership",info[0]==id && info[1]==181 && info[2]==180,c)
21 let sz:*i64=sys_mmap(16) as *i64;let b:*u8=sys_read_file(p,sz)
22 gv_check("returned identity has CLAIMED marker",jr_state_of(b,sz[0])==JR_ST_CLAIMED,c)
23 let next:i64=jr_reserve(dir,base,sys_now_ms()+budget,p,JR_PATH,line,JR_LINE,info)
24 gv_check("next reservation cannot reuse owned ID",next==id+1,c)
25 jr_mkpath(p,JR_PATH,dir,base+99,JR_EXT_CLAIM);let old:*u8=sys_read_file(p,sz)
26 gv_check("existing owner remains unchanged",jr_has(old,sz[0],"owner=fixture")==1,c)
27 let bad:*u8=sys_mmap(JR_PATH);let bn:i64=jr_cat(bad,jr_cat(bad,0,dir),"/missing");bad[bn]=0
28 gv_check("missing directory errno immediate without advancing",jr_reserve(bad,base,sys_now_ms()+budget,p,JR_PATH,line,JR_LINE,info)==(0-2) && info[1]==1 && info[0]==0,c)
29 gv_check("expired budget does not create claim",jr_reserve(dir,base,sys_now_ms(),p,JR_PATH,line,JR_LINE,info)==JR_ERR_DEADLINE && info[1]==0 && info[0]==0,c)
30 gv_check("small path buffer refuses before open",jr_reserve(dir,base,sys_now_ms()+budget,p,1,line,JR_LINE,info)==JR_ERR_PATH && info[1]==0,c)
31 gv_check("invalid ID refuses before open",jr_reserve(dir,0,sys_now_ms()+budget,p,JR_PATH,line,JR_LINE,info)==JR_ERR_INVALID && info[1]==0,c)
32 let orphan:i64=base+1000
33 jr_mkpath(p,JR_PATH,dir,orphan,JR_EXT_OUT);let ofd:i64=sys_openat_exclusive(p,MODE_0644);if ofd<0{return 3};sys_write(ofd,"retained",8);sys_close(ofd)
34 jr_mkpath(p,JR_PATH,dir,orphan+1,".tmp");let tfd:i64=sys_openat_exclusive(p,MODE_0644);if tfd<0{return 3};sys_close(tfd)
35 jr_mkpath(p,JR_PATH,dir,orphan+2,JR_EXT_OUT);if sys_symlinkat("/nonexistent-nishi-fixture-target",p)!=0{return 3}
36 gv_check("orphan output temp and dangling symlink remain occupied",jr_reserve(dir,orphan,sys_now_ms()+budget,p,JR_PATH,line,JR_LINE,info)==orphan+3 && info[3]==3,c)
37 jr_mkpath(p,JR_PATH,dir,orphan,JR_EXT_OUT);let ob:*u8=sys_read_file(p,sz)
38 gv_check("orphan output content preserved",sz[0]==8 && jr_has(ob,sz[0],"retained")==1,c)
39 jr_mkpath(p,JR_PATH,dir,JR_ID_MAX,JR_EXT_CLAIM);let maxfd:i64=sys_openat_exclusive(p,MODE_0644);if maxfd<0{return 3};sys_close(maxfd)
40 gv_check("occupied maximal ID refuses overflow",jr_reserve(dir,JR_ID_MAX,sys_now_ms()+budget,p,JR_PATH,line,JR_LINE,info)==JR_ERR_OVERFLOW && info[2]==1 && info[0]==0,c)
41 gv_puts("elapsed_ms=");gv_num(sys_now_ms()-start);gv_puts(" configured_reply_budget_ms=");gv_num(budget);gv_puts("\n")
42 return gv_verdict("job-reservation-shared",c,"Isolated real filesystem; no live tools daemon deployment")
43}