Files
dcalc/backend/tests/unit/test_gold_refresh.py
T
2026-11-03 21:44:30 +08:00

100 lines
3.0 KiB
Python

import asyncio
from api.utils import gold_refresh, thirdpart_gold
def test_both_periodic_jobs_run_without_requests_and_stop_cleanly(monkeypatch):
async def run():
calls = [0, 0]
ready = [asyncio.Event(), asyncio.Event()]
async def realtime():
calls[0] += 1
if calls[0] >= 2:
ready[0].set()
async def official():
calls[1] += 1
if calls[1] >= 2:
ready[1].set()
monkeypatch.setattr(gold_refresh, 'refresh_realtime', realtime)
monkeypatch.setattr(gold_refresh, 'refresh_official', official)
monkeypatch.setattr(gold_refresh, 'CHECK_INTERVAL_SECONDS', .01)
try:
await gold_refresh.start_periodic_refresh()
await gold_refresh.start_periodic_refresh()
assert len(gold_refresh._periodic_tasks) == 2
await asyncio.wait_for(asyncio.gather(*(event.wait() for event in ready)), 1)
finally:
await gold_refresh.stop_periodic_refresh()
assert not gold_refresh._periodic_tasks
snapshot = list(calls)
await asyncio.sleep(.02)
assert calls == snapshot
asyncio.run(run())
def test_periodic_job_survives_transient_failure(monkeypatch):
async def run():
calls = []
ready = asyncio.Event()
async def job():
calls.append(1)
if len(calls) == 1:
raise ConnectionError('Redis unavailable')
ready.set()
monkeypatch.setattr(gold_refresh, 'CHECK_INTERVAL_SECONDS', .01)
task = asyncio.create_task(gold_refresh._periodic(job))
try:
await asyncio.wait_for(ready.wait(), 1)
assert len(calls) >= 2
finally:
task.cancel()
await asyncio.gather(task, return_exceptions=True)
asyncio.run(run())
def test_realtime_can_launch_without_request_background_tasks(monkeypatch):
class Redis:
async def get(self, key):
return None
async def set(self, *args, **kwargs):
return True
launched = []
async def launch(token):
launched.append(token)
monkeypatch.setattr(thirdpart_gold, 'launch_refresh', launch)
assert asyncio.run(thirdpart_gold.schedule_refresh(Redis(), None, [])) is True
assert len(launched) == 1
def test_application_lifecycle_starts_and_stops_refresh_jobs(monkeypatch):
import main
calls = []
def callback(name):
async def call():
calls.append(name)
return call
monkeypatch.setattr(main, 'start_periodic_refresh', callback('start'))
monkeypatch.setattr(main, 'stop_periodic_refresh', callback('stop'))
monkeypatch.setattr(main, 'close_refresh_tasks', callback('refresh_closed'))
monkeypatch.setattr(main, 'close_connection_pools', callback('pools_closed'))
async def run():
async with main.lifespan(main.application):
assert calls == ['start']
asyncio.run(run())
assert calls == ['start', 'stop', 'refresh_closed', 'pools_closed']