From 40e0a77547b6a9dd20ba46b0d9953e2dc7139cad Mon Sep 17 00:00:00 2001 From: Mustafa Haiderbhai Date: Wed, 12 Aug 2026 21:01:27 -0700 Subject: [PATCH 1/9] Consolidate environment backend smoke tests --- .github/workflows/build.yaml | 3 +- .../test_cartpole_showcase_environments.py | 2 +- ...wcase_environments_with_stage_in_memory.py | 2 +- .../test_contrib_environments_smoke.py | 1 - .../test_pickplace_stack_environments.py | 1 - .../test/contrib/test_teleop_environments.py | 2 +- ...eleop_environments_with_stage_in_memory.py | 2 +- .../test/core/test_environments.py | 8 +-- .../test/core/test_environments_newton.py | 38 -------------- .../test_environments_with_stage_in_memory.py | 3 +- .../test/core/test_record_video.py | 2 +- source/isaaclab_tasks/test/env_test_utils.py | 50 ------------------- 12 files changed, 12 insertions(+), 102 deletions(-) delete mode 100644 source/isaaclab_tasks/test/core/test_environments_newton.py diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 2b5cb7d41226..3b51125704ee 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -966,8 +966,7 @@ jobs: # (dexterous, many contacts). Deformable/MPM kernels are not covered; # widen if a test job reports large cache growth. include-files: >- - test_environments.py, - test_environments_newton.py + test_environments.py # No Soft/Cloth: the deformable envs depend on optional extras the CI # image does not install (Soft needs pytetwild), so they only ever fail. test-k-expr: "Cartpole or Drawer or AnymalD or Handover" diff --git a/source/isaaclab_tasks/test/contrib/test_cartpole_showcase_environments.py b/source/isaaclab_tasks/test/contrib/test_cartpole_showcase_environments.py index 38b2ce277a19..7eda602252c9 100644 --- a/source/isaaclab_tasks/test/contrib/test_cartpole_showcase_environments.py +++ b/source/isaaclab_tasks/test/contrib/test_cartpole_showcase_environments.py @@ -26,7 +26,7 @@ @pytest.mark.parametrize( "task_name", setup_environment( - include_play=False, factory_envs=False, multi_agent=False, teleop_envs=False, cartpole_showcase_envs=True + factory_envs=False, multi_agent=False, teleop_envs=False, cartpole_showcase_envs=True ), ) @pytest.mark.isaacsim_ci diff --git a/source/isaaclab_tasks/test/contrib/test_cartpole_showcase_environments_with_stage_in_memory.py b/source/isaaclab_tasks/test/contrib/test_cartpole_showcase_environments_with_stage_in_memory.py index 536b209dbd47..185b24bec828 100644 --- a/source/isaaclab_tasks/test/contrib/test_cartpole_showcase_environments_with_stage_in_memory.py +++ b/source/isaaclab_tasks/test/contrib/test_cartpole_showcase_environments_with_stage_in_memory.py @@ -27,7 +27,7 @@ @pytest.mark.parametrize( "task_name", setup_environment( - include_play=False, factory_envs=False, multi_agent=False, teleop_envs=False, cartpole_showcase_envs=True + factory_envs=False, multi_agent=False, teleop_envs=False, cartpole_showcase_envs=True ), ) def test_cartpole_showcase_environments_with_stage_in_memory_and_clone_in_fabric_disabled(task_name, num_envs, device): diff --git a/source/isaaclab_tasks/test/contrib/test_contrib_environments_smoke.py b/source/isaaclab_tasks/test/contrib/test_contrib_environments_smoke.py index ea1ae57d9fc3..4c16760fc529 100644 --- a/source/isaaclab_tasks/test/contrib/test_contrib_environments_smoke.py +++ b/source/isaaclab_tasks/test/contrib/test_contrib_environments_smoke.py @@ -42,7 +42,6 @@ @pytest.mark.parametrize( "task_name", setup_environment( - include_play=False, multi_agent=False, factory_envs=False, cartpole_showcase_envs=False, diff --git a/source/isaaclab_tasks/test/contrib/test_pickplace_stack_environments.py b/source/isaaclab_tasks/test/contrib/test_pickplace_stack_environments.py index cbc10c272b73..8801aea9f71a 100644 --- a/source/isaaclab_tasks/test/contrib/test_pickplace_stack_environments.py +++ b/source/isaaclab_tasks/test/contrib/test_pickplace_stack_environments.py @@ -36,7 +36,6 @@ @pytest.mark.parametrize( "task_name", setup_environment( - include_play=False, factory_envs=False, multi_agent=False, teleop_envs=False, diff --git a/source/isaaclab_tasks/test/contrib/test_teleop_environments.py b/source/isaaclab_tasks/test/contrib/test_teleop_environments.py index c30af100038a..980b2f3046de 100644 --- a/source/isaaclab_tasks/test/contrib/test_teleop_environments.py +++ b/source/isaaclab_tasks/test/contrib/test_teleop_environments.py @@ -37,7 +37,7 @@ @pytest.mark.parametrize("num_envs, device", [(2, "cuda"), (1, "cuda")]) @pytest.mark.parametrize( - "task_name", setup_environment(include_play=False, factory_envs=False, multi_agent=False, teleop_envs=True) + "task_name", setup_environment(factory_envs=False, multi_agent=False, teleop_envs=True) ) @pytest.mark.isaacsim_ci def test_teleop_environments(task_name, num_envs, device): diff --git a/source/isaaclab_tasks/test/contrib/test_teleop_environments_with_stage_in_memory.py b/source/isaaclab_tasks/test/contrib/test_teleop_environments_with_stage_in_memory.py index 155543d0ed70..9379f0262962 100644 --- a/source/isaaclab_tasks/test/contrib/test_teleop_environments_with_stage_in_memory.py +++ b/source/isaaclab_tasks/test/contrib/test_teleop_environments_with_stage_in_memory.py @@ -38,7 +38,7 @@ @pytest.mark.parametrize("num_envs, device", [(2, "cuda")]) @pytest.mark.parametrize( - "task_name", setup_environment(include_play=False, factory_envs=False, multi_agent=False, teleop_envs=True) + "task_name", setup_environment(factory_envs=False, multi_agent=False, teleop_envs=True) ) def test_teleop_environments_with_stage_in_memory_and_clone_in_fabric_disabled(task_name, num_envs, device): # skip test if stage in memory is not supported diff --git a/source/isaaclab_tasks/test/core/test_environments.py b/source/isaaclab_tasks/test/core/test_environments.py index 5e37814c2058..3947b9ec3e23 100644 --- a/source/isaaclab_tasks/test/core/test_environments.py +++ b/source/isaaclab_tasks/test/core/test_environments.py @@ -21,17 +21,19 @@ # Local imports should be imported last from env_test_utils import _run_environments, setup_environment # isort: skip +@pytest.mark.parametrize("physics_preset_name", ["newton_mjwarp", "physx", "isaacsim_physx"]) @pytest.mark.parametrize("num_envs, device", [(2, "cuda"), (1, "cuda")]) @pytest.mark.parametrize( "task_name", setup_environment( - include_play=False, multi_agent=False, tier="core", ), ) @pytest.mark.isaacsim_ci -def test_environments(task_name, num_envs, device): +def test_environments(task_name, physics_preset_name, num_envs, device): # run environments without stage in memory - _run_environments(task_name, device, num_envs, create_stage_in_memory=False) + _run_environments( + task_name, device, num_envs, create_stage_in_memory=False, physics_preset_name=physics_preset_name + ) diff --git a/source/isaaclab_tasks/test/core/test_environments_newton.py b/source/isaaclab_tasks/test/core/test_environments_newton.py deleted file mode 100644 index 8618b04c6c34..000000000000 --- a/source/isaaclab_tasks/test/core/test_environments_newton.py +++ /dev/null @@ -1,38 +0,0 @@ -# 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 - -"""Launch Isaac Sim Simulator first.""" - -from isaaclab.app import AppLauncher - -# launch the simulator -app_launcher = AppLauncher(headless=True, enable_cameras=True, limit_cpu_threads=1) -simulation_app = app_launcher.app - - -"""Rest everything follows.""" - -import pytest - -import isaaclab_tasks # noqa: F401 - -# Local imports should be imported last -from env_test_utils import _run_environments, setup_environment # isort: skip - - -@pytest.mark.parametrize("num_envs, device", [(2, "cuda"), (1, "cuda")]) -@pytest.mark.parametrize( - "task_name", - setup_environment( - include_play=False, - multi_agent=False, - newton_mjwarp_envs=True, - tier="core", - ), -) -@pytest.mark.newton_ci -def test_environments_newton(task_name, num_envs, device): - # run environments with MJWarp physics preset - _run_environments(task_name, device, num_envs, physics_preset_name="newton_mjwarp", create_stage_in_memory=False) diff --git a/source/isaaclab_tasks/test/core/test_environments_with_stage_in_memory.py b/source/isaaclab_tasks/test/core/test_environments_with_stage_in_memory.py index 1457b01f9c96..ad6185ed45a6 100644 --- a/source/isaaclab_tasks/test/core/test_environments_with_stage_in_memory.py +++ b/source/isaaclab_tasks/test/core/test_environments_with_stage_in_memory.py @@ -29,7 +29,7 @@ # TODO(mtrepte): re-enable with fabric cloning fix # @pytest.mark.parametrize("num_envs, device", [(2, "cuda")]) -# @pytest.mark.parametrize("task_name", setup_environment(include_play=False,factory_envs=False, multi_agent=False)) +# @pytest.mark.parametrize("task_name", setup_environment(factory_envs=False, multi_agent=False)) # def test_environments_with_stage_in_memory_and_clone_in_fabric_disabled(task_name, num_envs, device): # # skip test if stage in memory is not supported # if get_isaac_sim_version().major < 5: @@ -43,7 +43,6 @@ @pytest.mark.parametrize( "task_name", setup_environment( - include_play=False, multi_agent=False, tier="core", ), diff --git a/source/isaaclab_tasks/test/core/test_record_video.py b/source/isaaclab_tasks/test/core/test_record_video.py index 329d42b5249a..46748e97cc8f 100644 --- a/source/isaaclab_tasks/test/core/test_record_video.py +++ b/source/isaaclab_tasks/test/core/test_record_video.py @@ -41,7 +41,7 @@ def setup_video_params(): return num_envs, device, video_length -@pytest.mark.parametrize("task_name", setup_environment(include_play=True, tier="core")) +@pytest.mark.parametrize("task_name", setup_environment(tier="core")) def test_record_video(task_name, setup_video_params): """Run random actions agent with internal VideoRecorder capturing from the active visualizer.""" num_envs, device, video_length = setup_video_params diff --git a/source/isaaclab_tasks/test/env_test_utils.py b/source/isaaclab_tasks/test/env_test_utils.py index 3547c175fd66..da645a3234e5 100644 --- a/source/isaaclab_tasks/test/env_test_utils.py +++ b/source/isaaclab_tasks/test/env_test_utils.py @@ -76,49 +76,18 @@ def _task_tier(task_spec) -> str | None: return None -def _has_physics_preset(raw_cfg, preset_name: str) -> bool: - """Check if a raw (unresolved) env config has a named physics preset. - - Must be called with the result of :func:`load_cfg_from_registry`, not - :func:`parse_env_cfg`, because the latter resolves all PresetCfg wrappers - to their default before returning. - - Args: - raw_cfg: Raw env config from :func:`load_cfg_from_registry`. - preset_name: Name of the preset to check for (e.g., 'newton_mjwarp'). - - Returns: - True if ``raw_cfg.sim.physics`` is a PresetCfg with the given preset field. - """ - if isinstance(raw_cfg, dict): - return False - # If the top-level cfg is itself a PresetCfg wrapper, unwrap to its default. - env_cfg = raw_cfg - if ( - hasattr(env_cfg, "__dataclass_fields__") - and hasattr(env_cfg, "default") - and not hasattr(type(env_cfg), "class_type") - ): - env_cfg = env_cfg.default - physics = getattr(getattr(env_cfg, "sim", None), "physics", None) - return physics is not None and hasattr(physics, preset_name) - - def setup_environment( - include_play: bool = False, factory_envs: bool | None = None, multi_agent: bool | None = None, teleop_envs: bool | None = None, cartpole_showcase_envs: bool | None = None, pickplace_stack_envs: bool | None = None, - newton_mjwarp_envs: bool | None = None, tier: str | None = None, ) -> list[str]: """ Acquire all registered Isaac environment task IDs with optional filters. Args: - include_play: If True, include environments ending in 'Play-v0'. factory_envs: - True: include only Factory environments - False: exclude Factory environments @@ -139,10 +108,6 @@ def setup_environment( - True: include only PickPlace/Stack environments - False: exclude PickPlace/Stack environments - None: include all environments regardless of pick-place/stack type - newton_mjwarp_envs: - - True: include only environments that have an MJWarp physics preset. - - False: exclude environments that have an MJWarp physics preset. - - None: include all environments regardless of MJWarp preset availability. tier: - "core": include only core environments (registered under ``isaaclab_tasks.core``). - "contrib": include only contributed environments (registered under ``isaaclab_tasks.contrib``). @@ -161,10 +126,6 @@ def setup_environment( if "Isaac" not in task_spec.id: continue - # filter Play environments, if needed - if not include_play and task_spec.id.endswith("Play-v0"): - continue - # apply core/contrib tier filter if tier is not None and _task_tier(task_spec) != tier: continue @@ -211,17 +172,6 @@ def setup_environment( continue # if None: no filter - # apply MJWarp preset filter - if newton_mjwarp_envs is not None: - # Use load_cfg_from_registry (not parse_env_cfg) so that the PresetCfg - # wrapper on sim.physics is not yet resolved to its default. - raw_cfg = load_cfg_from_registry(task_spec.id, "env_cfg_entry_point") - has_newton_mjwarp = _has_physics_preset(raw_cfg, "newton_mjwarp") - if (newton_mjwarp_envs is True and not has_newton_mjwarp) or ( - newton_mjwarp_envs is False and has_newton_mjwarp - ): - continue - # if None: no filter registered_tasks.append(task_spec.id) From 33e337cae7db54b3dedce720148887b9bb644a44 Mon Sep 17 00:00:00 2001 From: Mustafa Haiderbhai Date: Thu, 13 Aug 2026 00:51:11 -0700 Subject: [PATCH 2/9] Run contributed environments in shared smoke test --- .../test_contrib_environments_smoke.py | 55 ------------------- .../test/core/test_environments.py | 16 ++++++ 2 files changed, 16 insertions(+), 55 deletions(-) delete mode 100644 source/isaaclab_tasks/test/contrib/test_contrib_environments_smoke.py diff --git a/source/isaaclab_tasks/test/contrib/test_contrib_environments_smoke.py b/source/isaaclab_tasks/test/contrib/test_contrib_environments_smoke.py deleted file mode 100644 index 4c16760fc529..000000000000 --- a/source/isaaclab_tasks/test/contrib/test_contrib_environments_smoke.py +++ /dev/null @@ -1,55 +0,0 @@ -# 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 - -"""Basic smoke test for contributed environments. - -Instantiates each contributed task (registered under ``isaaclab_tasks.contrib``) and steps -it with random actions to verify it loads and runs without error. Environment families that -require dedicated handling are covered by their own test files in this directory and are -excluded here to avoid duplication: - -- Factory / Forge: ``test_factory_environments.py`` -- Cartpole Showcase: ``test_cartpole_showcase_environments.py`` -- PickPlace / Stack / Place: ``test_pickplace_stack_environments.py`` -- Teleop: ``test_teleop_environments.py`` -- AutoMate: ``test_environments_automate.py`` -- Skillgen: ``test_environments_skillgen.py`` -""" - -"""Launch Isaac Sim Simulator first.""" - -from isaaclab.app import AppLauncher - -# launch the simulator -app_launcher = AppLauncher(headless=True, enable_cameras=True) -simulation_app = app_launcher.app - - -"""Rest everything follows.""" - -import pytest - -import isaaclab_tasks # noqa: F401 - -# Local imports should be imported last -from env_test_utils import _run_environments, setup_environment # isort: skip - - -@pytest.mark.smoke -@pytest.mark.parametrize("num_envs, device", [(2, "cuda")]) -@pytest.mark.parametrize( - "task_name", - setup_environment( - multi_agent=False, - factory_envs=False, - cartpole_showcase_envs=False, - pickplace_stack_envs=False, - teleop_envs=False, - tier="contrib", - ), -) -def test_contrib_environments_smoke(task_name, num_envs, device): - # run a short rollout with random actions to verify the environment loads and steps - _run_environments(task_name, device, num_envs, create_stage_in_memory=False) diff --git a/source/isaaclab_tasks/test/core/test_environments.py b/source/isaaclab_tasks/test/core/test_environments.py index 3947b9ec3e23..920861215dd2 100644 --- a/source/isaaclab_tasks/test/core/test_environments.py +++ b/source/isaaclab_tasks/test/core/test_environments.py @@ -37,3 +37,19 @@ def test_environments(task_name, physics_preset_name, num_envs, device): _run_environments( task_name, device, num_envs, create_stage_in_memory=False, physics_preset_name=physics_preset_name ) + + +@pytest.mark.parametrize("num_envs, device", [(2, "cuda")]) +@pytest.mark.parametrize( + "task_name", + setup_environment( + multi_agent=False, + factory_envs=False, + cartpole_showcase_envs=False, + pickplace_stack_envs=False, + teleop_envs=False, + tier="contrib", + ), +) +@pytest.mark.isaacsim_ci +def test_contrib_environments(task_name, num_envs, device): From 419ba1e4eed97c769c51b89da78ae7c0d1f16a57 Mon Sep 17 00:00:00 2001 From: Mustafa Haiderbhai Date: Thu, 13 Aug 2026 00:56:31 -0700 Subject: [PATCH 3/9] Collect environment objects before teardown --- source/isaaclab_tasks/test/env_test_utils.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source/isaaclab_tasks/test/env_test_utils.py b/source/isaaclab_tasks/test/env_test_utils.py index da645a3234e5..c28dd3e699d9 100644 --- a/source/isaaclab_tasks/test/env_test_utils.py +++ b/source/isaaclab_tasks/test/env_test_utils.py @@ -5,6 +5,7 @@ """Shared test utilities for Isaac Lab environments.""" +import gc import importlib import os import sys @@ -471,6 +472,11 @@ def _check_random_actions( if env is not None: env.close() + # Drop unreachable environment objects while the device is still alive. Warp arrays + # free device memory from a finalizer, so collect them before the simulation teardown + # destroys their streams. + gc.collect() + # Clear the simulation context singleton (also closes the USD context stage) SimulationContext.clear_instance() From f2d38fb26e8aaebaec60041d6101907c0c4ebb91 Mon Sep 17 00:00:00 2001 From: Mustafa Haiderbhai Date: Thu, 13 Aug 2026 00:57:22 -0700 Subject: [PATCH 4/9] Update preset tests for Newton defaults --- .../test/core/test_preset_kit_decision.py | 42 ++++++++++--------- .../test/core/test_runtime_compatibility.py | 22 +++++----- 2 files changed, 34 insertions(+), 30 deletions(-) diff --git a/source/isaaclab_tasks/test/core/test_preset_kit_decision.py b/source/isaaclab_tasks/test/core/test_preset_kit_decision.py index 73a119182f3c..5b14f3c7934e 100644 --- a/source/isaaclab_tasks/test/core/test_preset_kit_decision.py +++ b/source/isaaclab_tasks/test/core/test_preset_kit_decision.py @@ -15,6 +15,7 @@ import gymnasium as gym import pytest +from isaaclab_newton.physics import NewtonCfg from isaaclab_ov.physics import OvPhysxCfg from isaaclab_ov.renderers import OVRTXRendererCfg from isaaclab_physx.physics import PhysxCfg @@ -87,11 +88,12 @@ def test_isaacsim_physx_is_physics_selector(): assert "isaacsim_physx" in preset_map[PresetTarget.PHYSICS] -def test_registered_task_physx_presets_keep_auto_selection_explicit(): - """PhysX defaults are concrete while ``physx`` remains the automatic selector.""" +def test_core_task_physx_presets_keep_auto_selection_explicit(): + """Core tasks retain explicit PhysX variants alongside automatic ``physx``.""" for task_id, task_spec in gym.registry.items(): - if not task_id.startswith(("Isaac-", "IsaacContrib-")) or "env_cfg_entry_point" not in task_spec.kwargs: + entry_point = task_spec.kwargs.get("env_cfg_entry_point", "") + if not task_id.startswith("Isaac-") or "isaaclab_tasks.core" not in str(entry_point): continue env_cfg = load_cfg_from_registry(task_id, "env_cfg_entry_point") presets = collect_presets(env_cfg) @@ -137,24 +139,24 @@ def test_preset_mjwarp_ovrtx_does_not_need_kit(): assert needs_kit is False -def test_preset_rtx_with_default_physx_resolves_to_isaac_sim_backends(): - """Automatic RTX follows the default concrete Isaac Sim PhysX backend.""" +def test_preset_rtx_with_default_newton_resolves_to_isaac_sim_backends(): + """Explicit RTX retains the default Newton physics while requiring Isaac Sim.""" env_cfg = _resolve_with_presets("rtx") config_scan = _resolve_runtime_renderer(env_cfg) - assert isinstance(env_cfg.sim.physics, PhysxCfg) - assert isinstance(env_cfg.tiled_camera.renderer_cfg, IsaacRtxRendererCfg) - assert config_scan.needs_kit is True + assert isinstance(env_cfg.sim.physics, NewtonCfg) + assert isinstance(env_cfg.tiled_camera.renderer_cfg, OVRTXRendererCfg) + assert config_scan.needs_kit is False -def test_renderer_selector_rtx_with_default_physx_resolves_to_isaac_sim_backends(): - """The RTX selector follows the default concrete Isaac Sim PhysX backend.""" +def test_renderer_selector_rtx_with_default_newton_resolves_to_isaac_sim_backends(): + """The RTX selector retains the default Newton physics while requiring Isaac Sim.""" env_cfg = _resolve_with_args("renderer=rtx") config_scan = _resolve_runtime_renderer(env_cfg) - assert isinstance(env_cfg.sim.physics, PhysxCfg) - assert isinstance(env_cfg.tiled_camera.renderer_cfg, IsaacRtxRendererCfg) - assert config_scan.needs_kit is True + assert isinstance(env_cfg.sim.physics, NewtonCfg) + assert isinstance(env_cfg.tiled_camera.renderer_cfg, OVRTXRendererCfg) + assert config_scan.needs_kit is False def test_renderer_selector_physx_rtx_resolves_to_ovphysx_without_kit(): @@ -227,20 +229,20 @@ def test_preset_mjwarp_newton_renderer_does_not_need_kit(): assert needs_kit is False -def test_preset_physx_with_default_kit_camera_resolves_to_physx(): - """Automatic PhysX resolves to Isaac Sim PhysX when the default camera requires Kit.""" +def test_preset_physx_with_default_newton_camera_resolves_to_ovphysx(): + """Automatic PhysX resolves to OvPhysX when the default camera is kitless.""" env_cfg = _resolve_with_presets("physx") config_scan = scan(env_cfg) - assert isinstance(env_cfg.sim.physics, PhysxCfg) - assert config_scan.needs_kit is True + assert isinstance(env_cfg.sim.physics, OvPhysxCfg) + assert config_scan.needs_kit is False -def test_preset_default_needs_kit(): - """Default concrete Isaac Sim PhysX plus Isaac RTX requires Kit.""" +def test_preset_default_is_kitless(): + """Default Newton MJWarp plus Newton renderer does not require Kit.""" env_cfg = _resolve_with_presets("default") needs_kit = scan(env_cfg).needs_kit - assert needs_kit is True + assert needs_kit is False def test_preset_mjwarp_isaac_rtx_needs_kit(): diff --git a/source/isaaclab_tasks/test/core/test_runtime_compatibility.py b/source/isaaclab_tasks/test/core/test_runtime_compatibility.py index 6ca07657def5..30acafbf7622 100644 --- a/source/isaaclab_tasks/test/core/test_runtime_compatibility.py +++ b/source/isaaclab_tasks/test/core/test_runtime_compatibility.py @@ -18,6 +18,7 @@ import sys import pytest +from isaaclab_newton.physics import NewtonCfg from isaaclab_ov.physics import OvPhysxCfg from isaaclab_ov.renderers import OVRTXRendererCfg from isaaclab_physx.physics import PhysxCfg @@ -226,13 +227,14 @@ def test_newton_plus_ovrtx_is_valid(): validate_runtime_compatibility(env_cfg) -def test_default_isaacsim_physx_plus_ovrtx_raises(): - """The concrete default Isaac Sim PhysX backend is incompatible with OVRTX.""" +def test_default_newton_plus_ovrtx_is_valid(): + """The default Newton backend is compatible with OVRTX.""" env_cfg = _resolve_with_presets("ovrtx") - assert isinstance(env_cfg.sim.physics, PhysxCfg) - with pytest.raises(ValueError, match="PhysxCfg"): - validate_runtime_compatibility(env_cfg) + assert isinstance(env_cfg.sim.physics, NewtonCfg) + config_scan = validate_runtime_compatibility(env_cfg) + assert isinstance(env_cfg.tiled_camera.renderer_cfg, OVRTXRendererCfg) + assert config_scan.needs_kit is False def test_explicit_auto_physx_plus_ovrtx_resolves_to_ovphysx(): @@ -302,14 +304,14 @@ def test_default_preset_is_valid(): validate_runtime_compatibility(env_cfg) -def test_rtx_with_default_physx_is_valid_and_resolves_to_isaac_sim_backends(): - """The RTX selector follows the default concrete Isaac Sim PhysX backend.""" +def test_rtx_with_default_newton_is_valid_and_resolves_to_isaac_sim_backends(): + """The RTX selector retains default Newton physics and requires Isaac Sim.""" env_cfg = _resolve_with_presets("rtx") config_scan = validate_runtime_compatibility(env_cfg) - assert isinstance(env_cfg.sim.physics, PhysxCfg) - assert isinstance(env_cfg.tiled_camera.renderer_cfg, IsaacRtxRendererCfg) - assert config_scan.needs_kit is True + assert isinstance(env_cfg.sim.physics, NewtonCfg) + assert isinstance(env_cfg.tiled_camera.renderer_cfg, OVRTXRendererCfg) + assert config_scan.needs_kit is False def test_renderer_selector_physx_rtx_is_valid_and_resolves_to_ovphysx_and_ovrtx(): From 55a17806127d417842c9a1d5a0ff657abaf1399f Mon Sep 17 00:00:00 2001 From: Mustafa Haiderbhai Date: Thu, 13 Aug 2026 00:59:27 -0700 Subject: [PATCH 5/9] Revert "Update preset tests for Newton defaults" This reverts commit f2d38fb26e8aaebaec60041d6101907c0c4ebb91. --- .../test/core/test_preset_kit_decision.py | 42 +++++++++---------- .../test/core/test_runtime_compatibility.py | 22 +++++----- 2 files changed, 30 insertions(+), 34 deletions(-) diff --git a/source/isaaclab_tasks/test/core/test_preset_kit_decision.py b/source/isaaclab_tasks/test/core/test_preset_kit_decision.py index 5b14f3c7934e..73a119182f3c 100644 --- a/source/isaaclab_tasks/test/core/test_preset_kit_decision.py +++ b/source/isaaclab_tasks/test/core/test_preset_kit_decision.py @@ -15,7 +15,6 @@ import gymnasium as gym import pytest -from isaaclab_newton.physics import NewtonCfg from isaaclab_ov.physics import OvPhysxCfg from isaaclab_ov.renderers import OVRTXRendererCfg from isaaclab_physx.physics import PhysxCfg @@ -88,12 +87,11 @@ def test_isaacsim_physx_is_physics_selector(): assert "isaacsim_physx" in preset_map[PresetTarget.PHYSICS] -def test_core_task_physx_presets_keep_auto_selection_explicit(): - """Core tasks retain explicit PhysX variants alongside automatic ``physx``.""" +def test_registered_task_physx_presets_keep_auto_selection_explicit(): + """PhysX defaults are concrete while ``physx`` remains the automatic selector.""" for task_id, task_spec in gym.registry.items(): - entry_point = task_spec.kwargs.get("env_cfg_entry_point", "") - if not task_id.startswith("Isaac-") or "isaaclab_tasks.core" not in str(entry_point): + if not task_id.startswith(("Isaac-", "IsaacContrib-")) or "env_cfg_entry_point" not in task_spec.kwargs: continue env_cfg = load_cfg_from_registry(task_id, "env_cfg_entry_point") presets = collect_presets(env_cfg) @@ -139,24 +137,24 @@ def test_preset_mjwarp_ovrtx_does_not_need_kit(): assert needs_kit is False -def test_preset_rtx_with_default_newton_resolves_to_isaac_sim_backends(): - """Explicit RTX retains the default Newton physics while requiring Isaac Sim.""" +def test_preset_rtx_with_default_physx_resolves_to_isaac_sim_backends(): + """Automatic RTX follows the default concrete Isaac Sim PhysX backend.""" env_cfg = _resolve_with_presets("rtx") config_scan = _resolve_runtime_renderer(env_cfg) - assert isinstance(env_cfg.sim.physics, NewtonCfg) - assert isinstance(env_cfg.tiled_camera.renderer_cfg, OVRTXRendererCfg) - assert config_scan.needs_kit is False + assert isinstance(env_cfg.sim.physics, PhysxCfg) + assert isinstance(env_cfg.tiled_camera.renderer_cfg, IsaacRtxRendererCfg) + assert config_scan.needs_kit is True -def test_renderer_selector_rtx_with_default_newton_resolves_to_isaac_sim_backends(): - """The RTX selector retains the default Newton physics while requiring Isaac Sim.""" +def test_renderer_selector_rtx_with_default_physx_resolves_to_isaac_sim_backends(): + """The RTX selector follows the default concrete Isaac Sim PhysX backend.""" env_cfg = _resolve_with_args("renderer=rtx") config_scan = _resolve_runtime_renderer(env_cfg) - assert isinstance(env_cfg.sim.physics, NewtonCfg) - assert isinstance(env_cfg.tiled_camera.renderer_cfg, OVRTXRendererCfg) - assert config_scan.needs_kit is False + assert isinstance(env_cfg.sim.physics, PhysxCfg) + assert isinstance(env_cfg.tiled_camera.renderer_cfg, IsaacRtxRendererCfg) + assert config_scan.needs_kit is True def test_renderer_selector_physx_rtx_resolves_to_ovphysx_without_kit(): @@ -229,20 +227,20 @@ def test_preset_mjwarp_newton_renderer_does_not_need_kit(): assert needs_kit is False -def test_preset_physx_with_default_newton_camera_resolves_to_ovphysx(): - """Automatic PhysX resolves to OvPhysX when the default camera is kitless.""" +def test_preset_physx_with_default_kit_camera_resolves_to_physx(): + """Automatic PhysX resolves to Isaac Sim PhysX when the default camera requires Kit.""" env_cfg = _resolve_with_presets("physx") config_scan = scan(env_cfg) - assert isinstance(env_cfg.sim.physics, OvPhysxCfg) - assert config_scan.needs_kit is False + assert isinstance(env_cfg.sim.physics, PhysxCfg) + assert config_scan.needs_kit is True -def test_preset_default_is_kitless(): - """Default Newton MJWarp plus Newton renderer does not require Kit.""" +def test_preset_default_needs_kit(): + """Default concrete Isaac Sim PhysX plus Isaac RTX requires Kit.""" env_cfg = _resolve_with_presets("default") needs_kit = scan(env_cfg).needs_kit - assert needs_kit is False + assert needs_kit is True def test_preset_mjwarp_isaac_rtx_needs_kit(): diff --git a/source/isaaclab_tasks/test/core/test_runtime_compatibility.py b/source/isaaclab_tasks/test/core/test_runtime_compatibility.py index 30acafbf7622..6ca07657def5 100644 --- a/source/isaaclab_tasks/test/core/test_runtime_compatibility.py +++ b/source/isaaclab_tasks/test/core/test_runtime_compatibility.py @@ -18,7 +18,6 @@ import sys import pytest -from isaaclab_newton.physics import NewtonCfg from isaaclab_ov.physics import OvPhysxCfg from isaaclab_ov.renderers import OVRTXRendererCfg from isaaclab_physx.physics import PhysxCfg @@ -227,14 +226,13 @@ def test_newton_plus_ovrtx_is_valid(): validate_runtime_compatibility(env_cfg) -def test_default_newton_plus_ovrtx_is_valid(): - """The default Newton backend is compatible with OVRTX.""" +def test_default_isaacsim_physx_plus_ovrtx_raises(): + """The concrete default Isaac Sim PhysX backend is incompatible with OVRTX.""" env_cfg = _resolve_with_presets("ovrtx") - assert isinstance(env_cfg.sim.physics, NewtonCfg) - config_scan = validate_runtime_compatibility(env_cfg) - assert isinstance(env_cfg.tiled_camera.renderer_cfg, OVRTXRendererCfg) - assert config_scan.needs_kit is False + assert isinstance(env_cfg.sim.physics, PhysxCfg) + with pytest.raises(ValueError, match="PhysxCfg"): + validate_runtime_compatibility(env_cfg) def test_explicit_auto_physx_plus_ovrtx_resolves_to_ovphysx(): @@ -304,14 +302,14 @@ def test_default_preset_is_valid(): validate_runtime_compatibility(env_cfg) -def test_rtx_with_default_newton_is_valid_and_resolves_to_isaac_sim_backends(): - """The RTX selector retains default Newton physics and requires Isaac Sim.""" +def test_rtx_with_default_physx_is_valid_and_resolves_to_isaac_sim_backends(): + """The RTX selector follows the default concrete Isaac Sim PhysX backend.""" env_cfg = _resolve_with_presets("rtx") config_scan = validate_runtime_compatibility(env_cfg) - assert isinstance(env_cfg.sim.physics, NewtonCfg) - assert isinstance(env_cfg.tiled_camera.renderer_cfg, OVRTXRendererCfg) - assert config_scan.needs_kit is False + assert isinstance(env_cfg.sim.physics, PhysxCfg) + assert isinstance(env_cfg.tiled_camera.renderer_cfg, IsaacRtxRendererCfg) + assert config_scan.needs_kit is True def test_renderer_selector_physx_rtx_is_valid_and_resolves_to_ovphysx_and_ovrtx(): From 9f3bb5e095d913dc17bb831f39b84c86bfe07c44 Mon Sep 17 00:00:00 2001 From: Mustafa Haiderbhai Date: Thu, 13 Aug 2026 01:07:36 -0700 Subject: [PATCH 6/9] Fix contributed environment smoke coverage --- .../isaaclab_tasks/changelog.d/test-contrib-environments.skip | 1 + .../test/contrib/test_cartpole_showcase_environments.py | 4 +--- ...est_cartpole_showcase_environments_with_stage_in_memory.py | 4 +--- .../isaaclab_tasks/test/contrib/test_teleop_environments.py | 4 +--- .../contrib/test_teleop_environments_with_stage_in_memory.py | 4 +--- source/isaaclab_tasks/test/core/test_environments.py | 3 ++- source/isaaclab_tasks/test/env_test_utils.py | 1 - 7 files changed, 7 insertions(+), 14 deletions(-) create mode 100644 source/isaaclab_tasks/changelog.d/test-contrib-environments.skip diff --git a/source/isaaclab_tasks/changelog.d/test-contrib-environments.skip b/source/isaaclab_tasks/changelog.d/test-contrib-environments.skip new file mode 100644 index 000000000000..8b137891791f --- /dev/null +++ b/source/isaaclab_tasks/changelog.d/test-contrib-environments.skip @@ -0,0 +1 @@ + diff --git a/source/isaaclab_tasks/test/contrib/test_cartpole_showcase_environments.py b/source/isaaclab_tasks/test/contrib/test_cartpole_showcase_environments.py index 7eda602252c9..207f8ec10753 100644 --- a/source/isaaclab_tasks/test/contrib/test_cartpole_showcase_environments.py +++ b/source/isaaclab_tasks/test/contrib/test_cartpole_showcase_environments.py @@ -25,9 +25,7 @@ @pytest.mark.parametrize("num_envs, device", [(2, "cuda"), (1, "cuda")]) @pytest.mark.parametrize( "task_name", - setup_environment( - factory_envs=False, multi_agent=False, teleop_envs=False, cartpole_showcase_envs=True - ), + setup_environment(factory_envs=False, multi_agent=False, teleop_envs=False, cartpole_showcase_envs=True), ) @pytest.mark.isaacsim_ci def test_cartpole_showcase_environments(task_name, num_envs, device): diff --git a/source/isaaclab_tasks/test/contrib/test_cartpole_showcase_environments_with_stage_in_memory.py b/source/isaaclab_tasks/test/contrib/test_cartpole_showcase_environments_with_stage_in_memory.py index 185b24bec828..2ac712a34ba3 100644 --- a/source/isaaclab_tasks/test/contrib/test_cartpole_showcase_environments_with_stage_in_memory.py +++ b/source/isaaclab_tasks/test/contrib/test_cartpole_showcase_environments_with_stage_in_memory.py @@ -26,9 +26,7 @@ @pytest.mark.parametrize("num_envs, device", [(2, "cuda")]) @pytest.mark.parametrize( "task_name", - setup_environment( - factory_envs=False, multi_agent=False, teleop_envs=False, cartpole_showcase_envs=True - ), + setup_environment(factory_envs=False, multi_agent=False, teleop_envs=False, cartpole_showcase_envs=True), ) def test_cartpole_showcase_environments_with_stage_in_memory_and_clone_in_fabric_disabled(task_name, num_envs, device): # skip test if stage in memory is not supported diff --git a/source/isaaclab_tasks/test/contrib/test_teleop_environments.py b/source/isaaclab_tasks/test/contrib/test_teleop_environments.py index 980b2f3046de..11e0fab76008 100644 --- a/source/isaaclab_tasks/test/contrib/test_teleop_environments.py +++ b/source/isaaclab_tasks/test/contrib/test_teleop_environments.py @@ -36,9 +36,7 @@ @pytest.mark.parametrize("num_envs, device", [(2, "cuda"), (1, "cuda")]) -@pytest.mark.parametrize( - "task_name", setup_environment(factory_envs=False, multi_agent=False, teleop_envs=True) -) +@pytest.mark.parametrize("task_name", setup_environment(factory_envs=False, multi_agent=False, teleop_envs=True)) @pytest.mark.isaacsim_ci def test_teleop_environments(task_name, num_envs, device): # run teleop environments without stage in memory diff --git a/source/isaaclab_tasks/test/contrib/test_teleop_environments_with_stage_in_memory.py b/source/isaaclab_tasks/test/contrib/test_teleop_environments_with_stage_in_memory.py index 9379f0262962..f2cfbd83f2b2 100644 --- a/source/isaaclab_tasks/test/contrib/test_teleop_environments_with_stage_in_memory.py +++ b/source/isaaclab_tasks/test/contrib/test_teleop_environments_with_stage_in_memory.py @@ -37,9 +37,7 @@ @pytest.mark.parametrize("num_envs, device", [(2, "cuda")]) -@pytest.mark.parametrize( - "task_name", setup_environment(factory_envs=False, multi_agent=False, teleop_envs=True) -) +@pytest.mark.parametrize("task_name", setup_environment(factory_envs=False, multi_agent=False, teleop_envs=True)) def test_teleop_environments_with_stage_in_memory_and_clone_in_fabric_disabled(task_name, num_envs, device): # skip test if stage in memory is not supported if get_isaac_sim_version().major < 5: diff --git a/source/isaaclab_tasks/test/core/test_environments.py b/source/isaaclab_tasks/test/core/test_environments.py index 920861215dd2..79f8737500c2 100644 --- a/source/isaaclab_tasks/test/core/test_environments.py +++ b/source/isaaclab_tasks/test/core/test_environments.py @@ -21,8 +21,8 @@ # Local imports should be imported last from env_test_utils import _run_environments, setup_environment # isort: skip -@pytest.mark.parametrize("physics_preset_name", ["newton_mjwarp", "physx", "isaacsim_physx"]) +@pytest.mark.parametrize("physics_preset_name", ["newton_mjwarp", "physx", "isaacsim_physx"]) @pytest.mark.parametrize("num_envs, device", [(2, "cuda"), (1, "cuda")]) @pytest.mark.parametrize( "task_name", @@ -53,3 +53,4 @@ def test_environments(task_name, physics_preset_name, num_envs, device): ) @pytest.mark.isaacsim_ci def test_contrib_environments(task_name, num_envs, device): + _run_environments(task_name, device, num_envs, create_stage_in_memory=False) diff --git a/source/isaaclab_tasks/test/env_test_utils.py b/source/isaaclab_tasks/test/env_test_utils.py index c28dd3e699d9..880a8668bedc 100644 --- a/source/isaaclab_tasks/test/env_test_utils.py +++ b/source/isaaclab_tasks/test/env_test_utils.py @@ -173,7 +173,6 @@ def setup_environment( continue # if None: no filter - registered_tasks.append(task_spec.id) # sort environments alphabetically From fe80addd3bb32467faa664a6df85ca0805a8f1f6 Mon Sep 17 00:00:00 2001 From: Mustafa Haiderbhai Date: Thu, 13 Aug 2026 01:07:43 -0700 Subject: [PATCH 7/9] Normalize contrib test changelog fragment --- source/isaaclab_tasks/changelog.d/test-contrib-environments.skip | 1 - 1 file changed, 1 deletion(-) diff --git a/source/isaaclab_tasks/changelog.d/test-contrib-environments.skip b/source/isaaclab_tasks/changelog.d/test-contrib-environments.skip index 8b137891791f..e69de29bb2d1 100644 --- a/source/isaaclab_tasks/changelog.d/test-contrib-environments.skip +++ b/source/isaaclab_tasks/changelog.d/test-contrib-environments.skip @@ -1 +0,0 @@ - From 31c3cc40a7969d6ff4819ff7c8ad461d7ee74e5a Mon Sep 17 00:00:00 2001 From: Mustafa Haiderbhai Date: Thu, 13 Aug 2026 01:08:06 -0700 Subject: [PATCH 8/9] Limit PhysX preset invariant to core tasks --- source/isaaclab_tasks/test/core/test_preset_kit_decision.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/isaaclab_tasks/test/core/test_preset_kit_decision.py b/source/isaaclab_tasks/test/core/test_preset_kit_decision.py index 73a119182f3c..515ca8186f99 100644 --- a/source/isaaclab_tasks/test/core/test_preset_kit_decision.py +++ b/source/isaaclab_tasks/test/core/test_preset_kit_decision.py @@ -88,10 +88,11 @@ def test_isaacsim_physx_is_physics_selector(): def test_registered_task_physx_presets_keep_auto_selection_explicit(): - """PhysX defaults are concrete while ``physx`` remains the automatic selector.""" + """Core tasks retain explicit PhysX variants alongside automatic ``physx``.""" for task_id, task_spec in gym.registry.items(): - if not task_id.startswith(("Isaac-", "IsaacContrib-")) or "env_cfg_entry_point" not in task_spec.kwargs: + entry_point = task_spec.kwargs.get("env_cfg_entry_point", "") + if not task_id.startswith("Isaac-") or "isaaclab_tasks.core" not in str(entry_point): continue env_cfg = load_cfg_from_registry(task_id, "env_cfg_entry_point") presets = collect_presets(env_cfg) From c1859a8d1a1683da35dac0630abe4ac34db3be0f Mon Sep 17 00:00:00 2001 From: Maximilian Krause Date: Thu, 13 Aug 2026 09:41:35 -0700 Subject: [PATCH 9/9] Generate Pour reset dataset for smoke test --- .../test/core/test_environments.py | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/source/isaaclab_tasks/test/core/test_environments.py b/source/isaaclab_tasks/test/core/test_environments.py index 79f8737500c2..2b7dc2955b7e 100644 --- a/source/isaaclab_tasks/test/core/test_environments.py +++ b/source/isaaclab_tasks/test/core/test_environments.py @@ -14,6 +14,10 @@ """Rest everything follows.""" +import subprocess +import sys +from pathlib import Path + import pytest import isaaclab_tasks # noqa: F401 @@ -22,6 +26,31 @@ from env_test_utils import _run_environments, setup_environment # isort: skip +def _ensure_franka_pour_reset_dataset() -> None: + """Generate the smallest valid reset dataset when the Pour smoke test needs it.""" + repo_root = Path(__file__).resolve().parents[4] + dataset_path = repo_root / "datasets/franka_pour/reset_dataset.pt" + if dataset_path.is_file(): + return + + subprocess.run( + [ + sys.executable, + str(repo_root / "scripts/tools/generate_franka_pour_reset_dataset.py"), + "--device", + "cuda:0", + "--grasping_count", + "100", + "--non_grasping_count", + "6", + "--batch_size", + "128", + ], + cwd=repo_root, + check=True, + ) + + @pytest.mark.parametrize("physics_preset_name", ["newton_mjwarp", "physx", "isaacsim_physx"]) @pytest.mark.parametrize("num_envs, device", [(2, "cuda"), (1, "cuda")]) @pytest.mark.parametrize( @@ -53,4 +82,6 @@ def test_environments(task_name, physics_preset_name, num_envs, device): ) @pytest.mark.isaacsim_ci def test_contrib_environments(task_name, num_envs, device): + if task_name == "IsaacContrib-Franka-Pour": + _ensure_franka_pour_reset_dataset() _run_environments(task_name, device, num_envs, create_stage_in_memory=False)