Skip to content

Commit ca87aff

Browse files
committed
tests: setup test utilities
1 parent 64e4d0c commit ca87aff

1 file changed

Lines changed: 125 additions & 0 deletions

File tree

test/utils.py

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
"""Utility functions for testing the manager state transitions."""
2+
3+
4+
import builtins
5+
import io
6+
7+
8+
def setup_manager_to_connected(manager):
9+
"""Move manager to connected state."""
10+
manager.trigger("connect", event=None)
11+
assert manager.state == "connected"
12+
13+
14+
def setup_manager_to_world_ready(manager, monkeypatch):
15+
"""Move manager to world_ready state."""
16+
17+
setup_manager_to_connected(manager)
18+
19+
# Use ConfigurationModel for valid world config
20+
from manager.libs.launch_world_model import ConfigurationModel
21+
22+
valid_world_cfg = ConfigurationModel(
23+
world="test_world", launch_file_path="/path/to/launch_file.launch"
24+
).model_dump()
25+
26+
event_data = {
27+
"world": valid_world_cfg,
28+
"robot": {
29+
"world": None, # No robot specified
30+
"robot_config": {"name": "test_robot", "type": "simple"},
31+
},
32+
}
33+
manager.trigger("launch_world", data=event_data)
34+
35+
# State should now be 'world_ready'
36+
assert manager.state == "world_ready"
37+
38+
# Patch LauncherWorld to avoid starting real worlds
39+
class DummyConsumer:
40+
def __init__(self):
41+
self.launched = False
42+
43+
def consume(self, *args, **kwargs):
44+
pass
45+
46+
class DummyLauncherWorld:
47+
def __init__(self, *args, **kwargs):
48+
self.launched = False
49+
50+
51+
def setup_manager_to_visualization_ready(manager, monkeypatch):
52+
"""Move manager to visualization_ready state."""
53+
54+
# Move to 'world_ready' state first
55+
setup_manager_to_world_ready(manager, monkeypatch)
56+
57+
# Trigger visualization ready state
58+
manager.trigger(
59+
"prepare_visualization",
60+
data={
61+
"type": "gazebo_rae",
62+
"file": "test_file",
63+
},
64+
)
65+
66+
assert manager.state == "visualization_ready"
67+
68+
69+
def setup_manager_to_application_running(manager, monkeypatch):
70+
"""Move manager to application_running state."""
71+
72+
setup_manager_to_visualization_ready(manager, monkeypatch)
73+
74+
class DummyProc:
75+
def __init__(self):
76+
self.pid = 123
77+
78+
def kill(self):
79+
pass
80+
81+
def suspend(self):
82+
pass
83+
84+
original_open = builtins.open
85+
86+
def fake_open(file, mode="r", *args, **kwargs):
87+
if file == "/workspace/code/app.zip":
88+
if "w" in mode:
89+
return io.BytesIO()
90+
elif "r" in mode:
91+
return io.BytesIO(b"fake zip content")
92+
return original_open(file, mode, *args, **kwargs)
93+
94+
# Mock file system and subprocess operations
95+
monkeypatch.setattr("os.path.isfile", lambda path: True)
96+
monkeypatch.setattr("os.listdir", lambda path: ["0", "1", "2"])
97+
monkeypatch.setattr("builtins.open", fake_open)
98+
monkeypatch.setattr("subprocess.Popen", lambda *a, **k: DummyProc())
99+
monkeypatch.setattr("os.mkdir", lambda path: None)
100+
monkeypatch.setattr("os.path.exists", lambda path: True)
101+
monkeypatch.setattr("shutil.rmtree", lambda path: None)
102+
monkeypatch.setattr(
103+
"zipfile.ZipFile",
104+
lambda *a, **k: type(
105+
"Zip",
106+
(),
107+
{"extractall": lambda self, path: None, "close": lambda self: None},
108+
)(),
109+
)
110+
monkeypatch.setattr("base64.b64decode", lambda s: b"print('hello')")
111+
monkeypatch.setattr(
112+
"manager.manager.manager.Manager.unpause_sim", lambda self: None
113+
)
114+
# Mock linter to return no errors
115+
manager.linter.evaluate_code = lambda code, ros_version: ""
116+
# Trigger application running state
117+
manager.trigger(
118+
"run_application",
119+
data={"type": "robotics-academy", "code": "data:base64,ZmFrZV9jb2Rl"},
120+
)
121+
# Assert state is now application_running
122+
assert manager.state == "application_running"
123+
124+
# Ensure application process is not None
125+
manager.application_process = DummyProc()

0 commit comments

Comments
 (0)