Files
qwenpaw/tests/unit/providers/test_model_capability_cache.py
agent-radar 1a3a4ccde1
Creator App Tests / PR Spam Gate (push) Skipped
Frontend Tests / PR Spam Gate (push) Skipped
NPM Format (website & console) / PR Spam Gate (push) Skipped
Pre-commit Checks / PR Spam Gate (push) Skipped
QwenPaw Creator Plugin Release / check-version (push) Canceled after 0s
QwenPaw Creator Plugin Release / upload-oss (push) Canceled after 0s
Tests / PR Spam Gate (push) Skipped
CodeQL / CodeQL (python) (push) Canceled after 0s
CodeQL / CodeQL (typescript) (push) Canceled after 0s
Creator App Tests / Creator Backend Tests (push) Canceled after 0s
Creator App Tests / Creator UI Build & Tests (push) Canceled after 0s
E2E Smoke Tests / Playwright UI Smoke (push) Canceled after 0s
Frontend Tests / Detect console changes (push) Canceled after 0s
NPM Format (website & console) / website format check (push) Canceled after 0s
NPM Format (website & console) / console format check (push) Canceled after 0s
Pre-commit Checks / Pre-commit (push) Canceled after 0s
QwenPaw Data Plugin Release / check-version (push) Canceled after 0s
Tests / Detect code changes (push) Canceled after 0s
Frontend Tests / Vitest Unit Tests (push) Canceled after 0s
Frontend Tests / Frontend Summary (push) Canceled after 0s
QwenPaw Data Plugin Release / upload-oss (push) Canceled after 0s
Tests / Maintainer Approval (push) Canceled after 0s
Tests / Unit Tests - py3.11 - macos-latest (push) Canceled after 0s
Tests / Unit Tests - py3.11 - ubuntu-latest (push) Canceled after 0s
Tests / Unit Tests - py3.13 - ubuntu-latest (push) Canceled after 0s
Tests / Unit Tests - py3.11 - windows-latest (push) Canceled after 0s
Tests / Contract Tests - py3.11 - macos-latest (push) Canceled after 0s
Tests / Contract Tests - py3.11 - ubuntu-latest (push) Canceled after 0s
Tests / Contract Tests - py3.13 - ubuntu-latest (push) Canceled after 0s
Tests / Contract Tests - py3.11 - windows-latest (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - macos-latest - p0 (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - macos-latest - p1 (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - macos-latest - p2 (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - ubuntu-latest - fallback (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - ubuntu-latest - p0 (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - ubuntu-latest - p1 (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - ubuntu-latest - p2 (push) Canceled after 0s
Tests / Integrated Tests - py3.13 - ubuntu-latest - p0 (push) Canceled after 0s
Tests / Integrated Tests - py3.13 - ubuntu-latest - p1 (push) Canceled after 0s
Tests / Integrated Tests - py3.13 - ubuntu-latest - p2 (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - windows-latest - p0 (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - windows-latest - p1 (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - windows-latest - p2 (push) Canceled after 0s
Tests / Coverage Report (push) Canceled after 0s
Tests / Test Summary (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:01:50 +08:00

117 lines
3.8 KiB
Python

# -*- coding: utf-8 -*-
# pylint: disable=protected-access,redefined-outer-name
from __future__ import annotations
import time
from unittest import mock
import pytest
from qwenpaw.providers.model_capability_cache import ModelCapabilityCache
_TTL = "qwenpaw.providers.model_capability_cache.CAPABILITY_CACHE_TTL_SECONDS"
@pytest.fixture()
def cache() -> ModelCapabilityCache:
return ModelCapabilityCache()
def test_learn_and_get_roundtrip(cache: ModelCapabilityCache) -> None:
cache.learn("p:m", "rejects_media", True)
assert cache.get("p:m", "rejects_media", False) is True
def test_get_returns_default_when_unlearned(
cache: ModelCapabilityCache,
) -> None:
assert cache.get("p:m", "rejects_media", False) is False
assert cache.get("p:m", "rejects_media") is None
def test_clear_all(cache: ModelCapabilityCache) -> None:
cache.learn("p:m", "rejects_media", True)
cache.clear()
assert cache.get("p:m", "rejects_media", False) is False
def test_clear_single_model_key(cache: ModelCapabilityCache) -> None:
cache.learn("a:m", "rejects_media", True)
cache.learn("b:n", "rejects_media", True)
cache.clear("a:m")
assert cache.get("a:m", "rejects_media", False) is False
assert cache.get("b:n", "rejects_media", False) is True
def test_forget_drops_single_capability(cache: ModelCapabilityCache) -> None:
cache.learn("p:m", "rejects_media", True)
cache.learn("p:m", "needs_reasoning_content", True)
cache.forget("p:m", "rejects_media")
assert cache.get("p:m", "rejects_media", False) is False
assert cache.get("p:m", "needs_reasoning_content", False) is True
def test_forget_preserves_other_models(cache: ModelCapabilityCache) -> None:
cache.learn("a:m", "rejects_media", True)
cache.learn("b:n", "rejects_media", True)
cache.forget("a:m", "rejects_media")
assert cache.get("a:m", "rejects_media", False) is False
assert cache.get("b:n", "rejects_media", False) is True
def test_forget_unknown_key_is_noop(cache: ModelCapabilityCache) -> None:
cache.forget("nonexistent", "rejects_media")
cache.learn("p:m", "rejects_media", True)
cache.forget("p:m", "needs_reasoning_content")
assert cache.get("p:m", "rejects_media", False) is True
def test_relearn_same_value_refreshes_timestamp(
cache: ModelCapabilityCache,
) -> None:
with mock.patch(
"qwenpaw.providers.model_capability_cache.time.monotonic",
side_effect=[100.0, 200.0],
):
cache.learn("p:m", "rejects_media", True)
set_at_before = cache._learned["p:m"]["rejects_media"].set_at
cache.learn("p:m", "rejects_media", True)
set_at_after = cache._learned["p:m"]["rejects_media"].set_at
assert set_at_after > set_at_before
assert cache._learned["p:m"]["rejects_media"].value is True
def test_relearn_different_value_overwrites(
cache: ModelCapabilityCache,
) -> None:
cache.learn("p:m", "rejects_media", True)
cache.learn("p:m", "rejects_media", False)
assert cache.get("p:m", "rejects_media") is False
def test_expired_entry_returns_default(
cache: ModelCapabilityCache,
) -> None:
with mock.patch(_TTL, 0.05):
cache.learn("p:m", "rejects_media", True)
assert cache.get("p:m", "rejects_media", False) is True
time.sleep(0.08)
assert cache.get("p:m", "rejects_media", False) is False
def test_expired_entry_is_evicted_from_bucket(
cache: ModelCapabilityCache,
) -> None:
with mock.patch(_TTL, 0.05):
cache.learn("p:m", "rejects_media", True)
time.sleep(0.08)
cache.get("p:m", "rejects_media", False)
assert "p:m" not in cache._learned
def test_ttl_zero_disables_expiry(cache: ModelCapabilityCache) -> None:
with mock.patch(_TTL, 0.0):
cache.learn("p:m", "rejects_media", True)
time.sleep(0.05)
assert cache.get("p:m", "rejects_media", False) is True