swayfx-mosaic/tooling/probes/step20c-optimized-blur-cache/test-budget.py

36 lines
1.7 KiB
Python

"""Offline exhaustion, corruption, cross-LAB refusal and lock contention."""
import json,multiprocessing,tempfile
from pathlib import Path
from budget import reserve
def denied(call):
try:call()
except (ValueError,RuntimeError):return
raise AssertionError('accepted invalid reservation')
with tempfile.TemporaryDirectory() as tmp:
p=Path(tmp)/'budget.json'
denied(lambda:reserve(tmp,'C2','capture',p))
for mode in ('C0','C1','C2'):
reserve(tmp,mode,'run',p)
denied(lambda:reserve(tmp,mode,'run',p))
for _ in range(4):reserve(tmp,mode,'mutation',p)
denied(lambda:reserve(tmp,mode,'mutation',p))
for _ in range(20):reserve(tmp,mode,'capture',p)
denied(lambda:reserve(tmp,mode,'capture',p))
if mode!='C0':reserve(tmp,mode,'cycle',p)
denied(lambda:reserve(tmp,mode,'cycle',p))
reserve(tmp,'C2','camera_pair',p);denied(lambda:reserve(tmp,'C2','camera_pair',p))
reserve(tmp,'C2','calibration',p);denied(lambda:reserve(tmp,'C2','calibration',p))
denied(lambda:reserve(tmp+'new','C0','run',p))
s=json.loads(p.read_text());assert sum(v['capture'] for v in s['modes'].values())==60
p.write_text('');denied(lambda:reserve(tmp,'C0','run',p))
print('PASS exhaustion, no refunds/reset, cross-LAB protection, corruption')
def contender(root,q):
try:reserve(root,'C0','run',Path(root)/'lock-test.json');q.put('accepted')
except RuntimeError:q.put('denied')
with tempfile.TemporaryDirectory() as tmp:
ctx=multiprocessing.get_context('fork');q=ctx.Queue();ps=[ctx.Process(target=contender,args=(tmp,q)) for _ in range(2)]
for p in ps:p.start()
for p in ps:p.join(5);assert p.exitcode==0
assert sorted(q.get(timeout=1) for p in ps)==['accepted','denied']
print('PASS concurrent reservation')