DevOps_Debugger / tests /test_env.py
printf-sourav's picture
Initial commit
27cdb3e
Raw
History Blame Contribute Delete
5 kB
"""
Tests for the DevOps RL Environment.
"""
import pytest
from devops_env.env import DevOpsEnv
from scenarios.registry import ScenarioRegistry, Scenario
def _make_test_registry():
"""Create a minimal registry for testing."""
registry = ScenarioRegistry()
registry.register(Scenario(
id="test_missing_pkg",
level=1,
description="Test: missing package",
initial_state={},
success_condition=lambda out: "successfully installed" in out.lower(),
hint_commands=["pip install testpkg"],
error_fingerprint=r"ModuleNotFoundError",
initial_error_log="ModuleNotFoundError: No module named 'testpkg'",
))
return registry
class TestDevOpsEnv:
"""Tests for the OpenEnv-style environment."""
def test_reset_returns_observation(self):
registry = _make_test_registry()
env = DevOpsEnv(scenario_registry=registry, max_steps=5)
obs, info = env.reset(options={"scenario_id": "test_missing_pkg"})
assert "error_log" in obs
assert "command_history" in obs
assert "step_count" in obs
assert "scenario_id" in obs
assert "error_type" in obs
assert "error_confidence" in obs
assert "is_terminal" in obs
assert "solved" in obs
assert obs["scenario_id"] == "test_missing_pkg"
assert obs["step_count"] == 0
env.close()
def test_step_returns_correct_tuple(self):
registry = _make_test_registry()
env = DevOpsEnv(scenario_registry=registry, max_steps=5)
obs, _ = env.reset(options={"scenario_id": "test_missing_pkg"})
result = env.step("echo hello")
assert len(result) == 5 # obs, reward, terminated, truncated, info
obs, reward, terminated, truncated, info = result
assert isinstance(reward, float)
assert isinstance(terminated, bool)
assert isinstance(truncated, bool)
assert isinstance(info, dict)
env.close()
def test_max_steps_truncates(self):
registry = _make_test_registry()
env = DevOpsEnv(scenario_registry=registry, max_steps=3)
env.reset(options={"scenario_id": "test_missing_pkg"})
truncated = False
for i in range(3):
_, _, terminated, truncated, _ = env.step("echo step")
if terminated or truncated:
break
assert truncated or terminated # Should end by step 3
env.close()
def test_error_type_classified(self):
registry = _make_test_registry()
env = DevOpsEnv(scenario_registry=registry)
obs, info = env.reset(options={"scenario_id": "test_missing_pkg"})
assert obs["error_type"] == "missing_package"
env.close()
def test_episode_summary(self):
registry = _make_test_registry()
env = DevOpsEnv(scenario_registry=registry, max_steps=2)
env.reset(options={"scenario_id": "test_missing_pkg"})
env.step("echo test")
summary = env.get_episode_summary()
assert summary["scenario_id"] == "test_missing_pkg"
assert summary["level"] == 1
assert len(summary["steps"]) == 1
env.close()
def test_cannot_step_after_done(self):
registry = _make_test_registry()
env = DevOpsEnv(scenario_registry=registry, max_steps=1)
env.reset(options={"scenario_id": "test_missing_pkg"})
env.step("echo done")
with pytest.raises(RuntimeError):
env.step("echo again")
env.close()
class TestScenarioRegistry:
"""Tests for the scenario registry."""
def test_register_and_get(self):
registry = ScenarioRegistry()
scenario = Scenario(
id="test1", level=1, description="test",
initial_state={}, success_condition=lambda x: True,
hint_commands=["echo"], error_fingerprint="test",
)
registry.register(scenario)
assert registry.get("test1").id == "test1"
def test_duplicate_registration_raises(self):
registry = ScenarioRegistry()
scenario = Scenario(
id="dup", level=1, description="test",
initial_state={}, success_condition=lambda x: True,
hint_commands=["echo"], error_fingerprint="test",
)
registry.register(scenario)
with pytest.raises(ValueError):
registry.register(scenario)
def test_get_by_level(self):
registry = ScenarioRegistry()
registry.register_defaults()
level1 = registry.get_by_level(1)
assert len(level1) >= 3
assert all(s.level == 1 for s in level1)
def test_get_random(self):
registry = ScenarioRegistry()
registry.register_defaults()
scenario = registry.get_random(level=1)
assert scenario.level == 1
def test_register_defaults(self):
registry = ScenarioRegistry()
registry.register_defaults()
assert registry.count >= 9 # 3+ per level