approval-engine/tests/test_cas.py

71 lines
2 KiB
Python
Raw Normal View History

import tempfile
import threading
from pathlib import Path
from approval_engine.errors import Conflict
from approval_engine.store import Engine
from tests.conftest import approve
def test_second_supersession_loses(engine):
obj = approve(engine)
first = engine.supersede(obj.id)
assert engine.get(obj.id).status == "superseded"
assert first["successor_id"]
try:
engine.supersede(obj.id)
raise AssertionError("second supersession must conflict")
except Conflict:
pass
claim = engine.claim(obj.id)
assert claim["valid_now"] is False
assert claim["reason_code"] == "superseded"
def test_concurrent_supersessions_one_winner():
with tempfile.TemporaryDirectory() as tmp:
path = Path(tmp) / "a.sqlite"
setup = Engine(path)
obj = approve(setup)
setup.close()
winners: list[str] = []
errors: list[str] = []
barrier = threading.Barrier(2)
def race():
eng = Engine(path)
barrier.wait()
try:
result = eng.supersede(obj.id)
winners.append(result["successor_id"])
except Conflict as exc:
errors.append(str(exc))
finally:
eng.close()
threads = [threading.Thread(target=race) for _ in range(2)]
for t in threads:
t.start()
for t in threads:
t.join()
assert len(winners) == 1
assert len(errors) == 1
check = Engine(path)
assert check.get(obj.id).status == "superseded"
check.close()
def test_internal_consume_cas_once(engine):
obj = approve(engine)
engine._cas_consume(obj.id)
try:
engine._cas_consume(obj.id)
raise AssertionError("double consume must conflict")
except Conflict:
pass
claim = engine.claim(obj.id)
assert claim["consumed"] is True
assert claim["valid_now"] is False
assert claim["reason_code"] == "consumed"