"""Absolute native budgets/source pins; no actual-v2 positive admission claim.""" from datetime import datetime,timedelta,timezone from pathlib import Path import signal import sys import threading import time from types import SimpleNamespace import pytest sys.path.insert(0,str(Path(__file__).resolve().parents[1]/'scripts')) from test_task_execution_native_fixture import owner,bao_dev,compiler from task_execution_native_fixture import NativeFixtureAdapter,_absolute_budget from task_execution_journal import Refused def test_absolute_budget_interrupts_source_work_and_restores_timer(): before=signal.getitimer(signal.ITIMER_REAL) started=time.monotonic() with pytest.raises(Refused): with _absolute_budget(.03):time.sleep(.5) assert time.monotonic()-started<.3 assert signal.getitimer(signal.ITIMER_REAL)==before def test_nested_budget_cannot_refresh_outer_deadline(): started=time.monotonic() with pytest.raises(Refused): with _absolute_budget(.05): time.sleep(.02) with _absolute_budget(1):time.sleep(.5) assert time.monotonic()-started<.3 def test_absolute_budget_rejects_foreign_threads(): refused=[] def run(): try: with _absolute_budget(1):pass except Refused:refused.append(True) worker=threading.Thread(target=run);worker.start();worker.join(2) assert refused==[True] def test_slow_compiler_is_interrupted_before_native_effect(): native=object.__new__(NativeFixtureAdapter) native.deadline=datetime.now(timezone.utc)+timedelta(seconds=5.05) native.monotonic_deadline=time.monotonic()+5.05 native.binding='synthetic';native.plan=None;native.task=object();native._next_metadata=0 native.journal=SimpleNamespace(_held=True,_admission='synthetic',_consumed_admission='synthetic',observe=lambda binding:{'state':'applying'}) native.compiler=SimpleNamespace(pins=[],before_call=lambda *args:time.sleep(.5)) sent=[];native._business=lambda *args,**kwargs:sent.append(True) with pytest.raises(Refused):native.metadata_call(0) assert sent==[] @pytest.mark.parametrize('phase',['headers','body','body-and-slow-close']) def test_absolute_transport_budget_interrupts_drip(phase,monkeypatch): from http.server import BaseHTTPRequestHandler,ThreadingHTTPServer class Drip(BaseHTTPRequestHandler): def log_message(self,*args):pass def do_GET(self): if phase=='headers': try: for value in b'HTTP/1.1 200 OK\r\nX-Drip: '+b' '*1000: self.connection.sendall(bytes([value]));time.sleep(.05) except (BrokenPipeError,ConnectionResetError):pass return self.send_response(200);self.send_header('Content-Type','application/json');self.send_header('Content-Length','1000');self.end_headers() try: for _ in range(1000): self.wfile.write(b' ');self.wfile.flush();time.sleep(.05) except (BrokenPipeError,ConnectionResetError):pass server=ThreadingHTTPServer(('127.0.0.1',0),Drip) server.daemon_threads=True thread=threading.Thread(target=server.serve_forever,daemon=True);thread.start() native=object.__new__(NativeFixtureAdapter);native.host='127.0.0.1';native.port=server.server_port native.admission=SimpleNamespace(server_process=SimpleNamespace(poll=lambda:None)) if phase=='body-and-slow-close': import http.client original_close=http.client.HTTPConnection.close def slow_close(connection): original_close(connection);time.sleep(5) monkeypatch.setattr(http.client.HTTPConnection,'close',slow_close) start=time.monotonic() try: with pytest.raises(Refused):native._http('GET','drip','synthetic') assert time.monotonic()-start<2.6 finally:server.shutdown();server.server_close();thread.join(2) def test_cleanup_remains_independent_but_absolute_after_business_expiry(owner,monkeypatch): from test_task_execution_native_fixture import admit from task_execution_cleanup import run_cleanup native,journal,binding,call,*_=owner with journal.locked(): admit(native,journal,binding);native.materialize_grant() original=native._http def stalled(method,path,token,body=b''): if path=='auth/token/revoke-self' and token==native.task.token:time.sleep(5) return original(method,path,token,body) monkeypatch.setattr(native,'_http',stalled) native.monotonic_deadline=time.monotonic()-1 native._task_monotonic_deadline=time.monotonic()-1 started=time.monotonic();result=run_cleanup(journal,binding,native) assert time.monotonic()-started<3 assert not result['confirmed'] assert [x['outcome'] for x in result['obligations']]==['unconfirmed','confirmed','confirmed'] assert journal.observe(binding)['external_outcome_unknown'] # Explicit independent synthetic owner recovery, never adapter retry. assert call('POST','auth/token/revoke-accessor',{'accessor':native.task.accessor})[0] in {200,204} def test_absolute_budget_invalid_input_and_conflicting_timer_refuse(): original_handler=signal.getsignal(signal.SIGALRM) original_timer=signal.getitimer(signal.ITIMER_REAL) for value in [True,None,0,-1,float('nan'),float('inf')]: with pytest.raises(Refused): with _absolute_budget(value):pass assert signal.getsignal(signal.SIGALRM)==original_handler assert signal.getitimer(signal.ITIMER_REAL)==original_timer try: signal.signal(signal.SIGALRM,lambda *args:None) signal.setitimer(signal.ITIMER_REAL,1) with pytest.raises(Refused): with _absolute_budget(.1):pass assert signal.getitimer(signal.ITIMER_REAL)[0]>0 finally: signal.setitimer(signal.ITIMER_REAL,0) signal.signal(signal.SIGALRM,original_handler) def test_actual_credential_bound_interrupts_before_later_global_deadline(): native=object.__new__(NativeFixtureAdapter) native.deadline=datetime.now(timezone.utc)+timedelta(minutes=10) native.monotonic_deadline=time.monotonic()+600 native._task_wall_deadline=datetime.now(timezone.utc)+timedelta(seconds=5.05) native._task_monotonic_deadline=time.monotonic()+5.05 native.binding='synthetic';native.plan=None;native.task=object();native._next_metadata=0 native.journal=SimpleNamespace(_held=True,_admission='synthetic',_consumed_admission='synthetic',observe=lambda binding:{'state':'applying'}) native.compiler=SimpleNamespace(pins=[],before_call=lambda *args:time.sleep(.5)) sent=[];native._business=lambda *args,**kwargs:sent.append(True) started=time.monotonic() with pytest.raises(Refused):native.metadata_call(0) assert time.monotonic()-started<.3 and sent==[] @pytest.mark.parametrize('case',['valid','drift','writable','symlink','fifo','oversize']) def test_exact_owner_source_bundle_is_bounded_and_fails_closed(tmp_path,case): import hashlib import os from task_execution_mediator import _source_bundle source=tmp_path/'owner-source.py';source.write_bytes(b'# independently installed source\n');source.chmod(0o600) roles=['engine_dispatcher','platform_mediator','typed_ccr','policy_auth'] item={'path':str(source),'sha256':'sha256:'+hashlib.sha256(source.read_bytes()).hexdigest()} descriptor={'source_bundle':{role:dict(item) for role in roles}} if case=='valid':_source_bundle(descriptor);return if case=='drift':source.write_bytes(b'# drift\n') elif case=='writable':source.chmod(0o666) elif case=='symlink': target=tmp_path/'target.py';source.rename(target);source.symlink_to(target) elif case=='fifo':source.unlink();os.mkfifo(source,0o600) elif case=='oversize':source.write_bytes(b'X'*1048577) started=time.monotonic() with pytest.raises(Refused):_source_bundle(descriptor) assert time.monotonic()-started<.5