Refactor the gateway integration test suite into a dedicated ros2_medkit_integration_tests package#227
Open
Refactor the gateway integration test suite into a dedicated ros2_medkit_integration_tests package#227
ros2_medkit_integration_tests package#227Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This pull request extracts integration tests and demo nodes from ros2_medkit_gateway into a new dedicated package ros2_medkit_integration_tests. The refactoring improves test organization by separating integration tests into two categories: scenario tests (end-to-end stories) and feature tests (atomic, independent tests). A new ros2_medkit_test_utils Python package provides shared utilities including launch helpers, base test classes, and constants.
Changes:
- Created new
ros2_medkit_integration_testspackage with demo nodes, test utilities, and reorganized tests - Moved 9 demo node C++ files from
ros2_medkit_gateway/test/demo_nodes/to the new package - Split monolithic integration tests into 23 smaller test files organized by scenario vs. feature
- Removed integration test dependencies from
ros2_medkit_gatewaypackage.xml and CMakeLists.txt - Updated launch files and test references to use new package names
Reviewed changes
Copilot reviewed 39 out of 49 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| src/ros2_medkit_integration_tests/package.xml | New package metadata with test and demo node dependencies |
| src/ros2_medkit_integration_tests/CMakeLists.txt | Build config for demo nodes and test registration with proper timeouts |
| src/ros2_medkit_integration_tests/setup.cfg | Python package setup for test utilities |
| src/ros2_medkit_integration_tests/ros2_medkit_test_utils/* | Shared test utilities: constants, coverage helpers, launch factories, base test class |
| src/ros2_medkit_integration_tests/test/scenarios/* | 9 scenario test files (end-to-end stories, 300s timeout) |
| src/ros2_medkit_integration_tests/test/features/* | 14 feature test files (atomic tests, 120s timeout) |
| src/ros2_medkit_integration_tests/demo_nodes/* | 9 demo node C++ files moved from gateway package |
| src/ros2_medkit_integration_tests/launch/demo_nodes.launch.py | Launch file updated to reference new package |
| src/ros2_medkit_gateway/package.xml | Removed test dependencies (pytest, launch_testing, etc.) |
| src/ros2_medkit_gateway/CMakeLists.txt | Removed integration tests and demo node build targets |
ros2_medkit_integration_tests package
ae470cf to
8050710
Compare
8050710 to
86cd8f4
Compare
Four modules replacing ~1200 lines of duplicated code: - constants.py: API paths, ports, timeouts - coverage.py: unified get_coverage_env() - launch_helpers.py: factory for gateway/demo/fault_manager nodes - gateway_test_case.py: base class with health polling, HTTP helpers, wait helpers, and discovery assertions Refs #139, #222
Replaces test_discovery_manifest and test_discovery_hybrid from gateway package with scenario-style tests using shared assertion helpers. Each scenario validates entity structure, capabilities, and mode-specific behavior. Refs #139
Migrated from gateway package with scenario-style structure. Using shared test_utils for launch helpers and base test case. Refs #139
- Add 'calibration_service' and 'long_calibration_action' aliases to DEMO_NODE_REGISTRY (fixes KeyError in test_entity_routing and test_operations_api) - Fix camelCase 'faultCode' -> snake_case 'fault_code' in test_scenario_fault_lifecycle to match actual API response - Replace strict assertExitCodes with SIGTERM-tolerant exit code check across all 24 test files (exit code -15 is expected during launch_testing shutdown) - Add polling loop in test_scenario_discovery_hybrid test_15 to wait for runtime linking (apps become online asynchronously after nodes start)
- long_calibration_action: replace detached thread with joinable thread and atomic shutdown flag; add try-catch for goal handle interactions; use set_terminate to handle rclcpp_action race during SIGINT shutdown - All timer-based demo nodes: cancel timers in destructor to prevent callbacks firing during node destruction (fixes SIGSEGV on Humble) - Revert gateway-only exit code guard: all processes must exit cleanly - Fix test_discovery_heuristic exit code check (was silently passing)
…n tests package - Add README.md with package structure, test templates, and GatewayTestCase API - Add design/index.rst with PlantUML architecture diagram and test catalog - Add symlink and toctree entry in docs/design/ - Add package description in docs/introduction.rst - Fix demo_nodes.launch.py package reference in getting_started.rst - Update devcontainer.rst test filtering for new package structure
- Add REQUIRED_APPS to test_hateoas discovery wait so temp_sensor is guaranteed to be discovered before tests run (fixes 404 on all platforms) - Increase fault_manager test timeout from 1s to 3s for Humble's slower DDS service discovery - Accept either "not available" or "timed out" error in service availability tests (wait_for_service behavior varies across distros) - Exclude vendored/ from coverage in both codecov.yml and CI lcov filter
On Humble (CycloneDDS), reusing the same node name across sequential GTest cases causes stale DDS participant discovery state. This corrupts service responses in the second test when the first test did not create a service. Using unique node names per test eliminates the collision. Fixes test_fault_manager on Humble CI (GetSnapshotsSuccessWithValidJson).
86cd8f4 to
f0d0c3f
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pull Request
Summary
Refactor the gateway integration test suite into a dedicated
ros2_medkit_integration_testspackage with a shared Python test library (ros2_medkit_test_utils), two-tier test organization (features + scenarios), CMake labels, and structural fixes for flaky tests.What changed:
ros2_medkit_integration_tests- contains all integration tests, demo nodes, launch files, config YAMLs, and a shared Python test libraryros2_medkit_test_utils(4 modules) - eliminates ~1,200 lines of duplicated code:get_coverage_env()(9 copies), health polling (9 variants), demo node launch boilerplate, HTTP helperstest_integration.test.py(4,990 lines, 141 tests) split into 16 feature test files (~90 tests) and 10 scenario test files (~50 tests) - each file launches its own gateway with only the demo nodes it needsintegration;feature,integration;scenario) enablecolcon test --ctest-args -L featurefilteringKey library modules:
constants.py- shared API paths, ports, timeouts (replaces 50+ duplicated lines)coverage.py- singleget_coverage_env()(replaces 9 copies, ~270 lines)launch_helpers.py-create_test_launch()factory (replaces ~500 lines of inline launch boilerplate)gateway_test_case.py-GatewayTestCasebase class with health polling, HTTP helpers, discovery waiters, assertion helpersIssue
Type
Testing
Build verification:
Gateway unit tests (unchanged):
Integration test registration:
Run integration tests:
colcon test --packages-select ros2_medkit_integration_tests colcon test-result --verboseCoverage still works from separate package -
get_coverage_env()resolvesros2_medkit_gateway's build dir viaament_index_python, gateway binary writes.gcdatoGCOV_PREFIX, CIlcov --capture --directory buildscans the entire build directory.Issue #222 (flaky test_101): The race condition is resolved structurally -
test_scenario_action_lifecycle.test.pyreplaces the problematic test_100 + test_101 sequence. Each test creates its own execution (no concurrent action goals from previous tests).Issue #139 (multi-discovery-mode): Two new scenario files (
test_scenario_discovery_manifest.test.py,test_scenario_discovery_hybrid.test.py) test manifest-only and hybrid modes. Shared assertion helpers (assert_entity_exists,assert_entity_has_capabilities, etc.) inGatewayTestCasesupport mode-specific validation. Runtime mode is tested implicitly by all feature tests (default mode).Checklist