open-range / tests /test_protocols.py
Aaron Brown
Full OpenRange implementation: environment, builder, validator, agents, tests
8c486a8
"""Tests for agent protocols and dynamic component resolution."""
import pytest
from open_range.protocols import (
BuildContext,
SnapshotBuilder,
NPCBehavior,
ValidatorCheck,
SnapshotSpec,
NPCPersona,
Stimulus,
NPCAction,
CheckResult,
ContainerSet,
)
from open_range.resolve import resolve_component
class TestProtocolCompliance:
"""Builder implementations satisfy the SnapshotBuilder protocol."""
def test_template_only_builder_satisfies_protocol(self):
from open_range.builder.builder import TemplateOnlyBuilder
b = TemplateOnlyBuilder()
assert isinstance(b, SnapshotBuilder)
def test_file_builder_satisfies_protocol(self):
from open_range.builder.builder import FileBuilder
b = FileBuilder()
assert isinstance(b, SnapshotBuilder)
def test_llm_snapshot_builder_satisfies_protocol(self):
from open_range.builder.builder import LLMSnapshotBuilder
b = LLMSnapshotBuilder()
assert isinstance(b, SnapshotBuilder)
class TestValidatorCheckProtocol:
"""Validator check classes satisfy ValidatorCheck protocol."""
def test_build_boot_check(self):
from open_range.validator.build_boot import BuildBootCheck
assert isinstance(BuildBootCheck(), ValidatorCheck)
def test_exploitability_check(self):
from open_range.validator.exploitability import ExploitabilityCheck
assert isinstance(ExploitabilityCheck(), ValidatorCheck)
def test_difficulty_check(self):
from open_range.validator.difficulty import DifficultyCheck
assert isinstance(DifficultyCheck(), ValidatorCheck)
def test_isolation_check(self):
from open_range.validator.isolation import IsolationCheck
assert isinstance(IsolationCheck(), ValidatorCheck)
def test_evidence_check(self):
from open_range.validator.evidence import EvidenceCheck
assert isinstance(EvidenceCheck(), ValidatorCheck)
def test_npc_consistency_check(self):
from open_range.validator.npc_consistency import NPCConsistencyCheck
assert isinstance(NPCConsistencyCheck(), ValidatorCheck)
class TestResolveComponent:
"""resolve_component imports and protocol-checks correctly."""
def test_resolve_valid_builder(self):
instance = resolve_component(
"open_range.builder.builder.TemplateOnlyBuilder",
{},
SnapshotBuilder,
)
assert isinstance(instance, SnapshotBuilder)
def test_resolve_valid_validator_check(self):
instance = resolve_component(
"open_range.validator.build_boot.BuildBootCheck",
{},
ValidatorCheck,
)
assert isinstance(instance, ValidatorCheck)
def test_resolve_nonexistent_module_raises(self):
with pytest.raises(ModuleNotFoundError):
resolve_component(
"nonexistent.module.FakeClass",
{},
SnapshotBuilder,
)
def test_resolve_nonexistent_class_raises(self):
with pytest.raises(AttributeError):
resolve_component(
"open_range.builder.builder.DoesNotExist",
{},
SnapshotBuilder,
)
def test_resolve_non_compliant_class_raises(self):
"""A class that doesn't satisfy the protocol raises TypeError."""
with pytest.raises(TypeError, match="does not satisfy"):
resolve_component(
"open_range.server.models.RangeAction",
{"command": "x", "mode": "red"},
SnapshotBuilder,
)
class TestBuildContext:
"""BuildContext model basics."""
def test_defaults(self):
ctx = BuildContext()
assert ctx.tier == 1
assert ctx.seed is None
assert ctx.previous_vuln_classes == []
assert ctx.red_solve_rate == 0.0
def test_with_values(self):
ctx = BuildContext(
seed=42,
tier=3,
previous_vuln_classes=["sqli", "xss"],
weak_areas=["ssrf"],
)
assert ctx.seed == 42
assert ctx.tier == 3
assert "sqli" in ctx.previous_vuln_classes