Files
Pyra/tests/unit/test_vault_rw.py
T
curo1305 251e509ee0 test: comprehensive test suite
Unit tests:
- test_security_boundaries.py: vault block, vault lock sentinel
- test_security_injection.py: all 4 injection categories, case-insensitive
- test_vault_rw.py: roundtrip, file permissions (chmod 400), no key in config
- test_config.py: schema roundtrip, no api_key field, chmod 600 on config.yaml
- test_memory_reader.py: list, read, sandboxing, context loading
- test_memory_writer.py: write, append, index update, traversal blocked, chmod 600
- test_providers.py: required fields, unique IDs, litellm prefix format
- test_renderer.py: key redaction for sk-ant-, sk-, AIza patterns

Security tests:
- test_vault_ai_isolation.py: 7 traversal patterns blocked via memory read/write
- test_path_traversal.py: 20+ traversal patterns — all rejected for read and write
- test_prompt_injection.py: 21-item corpus + 5 clean texts (no false positives)

Integration tests:
- test_lmstudio.py: live call to localhost:1234, streaming, full stack session,
  injection scan on real output (skips if LM Studio not running)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 12:55:06 +02:00

70 lines
1.9 KiB
Python

import json
import pytest
def test_set_and_get_key(tmp_pyra_home):
from pyra.vault.writer import set_key
from pyra.vault.reader import get_key
set_key("anthropic", "sk-ant-test-secret")
result = get_key("anthropic")
assert result == "sk-ant-test-secret"
def test_key_not_in_config(tmp_pyra_home):
from pyra.vault.writer import set_key
from pyra.config.schema import ProviderConfig, PyraConfig
from pyra.config.manager import save_config, load_config
set_key("openai", "sk-supersecret")
cfg = PyraConfig(ai=ProviderConfig(provider_id="openai", model="gpt-4o"))
save_config(cfg)
config_text = (tmp_pyra_home / "config.yaml").read_text()
assert "sk-supersecret" not in config_text
assert "supersecret" not in config_text
def test_keys_file_permissions(tmp_pyra_home):
import os
from pyra.vault.writer import set_key
set_key("deepseek", "test-key-value")
keys_file = tmp_pyra_home / "vault" / "secrets" / "api_keys.json"
if os.name != "nt":
mode = oct(keys_file.stat().st_mode)[-3:]
assert mode == "400", f"Expected 400, got {mode}"
def test_multiple_providers(tmp_pyra_home):
from pyra.vault.writer import set_key
from pyra.vault.reader import get_key
set_key("anthropic", "key-1")
set_key("openai", "key-2")
set_key("gemini", "key-3")
assert get_key("anthropic") == "key-1"
assert get_key("openai") == "key-2"
assert get_key("gemini") == "key-3"
def test_delete_key(tmp_pyra_home):
from pyra.vault.writer import set_key, delete_key
from pyra.vault.reader import get_key
set_key("anthropic", "to-be-deleted")
assert get_key("anthropic") == "to-be-deleted"
existed = delete_key("anthropic")
assert existed is True
assert get_key("anthropic") is None
def test_get_missing_key_returns_none(tmp_pyra_home):
from pyra.vault.reader import get_key
result = get_key("nonexistent_provider")
assert result is None