"""Unit tests for the agent roster: roles, registry, and legality under play. The environment raises on any illegal action, so a tournament completing at all is itself the proof that every agent policy stayed within the law — the core contract of adversarial self-play here: capture objectives, legal moves. """ from __future__ import annotations import json import pytest from fable_selfplay.agents import AGENT_REGISTRY from fable_selfplay.tournament import run_tournament from .conftest import episode_dicts, make_config CORE_ROLES = {"honest", "drainer", "entrencher", "suppressor"} def test_registry_contains_all_core_roles(): assert CORE_ROLES <= set(AGENT_REGISTRY), ( f"missing roles: {sorted(CORE_ROLES - set(AGENT_REGISTRY))}" ) @pytest.mark.parametrize("role", sorted(CORE_ROLES - {"honest"})) def test_each_adversarial_role_plays_legally_to_completion(kernel_v01, role): config = make_config(kernel_v01, {"honest": 4, role: 2}, seed=17, episodes=2, max_turns=50, name=f"unit-{role}") result = run_tournament(config) # raises if any move was illegal assert len(episode_dicts(result)) == 2 @pytest.mark.parametrize("role", sorted(CORE_ROLES - {"honest"})) def test_each_adversarial_role_plays_legally_on_patched_kernel(kernel_v02, role): config = make_config(kernel_v02, {"honest": 4, role: 2}, seed=19, episodes=2, max_turns=50, name=f"unit-{role}-v02") result = run_tournament(config) assert len(episode_dicts(result)) == 2 def test_agent_policies_are_seed_deterministic(kernel_v01): config = make_config(kernel_v01, {"honest": 4, "drainer": 1}, seed=23, episodes=2, max_turns=50, name="unit-det") a = episode_dicts(run_tournament(config)) b = episode_dicts(run_tournament(config)) assert json.dumps(a, sort_keys=True, default=str) == \ json.dumps(b, sort_keys=True, default=str)