soulsync/tests/metadata/test_cache_maintenance_retry.py
Broque Thomas b9af4ef4ef Handle transient SQLite IO during maintenance
Keep full refresh moving when post-clear VACUUM hits a transient disk I/O error, and retry clear_server_data once when the clear step itself sees the same transient SQLite failure.

Retry metadata cache maintenance writes once on transient disk I/O errors so first-attempt cache jobs do not fail when an immediate retry would succeed.

Tests cover best-effort VACUUM, clear retry behavior, and cache maintenance retry behavior.
2026-05-21 17:50:30 -07:00

44 lines
1.2 KiB
Python

import sqlite3
from types import SimpleNamespace
import core.metadata.cache as cache_module
from core.metadata.cache import MetadataCache
def test_maintenance_write_retries_once_after_disk_io(monkeypatch):
cache = MetadataCache()
attempts = []
class _Conn:
def close(self):
pass
monkeypatch.setattr(cache, "_get_db", lambda: SimpleNamespace(_get_connection=lambda: _Conn()))
monkeypatch.setattr(cache_module.time, "sleep", lambda _seconds: None)
def _operation(_conn):
attempts.append(1)
if len(attempts) == 1:
raise sqlite3.OperationalError("disk I/O error")
return 9
assert cache._run_maintenance_write("Cache eviction", _operation) == 9
assert len(attempts) == 2
def test_maintenance_write_does_not_retry_non_io_errors(monkeypatch):
cache = MetadataCache()
attempts = []
class _Conn:
def close(self):
pass
monkeypatch.setattr(cache, "_get_db", lambda: SimpleNamespace(_get_connection=lambda: _Conn()))
def _operation(_conn):
attempts.append(1)
raise sqlite3.OperationalError("syntax error")
assert cache._run_maintenance_write("Cache eviction", _operation) == 0
assert len(attempts) == 1