Files
wehub-resource-sync 7a0da7932b
OSV-Scanner (Scheduled) / scan-scheduled (push) Failing after 0s
Create Release / test-gate (push) Has been cancelled
Create Release / release-gate (push) Has been cancelled
Create Release / ci-gate (push) Has been cancelled
Create Release / version-check (push) Has been cancelled
Create Release / e2e-test-gate (push) Has been cancelled
Create Release / responsive-test-gate (push) Has been cancelled
Create Release / compat-test-gate (push) Has been cancelled
Create Release / compose-integration-gate (push) Has been cancelled
Create Release / vulture-gate (push) Has been cancelled
Create Release / build (push) Has been cancelled
Create Release / provenance (push) Has been cancelled
Create Release / prerelease-docker (push) Has been cancelled
Create Release / publish-docker (push) Has been cancelled
Create Release / create-release (push) Has been cancelled
Create Release / cleanup-changelog (push) Has been cancelled
Create Release / trigger-pypi (push) Has been cancelled
Create Release / monitor-pypi (push) Has been cancelled
Create Release / Clean up orphan prerelease tags and signatures (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-form] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-metrics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-workflow] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-core] (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [history-news] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [library] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [link-analytics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-core] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-lifecycle] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [error-benchmark] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) (push) Has been cancelled
Docker Tests (Consolidated) / Accessibility Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Unit Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Example Tests (push) Has been cancelled
Docker Tests (Consolidated) / Production Image Smoke Test (push) Has been cancelled
Docker Tests (Consolidated) / Infrastructure Tests (push) Has been cancelled
OSSF Scorecard / OSSF Security Scorecard Analysis (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [mobile] (push) Has been cancelled
Backwards Compatibility / Verify Encryption Constants (push) Has been cancelled
Backwards Compatibility / PyPI Version Compatibility (push) Has been cancelled
Backwards Compatibility / Database Migration Tests (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Docker Tests (Consolidated) / detect-changes (push) Has been cancelled
Docker Tests (Consolidated) / Build Test Image (push) Has been cancelled
Docker Tests (Consolidated) / All Pytest Tests + Coverage (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [accessibility] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [api-crud] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-login] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-register] (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:08:55 +08:00

339 lines
13 KiB
Python

"""Pure-function tests for hardware warning checks — zero mocking needed."""
from unittest.mock import patch
from local_deep_research.web.warning_checks.hardware import (
LOCAL_PROVIDERS,
check_high_context,
check_legacy_server_config,
check_model_mismatch,
)
class TestLocalProviders:
"""Verify the LOCAL_PROVIDERS constant."""
def test_contains_expected_providers(self):
assert LOCAL_PROVIDERS == frozenset({"ollama", "llamacpp", "lmstudio"})
def test_is_frozenset(self):
assert isinstance(LOCAL_PROVIDERS, frozenset)
class TestCheckHighContext:
"""Tests for check_high_context."""
def test_warns_local_provider_above_8192(self):
result = check_high_context("ollama", 16384, dismissed=False)
assert result is not None
assert result["type"] == "high_context"
assert "16,384" in result["message"]
def test_no_warning_at_8192(self):
assert check_high_context("ollama", 8192, dismissed=False) is None
def test_no_warning_below_8192(self):
assert check_high_context("ollama", 4096, dismissed=False) is None
def test_no_warning_non_local_provider(self):
assert check_high_context("openai", 32000, dismissed=False) is None
def test_no_warning_when_dismissed(self):
assert check_high_context("ollama", 16384, dismissed=True) is None
def test_all_local_providers_trigger(self):
for provider in LOCAL_PROVIDERS:
result = check_high_context(provider, 16384, dismissed=False)
assert result is not None, f"{provider} should trigger warning"
def test_warns_at_boundary_8193(self):
"""8193 is just above the 8192 threshold — should trigger."""
result = check_high_context("ollama", 8193, dismissed=False)
assert result is not None
assert result["type"] == "high_context"
def test_context_size_in_message(self):
result = check_high_context("ollama", 16384, dismissed=False)
assert "16,384" in result["message"]
def test_warning_dict_has_all_required_keys(self):
result = check_high_context("ollama", 16384, dismissed=False)
assert set(result.keys()) == {
"type",
"icon",
"title",
"message",
"dismissKey",
"actionUrl",
"actionLabel",
}
def test_dismiss_key(self):
result = check_high_context("ollama", 16384, dismissed=False)
assert result["dismissKey"] == "app.warnings.dismiss_high_context"
def test_warning_dict_has_action_link(self):
result = check_high_context("ollama", 16384, dismissed=False)
assert result["actionUrl"] == "/metrics/context-overflow"
assert result["actionLabel"] == "View context metrics"
class TestCheckModelMismatch:
"""Tests for check_model_mismatch."""
def test_warns_70b_model_high_context(self):
result = check_model_mismatch(
"ollama", "llama3.1:70b", 16384, dismissed=False
)
assert result is not None
assert result["type"] == "model_mismatch"
def test_case_insensitive_70b(self):
result = check_model_mismatch(
"ollama", "Mixtral-70B-v2", 16384, dismissed=False
)
assert result is not None
def test_no_warning_small_model(self):
result = check_model_mismatch(
"ollama", "llama3:8b", 16384, dismissed=False
)
assert result is None
def test_no_warning_empty_model(self):
result = check_model_mismatch("ollama", "", 16384, dismissed=False)
assert result is None
def test_no_warning_non_local_provider(self):
result = check_model_mismatch(
"openai", "gpt-4-70b-fake", 16384, dismissed=False
)
assert result is None
def test_no_warning_at_boundary_8192(self):
"""Context exactly at 8192 should NOT trigger (uses <=)."""
result = check_model_mismatch(
"ollama", "llama3.1:70b", 8192, dismissed=False
)
assert result is None
def test_warns_at_boundary_8193(self):
"""Context at 8193 is just above the threshold — should trigger."""
result = check_model_mismatch(
"ollama", "llama3.1:70b", 8193, dismissed=False
)
assert result is not None
assert result["type"] == "model_mismatch"
def test_no_warning_low_context(self):
result = check_model_mismatch(
"ollama", "llama3.1:70b", 4096, dismissed=False
)
assert result is None
def test_no_warning_when_dismissed(self):
result = check_model_mismatch(
"ollama", "llama3.1:70b", 16384, dismissed=True
)
assert result is None
def test_model_name_in_message(self):
result = check_model_mismatch(
"ollama", "deepseek-r1:70b", 16384, dismissed=False
)
assert "deepseek-r1:70b" in result["message"]
def test_context_value_in_message(self):
result = check_model_mismatch(
"ollama", "llama3.1:70b", 32000, dismissed=False
)
assert "32,000" in result["message"]
def test_warning_dict_has_all_required_keys(self):
result = check_model_mismatch(
"ollama", "llama3.1:70b", 16384, dismissed=False
)
assert set(result.keys()) == {
"type",
"icon",
"title",
"message",
"dismissKey",
"actionUrl",
"actionLabel",
}
def test_no_warning_none_model(self):
"""None model should not crash — treated as falsy like empty string."""
result = check_model_mismatch("ollama", None, 16384, dismissed=False)
assert result is None
def test_dismiss_key(self):
result = check_model_mismatch(
"ollama", "llama3.1:70b", 16384, dismissed=False
)
assert result["dismissKey"] == "app.warnings.dismiss_model_mismatch"
def test_warning_dict_has_action_link(self):
result = check_model_mismatch(
"ollama", "llama3.1:70b", 16384, dismissed=False
)
assert result["actionUrl"] == "/metrics/context-overflow"
assert result["actionLabel"] == "View context metrics"
class TestCheckLegacyServerConfig:
"""Tests for check_legacy_server_config."""
def test_no_warning_when_dismissed(self, tmp_path):
config_file = tmp_path / "server_config.json"
config_file.write_text('{"port": 9999}', encoding="utf-8")
with patch(
"local_deep_research.web.server_config.get_server_config_path",
return_value=config_file,
):
assert check_legacy_server_config(dismissed=True) is None
def test_no_warning_when_file_missing(self, tmp_path):
config_file = tmp_path / "server_config.json"
with patch(
"local_deep_research.web.server_config.get_server_config_path",
return_value=config_file,
):
assert check_legacy_server_config(dismissed=False) is None
def test_no_warning_when_all_defaults(self, tmp_path):
"""File exists but all values match defaults — no warning."""
import json
from local_deep_research.web.server_config import _DEFAULTS
config_file = tmp_path / "server_config.json"
config_file.write_text(json.dumps(_DEFAULTS), encoding="utf-8")
with patch(
"local_deep_research.web.server_config.get_server_config_path",
return_value=config_file,
):
assert check_legacy_server_config(dismissed=False) is None
def test_no_warning_when_empty_object(self, tmp_path):
"""Empty JSON object has no customizations — no warning."""
config_file = tmp_path / "server_config.json"
config_file.write_text("{}", encoding="utf-8")
with patch(
"local_deep_research.web.server_config.get_server_config_path",
return_value=config_file,
):
assert check_legacy_server_config(dismissed=False) is None
def test_warns_when_non_default_value(self, tmp_path):
"""File has a customized value — should warn."""
config_file = tmp_path / "server_config.json"
config_file.write_text('{"port": 9999}', encoding="utf-8")
with patch(
"local_deep_research.web.server_config.get_server_config_path",
return_value=config_file,
):
result = check_legacy_server_config(dismissed=False)
assert result is not None
assert result["type"] == "legacy_server_config"
assert result["dismissKey"] == "app.warnings.dismiss_legacy_config"
assert set(result.keys()) == {
"type",
"icon",
"title",
"message",
"dismissKey",
}
def test_warns_when_unrecognized_keys(self, tmp_path):
"""File has unrecognized keys — should warn."""
config_file = tmp_path / "server_config.json"
config_file.write_text('{"custom_thing": true}', encoding="utf-8")
with patch(
"local_deep_research.web.server_config.get_server_config_path",
return_value=config_file,
):
result = check_legacy_server_config(dismissed=False)
assert result is not None
assert result["type"] == "legacy_server_config"
def test_no_warning_on_malformed_json(self, tmp_path):
"""Malformed JSON should not crash — just return None."""
config_file = tmp_path / "server_config.json"
config_file.write_text("not valid json", encoding="utf-8")
with patch(
"local_deep_research.web.server_config.get_server_config_path",
return_value=config_file,
):
assert check_legacy_server_config(dismissed=False) is None
def test_no_warning_on_non_dict_json(self, tmp_path):
"""JSON array instead of object should not crash — just return None."""
config_file = tmp_path / "server_config.json"
config_file.write_text("[1, 2, 3]", encoding="utf-8")
with patch(
"local_deep_research.web.server_config.get_server_config_path",
return_value=config_file,
):
assert check_legacy_server_config(dismissed=False) is None
def test_warns_with_partial_defaults_and_one_custom(self, tmp_path):
"""Mix of default and non-default values — should warn on the mismatch."""
import json
config_file = tmp_path / "server_config.json"
config_file.write_text(
json.dumps({"host": "0.0.0.0", "port": 5000, "debug": True}),
encoding="utf-8",
)
with patch(
"local_deep_research.web.server_config.get_server_config_path",
return_value=config_file,
):
result = check_legacy_server_config(dismissed=False)
assert result is not None
assert result["type"] == "legacy_server_config"
def test_warns_unrecognized_keys_with_default_recognized(self, tmp_path):
"""All recognized keys match defaults but an unknown key exists — should warn."""
import json
from local_deep_research.web.server_config import _DEFAULTS
data = dict(_DEFAULTS)
data["unknown"] = "val"
config_file = tmp_path / "server_config.json"
config_file.write_text(json.dumps(data), encoding="utf-8")
with patch(
"local_deep_research.web.server_config.get_server_config_path",
return_value=config_file,
):
result = check_legacy_server_config(dismissed=False)
assert result is not None
assert result["type"] == "legacy_server_config"
def test_warns_when_value_is_none(self, tmp_path):
"""null value differs from default — should warn."""
config_file = tmp_path / "server_config.json"
config_file.write_text('{"port": null}', encoding="utf-8")
with patch(
"local_deep_research.web.server_config.get_server_config_path",
return_value=config_file,
):
result = check_legacy_server_config(dismissed=False)
assert result is not None
assert result["type"] == "legacy_server_config"
def test_warns_when_type_differs_from_default(self, tmp_path):
"""String '5000' != int 5000 — strict comparison should catch this."""
config_file = tmp_path / "server_config.json"
config_file.write_text('{"port": "5000"}', encoding="utf-8")
with patch(
"local_deep_research.web.server_config.get_server_config_path",
return_value=config_file,
):
result = check_legacy_server_config(dismissed=False)
assert result is not None
assert result["type"] == "legacy_server_config"