Architecture: - Remove Chrome extension (project fully device-side, no target-machine deps) - Update all docs from "three-layer" to "two-layer" privacy (video redact + network intercept) - Add comprehensive architecture docs (overview, subsystem designs) Services: - kvm_agent: hybrid planner (template/local/cloud), screen state detection, mouse-first architecture, app launcher, visual workflow tests - privacy_gateway: upload scanner, privacy LLM integration, REST API - doc_processor: new document processing service Deployment: - Add kvm-bridge, kvm-meta, kvm-privacy deb package definitions - New systemd services (doc-processor, kvm-gateway, rkllm-server) - Network deploy configs, journald forwarding - Remove secrets.env templates from packages Plans & Docs: - HDMI-TX DRM local output + OSD design (drm_output.c, VOP2 multi-plane) - AI Agent token optimization plan (72% savings via caching/pruning/fingerprint) - Model sync: all RKNN/ONNX models now in project directory - Native H.264 adaptive bitrate plan Submodules updated: - deps/KVM: WebUI i18n, RBAC, DDNS, Agent API, OCR models (LFS) - deps/embedding: models synced (LFS), benchmarks, Ollama backend - deps/info-privacy-rs: regex PII detection, face detection integration Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
75 lines
2.5 KiB
Python
75 lines
2.5 KiB
Python
"""Root conftest — shared fixtures for all Python test suites."""
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
# Ensure services/ packages are importable from project root
|
|
_SERVICES = Path(__file__).parent / "services"
|
|
if str(_SERVICES) not in sys.path:
|
|
sys.path.insert(0, str(_SERVICES))
|
|
|
|
TESTDATA_DIR = Path(__file__).parent / "testdata"
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def testdata_dir() -> Path:
|
|
"""Return the project-wide testdata/ directory."""
|
|
return TESTDATA_DIR
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def pii_samples(testdata_dir: Path) -> dict:
|
|
"""Load testdata/pii/samples.json as a dict."""
|
|
return json.loads((testdata_dir / "pii" / "samples.json").read_text())
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def pii_positive(pii_samples: dict) -> dict[str, list[dict]]:
|
|
"""Shortcut: positive PII samples keyed by entity type."""
|
|
return pii_samples["positive"]
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def pii_negative(pii_samples: dict) -> dict[str, list[dict]]:
|
|
"""Shortcut: negative (false-positive trap) samples keyed by entity type."""
|
|
return pii_samples["negative"]
|
|
|
|
|
|
# ── Workflow fixtures (testdata/workflow/) ────────────────────────────────
|
|
|
|
def _load_json_dir(directory: Path) -> dict[str, dict]:
|
|
"""Load all .json files from a directory into a {stem: data} dict."""
|
|
result = {}
|
|
if directory.is_dir():
|
|
for f in sorted(directory.glob("*.json")):
|
|
result[f.stem] = json.loads(f.read_text())
|
|
return result
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def workflow_scenes(testdata_dir: Path) -> dict[str, dict]:
|
|
"""Load testdata/workflow/scenes/*.json as {name: data}."""
|
|
return _load_json_dir(testdata_dir / "workflow" / "scenes")
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def llm_responses(testdata_dir: Path) -> dict[str, dict]:
|
|
"""Load testdata/workflow/llm_responses/*.json as {name: data}."""
|
|
return _load_json_dir(testdata_dir / "workflow" / "llm_responses")
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def memory_responses(testdata_dir: Path) -> dict[str, dict]:
|
|
"""Load testdata/workflow/memory/*.json as {name: data}."""
|
|
return _load_json_dir(testdata_dir / "workflow" / "memory")
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def operation_templates(testdata_dir: Path) -> dict[str, dict]:
|
|
"""Load testdata/workflow/templates/*.json as {name: data}."""
|
|
return _load_json_dir(testdata_dir / "workflow" / "templates")
|