# -*- coding: utf-8 -*- import os from services.cache import MaterialCache, _extract_cache_key def test_cache_lock_acquire_release(tmp_path): cache = MaterialCache(cache_dir=str(tmp_path), enabled=True, max_size_gb=0) cache_key = _extract_cache_key("https://example.com/path/file.mp4?token=abc") lock_path = cache._acquire_lock(cache_key) assert lock_path assert os.path.exists(lock_path) cache._release_lock(lock_path) assert not os.path.exists(lock_path) def test_get_or_download_cache_hit_does_not_wait_lock(tmp_path, monkeypatch): cache = MaterialCache(cache_dir=str(tmp_path), enabled=True, max_size_gb=0) url = "https://example.com/path/video.mp4?token=abc" cache_path = cache.get_cache_path(url) with open(cache_path, 'wb') as file_obj: file_obj.write(b'cached-data') destination = tmp_path / "result.bin" def _unexpected_acquire(*args, **kwargs): raise AssertionError("cache hit path should not acquire lock") monkeypatch.setattr(cache, "_acquire_lock", _unexpected_acquire) assert cache.get_or_download(url, str(destination), timeout=1) is True assert destination.read_bytes() == b'cached-data' def test_get_or_download_lock_timeout_can_still_use_ready_cache(tmp_path, monkeypatch): cache = MaterialCache(cache_dir=str(tmp_path), enabled=True, max_size_gb=0) url = "https://example.com/path/audio.aac?token=abc" cache_path = cache.get_cache_path(url) with open(cache_path, 'wb') as file_obj: file_obj.write(b'audio-cache') destination = tmp_path / "audio.aac" download_called = {"value": False} monkeypatch.setattr(cache, "_acquire_lock", lambda *args, **kwargs: None) def _fake_download(*args, **kwargs): download_called["value"] = True return False monkeypatch.setattr("services.cache.storage.download_file", _fake_download) assert cache.get_or_download(url, str(destination), timeout=1) is True assert destination.read_bytes() == b'audio-cache' assert download_called["value"] is False def test_get_or_download_uses_short_lock_timeout(tmp_path, monkeypatch): cache = MaterialCache(cache_dir=str(tmp_path), enabled=True, max_size_gb=0) url = "https://example.com/path/segment.ts?token=abc" destination = tmp_path / "segment.ts" captured = {"timeout_sec": None} def _fake_acquire(cache_key, timeout_sec=None): captured["timeout_sec"] = timeout_sec return None monkeypatch.setattr(cache, "_acquire_lock", _fake_acquire) monkeypatch.setattr("services.cache.storage.download_file", lambda *args, **kwargs: True) assert cache.get_or_download(url, str(destination), timeout=1) is True assert captured["timeout_sec"] == cache.DOWNLOAD_LOCK_TIMEOUT_SEC def test_get_or_download_with_metrics_cache_hit_wait_zero(tmp_path): cache = MaterialCache(cache_dir=str(tmp_path), enabled=True, max_size_gb=0) url = "https://example.com/path/hit.mp4?token=abc" cache_path = cache.get_cache_path(url) with open(cache_path, 'wb') as file_obj: file_obj.write(b'hit-data') destination = tmp_path / "hit.mp4" success, metrics = cache.get_or_download_with_metrics(url, str(destination), timeout=1) assert success is True assert metrics["lock_wait_ms"] == 0 assert metrics["lock_acquired"] is False assert metrics["cache_path_used"] == "cache" def test_get_or_download_with_metrics_reports_lock_wait_ms(tmp_path, monkeypatch): cache = MaterialCache(cache_dir=str(tmp_path), enabled=True, max_size_gb=0) url = "https://example.com/path/miss.mp4?token=abc" destination = tmp_path / "miss.mp4" monkeypatch.setattr(cache, "_acquire_lock_with_wait", lambda *args, **kwargs: (None, 4321)) monkeypatch.setattr("services.cache.storage.download_file", lambda *args, **kwargs: True) success, metrics = cache.get_or_download_with_metrics(url, str(destination), timeout=1) assert success is True assert metrics["lock_wait_ms"] == 4321 assert metrics["lock_acquired"] is False assert metrics["cache_path_used"] == "direct"