Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ on:
- cron: "0 */6 * * 1-5"

jobs:
# Lint and non-integration tests for all packages
integration-test-in-studio-container:
uses: PickNikRobotics/moveit_pro_ci/.github/workflows/workspace_integration_test.yaml@v0.0.7
with:
Expand All @@ -22,6 +23,32 @@ jobs:
secrets:
moveit_license_key: ${{ secrets.STUDIO_CI_LICENSE_KEY }}

# Per-config objective integration tests (run in parallel via matrix)
objective-integration-test:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The downside to doing this with a matrix is that it launches a separate Github Actions runner for each invocation of the matrix. If we do these all as a single colcon test --packages-select <list_of_packages>, many of them can still be run in parallel but we only spin up an instance, install dependencies, clone stuff, etc. once. Also, we should be doing this test for at least Humble and Jazzy (in a matrix because they are completely different environments).

strategy:
fail-fast: false
matrix:
config_package:
- lab_sim
- kitchen_sim
- april_tag_sim
- grinding_sim
- dual_arm_sim
- factory_sim
- hangar_sim
- kinova_sim
- space_satellite_sim
- space_satellite_sim_camera_cal
- mock_sim
- multi_arm_sim
uses: PickNikRobotics/moveit_pro_ci/.github/workflows/workspace_integration_test.yaml@v0.0.6
with:
image_tag: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.ref || github.ref_name }}
config_package: ${{ matrix.config_package }}
colcon_test_args: "--executor sequential"
secrets:
moveit_license_key: ${{ secrets.STUDIO_CI_LICENSE_KEY }}

ensure-no-ssh-in-gitmodules:
name: Ensure no SSH URLs in .gitmodules
runs-on: ubuntu-22.04
Expand Down
5 changes: 5 additions & 0 deletions src/april_tag_sim/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,13 @@ install(
)

if(BUILD_TESTING)
find_package(ament_cmake_pytest REQUIRED)
find_package(ament_lint_auto REQUIRED)
ament_lint_auto_find_test_dependencies()
ament_add_pytest_test(
objectives_integration_test test/objectives_integration_test.py
TIMEOUT 600
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

10 minutes? We usually give 10 minutes for all of colcon test. Does it actually take anywhere near this long?

ENV MOVEIT_CONFIG_PACKAGE=april_tag_sim MOVEIT_HOST_USER_WORKSPACE=${CMAKE_SOURCE_DIR})
endif()

ament_package()
2 changes: 2 additions & 0 deletions src/april_tag_sim/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@
<exec_depend>ur_description</exec_depend>
<exec_depend>velocity_force_controller</exec_depend>

<test_depend>ament_cmake_pytest</test_depend>
<test_depend>ament_lint_auto</test_depend>
<test_depend>moveit_pro_test_utils</test_depend>

<test_depend>ament_clang_format</test_depend>
<test_depend>ament_clang_tidy</test_depend>
Expand Down
57 changes: 57 additions & 0 deletions src/april_tag_sim/test/objectives_integration_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Copyright 2026 PickNik Inc.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# * Neither the name of the PickNik Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

import pytest
from moveit_pro_test_utils.objective_test_fixture import (
ExecuteObjectiveResource,
execute_objective_resource as execute_objective_resource,
get_objective_pytest_params,
run_objective,
)

cancel_objectives = set()

# Objectives requiring AprilTag camera perception (no simulated camera feed in CI)
skip_objectives = {
"Pick April Tag Labeled Object", # Requires AprilTag detection + camera
"Collect Angled AprilTag Detection Data", # Requires camera feed
"Collect AprilTag Detection Data", # Requires camera feed
"Collect Parallel AprilTag Detection Data", # Requires camera feed
}


@pytest.mark.parametrize(
"objective_id, should_cancel",
get_objective_pytest_params("april_tag_sim", cancel_objectives, skip_objectives),
)
def test_all_objectives(
objective_id: str,
should_cancel: bool,
execute_objective_resource: ExecuteObjectiveResource,
):
run_objective(objective_id, should_cancel, execute_objective_resource)
5 changes: 5 additions & 0 deletions src/dual_arm_sim/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,13 @@ install(
)

if(BUILD_TESTING)
find_package(ament_cmake_pytest REQUIRED)
find_package(ament_lint_auto REQUIRED)
ament_lint_auto_find_test_dependencies()
ament_add_pytest_test(
objectives_integration_test test/objectives_integration_test.py
TIMEOUT 600
ENV MOVEIT_CONFIG_PACKAGE=dual_arm_sim MOVEIT_HOST_USER_WORKSPACE=${CMAKE_SOURCE_DIR})
endif()

ament_package()
2 changes: 2 additions & 0 deletions src/dual_arm_sim/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@
<test_depend>ament_clang_tidy</test_depend>
<test_depend>ament_cmake_copyright</test_depend>
<test_depend>ament_cmake_lint_cmake</test_depend>
<test_depend>ament_cmake_pytest</test_depend>
<test_depend>ament_flake8</test_depend>
<test_depend>ament_lint_auto</test_depend>
<test_depend>moveit_pro_test_utils</test_depend>
<test_depend>picknik_ament_copyright</test_depend>

<export>
Expand Down
54 changes: 54 additions & 0 deletions src/dual_arm_sim/test/objectives_integration_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Copyright 2026 PickNik Inc.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# * Neither the name of the PickNik Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

import pytest
from moveit_pro_test_utils.objective_test_fixture import (
ExecuteObjectiveResource,
execute_objective_resource as execute_objective_resource,
get_objective_pytest_params,
run_objective,
)

cancel_objectives = set()

# Objectives requiring user input or ML/GPU inference
skip_objectives = {
"Teleoperate", # Requires user teleoperation input
}


