Skip to content

Commit b403260

Browse files
committed
tests: add test for 'prepare_visualization' transition
1 parent 6d9ca41 commit b403260

1 file changed

Lines changed: 168 additions & 0 deletions

File tree

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
"""Tests for transitioning Manager from 'connected' to 'world_ready' state."""
2+
3+
import pytest
4+
5+
from manager.manager.manager import Manager
6+
7+
8+
class DummyConsumer:
9+
"""A dummy consumer to capture messages sent by the Manager."""
10+
11+
def __init__(self):
12+
"""
13+
Initialize the DummyConsumer with empty message storage.
14+
15+
This constructor sets up the messages list and last_message attribute.
16+
"""
17+
self.messages = []
18+
self.last_message = None
19+
20+
def send_message(self, *args, **kwargs):
21+
"""
22+
Capture and store a message sent by the Manager.
23+
24+
Stores the message arguments and updates the last_message attribute.
25+
"""
26+
self.messages.append((args, kwargs))
27+
self.last_message = (args, kwargs)
28+
29+
30+
@pytest.fixture
31+
def manager(monkeypatch):
32+
"""Fixture to provide a Manager instance with patched dependencies for testing."""
33+
34+
# Patch subprocess.check_output for ROS_DISTRO and IMAGE_TAG
35+
def fake_check_output(cmd, *a, **k):
36+
if "ROS_DISTRO" in cmd[-1]:
37+
return b"humble"
38+
if "IMAGE_TAG" in cmd[-1]:
39+
return b"test_image_tag"
40+
return b""
41+
42+
monkeypatch.setattr("subprocess.check_output", fake_check_output)
43+
44+
# Patch check_gpu_acceleration where it is used
45+
monkeypatch.setattr(
46+
"manager.manager.manager.check_gpu_acceleration", lambda x=None: "OFF"
47+
)
48+
49+
# Patch os.makedirs and os.path.isdir to avoid real FS operations
50+
monkeypatch.setattr("os.makedirs", lambda path, exist_ok=False: None)
51+
monkeypatch.setattr("os.path.isdir", lambda path: True)
52+
53+
# Patch LauncherWorld to avoid launching real processes
54+
class DummyLauncherWorld:
55+
def __init__(self, *a, **k):
56+
self.launched = False
57+
58+
def launch(self):
59+
self.launched = True
60+
61+
def run(self):
62+
self.launched = True
63+
# Simulate running the world
64+
return
65+
66+
def terminate(self):
67+
pass
68+
69+
monkeypatch.setattr("manager.manager.manager.LauncherWorld", DummyLauncherWorld)
70+
71+
# Patch Server and FileWatchdog to avoid starting real servers
72+
class DummyServer:
73+
def __init__(self, port, update_callback):
74+
self.port = port
75+
self.update_callback = update_callback
76+
self.started = False
77+
78+
def start(self):
79+
self.started = True
80+
81+
def stop(self):
82+
self.started = False
83+
84+
class DummyFileWatchdog:
85+
def __init__(self, path, update_callback):
86+
self.path = path
87+
self.update_callback = update_callback
88+
self.started = False
89+
90+
def start(self):
91+
self.started = True
92+
93+
def stop(self):
94+
self.started = False
95+
96+
class DummyVisualizationLauncher:
97+
def __init__(self, *args, **kwargs):
98+
self.launchers = []
99+
100+
def run(self):
101+
# Simulate running the visualization launcher
102+
return
103+
104+
def terminate(self):
105+
pass
106+
107+
monkeypatch.setattr(
108+
"manager.manager.manager.LauncherVisualization", DummyVisualizationLauncher
109+
)
110+
monkeypatch.setattr("manager.manager.manager.Server", DummyServer)
111+
monkeypatch.setattr("manager.manager.manager.FileWatchdog", DummyFileWatchdog)
112+
113+
# Setup Manager with dummy consumer
114+
m = Manager(host="localhost", port=12345)
115+
m.consumer = DummyConsumer()
116+
# Move to 'connected' state first
117+
m.trigger("connect", event=None)
118+
return m
119+
120+
121+
def test_on_prepare_visualization_valid(manager):
122+
"""
123+
Test the transition from 'world_ready' to 'visualization_ready' state.
124+
125+
Tests the preparation of the visualization state by triggering the
126+
prepare_visualization event with valid values.
127+
"""
128+
# Ensure the manager is in 'world_ready' state
129+
manager.state = "world_ready"
130+
# Trigger the prepare_visualization event
131+
manager.trigger(
132+
"prepare_visualization",
133+
data={
134+
"type": "gazebo_rae",
135+
"file": "test_file",
136+
},
137+
)
138+
139+
# Check if the state has transitioned to 'visualization_ready'
140+
assert manager.state == "visualization_ready"
141+
142+
print(manager.consumer.last_message)
143+
144+
# Verify that the correct message was sent
145+
assert manager.consumer.last_message[0][0]["state"] == "visualization_ready"
146+
147+
148+
def test_on_prepare_visualization_invalid(manager):
149+
"""
150+
Test the transition from 'world_ready' to 'visualization_ready' state.
151+
152+
Tests that the prepare_visualization event does not change the state
153+
when invalid values are provided.
154+
"""
155+
# Ensure the manager is in 'world_ready' state
156+
manager.state = "world_ready"
157+
# Trigger the prepare_visualization event with invalid data
158+
with pytest.raises(KeyError):
159+
# This should raise an error due to missing 'type' in data
160+
manager.trigger(
161+
"prepare_visualization",
162+
data={
163+
"file": "test_file",
164+
},
165+
)
166+
167+
# Check if the state remains 'world_ready'
168+
assert manager.state == "world_ready"

0 commit comments

Comments
 (0)