"""Self-check for the concurrent dealgod.supply() batcher. No network — fake httpx client. Run: .venv/bin/python test_dealgod_supply.py""" import asyncio import app.dealgod as dg SEEN = [] # batches the fake client received class _Resp: status_code = 200 def __init__(self, ids): self.ids = ids def json(self): return {"results": {str(i): {"n": 1} for i in self.ids}} class _FakeClient: def __init__(self, *a, **k): pass async def __aenter__(self): return self async def __aexit__(self, *a): return False async def post(self, url, json=None): ids = json["ids"] SEEN.append(list(ids)) if -1 in ids: # poison sentinel → simulate a failing batch raise RuntimeError("simulated batch failure") return _Resp(ids) async def _fake_key(db): return "fake-key" def test_supply(): orig_client, orig_key = dg.httpx.AsyncClient, dg._key dg.httpx.AsyncClient, dg._key = _FakeClient, _fake_key try: # 450 ids → 3 batches (200/200/50), all results merged SEEN.clear() res = asyncio.run(dg.supply(None, list(range(450)))) assert len(SEEN) == 3, SEEN assert sorted(len(b) for b in SEEN) == [50, 200, 200] assert len(res) == 450 and res["0"] == {"n": 1} and res["449"] == {"n": 1} # empty ids → {} with zero calls SEEN.clear() assert asyncio.run(dg.supply(None, [])) == {} and SEEN == [] # ONE failing batch among several is dropped; the others still merge (isolation) SEEN.clear() ids2 = list(range(200)) + [-1] + list(range(201, 250)) # batch 2 holds the poison res2 = asyncio.run(dg.supply(None, ids2)) assert len(SEEN) == 2 assert len(res2) == 200 and "0" in res2 and "201" not in res2 print("ok — concurrent batching, merge, empty-guard, degrade-isolation all pass") finally: dg.httpx.AsyncClient, dg._key = orig_client, orig_key if __name__ == "__main__": test_supply()