forked from isaac-sim/IsaacLab
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_wheel_builder_smoke.py
More file actions
192 lines (162 loc) · 8.66 KB
/
Copy pathtest_wheel_builder_smoke.py
File metadata and controls
192 lines (162 loc) · 8.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# Copyright (c) 2022-2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md).
# All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
"""
Setup:
- uv build --wheel tools/wheel_builder --out-dir tools/wheel_builder/build/dist
- ./isaaclab.sh -u
- uv pip install <wheel>[sb3,skrl,rsl-rl]
Tests:
- import isaaclab -> verify importable
- from isaaclab import __version__ -> verify version matches wheel filename
- inspect the wheel and isaaclab.__path__ -> verify the core package has a flat layout
- from isaaclab import _deprioritize_prebundle_paths -> verify wheel exports path sanitizer
- from isaaclab.app import AppLauncher -> verify importable
- from isaaclab.envs import VideoRecorderCfg -> verify importable
- from isaaclab_assets.robots.allegro import ALLEGRO_HAND_CFG -> verify importable
- from isaaclab.scene import InteractiveSceneCfg -> verify importable
- python -m isaaclab --help -> verify CLI functional
- verify project-generator resources are installed
- import pinocchio -> verify importable
- python -c "import importlib.util; raise SystemExit(importlib.util.find_spec('pytetwild') is not None)"
-> verify the RL extras omit tetrahedralization dependencies
"""
from __future__ import annotations
import glob
import shutil
import zipfile
import pytest
from utils import UV_Mixin, run_cmd
@pytest.mark.smoke
class Test_Wheel_Builder_Smoke(UV_Mixin):
"""Test building and installing the Isaac Lab wheel with selected RL extras."""
_wheel: str = ""
_extras: str = "[sb3,skrl,rsl-rl]"
@classmethod
def setup_class(cls):
if not shutil.which("uv"):
pytest.skip("uv is not available")
@pytest.fixture(autouse=True, scope="class")
def _build_and_install_wheel(self, isaaclab_root):
"""Build the wheel and install it in a uv environment once for all tests."""
cls = self.__class__
builder_dir = isaaclab_root / "tools" / "wheel_builder"
dist_dir = builder_dir / "build" / "dist"
shutil.rmtree(dist_dir, ignore_errors=True)
dist_dir.mkdir(parents=True)
# Build through the PEP 517 entry point used by Git-source consumers. Capture output
# silently to avoid spamming the test log with 10k+
# setuptools/pip lines; the captured output is included in the assertion if it fails).
result = run_cmd(
["uv", "build", "--wheel", str(builder_dir), "--out-dir", str(dist_dir)],
cwd=isaaclab_root,
stream=False,
)
assert result.returncode == 0, f"PEP 517 wheel build failed:\n{result.stdout}\n{result.stderr}"
# Find the built wheel
wheels = glob.glob(str(dist_dir / "isaaclab-*.whl"))
assert len(wheels) == 1, f"Expected exactly 1 wheel in {dist_dir}, found: {wheels}"
cls._wheel = wheels[0]
# Create uv environment and install the wheel
self.create_uv_env(isaaclab_root)
# Share env state with all test instances via the class
cls.env_path = self.env_path
cls.python = self.python
cls.cli_script = self.cli_script
result = self.run_in_uv_env(["uv", "pip", "install", cls._wheel + cls._extras])
assert result.returncode == 0, f"uv pip install wheel failed:\n{result.stdout}\n{result.stderr}"
yield
self.destroy_uv_env()
# import isaaclab
def test_isaaclab_importable(self):
"""Verify 'isaaclab' is importable."""
result = self.run_in_uv_env(["python", "-c", "import isaaclab;"])
assert result.returncode == 0, f"import isaaclab failed:\n{result.stdout}\n{result.stderr}"
# from isaaclab import __version__; print(__version__)
def test_isaaclab_version_matches_wheel(self):
"""Verify isaaclab.__version__ matches the wheel version."""
result = self.run_in_uv_env(["python", "-c", "from isaaclab import __version__; print(__version__)"])
imported_version = result.stdout.strip()
expected_version = self._wheel.split("/")[-1].split("-")[1]
assert imported_version == expected_version, (
f"isaaclab.__version__ mismatch: expected {expected_version}, got {imported_version}"
)
def test_isaaclab_package_has_flat_layout(self):
"""Verify core modules are installed directly under the top-level package."""
with zipfile.ZipFile(self._wheel) as wheel:
names = set(wheel.namelist())
assert "isaaclab/app/__init__.py" in names
assert "isaaclab/apps/isaaclab.python.kit" in names
nested_prefix = "isaaclab/source/isaaclab/isaaclab/"
assert not any(name.startswith(nested_prefix) for name in names)
result = self.run_in_uv_env(
[
"python",
"-c",
"import isaaclab; "
"from pathlib import Path; "
"assert list(isaaclab.__path__) == [str(Path(isaaclab.__file__).parent)]",
]
)
assert result.returncode == 0, f"isaaclab has multiple package roots:\n{result.stdout}\n{result.stderr}"
# from isaaclab import _deprioritize_prebundle_paths
def test_isaaclab_prebundle_path_sanitizer_exported(self):
"""Verify the wheel exports the prebundle path sanitizer used by AppLauncher."""
result = self.run_in_uv_env(
["python", "-c", "from isaaclab import _deprioritize_prebundle_paths; _deprioritize_prebundle_paths()"]
)
assert result.returncode == 0, f"import path sanitizer failed:\n{result.stdout}\n{result.stderr}"
# from isaaclab.app import AppLauncher
def test_isaaclab_app_importable(self):
"""Verify isaaclab.app and AppLauncher are importable."""
result = self.run_in_uv_env(["python", "-c", "from isaaclab.app import AppLauncher"])
assert result.returncode == 0, f"import isaaclab.app failed:\n{result.stdout}\n{result.stderr}"
# from isaaclab.envs import VideoRecorderCfg
def test_isaaclab_envs_importable(self):
"""Verify isaaclab.envs is importable."""
result = self.run_in_uv_env(["python", "-c", "from isaaclab.envs import VideoRecorderCfg"])
assert result.returncode == 0, f"import isaaclab.envs failed:\n{result.stdout}\n{result.stderr}"
# from isaaclab_assets.robots.allegro import ALLEGRO_HAND_CFG
def test_isaaclab_assets_importable(self):
"""Verify isaaclab_assets is importable."""
result = self.run_in_uv_env(["python", "-c", "from isaaclab_assets.robots.allegro import ALLEGRO_HAND_CFG"])
assert result.returncode == 0, f"import isaaclab_assets failed:\n{result.stdout}\n{result.stderr}"
# from isaaclab.scene import InteractiveSceneCfg
def test_isaaclab_scene_importable(self):
"""Verify isaaclab.scene and InteractiveSceneCfg are importable."""
result = self.run_in_uv_env(["python", "-c", "from isaaclab.scene import InteractiveSceneCfg"])
assert result.returncode == 0, f"import isaaclab.scene failed:\n{result.stdout}\n{result.stderr}"
# python -m isaaclab --help
def test_python_m_isaaclab_help_works(self):
"""Verify the isaaclab CLI is functional."""
result = self.run_in_uv_env(["python", "-m", "isaaclab", "--help"])
assert result.returncode == 0, f"isaaclab CLI help failed:\n{result.stdout}\n{result.stderr}"
def test_project_generator_is_bundled(self):
"""Verify the installed CLI includes the project generator."""
result = self.run_in_uv_env(
[
"python",
"-c",
"from isaaclab.cli.utils import ISAACLAB_ROOT; "
"assert (ISAACLAB_ROOT / 'tools/template/cli.py').is_file()",
]
)
assert result.returncode == 0, f"project generator is missing from the wheel:\n{result.stderr}"
# import pinocchio as pin; print(pin.__version__)
def test_pinocchio_importable(self):
"""Verify pinocchio is importable and has the expected version."""
result = self.run_in_uv_env(["python", "-c", "import pinocchio as pin; print(pin.__version__)"])
assert result.returncode == 0, f"import pinocchio failed:\n{result.stdout}\n{result.stderr}"
def test_install_rl_extras_omits_tetrahedralization_dependencies(self):
"""Verify the wheel's RL extras do not install pytetwild."""
result = self.run_in_uv_env(
[
"python",
"-c",
"import importlib.util; raise SystemExit(importlib.util.find_spec('pytetwild') is not None)",
]
)
assert result.returncode == 0, (
f"pytetwild should not be installed by {self._extras}:\n{result.stdout}\n{result.stderr}"
)