Files
tracer-cloud--opensre/tests/platform/guardrails/test_rules.py
T
wehub-resource-sync 4b6817381b
CI (OpenClaw E2E) / openclaw test (push) Has been cancelled
CI / coverage-report (push) Has been cancelled
CI / test-kubernetes (push) Has been cancelled
CI / should-run-thorough (push) Has been cancelled
CI / test-thorough (cloudwatch-demo) (push) Has been cancelled
CI / test-thorough (flink-ecs) (push) Has been cancelled
CI / test-thorough (upstream-lambda) (push) Has been cancelled
CI / test-thorough (prefect-ecs-fargate) (push) Has been cancelled
Release / build-binaries (zip, opensre.exe, onefile, windows-latest, windows-x64) (push) Has been cancelled
Benchmark image — build + push to ECR (any adapter) / build + push (push) Has been cancelled
CI / quality (ubuntu-latest) (push) Has been cancelled
CI / test (tools-runtime) (push) Has been cancelled
CI / test (e2e-general) (push) Has been cancelled
CI / test (cli-runtime) (push) Has been cancelled
CI / test (e2e-provider-and-openclaw) (push) Has been cancelled
CI / test (integrations-and-misc) (push) Has been cancelled
Release / verify (push) Has been cancelled
Release / build-python-dist (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-15-intel, darwin-x64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-latest, darwin-arm64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04, linux-x64) (push) Has been cancelled
Release / publish-release (push) Has been cancelled
Release / publish-main-release (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-checks (no-LLM) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-live shard ${{ matrix.shard_index }} (push) Has been cancelled
Release / prepare (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04-arm, linux-arm64) (push) Has been cancelled
Synthetic Deterministic Tests / Synthetic offline (deterministic) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:10:45 +08:00

178 lines
5.5 KiB
Python

from __future__ import annotations
from pathlib import Path
import yaml
from platform.guardrails.rules import GuardrailAction, load_rules
def _write_config(tmp_path: Path, data: dict) -> Path:
path = tmp_path / "guardrails.yml"
path.write_text(yaml.dump(data), encoding="utf-8")
return path
class TestLoadRules:
def test_returns_empty_when_file_missing(self, tmp_path: Path) -> None:
assert load_rules(tmp_path / "nonexistent.yml") == []
def test_returns_empty_for_malformed_yaml(self, tmp_path: Path) -> None:
path = tmp_path / "guardrails.yml"
path.write_text(": : : bad yaml {{", encoding="utf-8")
assert load_rules(path) == []
def test_returns_empty_when_rules_key_missing(self, tmp_path: Path) -> None:
path = _write_config(tmp_path, {"version": 1})
assert load_rules(path) == []
def test_parses_pattern_rule(self, tmp_path: Path) -> None:
path = _write_config(
tmp_path,
{
"rules": [
{"name": "aws_key", "action": "redact", "patterns": ["AKIA[0-9A-Z]{16}"]},
]
},
)
rules = load_rules(path)
assert len(rules) == 1
assert rules[0].name == "aws_key"
assert rules[0].action == GuardrailAction.REDACT
assert len(rules[0].patterns) == 1
def test_parses_keyword_rule(self, tmp_path: Path) -> None:
path = _write_config(
tmp_path,
{
"rules": [
{"name": "internal", "action": "audit", "keywords": ["prod-db.internal"]},
]
},
)
rules = load_rules(path)
assert len(rules) == 1
assert rules[0].keywords == ("prod-db.internal",)
def test_parses_mixed_pattern_and_keyword(self, tmp_path: Path) -> None:
path = _write_config(
tmp_path,
{
"rules": [
{
"name": "mixed",
"action": "redact",
"patterns": ["\\bsecret\\b"],
"keywords": ["api_key"],
},
]
},
)
rules = load_rules(path)
assert len(rules) == 1
assert len(rules[0].patterns) == 1
assert rules[0].keywords == ("api_key",)
def test_skips_rule_with_invalid_regex(self, tmp_path: Path) -> None:
bad_pattern = "[invalid"
path = _write_config(
tmp_path,
{
"rules": [
{"name": "bad_regex", "action": "redact", "patterns": [bad_pattern]},
]
},
)
rules = load_rules(path)
assert len(rules) == 0
def test_skips_rule_with_no_patterns_or_keywords(self, tmp_path: Path) -> None:
path = _write_config(
tmp_path,
{
"rules": [
{"name": "empty", "action": "redact"},
]
},
)
assert load_rules(path) == []
def test_skips_rule_with_invalid_action(self, tmp_path: Path) -> None:
path = _write_config(
tmp_path,
{
"rules": [
{"name": "bad", "action": "explode", "patterns": ["test"]},
]
},
)
assert load_rules(path) == []
def test_respects_enabled_false(self, tmp_path: Path) -> None:
path = _write_config(
tmp_path,
{
"rules": [
{
"name": "disabled",
"action": "redact",
"patterns": ["test"],
"enabled": False,
},
]
},
)
rules = load_rules(path)
assert len(rules) == 1
assert rules[0].enabled is False
def test_defaults_action_to_audit(self, tmp_path: Path) -> None:
path = _write_config(
tmp_path,
{
"rules": [
{"name": "default_action", "keywords": ["sensitive"]},
]
},
)
rules = load_rules(path)
assert rules[0].action == GuardrailAction.AUDIT
def test_parses_description_and_replacement(self, tmp_path: Path) -> None:
path = _write_config(
tmp_path,
{
"rules": [
{
"name": "cc",
"action": "redact",
"patterns": ["\\d{16}"],
"description": "Credit cards",
"replacement": "[CC_REDACTED]",
},
]
},
)
rules = load_rules(path)
assert rules[0].description == "Credit cards"
assert rules[0].replacement == "[CC_REDACTED]"
def test_multiple_rules(self, tmp_path: Path) -> None:
path = _write_config(
tmp_path,
{
"rules": [
{"name": "r1", "action": "redact", "patterns": ["aaa"]},
{"name": "r2", "action": "block", "keywords": ["bbb"]},
{"name": "r3", "action": "audit", "keywords": ["ccc"]},
]
},
)
rules = load_rules(path)
assert len(rules) == 3
assert [r.action for r in rules] == [
GuardrailAction.REDACT,
GuardrailAction.BLOCK,
GuardrailAction.AUDIT,
]