coenv / tests /test_executor.py
SandyTheAdventurer's picture
Upload folder using huggingface_hub
05a686e verified
import pytest
from unittest.mock import MagicMock, call
from server.actions import (
ScaleAction,
DeletePodAction,
PatchAction,
RolloutRestartAction,
SetHPAAction,
DrainNodeAction,
DescribeAction,
WaitAction,
)
from server.executor import execute
from server.models import ClusterObservation
class MockWorld:
def __init__(self):
self.scale_called_with = None
self.delete_pod_called_with = None
self.apply_patch_called_with = None
self.rollout_restart_called_with = None
self.set_hpa_called_with = None
self.drain_node_called_with = None
self.describe_called_with = None
self.tick_called = False
self._observation = ClusterObservation(nodes=[], pods=[], deployments=[], services=[], configmaps=[], hpa=[], events=[], step=0, objective="")
self._raw_state = {"nodes": [], "pods": [], "deployments": [], "services": [], "configmaps": []}
def scale(self, deployment, replicas):
self.scale_called_with = (deployment, replicas)
def delete_pod(self, pod_name):
self.delete_pod_called_with = pod_name
def apply_patch(self, resource_type, name, patch):
self.apply_patch_called_with = (resource_type, name, patch)
def rollout_restart(self, deployment):
self.rollout_restart_called_with = deployment
def set_hpa(self, deployment, min_replicas, max_replicas, cpu_target_percent):
self.set_hpa_called_with = (deployment, min_replicas, max_replicas, cpu_target_percent)
def drain_node(self, node_name):
self.drain_node_called_with = node_name
def describe(self, resource_type, name):
self.describe_called_with = (resource_type, name)
return {"type": resource_type, "name": name, "detail": "mock detail"}
def tick(self):
self.tick_called = True
def get_observation(self):
return self._observation
def get_raw_state(self):
return self._raw_state
class TestExecutorScale:
def test_scale_calls_world_scale_and_ticks(self):
mock_world = MockWorld()
action = ScaleAction(action_type="scale", deployment="frontend", replicas=3)
result = execute(action, mock_world)
assert mock_world.scale_called_with == ("frontend", 3)
assert mock_world.tick_called is True
assert result.tick_advanced is True
assert "Scaled" in result.action_applied
def test_scale_action_applied_message(self):
mock_world = MockWorld()
action = ScaleAction(action_type="scale", deployment="frontend", replicas=5)
result = execute(action, mock_world)
assert result.action_applied == "Scaled 'frontend' to 5 replicas"
class TestExecutorDeletePod:
def test_delete_pod_calls_world_and_ticks(self):
mock_world = MockWorld()
action = DeletePodAction(action_type="delete_pod", pod_name="frontend-7d9f-xkp2")
result = execute(action, mock_world)
assert mock_world.delete_pod_called_with == "frontend-7d9f-xkp2"
assert mock_world.tick_called is True
assert result.tick_advanced is True
class TestExecutorPatch:
def test_patch_calls_world_and_ticks(self):
mock_world = MockWorld()
action = PatchAction(
action_type="patch",
resource_type="deployment",
name="frontend",
patch={"env": [{"name": "DB_HOST", "value": "db.prod.internal"}]}
)
result = execute(action, mock_world)
assert mock_world.apply_patch_called_with == (
"deployment",
"frontend",
{"env": [{"name": "DB_HOST", "value": "db.prod.internal"}]}
)
assert mock_world.tick_called is True
assert result.tick_advanced is True
class TestExecutorRolloutRestart:
def test_rollout_restart_calls_world_and_ticks(self):
mock_world = MockWorld()
action = RolloutRestartAction(action_type="rollout_restart", deployment="frontend")
result = execute(action, mock_world)
assert mock_world.rollout_restart_called_with == "frontend"
assert mock_world.tick_called is True
assert result.tick_advanced is True
class TestExecutorSetHPA:
def test_set_hpa_calls_world_and_ticks(self):
mock_world = MockWorld()
action = SetHPAAction(
action_type="set_hpa",
deployment="api",
min_replicas=2,
max_replicas=10,
cpu_target_percent=70
)
result = execute(action, mock_world)
assert mock_world.set_hpa_called_with == ("api", 2, 10, 70)
assert mock_world.tick_called is True
assert result.tick_advanced is True
class TestExecutorDrainNode:
def test_drain_node_calls_world_and_ticks(self):
mock_world = MockWorld()
action = DrainNodeAction(action_type="drain_node", node_name="node-1")
result = execute(action, mock_world)
assert mock_world.drain_node_called_with == "node-1"
assert mock_world.tick_called is True
assert result.tick_advanced is True
class TestExecutorDescribe:
def test_describe_does_not_tick(self):
mock_world = MockWorld()
action = DescribeAction(
action_type="describe",
resource_type="deployment",
name="frontend"
)
result = execute(action, mock_world)
assert mock_world.describe_called_with == ("deployment", "frontend")
assert mock_world.tick_called is False
assert result.tick_advanced is False
def test_describe_returns_detail(self):
mock_world = MockWorld()
action = DescribeAction(
action_type="describe",
resource_type="deployment",
name="frontend"
)
result = execute(action, mock_world)
assert result.describe_detail is not None
assert result.describe_detail["type"] == "deployment"
class TestExecutorWait:
def test_wait_ticks_without_other_world_mutations(self):
mock_world = MockWorld()
action = WaitAction(action_type="wait")
result = execute(action, mock_world)
assert mock_world.tick_called is True
assert result.tick_advanced is True
assert result.action_applied == "Waited one simulation tick"