diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 33b8a7fa3e63..94b8378a2122 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -67,6 +67,13 @@ on: - develop - 'release/**' workflow_dispatch: + inputs: + marker: + description: >- + Run only the tests carrying this registered pytest marker, e.g. kitless. A job with no + marked file passes with an empty report. Empty runs every test. + type: string + default: '' # Concurrency control to prevent parallel runs on the same PR concurrency: @@ -266,6 +273,7 @@ jobs: lfs: true - uses: ./.github/actions/run-package-tests with: + ci-marker: ${{ inputs.marker || 'ov' }} image-tag: ${{ needs.config.outputs.ci_image_tag }} isaacsim-base-image: ${{ needs.config.outputs.isaacsim_image_name }} isaacsim-version: ${{ needs.config.outputs.isaacsim_image_tag }} @@ -294,6 +302,7 @@ jobs: lfs: true - uses: ./.github/actions/run-package-tests with: + ci-marker: ${{ inputs.marker || 'ov' }} image-tag: ${{ needs.config.outputs.ci_image_tag }} isaacsim-base-image: ${{ needs.config.outputs.isaacsim_image_name }} isaacsim-version: ${{ needs.config.outputs.isaacsim_image_tag }} @@ -322,6 +331,7 @@ jobs: lfs: true - uses: ./.github/actions/run-package-tests with: + ci-marker: ${{ inputs.marker || 'ov' }} image-tag: ${{ needs.config.outputs.ci_image_tag }} isaacsim-base-image: ${{ needs.config.outputs.isaacsim_image_name }} isaacsim-version: ${{ needs.config.outputs.isaacsim_image_tag }} @@ -349,6 +359,7 @@ jobs: lfs: true - uses: ./.github/actions/run-package-tests with: + ci-marker: ${{ inputs.marker || 'ov' }} image-tag: ${{ needs.config.outputs.ci_image_tag }} isaacsim-base-image: ${{ needs.config.outputs.isaacsim_image_name }} isaacsim-version: ${{ needs.config.outputs.isaacsim_image_tag }} @@ -376,6 +387,7 @@ jobs: lfs: true - uses: ./.github/actions/run-package-tests with: + ci-marker: ${{ inputs.marker || 'ov' }} image-tag: ${{ needs.config.outputs.ci_image_tag }} isaacsim-base-image: ${{ needs.config.outputs.isaacsim_image_name }} isaacsim-version: ${{ needs.config.outputs.isaacsim_image_tag }} @@ -403,6 +415,7 @@ jobs: lfs: true - uses: ./.github/actions/run-package-tests with: + ci-marker: ${{ inputs.marker || 'ov' }} image-tag: ${{ needs.config.outputs.ci_image_tag }} isaacsim-base-image: ${{ needs.config.outputs.isaacsim_image_name }} isaacsim-version: ${{ needs.config.outputs.isaacsim_image_tag }} @@ -434,6 +447,7 @@ jobs: lfs: true - uses: ./.github/actions/run-package-tests with: + ci-marker: ${{ inputs.marker || 'ov' }} image-tag: ${{ needs.config.outputs.ci_image_tag }} isaacsim-base-image: ${{ needs.config.outputs.isaacsim_image_name }} isaacsim-version: ${{ needs.config.outputs.isaacsim_image_tag }} @@ -468,6 +482,7 @@ jobs: id: ov_pins - uses: ./.github/actions/run-package-tests with: + ci-marker: ${{ inputs.marker || 'ov' }} image-tag: ${{ needs.config.outputs.ci_image_tag }} isaacsim-base-image: ${{ needs.config.outputs.isaacsim_image_name }} isaacsim-version: ${{ needs.config.outputs.isaacsim_image_tag }} @@ -499,6 +514,7 @@ jobs: lfs: true - uses: ./.github/actions/run-package-tests with: + ci-marker: ${{ inputs.marker || 'ov' }} image-tag: ${{ needs.config.outputs.ci_image_tag }} isaacsim-base-image: ${{ needs.config.outputs.isaacsim_image_name }} isaacsim-version: ${{ needs.config.outputs.isaacsim_image_tag }} @@ -523,6 +539,7 @@ jobs: lfs: true - uses: ./.github/actions/run-package-tests with: + ci-marker: ${{ inputs.marker || 'ov' }} image-tag: ${{ needs.config.outputs.ci_image_tag }} isaacsim-base-image: ${{ needs.config.outputs.isaacsim_image_name }} isaacsim-version: ${{ needs.config.outputs.isaacsim_image_tag }} @@ -546,6 +563,7 @@ jobs: lfs: true - uses: ./.github/actions/run-package-tests with: + ci-marker: ${{ inputs.marker || 'ov' }} image-tag: ${{ needs.config.outputs.ci_image_tag }} isaacsim-base-image: ${{ needs.config.outputs.isaacsim_image_name }} isaacsim-version: ${{ needs.config.outputs.isaacsim_image_tag }} @@ -570,6 +588,7 @@ jobs: lfs: true - uses: ./.github/actions/run-package-tests with: + ci-marker: ${{ inputs.marker || 'ov' }} image-tag: ${{ needs.config.outputs.ci_image_tag }} isaacsim-base-image: ${{ needs.config.outputs.isaacsim_image_name }} isaacsim-version: ${{ needs.config.outputs.isaacsim_image_tag }} @@ -594,6 +613,7 @@ jobs: lfs: true - uses: ./.github/actions/run-package-tests with: + ci-marker: ${{ inputs.marker || 'ov' }} image-tag: ${{ needs.config.outputs.ci_image_tag }} isaacsim-base-image: ${{ needs.config.outputs.isaacsim_image_name }} isaacsim-version: ${{ needs.config.outputs.isaacsim_image_tag }} @@ -618,6 +638,7 @@ jobs: lfs: true - uses: ./.github/actions/run-package-tests with: + ci-marker: ${{ inputs.marker || 'ov' }} image-tag: ${{ needs.config.outputs.ci_image_tag }} isaacsim-base-image: ${{ needs.config.outputs.isaacsim_image_name }} isaacsim-version: ${{ needs.config.outputs.isaacsim_image_tag }} @@ -641,6 +662,7 @@ jobs: lfs: true - uses: ./.github/actions/run-package-tests with: + ci-marker: ${{ inputs.marker || 'ov' }} image-tag: ${{ needs.config.outputs.ci_image_tag }} isaacsim-base-image: ${{ needs.config.outputs.isaacsim_image_name }} isaacsim-version: ${{ needs.config.outputs.isaacsim_image_tag }} @@ -664,6 +686,7 @@ jobs: lfs: true - uses: ./.github/actions/run-package-tests with: + ci-marker: ${{ inputs.marker || 'ov' }} image-tag: ${{ needs.config.outputs.ci_image_tag }} isaacsim-base-image: ${{ needs.config.outputs.isaacsim_image_name }} isaacsim-version: ${{ needs.config.outputs.isaacsim_image_tag }} @@ -688,6 +711,7 @@ jobs: lfs: true - uses: ./.github/actions/run-package-tests with: + ci-marker: ${{ inputs.marker || 'ov' }} image-tag: ${{ needs.config.outputs.ci_image_tag }} isaacsim-base-image: ${{ needs.config.outputs.isaacsim_image_name }} isaacsim-version: ${{ needs.config.outputs.isaacsim_image_tag }} @@ -717,6 +741,7 @@ jobs: id: ov_pins - uses: ./.github/actions/run-package-tests with: + ci-marker: ${{ inputs.marker || 'ov' }} image-tag: ${{ needs.config.outputs.ci_image_tag }} isaacsim-base-image: ${{ needs.config.outputs.isaacsim_image_name }} isaacsim-version: ${{ needs.config.outputs.isaacsim_image_tag }} @@ -761,6 +786,7 @@ jobs: lfs: true - uses: ./.github/actions/run-package-tests with: + ci-marker: ${{ inputs.marker || 'ov' }} image-tag: ${{ needs.config.outputs.ci_image_tag }}-curobo isaacsim-base-image: ${{ needs.config.outputs.isaacsim_image_name }} isaacsim-version: ${{ needs.config.outputs.isaacsim_image_tag }} @@ -802,6 +828,7 @@ jobs: lfs: true - uses: ./.github/actions/run-package-tests with: + ci-marker: ${{ inputs.marker || 'ov' }} image-tag: ${{ needs.config.outputs.ci_image_tag }}-curobo isaacsim-base-image: ${{ needs.config.outputs.isaacsim_image_name }} isaacsim-version: ${{ needs.config.outputs.isaacsim_image_tag }} @@ -834,6 +861,7 @@ jobs: lfs: true - uses: ./.github/actions/run-package-tests with: + ci-marker: ${{ inputs.marker || 'ov' }} image-tag: ${{ needs.config.outputs.ci_image_tag }} isaacsim-base-image: ${{ needs.config.outputs.isaacsim_image_name }} isaacsim-version: ${{ needs.config.outputs.isaacsim_image_tag }} @@ -857,6 +885,7 @@ jobs: lfs: true - uses: ./.github/actions/run-package-tests with: + ci-marker: ${{ inputs.marker || 'ov' }} image-tag: ${{ needs.config.outputs.ci_image_tag }} isaacsim-base-image: ${{ needs.config.outputs.isaacsim_image_name }} isaacsim-version: ${{ needs.config.outputs.isaacsim_image_tag }} @@ -901,6 +930,7 @@ jobs: id: ov_pins - uses: ./.github/actions/run-package-tests with: + ci-marker: ${{ inputs.marker || 'ov' }} image-tag: ${{ needs.config.outputs.ci_image_tag }} isaacsim-base-image: ${{ needs.config.outputs.isaacsim_image_name }} isaacsim-version: ${{ needs.config.outputs.isaacsim_image_tag }} @@ -948,6 +978,7 @@ jobs: id: ov_pins - uses: ./.github/actions/run-package-tests with: + ci-marker: ${{ inputs.marker || 'ov' }} image-tag: ${{ needs.config.outputs.ci_image_tag }} isaacsim-base-image: ${{ needs.config.outputs.isaacsim_image_name }} isaacsim-version: ${{ needs.config.outputs.isaacsim_image_tag }} @@ -1273,6 +1304,7 @@ jobs: lfs: true - uses: ./.github/actions/run-package-tests with: + ci-marker: ${{ inputs.marker || 'ov' }} image-tag: ${{ needs.config.outputs.ci_image_tag }} isaacsim-base-image: ${{ needs.config.outputs.isaacsim_image_name }} isaacsim-version: ${{ needs.config.outputs.isaacsim_image_tag }} @@ -1317,6 +1349,7 @@ jobs: id: ov_pins - uses: ./.github/actions/run-package-tests with: + ci-marker: ${{ inputs.marker || 'ov' }} image-tag: ${{ needs.config.outputs.ci_image_tag }} isaacsim-base-image: ${{ needs.config.outputs.isaacsim_image_name }} isaacsim-version: ${{ needs.config.outputs.isaacsim_image_tag }} diff --git a/pyproject.toml b/pyproject.toml index 75823806f714..73153a44bb42 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -373,6 +373,7 @@ markers = [ "rendering: test exercises the rendering / camera / visualizer pipeline", "smoke: tests for core installation, task, and RL functionality", "kitless: test must pass inside the Kit-less container, which has no Isaac Sim runtime", + "ov: test exercises the OV libraries (ovphysx, ovrtx, ovstage)", ] # Add pypi.nvidia.com so that `uv pip install isaaclab[isaacsim]` works without --extra-index-url. diff --git a/source/isaaclab/changelog.d/jichuanh-ci-marker-selection.skip b/source/isaaclab/changelog.d/jichuanh-ci-marker-selection.skip new file mode 100644 index 000000000000..9e1cbe23414d --- /dev/null +++ b/source/isaaclab/changelog.d/jichuanh-ci-marker-selection.skip @@ -0,0 +1 @@ +Rejected unregistered CI markers in the test orchestrator. diff --git a/source/isaaclab/test/cli/test_test_orchestrator_result_handling.py b/source/isaaclab/test/cli/test_test_orchestrator_result_handling.py index 07d712f4ba0b..2f2b69811275 100644 --- a/source/isaaclab/test/cli/test_test_orchestrator_result_handling.py +++ b/source/isaaclab/test/cli/test_test_orchestrator_result_handling.py @@ -718,3 +718,14 @@ def test_external_git_asset_tests_receive_extended_startup_deadline(): assert startup_deadline == orchestrator.test_settings.GIT_ASSET_STARTUP_TIMEOUT assert orchestrator._resolve_startup_deadline("test_sample.py", timeout=10000, is_cold_cache_test=False) == 120 + + +def test_ci_marker_must_be_a_registered_marker_name(): + """A marker run matches files by name, so an expression or a misspelling must not reach selection.""" + orchestrator = _load_orchestrator_module() + + registered = orchestrator._registered_markers(str(TOOLS_DIR.parent)) + + assert {"kitless", "arm_ci", "isaacsim_ci"} <= registered + assert "kitless and not rendering" not in registered + assert "kitles" not in registered diff --git a/source/isaaclab_newton/changelog.d/jichuanh-ci-marker-selection.skip b/source/isaaclab_newton/changelog.d/jichuanh-ci-marker-selection.skip new file mode 100644 index 000000000000..51bcbf53b393 --- /dev/null +++ b/source/isaaclab_newton/changelog.d/jichuanh-ci-marker-selection.skip @@ -0,0 +1 @@ +Marked the test files that run without Kit as kitless so a marker run can select them. diff --git a/source/isaaclab_newton/test/assets/test_cable_object.py b/source/isaaclab_newton/test/assets/test_cable_object.py index f26608129c86..08a5b294f4cf 100644 --- a/source/isaaclab_newton/test/assets/test_cable_object.py +++ b/source/isaaclab_newton/test/assets/test_cable_object.py @@ -30,6 +30,8 @@ from isaaclab_contrib.coupling import CouplerEntryCfg, CouplerProxyCfg, CouplerProxyMappingCfg +pytestmark = pytest.mark.kitless + @configclass class _CableSceneCfg(InteractiveSceneCfg): diff --git a/source/isaaclab_newton/test/assets/test_joint_coordinates.py b/source/isaaclab_newton/test/assets/test_joint_coordinates.py index 11b19f4c4602..8978b5b4d044 100644 --- a/source/isaaclab_newton/test/assets/test_joint_coordinates.py +++ b/source/isaaclab_newton/test/assets/test_joint_coordinates.py @@ -23,6 +23,8 @@ from newton.selection import ArticulationView from scipy.spatial.transform import Rotation +pytestmark = pytest.mark.kitless + # One revolute, one ball, one revolute -- the layout that hides an off-by-one when the tables are # built by walking the model instead of the view's own per-joint counts. COORD_COUNTS = [1, 4, 1] diff --git a/source/isaaclab_newton/test/assets/test_mpm_object.py b/source/isaaclab_newton/test/assets/test_mpm_object.py index fc47a9cac6fd..05158ee4c2e3 100644 --- a/source/isaaclab_newton/test/assets/test_mpm_object.py +++ b/source/isaaclab_newton/test/assets/test_mpm_object.py @@ -11,6 +11,8 @@ import pytest import torch +pytestmark = pytest.mark.kitless + newton = pytest.importorskip("newton") from isaaclab_newton.assets.mpm_object import MPMObject, MPMObjectCfg diff --git a/source/isaaclab_newton/test/cloner/test_clone_xform_math.py b/source/isaaclab_newton/test/cloner/test_clone_xform_math.py index 78507b19e4a7..3de464eeabed 100644 --- a/source/isaaclab_newton/test/cloner/test_clone_xform_math.py +++ b/source/isaaclab_newton/test/cloner/test_clone_xform_math.py @@ -10,6 +10,8 @@ import warp as wp from isaaclab_newton.cloner.newton_clone_utils import _quat_rotate +pytestmark = pytest.mark.kitless + _TOL = 1e-5 # Hand-picked quaternions (xyzw) that cover identity and the 180-degree cases where a sign diff --git a/source/isaaclab_newton/test/cloner/test_collision_approximation.py b/source/isaaclab_newton/test/cloner/test_collision_approximation.py index fee301834066..a946745358b4 100644 --- a/source/isaaclab_newton/test/cloner/test_collision_approximation.py +++ b/source/isaaclab_newton/test/cloner/test_collision_approximation.py @@ -12,6 +12,8 @@ from pxr import Sdf, Usd, UsdGeom, UsdPhysics, UsdShade +pytestmark = pytest.mark.kitless + _SOURCE = "/World/Asset" diff --git a/source/isaaclab_newton/test/cloner/test_newton_builder_world_hook.py b/source/isaaclab_newton/test/cloner/test_newton_builder_world_hook.py index b69f6bd41c57..ed1c13df6509 100644 --- a/source/isaaclab_newton/test/cloner/test_newton_builder_world_hook.py +++ b/source/isaaclab_newton/test/cloner/test_newton_builder_world_hook.py @@ -23,6 +23,8 @@ from isaaclab.cloner import make_clone_plan from isaaclab.sim import SimulationCfg, SimulationContext, SpawnerCfg, build_simulation_context +pytestmark = pytest.mark.kitless + replicate_module = importlib.import_module("isaaclab_newton.cloner.replicate") diff --git a/source/isaaclab_newton/test/cloner/test_rename_builder_labels.py b/source/isaaclab_newton/test/cloner/test_rename_builder_labels.py index caafc902e998..7966c168bbc0 100644 --- a/source/isaaclab_newton/test/cloner/test_rename_builder_labels.py +++ b/source/isaaclab_newton/test/cloner/test_rename_builder_labels.py @@ -11,6 +11,7 @@ import newton import numpy as np +import pytest import warp as wp from isaaclab_newton.cloner import NewtonReplicateContext from isaaclab_newton.cloner import newton_clone_utils as newton_clone_utils_module @@ -27,6 +28,8 @@ from isaaclab.sim import SimulationContext, SpawnerCfg from isaaclab.sim.schemas import define_deformable_curve_properties +pytestmark = pytest.mark.kitless + class TestReplicateBuilderMapping(unittest.TestCase): def test_world_prototypes_preserve_repeated_instances_and_default_poses(self): diff --git a/source/isaaclab_newton/test/cloner/test_visual_shape_import.py b/source/isaaclab_newton/test/cloner/test_visual_shape_import.py index 6cd49c001fba..9ff3a49c13f7 100644 --- a/source/isaaclab_newton/test/cloner/test_visual_shape_import.py +++ b/source/isaaclab_newton/test/cloner/test_visual_shape_import.py @@ -12,6 +12,8 @@ from pxr import Usd, UsdGeom, UsdPhysics +pytestmark = pytest.mark.kitless + @pytest.mark.parametrize("load_visual_shapes", [True, False]) @pytest.mark.parametrize("dynamic", [True, False]) diff --git a/source/isaaclab_newton/test/controllers/test_newton_controllers.py b/source/isaaclab_newton/test/controllers/test_newton_controllers.py index 61b3fa32af33..48b62dec6957 100644 --- a/source/isaaclab_newton/test/controllers/test_newton_controllers.py +++ b/source/isaaclab_newton/test/controllers/test_newton_controllers.py @@ -24,6 +24,8 @@ from isaaclab.utils import math as math_utils +pytestmark = pytest.mark.kitless + _NUM_ENVS = 3 _NUM_JOINTS = 7 _DEVICE = "cpu" diff --git a/source/isaaclab_newton/test/controllers/test_newton_ik_solver.py b/source/isaaclab_newton/test/controllers/test_newton_ik_solver.py index 7ea6e8733cce..d338747111c1 100644 --- a/source/isaaclab_newton/test/controllers/test_newton_ik_solver.py +++ b/source/isaaclab_newton/test/controllers/test_newton_ik_solver.py @@ -7,6 +7,7 @@ import isaaclab_newton.controllers.ik.newton_ik_objectives as objectives_module import isaaclab_newton.controllers.ik.newton_ik_solver as ik_solver_module +import pytest import torch import warp as wp from isaaclab_newton.controllers.ik.newton_ik_objectives import ( @@ -24,6 +25,8 @@ from isaaclab.utils import configclass +pytestmark = pytest.mark.kitless + # Maps the stub body names used across these tests to Newton link indices. _LINKS = {"ee": 0, "torso": 1, "custom": 0} diff --git a/source/isaaclab_newton/test/envs/test_events.py b/source/isaaclab_newton/test/envs/test_events.py index c60929ae347d..74ecb67b3a9d 100644 --- a/source/isaaclab_newton/test/envs/test_events.py +++ b/source/isaaclab_newton/test/envs/test_events.py @@ -36,6 +36,8 @@ from isaaclab.utils import configclass from isaaclab.visualizers import VisualizerCfg +pytestmark = pytest.mark.kitless + @configclass class ActionsCfg: diff --git a/source/isaaclab_newton/test/physics/test_mjwarp_tendon_control.py b/source/isaaclab_newton/test/physics/test_mjwarp_tendon_control.py index 93c6413fb639..da9490ca595b 100644 --- a/source/isaaclab_newton/test/physics/test_mjwarp_tendon_control.py +++ b/source/isaaclab_newton/test/physics/test_mjwarp_tendon_control.py @@ -15,6 +15,8 @@ ) from newton.solvers import SolverMuJoCo +pytestmark = pytest.mark.kitless + _TENDON = int(SolverMuJoCo.TrnType.TENDON) _JOINT = 0 diff --git a/source/isaaclab_newton/test/physics/test_mpm_reset_mask_contract.py b/source/isaaclab_newton/test/physics/test_mpm_reset_mask_contract.py index c22ba0b0d7e7..21151527d37d 100644 --- a/source/isaaclab_newton/test/physics/test_mpm_reset_mask_contract.py +++ b/source/isaaclab_newton/test/physics/test_mpm_reset_mask_contract.py @@ -13,6 +13,8 @@ from isaaclab_newton.physics import MPMSolverCfg, NewtonManager, NewtonMPMManager from newton.solvers import SolverImplicitMPM +pytestmark = pytest.mark.kitless + @pytest.fixture(scope="module") def cpu_mpm_solver_and_state(): diff --git a/source/isaaclab_newton/test/physics/test_newton_manager_abstraction.py b/source/isaaclab_newton/test/physics/test_newton_manager_abstraction.py index c5f219d72a1f..d46b3d290e97 100644 --- a/source/isaaclab_newton/test/physics/test_newton_manager_abstraction.py +++ b/source/isaaclab_newton/test/physics/test_newton_manager_abstraction.py @@ -70,6 +70,8 @@ from isaaclab.sim import SimulationCfg, SimulationContext, build_simulation_context from isaaclab.test.utils import test_devices +pytestmark = pytest.mark.kitless + # --------------------------------------------------------------------------- # Lightweight (no sim) parametrisation # --------------------------------------------------------------------------- diff --git a/source/isaaclab_newton/test/physics/test_vbd_core.py b/source/isaaclab_newton/test/physics/test_vbd_core.py index 112aa5dc166d..a8e5f196485a 100644 --- a/source/isaaclab_newton/test/physics/test_vbd_core.py +++ b/source/isaaclab_newton/test/physics/test_vbd_core.py @@ -20,6 +20,8 @@ from isaaclab.sim import BackendCfg, SimulationContext from isaaclab.utils import replace +pytestmark = pytest.mark.kitless + # The soft-contact and simulation axes are independent, so each value is covered once. @pytest.mark.parametrize( diff --git a/source/isaaclab_newton/test/renderers/test_segmentation.py b/source/isaaclab_newton/test/renderers/test_segmentation.py index e38194b21735..8a708f45ccd0 100644 --- a/source/isaaclab_newton/test/renderers/test_segmentation.py +++ b/source/isaaclab_newton/test/renderers/test_segmentation.py @@ -27,6 +27,8 @@ from isaaclab.renderers.segmentation_colors import BACKGROUND_ID, UNLABELLED_ID, pack_rgba, random_color_from_id from isaaclab.sim.utils.semantics import add_labels +pytestmark = pytest.mark.kitless + def _cfg(**overrides): """Minimal renderer-cfg stand-in exposing only the fields the mapper reads.""" diff --git a/source/isaaclab_newton/test/renderers/test_visual_material.py b/source/isaaclab_newton/test/renderers/test_visual_material.py index c873f109bb87..2663f8498646 100644 --- a/source/isaaclab_newton/test/renderers/test_visual_material.py +++ b/source/isaaclab_newton/test/renderers/test_visual_material.py @@ -5,6 +5,7 @@ """Tests for Newton's compiled visual-material writers.""" +import pytest import torch import warp as wp from isaaclab_newton.physics import NewtonBackendCfg, NewtonBuilderCfg @@ -21,6 +22,8 @@ from isaaclab.renderers.base_renderer import VisualMaterialBatch from isaaclab.sim import SimulationContext +pytestmark = pytest.mark.kitless + def _srgb(colors: torch.Tensor) -> torch.Tensor: return torch.where(colors <= 0.0031308, 12.92 * colors, 1.055 * colors.pow(1.0 / 2.4) - 0.055) diff --git a/source/isaaclab_newton/test/sensors/test_camera_opencv_distortion_newton.py b/source/isaaclab_newton/test/sensors/test_camera_opencv_distortion_newton.py index d5fb86f9fc33..a3cdce732fa3 100644 --- a/source/isaaclab_newton/test/sensors/test_camera_opencv_distortion_newton.py +++ b/source/isaaclab_newton/test/sensors/test_camera_opencv_distortion_newton.py @@ -28,7 +28,7 @@ from isaaclab.utils.configclass import configclass from isaaclab.utils.math import create_rotation_matrix_from_view, quat_from_matrix -pytestmark = [pytest.mark.integration, pytest.mark.rendering] +pytestmark = [pytest.mark.integration, pytest.mark.rendering, pytest.mark.kitless] SIM_DT = 1.0 / 60.0 WIDTH, HEIGHT = 640, 480 diff --git a/source/isaaclab_newton/test/sensors/test_contact_sensor.py b/source/isaaclab_newton/test/sensors/test_contact_sensor.py index 7babb6d24639..dde406fd214e 100644 --- a/source/isaaclab_newton/test/sensors/test_contact_sensor.py +++ b/source/isaaclab_newton/test/sensors/test_contact_sensor.py @@ -57,6 +57,8 @@ from isaaclab_assets.robots.allegro import ALLEGRO_HAND_CFG +pytestmark = pytest.mark.kitless + ## # Scene Configuration ## diff --git a/source/isaaclab_newton/test/sensors/test_contact_sensor_history.py b/source/isaaclab_newton/test/sensors/test_contact_sensor_history.py index 934758cdb923..f2bcbac81ce8 100644 --- a/source/isaaclab_newton/test/sensors/test_contact_sensor_history.py +++ b/source/isaaclab_newton/test/sensors/test_contact_sensor_history.py @@ -9,6 +9,7 @@ import warnings +import pytest import torch import warp as wp from isaaclab_newton.sensors.contact_sensor.contact_sensor_data import ContactSensorData @@ -17,6 +18,8 @@ update_contact_sensor_kernel, ) +pytestmark = pytest.mark.kitless + def test_force_matrix_history_rolls_newest_first_and_honors_mask(): """Test newest-first ordering of every history buffer without advancing masked environments. diff --git a/source/isaaclab_newton/test/sensors/test_frame_transformer.py b/source/isaaclab_newton/test/sensors/test_frame_transformer.py index ad1389bc23b2..94d52bf9db7d 100644 --- a/source/isaaclab_newton/test/sensors/test_frame_transformer.py +++ b/source/isaaclab_newton/test/sensors/test_frame_transformer.py @@ -32,6 +32,8 @@ ## from isaaclab_assets.robots.anymal import ANYMAL_C_CFG # isort:skip +pytestmark = pytest.mark.kitless + def quat_from_euler_rpy(roll, pitch, yaw, degrees=False): """Converts Euler XYZ to Quaternion (x, y, z, w).""" diff --git a/source/isaaclab_newton/test/sensors/test_imu.py b/source/isaaclab_newton/test/sensors/test_imu.py index fbb77ecbe00a..6e50a335f142 100644 --- a/source/isaaclab_newton/test/sensors/test_imu.py +++ b/source/isaaclab_newton/test/sensors/test_imu.py @@ -22,6 +22,8 @@ from isaaclab.terrains import TerrainImporterCfg from isaaclab.utils import configclass +pytestmark = pytest.mark.kitless + @configclass class ImuTestSceneCfg(InteractiveSceneCfg): diff --git a/source/isaaclab_newton/test/sensors/test_joint_wrench_sensor.py b/source/isaaclab_newton/test/sensors/test_joint_wrench_sensor.py index 7a7ccf9a74b1..1fa938c8ddca 100644 --- a/source/isaaclab_newton/test/sensors/test_joint_wrench_sensor.py +++ b/source/isaaclab_newton/test/sensors/test_joint_wrench_sensor.py @@ -36,6 +36,8 @@ from isaaclab_assets.robots.ant import ANT_CFG +pytestmark = pytest.mark.kitless + def _make_single_joint_articulation_cfg() -> ArticulationCfg: """Single-joint revolute test articulation (root ``CenterPivot`` + arm ``Arm``).""" diff --git a/source/isaaclab_newton/test/sensors/test_newton_raycast_sensor.py b/source/isaaclab_newton/test/sensors/test_newton_raycast_sensor.py index 6de5c0e0edc4..c1f8318993c2 100644 --- a/source/isaaclab_newton/test/sensors/test_newton_raycast_sensor.py +++ b/source/isaaclab_newton/test/sensors/test_newton_raycast_sensor.py @@ -40,6 +40,8 @@ from isaaclab.terrains import TerrainImporterCfg from isaaclab.utils import configclass +pytestmark = pytest.mark.kitless + SENSOR_HEIGHT = 2.0 RAY_OFFSET = 0.2 RAY_START_HEIGHT = SENSOR_HEIGHT - RAY_OFFSET diff --git a/source/isaaclab_newton/test/sensors/test_pva.py b/source/isaaclab_newton/test/sensors/test_pva.py index f7bdb49e9137..34ae63de71dc 100644 --- a/source/isaaclab_newton/test/sensors/test_pva.py +++ b/source/isaaclab_newton/test/sensors/test_pva.py @@ -22,6 +22,8 @@ from isaaclab.terrains import TerrainImporterCfg from isaaclab.utils import configclass +pytestmark = pytest.mark.kitless + @configclass class PvaTestSceneCfg(InteractiveSceneCfg): diff --git a/source/isaaclab_newton/test/sensors/test_site_injection.py b/source/isaaclab_newton/test/sensors/test_site_injection.py index 119925292059..2d192fc10e61 100644 --- a/source/isaaclab_newton/test/sensors/test_site_injection.py +++ b/source/isaaclab_newton/test/sensors/test_site_injection.py @@ -13,6 +13,8 @@ from isaaclab.utils.warp.math_ops import transform_to_vec_quat +pytestmark = pytest.mark.kitless + # --------------------------------------------------------------------------- # transform_to_vec_quat # --------------------------------------------------------------------------- diff --git a/source/isaaclab_newton/test/sim/test_cable_usd_import.py b/source/isaaclab_newton/test/sim/test_cable_usd_import.py index 7bcfae13e9de..cce29078fb39 100644 --- a/source/isaaclab_newton/test/sim/test_cable_usd_import.py +++ b/source/isaaclab_newton/test/sim/test_cable_usd_import.py @@ -10,6 +10,8 @@ from isaaclab.sim.spawners.materials import CableMaterialCfg from isaaclab.sim.spawners.shapes import CableCfg +pytestmark = pytest.mark.kitless + # Cable joint degrees of freedom, in the order Newton lays them out. _SHEAR_X, _SHEAR_Y, _STRETCH, _BEND_X, _BEND_Y, _TWIST = range(6) diff --git a/source/isaaclab_newton/test/sim/test_mpm_spawners.py b/source/isaaclab_newton/test/sim/test_mpm_spawners.py index 234a03ffcda6..bc4a087601b9 100644 --- a/source/isaaclab_newton/test/sim/test_mpm_spawners.py +++ b/source/isaaclab_newton/test/sim/test_mpm_spawners.py @@ -20,7 +20,7 @@ import isaaclab.sim as sim_utils -pytestmark = pytest.mark.unit +pytestmark = [pytest.mark.unit, pytest.mark.kitless] @pytest.fixture diff --git a/source/isaaclab_newton/test/sim/test_mpm_visualization.py b/source/isaaclab_newton/test/sim/test_mpm_visualization.py index 3b7e283e0988..82739938bf01 100644 --- a/source/isaaclab_newton/test/sim/test_mpm_visualization.py +++ b/source/isaaclab_newton/test/sim/test_mpm_visualization.py @@ -15,6 +15,8 @@ import isaaclab.sim as sim_utils +pytestmark = pytest.mark.kitless + _PRIM_PATHS = ["/World/envs/env_0/Sand/Particles", "/World/envs/env_1/Sand/Particles"] """Environment-namespaced points prims, matching the ``{ENV_REGEX_NS}//Particles`` paths used by MPMObject.""" diff --git a/source/isaaclab_newton/test/sim/test_views_xform_prim_newton.py b/source/isaaclab_newton/test/sim/test_views_xform_prim_newton.py index 236ddce46764..c7cc19fc7c7d 100644 --- a/source/isaaclab_newton/test/sim/test_views_xform_prim_newton.py +++ b/source/isaaclab_newton/test/sim/test_views_xform_prim_newton.py @@ -37,6 +37,8 @@ from isaaclab.sim import SimulationCfg, build_simulation_context from isaaclab.utils import configclass +pytestmark = pytest.mark.kitless + NEWTON_SIM_CFG = SimulationCfg(physics=NewtonCfg(solver_cfg=MJWarpSolverCfg())) WORLD_MARKER_POS = (5.0, 3.0, 1.0) SITE_PATH = "/World/Robot/SiteFrame" diff --git a/source/isaaclab_ov/changelog.d/jichuanh-ci-marker-selection.skip b/source/isaaclab_ov/changelog.d/jichuanh-ci-marker-selection.skip new file mode 100644 index 000000000000..51bcbf53b393 --- /dev/null +++ b/source/isaaclab_ov/changelog.d/jichuanh-ci-marker-selection.skip @@ -0,0 +1 @@ +Marked the test files that run without Kit as kitless so a marker run can select them. diff --git a/source/isaaclab_ov/test/assets/test_articulation.py b/source/isaaclab_ov/test/assets/test_articulation.py index 86cf41b91585..b22678bc7a95 100644 --- a/source/isaaclab_ov/test/assets/test_articulation.py +++ b/source/isaaclab_ov/test/assets/test_articulation.py @@ -72,7 +72,7 @@ from isaaclab_assets import FRANKA_PANDA_CFG # noqa: E402 -pytestmark = pytest.mark.integration +pytestmark = [pytest.mark.integration, pytest.mark.kitless] _FIXTURE = Path(__file__).parent / "data" / "articulation_ordering_branching.usda" _STIFFNESS, _DAMPING, _MAX_FORCE = 5.0, 0.5, 100.0 diff --git a/source/isaaclab_ov/test/assets/test_deformable_object.py b/source/isaaclab_ov/test/assets/test_deformable_object.py index b965811c1de8..15481b91858a 100644 --- a/source/isaaclab_ov/test/assets/test_deformable_object.py +++ b/source/isaaclab_ov/test/assets/test_deformable_object.py @@ -44,6 +44,8 @@ pretriangulated_surface_deformable_spawn_cfg, ) +pytestmark = pytest.mark.kitless + wp.init() diff --git a/source/isaaclab_ov/test/assets/test_rigid_object.py b/source/isaaclab_ov/test/assets/test_rigid_object.py index d6a5276fbcfa..04b2d0cfeb10 100644 --- a/source/isaaclab_ov/test/assets/test_rigid_object.py +++ b/source/isaaclab_ov/test/assets/test_rigid_object.py @@ -46,7 +46,7 @@ from isaaclab.utils import configclass # noqa: E402 from isaaclab.utils.math import quat_apply_inverse, quat_mul # noqa: E402 -pytestmark = pytest.mark.integration +pytestmark = [pytest.mark.integration, pytest.mark.kitless] _NUM_CUBES = 2 _NUM_ENVS, _NUM_BODIES = 2, 3 diff --git a/source/isaaclab_ov/test/conftest.py b/source/isaaclab_ov/test/conftest.py new file mode 100644 index 000000000000..49ad9038118e --- /dev/null +++ b/source/isaaclab_ov/test/conftest.py @@ -0,0 +1,14 @@ +# 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 + +"""Every test in this package exercises the OV libraries.""" + +import pytest + + +def pytest_itemcollected(item): + # Runs before ``-m`` deselects, so ``-m ov`` keeps these tests. The CI runner finds + # this marker by reading this file, as it does a module-level ``pytestmark``. + item.add_marker(pytest.mark.ov) diff --git a/source/isaaclab_ov/test/envs/test_events.py b/source/isaaclab_ov/test/envs/test_events.py index b84fab5973a6..7348f79d112b 100644 --- a/source/isaaclab_ov/test/envs/test_events.py +++ b/source/isaaclab_ov/test/envs/test_events.py @@ -32,6 +32,8 @@ from isaaclab.sim import SimulationCfg, build_simulation_context from isaaclab.test.utils import DeviceScope, test_devices +pytestmark = pytest.mark.kitless + @pytest.fixture(scope="module", params=test_devices(DeviceScope.CUDA)) def event_env(request, tmp_path_factory): diff --git a/source/isaaclab_ov/test/physics/test_ovphysx_compat.py b/source/isaaclab_ov/test/physics/test_ovphysx_compat.py index 53aaef7d3e54..46ca1cfa9a94 100644 --- a/source/isaaclab_ov/test/physics/test_ovphysx_compat.py +++ b/source/isaaclab_ov/test/physics/test_ovphysx_compat.py @@ -22,6 +22,7 @@ bool(_MISSING_MODULES), reason=f"requires optional modules: {', '.join(_MISSING_MODULES)}", ), + pytest.mark.kitless, ] if not _MISSING_MODULES: diff --git a/source/isaaclab_ov/test/physics/test_ovphysx_gravity.py b/source/isaaclab_ov/test/physics/test_ovphysx_gravity.py index 8661417e0bb9..beb117425a48 100644 --- a/source/isaaclab_ov/test/physics/test_ovphysx_gravity.py +++ b/source/isaaclab_ov/test/physics/test_ovphysx_gravity.py @@ -23,6 +23,8 @@ from isaaclab.sim import SimulationCfg, build_simulation_context from isaaclab.test.utils import DeviceScope, test_devices +pytestmark = pytest.mark.kitless + @pytest.mark.parametrize("device", test_devices(DeviceScope.CUDA)) def test_gravity_event_changes_rigid_body_motion(device): diff --git a/source/isaaclab_ov/test/physics/test_ovphysx_manager_lifecycle.py b/source/isaaclab_ov/test/physics/test_ovphysx_manager_lifecycle.py index 10fba55987d9..0b60cd9204ef 100644 --- a/source/isaaclab_ov/test/physics/test_ovphysx_manager_lifecycle.py +++ b/source/isaaclab_ov/test/physics/test_ovphysx_manager_lifecycle.py @@ -18,6 +18,8 @@ from isaaclab.test.utils import DeviceScope, test_devices +pytestmark = pytest.mark.kitless + pytest.importorskip("ovphysx.types", reason="ovphysx wheel not installed") _CPU_DEVICES = test_devices(DeviceScope.CPU) diff --git a/source/isaaclab_ov/test/physics/test_ovphysx_scene_data_backend.py b/source/isaaclab_ov/test/physics/test_ovphysx_scene_data_backend.py index 5228f92205bc..54ca18d3daef 100644 --- a/source/isaaclab_ov/test/physics/test_ovphysx_scene_data_backend.py +++ b/source/isaaclab_ov/test/physics/test_ovphysx_scene_data_backend.py @@ -12,6 +12,8 @@ import pytest +pytestmark = pytest.mark.kitless + # The OVPhysX runtime wheel is optional. Skip gracefully when it is not installed; # CI jobs that need OVPhysX coverage install it explicitly. pytest.importorskip("ovphysx.types", reason="ovphysx wheel not installed") diff --git a/source/isaaclab_ov/test/sensors/test_contact_sensor.py b/source/isaaclab_ov/test/sensors/test_contact_sensor.py index b919fae68fc2..d8f1683504c5 100644 --- a/source/isaaclab_ov/test/sensors/test_contact_sensor.py +++ b/source/isaaclab_ov/test/sensors/test_contact_sensor.py @@ -52,6 +52,8 @@ from isaaclab.test.utils import test_devices # noqa: E402 from isaaclab.utils import configclass, replace # noqa: E402 +pytestmark = pytest.mark.kitless + wp.init() diff --git a/source/isaaclab_ov/test/sensors/test_contact_sensor_kernels.py b/source/isaaclab_ov/test/sensors/test_contact_sensor_kernels.py index 0f751a084d2d..a3011b3b0cd7 100644 --- a/source/isaaclab_ov/test/sensors/test_contact_sensor_kernels.py +++ b/source/isaaclab_ov/test/sensors/test_contact_sensor_kernels.py @@ -12,6 +12,8 @@ from isaaclab.test.utils import DeviceScope, test_devices +pytestmark = pytest.mark.kitless + @pytest.mark.parametrize("device", test_devices(DeviceScope.CUDA)) @pytest.mark.parametrize("use_mask, capacity", [(False, None), (True, 5)]) diff --git a/source/isaaclab_ov/test/sensors/test_frame_transformer.py b/source/isaaclab_ov/test/sensors/test_frame_transformer.py index 6ac9e360f630..a4acb7a881cc 100644 --- a/source/isaaclab_ov/test/sensors/test_frame_transformer.py +++ b/source/isaaclab_ov/test/sensors/test_frame_transformer.py @@ -24,6 +24,8 @@ import torch import warp as wp +pytestmark = pytest.mark.kitless + # OVRTX-only CI jobs collect the consolidated isaaclab_ov test suite without # the optional ovphysx wheel. Skip the OVPhysX tests gracefully in that case. pytest.importorskip("ovphysx.types", reason="ovphysx wheel not installed") diff --git a/source/isaaclab_ov/test/sensors/test_imu.py b/source/isaaclab_ov/test/sensors/test_imu.py index 8ea15cae95c7..9a36e76181df 100644 --- a/source/isaaclab_ov/test/sensors/test_imu.py +++ b/source/isaaclab_ov/test/sensors/test_imu.py @@ -32,6 +32,8 @@ # --------------------------------------------------------------------------- import pytest +pytestmark = pytest.mark.kitless + pytest.importorskip("ovphysx.types", reason="ovphysx wheel not installed") _TT_module = pytest.importorskip( "isaaclab_ov.tensor_types", diff --git a/source/isaaclab_ov/test/sensors/test_joint_wrench_sensor.py b/source/isaaclab_ov/test/sensors/test_joint_wrench_sensor.py index b35efb30eb6d..5d57caa46435 100644 --- a/source/isaaclab_ov/test/sensors/test_joint_wrench_sensor.py +++ b/source/isaaclab_ov/test/sensors/test_joint_wrench_sensor.py @@ -45,6 +45,8 @@ from isaaclab_assets.robots.ant import ANT_CFG # noqa: E402 +pytestmark = pytest.mark.kitless + wp.init() diff --git a/source/isaaclab_ov/test/sensors/test_pva.py b/source/isaaclab_ov/test/sensors/test_pva.py index 39dff9597416..b10bbf60f8f1 100644 --- a/source/isaaclab_ov/test/sensors/test_pva.py +++ b/source/isaaclab_ov/test/sensors/test_pva.py @@ -27,6 +27,8 @@ # --------------------------------------------------------------------------- import pytest +pytestmark = pytest.mark.kitless + pytest.importorskip("ovphysx.types", reason="ovphysx wheel not installed") _TT_module = pytest.importorskip( "isaaclab_ov.tensor_types", diff --git a/source/isaaclab_ov/test/sensors/test_ray_caster.py b/source/isaaclab_ov/test/sensors/test_ray_caster.py index ff504b841cd1..e25f4c87d391 100644 --- a/source/isaaclab_ov/test/sensors/test_ray_caster.py +++ b/source/isaaclab_ov/test/sensors/test_ray_caster.py @@ -9,11 +9,14 @@ from types import SimpleNamespace +import pytest import torch import warp as wp from isaaclab_ov import tensor_types as TT from isaaclab_ov.sensors.ray_caster import ray_caster as ray_caster_module +pytestmark = pytest.mark.kitless + class _FakeBinding: shape = (3, 7) diff --git a/source/isaaclab_ov/test/sim/test_ovphysx_view.py b/source/isaaclab_ov/test/sim/test_ovphysx_view.py index 8bca85fad3cd..9d50cf817045 100644 --- a/source/isaaclab_ov/test/sim/test_ovphysx_view.py +++ b/source/isaaclab_ov/test/sim/test_ovphysx_view.py @@ -41,6 +41,8 @@ ) from ovphysx.types import TensorType # noqa: E402 +pytestmark = pytest.mark.kitless + wp.init() wp.set_device("cpu") _HAS_CUDA = wp.get_cuda_device_count() > 0 diff --git a/source/isaaclab_ov/test/sim/test_views_xform_prim_ovphysx.py b/source/isaaclab_ov/test/sim/test_views_xform_prim_ovphysx.py index b08cbd83c0a6..2cda878bb83a 100644 --- a/source/isaaclab_ov/test/sim/test_views_xform_prim_ovphysx.py +++ b/source/isaaclab_ov/test/sim/test_views_xform_prim_ovphysx.py @@ -25,6 +25,8 @@ from isaaclab.sim import SimulationCfg, build_simulation_context # noqa: E402 from isaaclab.sim.views import FrameView # noqa: E402 +pytestmark = pytest.mark.kitless + OVPHYSX_SIM_CFG = SimulationCfg(physics=OvPhysxCfg()) diff --git a/source/isaaclab_ov/test/test_cloner.py b/source/isaaclab_ov/test/test_cloner.py index 4503b1752acd..9f9edbf6ade5 100644 --- a/source/isaaclab_ov/test/test_cloner.py +++ b/source/isaaclab_ov/test/test_cloner.py @@ -20,6 +20,8 @@ from isaaclab.cloner import make_clone_plan from isaaclab.physics import PhysicsManager +pytestmark = pytest.mark.kitless + def _pose_matrix(position: tuple[float, float, float], quaternion: tuple[float, float, float, float]) -> Gf.Matrix4d: """Build a USD pose matrix from an xyzw quaternion.""" diff --git a/source/isaaclab_ov/test/test_ovrtx_annotator_utils.py b/source/isaaclab_ov/test/test_ovrtx_annotator_utils.py index 7cf343b56485..3ff13f345ae2 100644 --- a/source/isaaclab_ov/test/test_ovrtx_annotator_utils.py +++ b/source/isaaclab_ov/test/test_ovrtx_annotator_utils.py @@ -18,6 +18,7 @@ bool(_MISSING_MODULES), reason=f"requires optional modules: {', '.join(_MISSING_MODULES)}", ), + pytest.mark.kitless, ] if not _MISSING_MODULES: diff --git a/source/isaaclab_ov/test/test_ovrtx_clone_plan.py b/source/isaaclab_ov/test/test_ovrtx_clone_plan.py index 9c078b1a376c..3a2cfa6bb396 100644 --- a/source/isaaclab_ov/test/test_ovrtx_clone_plan.py +++ b/source/isaaclab_ov/test/test_ovrtx_clone_plan.py @@ -31,6 +31,7 @@ bool(_MISSING_MODULES), reason=f"requires optional modules: {', '.join(_MISSING_MODULES)}", ), + pytest.mark.kitless, ] if not _MISSING_MODULES: diff --git a/source/isaaclab_ov/test/test_ovrtx_compat.py b/source/isaaclab_ov/test/test_ovrtx_compat.py index 96abc4ff7cfc..c86e98a85cb1 100644 --- a/source/isaaclab_ov/test/test_ovrtx_compat.py +++ b/source/isaaclab_ov/test/test_ovrtx_compat.py @@ -22,6 +22,7 @@ bool(_MISSING_MODULES), reason=f"requires optional modules: {', '.join(_MISSING_MODULES)}", ), + pytest.mark.kitless, ] if not _MISSING_MODULES: diff --git a/source/isaaclab_ov/test/test_ovrtx_deformable_bindings.py b/source/isaaclab_ov/test/test_ovrtx_deformable_bindings.py index 51bbdd2542c4..2888aa2f5a62 100644 --- a/source/isaaclab_ov/test/test_ovrtx_deformable_bindings.py +++ b/source/isaaclab_ov/test/test_ovrtx_deformable_bindings.py @@ -19,7 +19,10 @@ _REQUIRED_MODULES = ("isaaclab_ov", "ovrtx", "pxr") _MISSING_MODULES = [module for module in _REQUIRED_MODULES if importlib.util.find_spec(module) is None] -pytestmark = pytest.mark.skipif(bool(_MISSING_MODULES), reason=f"requires optional modules: {_MISSING_MODULES}") +pytestmark = [ + pytest.mark.skipif(bool(_MISSING_MODULES), reason=f"requires optional modules: {_MISSING_MODULES}"), + pytest.mark.kitless, +] if not _MISSING_MODULES: import isaaclab_ov.renderers.ovrtx_renderer as ovrtx_renderer_module diff --git a/source/isaaclab_ov/test/test_ovrtx_renderer_contract.py b/source/isaaclab_ov/test/test_ovrtx_renderer_contract.py index 7317f8f8b12d..59374a252b07 100644 --- a/source/isaaclab_ov/test/test_ovrtx_renderer_contract.py +++ b/source/isaaclab_ov/test/test_ovrtx_renderer_contract.py @@ -34,6 +34,7 @@ bool(_MISSING_MODULES), reason=f"requires optional modules: {', '.join(_MISSING_MODULES)}", ), + pytest.mark.kitless, ] if not _MISSING_MODULES: diff --git a/source/isaaclab_ov/test/test_ovrtx_renderer_kernels.py b/source/isaaclab_ov/test/test_ovrtx_renderer_kernels.py index 09d5dcb5e52c..0d5e0831c3fa 100644 --- a/source/isaaclab_ov/test/test_ovrtx_renderer_kernels.py +++ b/source/isaaclab_ov/test/test_ovrtx_renderer_kernels.py @@ -15,6 +15,8 @@ from isaaclab.renderers.segmentation_colors import pack_rgba, random_color_from_id +pytestmark = pytest.mark.kitless + DEVICE = "cuda:0" diff --git a/source/isaaclab_ov/test/test_ovrtx_renderer_rigid_object_rendering.py b/source/isaaclab_ov/test/test_ovrtx_renderer_rigid_object_rendering.py index 5289866d9a23..5b89ae8d5c50 100644 --- a/source/isaaclab_ov/test/test_ovrtx_renderer_rigid_object_rendering.py +++ b/source/isaaclab_ov/test/test_ovrtx_renderer_rigid_object_rendering.py @@ -31,6 +31,7 @@ pytest.mark.rendering, pytest.mark.isaacsim_ci, pytest.mark.skipif(bool(_MISSING_MODULES), reason=f"requires optional modules: {', '.join(_MISSING_MODULES)}"), + pytest.mark.kitless, ] if not _MISSING_MODULES: diff --git a/source/isaaclab_ov/test/test_ovrtx_shader_cache_redirect.py b/source/isaaclab_ov/test/test_ovrtx_shader_cache_redirect.py index dda1a37cba0a..2d9708753913 100644 --- a/source/isaaclab_ov/test/test_ovrtx_shader_cache_redirect.py +++ b/source/isaaclab_ov/test/test_ovrtx_shader_cache_redirect.py @@ -19,6 +19,8 @@ redirect_shader_cache, ) +pytestmark = pytest.mark.kitless + _CACHE_PATH = "/tmp/isaaclab-ovrtx-kitless-cache" # Only ever forwarded to the patched applier factory, so its contents never matter. diff --git a/source/isaaclab_ov/test/test_ovrtx_usd.py b/source/isaaclab_ov/test/test_ovrtx_usd.py index ded8dc4feffb..fbcd69503b47 100644 --- a/source/isaaclab_ov/test/test_ovrtx_usd.py +++ b/source/isaaclab_ov/test/test_ovrtx_usd.py @@ -20,6 +20,7 @@ bool(_MISSING_MODULES), reason=f"requires optional modules: {', '.join(_MISSING_MODULES)}", ), + pytest.mark.kitless, ] if not _MISSING_MODULES: diff --git a/source/isaaclab_ov/test/test_ovrtx_visual_material_sync.py b/source/isaaclab_ov/test/test_ovrtx_visual_material_sync.py index 83e4f140cfb9..805a0115ee3b 100644 --- a/source/isaaclab_ov/test/test_ovrtx_visual_material_sync.py +++ b/source/isaaclab_ov/test/test_ovrtx_visual_material_sync.py @@ -15,9 +15,10 @@ _REQUIRED_MODULES = ("isaaclab_ov", "ovrtx") _MISSING_MODULES = [module for module in _REQUIRED_MODULES if importlib.util.find_spec(module) is None] -pytestmark = pytest.mark.skipif( - bool(_MISSING_MODULES), reason=f"requires optional modules: {', '.join(_MISSING_MODULES)}" -) +pytestmark = [ + pytest.mark.skipif(bool(_MISSING_MODULES), reason=f"requires optional modules: {', '.join(_MISSING_MODULES)}"), + pytest.mark.kitless, +] if not _MISSING_MODULES: from isaaclab_ov.renderers.ovrtx_renderer import OVRTXRenderer diff --git a/source/isaaclab_ov/test/test_ovstage_compat.py b/source/isaaclab_ov/test/test_ovstage_compat.py index fb0cbe0eb77b..e7bee66158bc 100644 --- a/source/isaaclab_ov/test/test_ovstage_compat.py +++ b/source/isaaclab_ov/test/test_ovstage_compat.py @@ -23,6 +23,7 @@ bool(_MISSING_MODULES), reason=f"requires optional modules: {', '.join(_MISSING_MODULES)}", ), + pytest.mark.kitless, ] if not _MISSING_MODULES: diff --git a/source/isaaclab_ov/test/test_randomize_rigid_body_collider_offsets_mdp.py b/source/isaaclab_ov/test/test_randomize_rigid_body_collider_offsets_mdp.py index d84bd48f851f..a3e83febfb11 100644 --- a/source/isaaclab_ov/test/test_randomize_rigid_body_collider_offsets_mdp.py +++ b/source/isaaclab_ov/test/test_randomize_rigid_body_collider_offsets_mdp.py @@ -38,6 +38,8 @@ from isaaclab_assets import CARTPOLE_CFG # isort:skip # noqa: E402 +pytestmark = pytest.mark.kitless + wp.init() diff --git a/source/isaaclab_ov/test/test_randomize_rigid_body_material_mdp.py b/source/isaaclab_ov/test/test_randomize_rigid_body_material_mdp.py index baca4bd4b497..39dc7486467d 100644 --- a/source/isaaclab_ov/test/test_randomize_rigid_body_material_mdp.py +++ b/source/isaaclab_ov/test/test_randomize_rigid_body_material_mdp.py @@ -33,6 +33,8 @@ from isaaclab.test.utils import DeviceScope, test_devices # noqa: E402 from isaaclab.utils.assets import ISAAC_NUCLEUS_DIR # noqa: E402 +pytestmark = pytest.mark.kitless + wp.init() diff --git a/source/isaaclab_ov/test/test_runtime_imports.py b/source/isaaclab_ov/test/test_runtime_imports.py index 3e3d75abb7aa..f91b6784a482 100644 --- a/source/isaaclab_ov/test/test_runtime_imports.py +++ b/source/isaaclab_ov/test/test_runtime_imports.py @@ -10,6 +10,8 @@ import pytest from isaaclab_ov._runtime import _OVPHYSX_INSTALL_MESSAGE, import_ovphysx +pytestmark = pytest.mark.kitless + def test_import_ovphysx_reports_install_command_when_runtime_missing(monkeypatch): """Missing root ``ovphysx`` imports raise the Isaac Lab install hint.""" diff --git a/source/isaaclab_tasks/changelog.d/jichuanh-ci-marker-selection.skip b/source/isaaclab_tasks/changelog.d/jichuanh-ci-marker-selection.skip new file mode 100644 index 000000000000..51bcbf53b393 --- /dev/null +++ b/source/isaaclab_tasks/changelog.d/jichuanh-ci-marker-selection.skip @@ -0,0 +1 @@ +Marked the test files that run without Kit as kitless so a marker run can select them. diff --git a/source/isaaclab_tasks/test/core/test_rendering_cartpole_kitless.py b/source/isaaclab_tasks/test/core/test_rendering_cartpole_kitless.py index ff2367b550db..e9e830268219 100644 --- a/source/isaaclab_tasks/test/core/test_rendering_cartpole_kitless.py +++ b/source/isaaclab_tasks/test/core/test_rendering_cartpole_kitless.py @@ -19,7 +19,7 @@ rendering_test_cartpole, ) -pytestmark = pytest.mark.arm_ci +pytestmark = [pytest.mark.arm_ci, pytest.mark.kitless, pytest.mark.ov] _RENDERING_PARAMS = [ pytest.param(*param.values, False, marks=param.marks, id=param.id) diff --git a/source/isaaclab_tasks/test/core/test_rendering_franka_cable_kitless.py b/source/isaaclab_tasks/test/core/test_rendering_franka_cable_kitless.py index 4170237a2664..e9c6713d64a4 100644 --- a/source/isaaclab_tasks/test/core/test_rendering_franka_cable_kitless.py +++ b/source/isaaclab_tasks/test/core/test_rendering_franka_cable_kitless.py @@ -18,6 +18,8 @@ rendering_test_franka_cable, ) +pytestmark = [pytest.mark.kitless, pytest.mark.ov] + _RENDERING_PARAMS = group_rendering_params(make_kitless_rendering_params_franka()) _COMPARISON_SCORES: list[dict] = [] diff --git a/source/isaaclab_tasks/test/core/test_rendering_franka_cloth_kitless.py b/source/isaaclab_tasks/test/core/test_rendering_franka_cloth_kitless.py index 77ba8da567b5..cae5588dd279 100644 --- a/source/isaaclab_tasks/test/core/test_rendering_franka_cloth_kitless.py +++ b/source/isaaclab_tasks/test/core/test_rendering_franka_cloth_kitless.py @@ -18,6 +18,8 @@ rendering_test_franka_cloth, ) +pytestmark = [pytest.mark.kitless, pytest.mark.ov] + _RENDERING_PARAMS = group_rendering_params(make_kitless_rendering_params_franka()) _COMPARISON_SCORES: list[dict] = [] diff --git a/source/isaaclab_tasks/test/core/test_rendering_franka_soft_kitless.py b/source/isaaclab_tasks/test/core/test_rendering_franka_soft_kitless.py index e34b3657bcdb..b344e9c2901e 100644 --- a/source/isaaclab_tasks/test/core/test_rendering_franka_soft_kitless.py +++ b/source/isaaclab_tasks/test/core/test_rendering_franka_soft_kitless.py @@ -18,6 +18,8 @@ rendering_test_franka_soft, ) +pytestmark = [pytest.mark.kitless, pytest.mark.ov] + _RENDERING_PARAMS = group_rendering_params(make_kitless_rendering_params_franka()) _COMPARISON_SCORES: list[dict] = [] diff --git a/source/isaaclab_tasks/test/core/test_rendering_kuka_visual_material_randomization_kitless.py b/source/isaaclab_tasks/test/core/test_rendering_kuka_visual_material_randomization_kitless.py index fbeaf8a2894a..b35be6a4aa5c 100644 --- a/source/isaaclab_tasks/test/core/test_rendering_kuka_visual_material_randomization_kitless.py +++ b/source/isaaclab_tasks/test/core/test_rendering_kuka_visual_material_randomization_kitless.py @@ -21,6 +21,7 @@ pytest.mark.integration, pytest.mark.rendering, pytest.mark.kitless, + pytest.mark.ov, ] _RENDERING_PARAMS = make_kitless_visual_material_rendering_params() diff --git a/source/isaaclab_tasks/test/core/test_rendering_lift_kuka_hetero_kitless.py b/source/isaaclab_tasks/test/core/test_rendering_lift_kuka_hetero_kitless.py index 92aa1df826be..1ce0468c561f 100644 --- a/source/isaaclab_tasks/test/core/test_rendering_lift_kuka_hetero_kitless.py +++ b/source/isaaclab_tasks/test/core/test_rendering_lift_kuka_hetero_kitless.py @@ -18,6 +18,8 @@ rendering_test_lift_kuka, ) +pytestmark = [pytest.mark.kitless, pytest.mark.ov] + # OVPhysX heterogeneous rendering goldens are not available yet. _RENDERING_PARAMS = group_rendering_params( [param for param in make_kitless_rendering_params_lift() if param.values[1] != "ovphysx"] diff --git a/source/isaaclab_tasks/test/core/test_rendering_lift_kuka_homo_kitless.py b/source/isaaclab_tasks/test/core/test_rendering_lift_kuka_homo_kitless.py index bda9c02b288c..d3acd63f0723 100644 --- a/source/isaaclab_tasks/test/core/test_rendering_lift_kuka_homo_kitless.py +++ b/source/isaaclab_tasks/test/core/test_rendering_lift_kuka_homo_kitless.py @@ -18,7 +18,7 @@ rendering_test_lift_kuka, ) -pytestmark = pytest.mark.arm_ci +pytestmark = [pytest.mark.arm_ci, pytest.mark.kitless, pytest.mark.ov] _RENDERING_PARAMS = group_rendering_params(make_kitless_rendering_params_lift()) _COMPARISON_SCORES: list[dict] = [] diff --git a/source/isaaclab_tasks/test/core/test_rendering_shadow_hand_kitless.py b/source/isaaclab_tasks/test/core/test_rendering_shadow_hand_kitless.py index b17e9c41a0c3..b360aa070b16 100644 --- a/source/isaaclab_tasks/test/core/test_rendering_shadow_hand_kitless.py +++ b/source/isaaclab_tasks/test/core/test_rendering_shadow_hand_kitless.py @@ -19,7 +19,7 @@ rendering_test_shadow_hand, ) -pytestmark = pytest.mark.arm_ci +pytestmark = [pytest.mark.kitless, pytest.mark.ov, pytest.mark.arm_ci] _RENDERING_PARAMS = group_rendering_params( make_kitless_rendering_params(MINIMAL_KITLESS_PHYSICS_RENDERER_AOV_COMBINATIONS) diff --git a/tools/conftest.py b/tools/conftest.py index 19b7be193180..512ab8b3e38f 100644 --- a/tools/conftest.py +++ b/tools/conftest.py @@ -14,6 +14,7 @@ import time from collections.abc import Callable from dataclasses import dataclass +from pathlib import Path import pytest import tomllib @@ -1697,6 +1698,13 @@ def _collect_test_node_ids_by_file(workspace_root: str) -> dict[str, list[str]]: return grouped +def _registered_markers(workspace_root: str) -> set[str]: + """Names of the markers registered in the root ``pyproject.toml``.""" + with open(os.path.join(workspace_root, "pyproject.toml"), "rb") as stream: + entries = tomllib.load(stream)["tool"]["pytest"]["ini_options"]["markers"] + return {entry.split(":", 1)[0].strip() for entry in entries} + + def _write_empty_report(): """Write an empty JUnit XML report so downstream CI steps find a valid file.""" os.makedirs("tests", exist_ok=True) @@ -1758,6 +1766,10 @@ def pytest_sessionstart(session): # filter is owned by Isaac Sim's external CI pipeline; the CI_MARKER path # leaves that contract untouched. ci_marker = os.environ.get("CI_MARKER", "") + # The file scan below matches a single marker name, and a job with no marked file passes empty, + # so an expression or a misspelt name would pass every job without running anything. + if ci_marker and ci_marker not in _registered_markers(workspace_root): + pytest.exit(f"CI_MARKER {ci_marker!r} is not a single marker registered in pyproject.toml", returncode=1) test_node_ids_by_file = _collect_test_node_ids_by_file(workspace_root) # Parse include files list (comma-separated paths) @@ -1819,10 +1831,16 @@ def pytest_sessionstart(session): marker_token = f"pytest.mark.{ci_marker}" new_test_files = [] for test_file in test_files: + # A folder's conftest.py can mark every test below it. + folder = os.path.dirname(os.path.abspath(test_file)) + marking_files = [test_file] + while folder.startswith(workspace_root) and folder != workspace_root: + if os.path.isfile(os.path.join(folder, "conftest.py")): + marking_files.append(os.path.join(folder, "conftest.py")) + folder = os.path.dirname(folder) try: - with open(test_file) as f: - if marker_token in f.read(): - new_test_files.append(test_file) + if any(marker_token in Path(path).read_text() for path in marking_files): + new_test_files.append(test_file) except OSError as exc: raise RuntimeError( f"ci_marker post-scan could not read {test_file}; refusing to" @@ -1842,6 +1860,10 @@ def pytest_sessionstart(session): logger.info("No quarantined tests configured — nothing to run.") _write_empty_report() pytest.exit("No quarantined tests configured", returncode=0) + if ci_marker: + logger.info(f"No selected test file carries marker '{ci_marker}' — nothing to run.") + _write_empty_report() + pytest.exit("No test files found for marker", returncode=0) if filter_pattern: logger.info(f"No test files found matching filter pattern '{filter_pattern}' — nothing to run.") _write_empty_report()