@pytest.mark.parametrize(
"objective_id, should_cancel",
get_objective_pytest_params("dual_arm_sim", cancel_objectives, skip_objectives),
)
def test_all_objectives(
objective_id: str,
should_cancel: bool,
execute_objective_resource: ExecuteObjectiveResource,
):
run_objective(objective_id, should_cancel, execute_objective_resource)
5 changes: 5 additions & 0 deletions src/factory_sim/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,13 @@ install(DIRECTORY "${PICKNIK_ACCESSORIES_PATH}"
FILES_MATCHING PATTERN "*")

if(BUILD_TESTING)
find_package(ament_cmake_pytest REQUIRED)
find_package(ament_lint_auto REQUIRED)
ament_lint_auto_find_test_dependencies()
ament_add_pytest_test(
objectives_integration_test test/objectives_integration_test.py
TIMEOUT 600
ENV MOVEIT_CONFIG_PACKAGE=factory_sim MOVEIT_HOST_USER_WORKSPACE=${CMAKE_SOURCE_DIR})
endif()

ament_package()
2 changes: 2 additions & 0 deletions src/factory_sim/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
<exec_depend>moveit_studio_agent</exec_depend>
<exec_depend>moveit_pro_behavior</exec_depend>

<test_depend>ament_cmake_pytest</test_depend>
<test_depend>ament_lint_auto</test_depend>
<test_depend>moveit_pro_test_utils</test_depend>

<test_depend>ament_clang_format</test_depend>
<test_depend>ament_clang_tidy</test_depend>
Expand Down
57 changes: 57 additions & 0 deletions src/factory_sim/test/objectives_integration_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Copyright 2026 PickNik Inc.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# * Neither the name of the PickNik Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

import pytest
from moveit_pro_test_utils.objective_test_fixture import (
ExecuteObjectiveResource,
execute_objective_resource as execute_objective_resource,
get_objective_pytest_params,
run_objective,
)

cancel_objectives = set()

# Objectives requiring user input or ML/GPU inference
skip_objectives = {
"Automask from File", # Requires ML segmentation model
"Automask from Camera", # Requires ML segmentation model + camera
"Automask Camera Iterate Masks", # Requires ML segmentation model + camera
"Pick and Place Brackets from Left Bin", # Requires ML perception pipeline
}


@pytest.mark.parametrize(
"objective_id, should_cancel",
get_objective_pytest_params("factory_sim", cancel_objectives, skip_objectives),
)
def test_all_objectives(
objective_id: str,
should_cancel: bool,
execute_objective_resource: ExecuteObjectiveResource,
):
run_objective(objective_id, should_cancel, execute_objective_resource)
5 changes: 5 additions & 0 deletions src/grinding_sim/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,13 @@ install(
)

if(BUILD_TESTING)
find_package(ament_cmake_pytest REQUIRED)
find_package(ament_lint_auto REQUIRED)
ament_lint_auto_find_test_dependencies()
ament_add_pytest_test(
objectives_integration_test test/objectives_integration_test.py
TIMEOUT 600
ENV MOVEIT_CONFIG_PACKAGE=grinding_sim MOVEIT_HOST_USER_WORKSPACE=${CMAKE_SOURCE_DIR})
endif()

ament_package()
2 changes: 2 additions & 0 deletions src/grinding_sim/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
<exec_depend>moveit_studio_agent</exec_depend>
<exec_depend>moveit_pro_behavior</exec_depend>

<test_depend>ament_cmake_pytest</test_depend>
<test_depend>ament_lint_auto</test_depend>
<test_depend>moveit_pro_test_utils</test_depend>

<test_depend>ament_clang_format</test_depend>
<test_depend>ament_clang_tidy</test_depend>
Expand Down
54 changes: 54 additions & 0 deletions src/grinding_sim/test/objectives_integration_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Copyright 2026 PickNik Inc.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# * Neither the name of the PickNik Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

import pytest
from moveit_pro_test_utils.objective_test_fixture import (
ExecuteObjectiveResource,
execute_objective_resource as execute_objective_resource,
get_objective_pytest_params,
run_objective,
)

cancel_objectives = set()

# Objectives requiring user input or perception hardware
skip_objectives = {
"Grind Machined Part", # Requires admittance control user interaction
}


@pytest.mark.parametrize(
"objective_id, should_cancel",
get_objective_pytest_params("grinding_sim", cancel_objectives, skip_objectives),
)
def test_all_objectives(
objective_id: str,
should_cancel: bool,
execute_objective_resource: ExecuteObjectiveResource,
):
run_objective(objective_id, should_cancel, execute_objective_resource)
5 changes: 5 additions & 0 deletions src/hangar_sim/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,13 @@ install(IMPORTED_RUNTIME_ARTIFACTS moveit_studio_plugins::dummy_controller_handl
lib)

if(BUILD_TESTING)
find_package(ament_cmake_pytest REQUIRED)
find_package(ament_lint_auto REQUIRED)
ament_lint_auto_find_test_dependencies()
ament_add_pytest_test(
objectives_integration_test test/objectives_integration_test.py
TIMEOUT 600
ENV MOVEIT_CONFIG_PACKAGE=hangar_sim MOVEIT_HOST_USER_WORKSPACE=${CMAKE_SOURCE_DIR})
endif()

ament_package()
2 changes: 2 additions & 0 deletions src/hangar_sim/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@
<exec_depend>ur_description</exec_depend>
<exec_depend>velocity_force_controller</exec_depend>

<test_depend>ament_cmake_pytest</test_depend>
<test_depend>ament_lint_auto</test_depend>
<test_depend>moveit_pro_test_utils</test_depend>

<test_depend>ament_clang_format</test_depend>
<test_depend>ament_clang_tidy</test_depend>
Expand Down
Loading
Loading