code wiki / (root) / nx_budget_alloc_test.nx

nx_budget_alloc_test.nx source

↩ module page · 129 lines · 5693 B

1// nx_budget_alloc_test.nx -- smoke for sovereign ceiling enforcement. 2// 3// Exercises: 4// 1. Allocations within budget succeed; ram_used increments correctly 5// 2. Allocation that WOULD exceed ceiling returns NULL; ram_used 6// unchanged (refusal BEFORE sys_mmap) 7// 3. Verdict-returning variant distinguishes OVER vs BAD_KIND vs OK 8// 4. release_logical decrements ram_used; subsequent allocations 9// succeed up to fresh headroom 10// 5. Multiple kinds enforce independently (RAM ceiling does not 11// block VRAM allocation and vice versa) 12// 6. Bad-input gates: null budget, zero size, negative size 13// 7. Sealed-enum verdict gate 14// 8. headroom() reflects state across allocations + releases 15// 16// Pure substrate: no /sys/fs/cgroup, no kernel cgroups, no Linux- 17// only assumptions. Same code path runs on every host. 18 19import "nx_syscalls.nx" 20import "nx_budget.nx" 21import "nx_budget_alloc.nx" 22 23func main() -> i64 { 24 // Budget: ram_max=1024, vram_max=2048, others=0 (won't allow 25 // any allocation of those kinds). 26 let b: *NxBudget = nx_budget_new(42, 1024, 2048, 0, 0, 0) 27 28 // ----- 1. Within-budget allocations succeed ----- 29 let p1: *u8 = nx_budget_mmap(b, NX_RES_RAM, 512) 30 if (p1 as i64) == 0 { return 1 } 31 if b.ram_used != 512 { return 2 } 32 if nx_budget_alloc_remaining(b, NX_RES_RAM) != 512 { return 3 } 33 34 let p2: *u8 = nx_budget_mmap(b, NX_RES_RAM, 256) 35 if (p2 as i64) == 0 { return 4 } 36 if b.ram_used != 768 { return 5 } 37 if nx_budget_alloc_remaining(b, NX_RES_RAM) != 256 { return 6 } 38 39 // ----- 2. Over-budget allocation refused; state unchanged ----- 40 // 512 more would put us at 1280, exceeding ram_max=1024. 41 let p_over: *u8 = nx_budget_mmap(b, NX_RES_RAM, 512) 42 if (p_over as i64) != 0 { return 7 } // NULL = refused 43 if b.ram_used != 768 { return 8 } // unchanged 44 if nx_budget_alloc_remaining(b, NX_RES_RAM) != 256 { return 9 } 45 46 // Even +1 more byte over the headroom is refused. 47 let p_over_tiny: *u8 = nx_budget_mmap(b, NX_RES_RAM, 257) 48 if (p_over_tiny as i64) != 0 { return 10 } 49 if b.ram_used != 768 { return 11 } 50 51 // ----- 3. Verdict-returning variant distinguishes failure modes ----- 52 let verdict_slot: *i64 = (sys_mmap(8)) as *i64 53 *verdict_slot = -99 54 55 // Over-budget -> NX_BUDGET_ALLOC_OVER 56 let v_over: *u8 = nx_budget_mmap_with_verdict(b, NX_RES_RAM, 512, verdict_slot) 57 if (v_over as i64) != 0 { return 12 } 58 if *verdict_slot != NX_BUDGET_ALLOC_OVER { return 13 } 59 if b.ram_used != 768 { return 14 } 60 61 // OK case 62 let v_ok: *u8 = nx_budget_mmap_with_verdict(b, NX_RES_RAM, 100, verdict_slot) 63 if (v_ok as i64) == 0 { return 15 } 64 if *verdict_slot != NX_BUDGET_ALLOC_OK { return 16 } 65 if b.ram_used != 868 { return 17 } 66 67 // Bad-kind verdict 68 let v_bad: *u8 = nx_budget_mmap_with_verdict(b, 99, 64, verdict_slot) 69 if (v_bad as i64) != 0 { return 18 } 70 if *verdict_slot != NX_BUDGET_ALLOC_BAD_KIND { return 19 } 71 72 // Bad-input verdict 73 let null_b: *NxBudget = (0 as i64) as *NxBudget 74 let v_nb: *u8 = nx_budget_mmap_with_verdict(null_b, NX_RES_RAM, 64, verdict_slot) 75 if (v_nb as i64) != 0 { return 20 } 76 if *verdict_slot != NX_BUDGET_ALLOC_BAD_INPUT { return 21 } 77 78 // Zero-size 79 let v_zero: *u8 = nx_budget_mmap_with_verdict(b, NX_RES_RAM, 0, verdict_slot) 80 if (v_zero as i64) != 0 { return 22 } 81 if *verdict_slot != NX_BUDGET_ALLOC_BAD_INPUT { return 23 } 82 83 // ----- 4. release_logical decrements ram_used ----- 84 if nx_budget_release_logical(b, NX_RES_RAM, 256) != NX_BUDGET_OK { return 24 } 85 if b.ram_used != 612 { return 25 } // 868 - 256 86 87 // Now an allocation that was previously over-budget succeeds. 88 let p_after_release: *u8 = nx_budget_mmap(b, NX_RES_RAM, 400) 89 if (p_after_release as i64) == 0 { return 26 } 90 if b.ram_used != 1012 { return 27 } 91 92 // ----- 5. Multiple kinds independent ----- 93 // RAM is at 1012/1024 (12 headroom). VRAM is at 0/2048. 94 // VRAM allocation independent of RAM state. 95 let p_vram: *u8 = nx_budget_mmap(b, NX_RES_VRAM, 1024) 96 if (p_vram as i64) == 0 { return 28 } 97 if b.vram_used != 1024 { return 29 } 98 if b.ram_used != 1012 { return 30 } // unchanged 99 100 // Disk has max=0; ANY allocation refused. 101 let p_disk: *u8 = nx_budget_mmap(b, NX_RES_DISK, 1) 102 if (p_disk as i64) != 0 { return 31 } 103 if b.disk_used != 0 { return 32 } 104 105 // ----- 6. Bad-input gates (silent mode) ----- 106 if (nx_budget_mmap(null_b, NX_RES_RAM, 64) as i64) != 0 { return 33 } 107 if (nx_budget_mmap(b, NX_RES_RAM, 0) as i64) != 0 { return 34 } 108 if (nx_budget_mmap(b, NX_RES_RAM, -1) as i64) != 0 { return 35 } 109 // Bad kind silent-mode 110 if (nx_budget_mmap(b, 99, 64) as i64) != 0 { return 36 } 111 if (nx_budget_mmap(b, -1, 64) as i64) != 0 { return 37 } 112 // State invariants preserved. 113 if b.ram_used != 1012 { return 38 } 114 if b.vram_used != 1024 { return 39 } 115 116 // ----- 7. Sealed-enum verdict gate ----- 117 if nx_budget_alloc_verdict_is_valid(NX_BUDGET_ALLOC_OK) != 1 { return 40 } 118 if nx_budget_alloc_verdict_is_valid(NX_BUDGET_ALLOC_OVER) != 1 { return 41 } 119 if nx_budget_alloc_verdict_is_valid(-1) != 0 { return 42 } 120 if nx_budget_alloc_verdict_is_valid(NX_BUDGET_ALLOC_N) != 0 { return 43 } 121 122 // ----- 8. headroom reflects state ----- 123 if nx_budget_alloc_remaining(b, NX_RES_RAM) != 12 { return 44 } // 1024 - 1012 124 if nx_budget_alloc_remaining(b, NX_RES_VRAM) != 1024 { return 45 } // 2048 - 1024 125 if nx_budget_alloc_remaining(b, NX_RES_DISK) != 0 { return 46 } 126 if nx_budget_alloc_remaining(null_b, NX_RES_RAM) != 0 { return 47 } 127 128 return 0 129}