Skip to content

Commit 1e5cdcf

Browse files
committed
feat: add smoke tests for all 3 demos with CI integration
Add host-driven smoke tests that exercise the gateway REST API against running Docker containers for sensor_diagnostics, turtlebot3, and moveit_pick_place demos. Sensor smoke tests (21 tests): health, entity discovery (areas, components, apps), data access, configurations, and full fault injection cycle (inject -> detect -> verify detail -> cleanup). Turtlebot3 and moveit smoke tests: health + entity discovery against their respective manifests. Shared test infrastructure in tests/smoke_lib.sh: pass/fail counters, colored output, api_get/poll_until helpers, wait_for_gateway, wait_for_runtime_linking, test_entity_discovery. CI changes: - All 3 demos build + run smoke tests in parallel jobs - Container logs shown on failure, teardown on always() - Docker Compose CI profiles for each demo Also fixes outdated medkit parameter names across all 3 demos (discovery_mode -> discovery.mode, manifest_path -> discovery.manifest_path) to match current ros2_medkit API. Closes #11
1 parent b1af18d commit 1e5cdcf

File tree

17 files changed

+505
-49
lines changed

17 files changed

+505
-49
lines changed

.github/workflows/ci.yml

Lines changed: 60 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ jobs:
3535
YAMLLINT_CONFIG="{extends: relaxed, rules: {line-length: {max: 120}}}"
3636
find . \( -name "*.yaml" -o -name "*.yml" \) -type f | xargs yamllint -d "$YAMLLINT_CONFIG"
3737
38-
docker-build:
38+
build-and-test-sensor:
3939
runs-on: ubuntu-24.04
4040
steps:
4141
- name: Show triggering source
@@ -54,20 +54,65 @@ jobs:
5454
- name: Checkout repository
5555
uses: actions/checkout@v4
5656

57-
- name: Set up Docker Buildx
58-
uses: docker/setup-buildx-action@v3
57+
- name: Build and start sensor_diagnostics demo
58+
working-directory: demos/sensor_diagnostics
59+
run: docker compose --profile ci up -d --build sensor-demo-ci
5960

60-
- name: Build Sensor Diagnostics demo image
61-
run: |
62-
cd demos/sensor_diagnostics
63-
docker build -t sensor-diagnostics-demo:test -f Dockerfile .
61+
- name: Run smoke tests
62+
run: ./tests/smoke_test.sh
6463

65-
- name: Build TurtleBot3 demo image
66-
run: |
67-
cd demos/turtlebot3_integration
68-
docker build -t turtlebot3-medkit-demo:test -f Dockerfile .
64+
- name: Show container logs on failure
65+
if: failure()
66+
working-directory: demos/sensor_diagnostics
67+
run: docker compose --profile ci logs sensor-demo-ci --tail=200
6968

70-
- name: Build MoveIt Pick-and-Place demo image
71-
run: |
72-
cd demos/moveit_pick_place
73-
docker build -t moveit-pick-place-demo:test -f Dockerfile .
69+
- name: Teardown
70+
if: always()
71+
working-directory: demos/sensor_diagnostics
72+
run: docker compose --profile ci down
73+
74+
build-and-test-turtlebot:
75+
runs-on: ubuntu-24.04
76+
steps:
77+
- name: Checkout repository
78+
uses: actions/checkout@v4
79+
80+
- name: Build and start turtlebot3 demo
81+
working-directory: demos/turtlebot3_integration
82+
run: docker compose --profile ci up -d --build turtlebot3-demo-ci
83+
84+
- name: Run smoke tests
85+
run: ./tests/smoke_test_turtlebot3.sh
86+
87+
- name: Show container logs on failure
88+
if: failure()
89+
working-directory: demos/turtlebot3_integration
90+
run: docker compose --profile ci logs turtlebot3-demo-ci --tail=200
91+
92+
- name: Teardown
93+
if: always()
94+
working-directory: demos/turtlebot3_integration
95+
run: docker compose --profile ci down
96+
97+
build-and-test-moveit:
98+
runs-on: ubuntu-24.04
99+
steps:
100+
- name: Checkout repository
101+
uses: actions/checkout@v4
102+
103+
- name: Build and start moveit demo
104+
working-directory: demos/moveit_pick_place
105+
run: docker compose --profile ci up -d --build moveit-demo-ci
106+
107+
- name: Run smoke tests
108+
run: ./tests/smoke_test_moveit.sh
109+
110+
- name: Show container logs on failure
111+
if: failure()
112+
working-directory: demos/moveit_pick_place
113+
run: docker compose --profile ci logs moveit-demo-ci --tail=200
114+
115+
- name: Teardown
116+
if: always()
117+
working-directory: demos/moveit_pick_place
118+
run: docker compose --profile ci down

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,19 @@ curl http://localhost:8080/api/v1/faults | jq
173173

174174
See individual demo READMEs for more examples.
175175

176+
## Testing
177+
178+
Each demo has automated smoke tests that verify the gateway starts and the REST API works correctly:
179+
180+
```bash
181+
# Run smoke tests against a running demo (default: http://localhost:8080)
182+
./tests/smoke_test.sh # Sensor diagnostics (21 tests, incl. fault injection)
183+
./tests/smoke_test_turtlebot3.sh # TurtleBot3 (entity discovery)
184+
./tests/smoke_test_moveit.sh # MoveIt pick-and-place (entity discovery)
185+
```
186+
187+
CI runs all 3 demos in parallel - each job builds the Docker image, starts the container, and runs the smoke tests against it. See [CI workflow](.github/workflows/ci.yml).
188+
176189
## Related Projects
177190

178191
- [ros2_medkit](https://github.com/selfpatch/ros2_medkit) — Core diagnostics library with SOVD-compliant gateway

demos/moveit_pick_place/config/medkit_params.yaml

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,11 @@ diagnostics:
1818
allow_credentials: false
1919
max_age_seconds: 86400
2020

21-
max_parallel_topic_samples: 10
22-
2321
# Discovery configuration
24-
discovery_mode: "hybrid" # runtime_only, manifest_only, or hybrid
25-
manifest_path: "" # Will be set via launch argument
26-
manifest_strict_validation: true
27-
2822
discovery:
23+
mode: "hybrid" # runtime_only, manifest_only, or hybrid
24+
manifest_path: "" # Will be set via launch argument
25+
manifest_strict_validation: true
2926
runtime:
3027
create_synthetic_components: false # Manifest defines components
3128

demos/moveit_pick_place/docker-compose.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,23 @@ services:
6262
source /root/demo_ws/install/setup.bash &&
6363
ros2 launch moveit_medkit_demo $${LAUNCH_FILE} headless:=$${HEADLESS}"
6464
65+
# For CI testing - fake hardware (no Gazebo), tests run externally
66+
moveit-demo-ci:
67+
profiles: ["ci"]
68+
build:
69+
context: .
70+
dockerfile: Dockerfile
71+
container_name: moveit_medkit_demo_ci
72+
environment:
73+
- ROS_DOMAIN_ID=40
74+
ports:
75+
- "8080:8080"
76+
command: >
77+
bash -c "mkdir -p /var/lib/ros2_medkit/rosbags &&
78+
source /opt/ros/jazzy/setup.bash &&
79+
source /root/demo_ws/install/setup.bash &&
80+
ros2 launch moveit_medkit_demo demo.launch.py headless:=true"
81+
6582
# SOVD Web UI — pre-built from GHCR
6683
sovd-web-ui:
6784
image: ghcr.io/selfpatch/sovd_web_ui:latest

demos/moveit_pick_place/launch/demo.launch.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ def generate_launch_description():
126126
medkit_params_file,
127127
{
128128
"use_sim_time": use_sim_time,
129-
"manifest_path": manifest_file,
129+
"discovery.manifest_path": manifest_file,
130130
},
131131
],
132132
),

demos/moveit_pick_place/launch/demo_gazebo.launch.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,7 @@ def generate_launch_description():
470470
medkit_params_file,
471471
{
472472
"use_sim_time": True,
473-
"manifest_path": manifest_file,
473+
"discovery.manifest_path": manifest_file,
474474
},
475475
],
476476
),

demos/sensor_diagnostics/config/medkit_params.yaml

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,11 @@ diagnostics:
1616
allow_credentials: false
1717
max_age_seconds: 86400
1818

19-
max_parallel_topic_samples: 10
20-
2119
# Discovery configuration
22-
discovery_mode: "hybrid" # runtime_only, manifest_only, or hybrid
23-
manifest_path: "" # Will be set via launch argument
24-
manifest_strict_validation: true
25-
2620
discovery:
21+
mode: "hybrid" # runtime_only, manifest_only, or hybrid
22+
manifest_path: "" # Will be set via launch argument
23+
manifest_strict_validation: true
2724
runtime:
2825
create_synthetic_components: false # Manifest defines components
2926

demos/sensor_diagnostics/docker-compose.yml

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ services:
2828
depends_on:
2929
- sensor-demo
3030

31-
# For CI testing - headless mode with quick exit
31+
# For CI testing - headless mode, tests run externally
3232
sensor-demo-ci:
3333
profiles: ["ci"]
3434
build:
@@ -43,8 +43,4 @@ services:
4343
bash -c "mkdir -p /var/lib/ros2_medkit/rosbags &&
4444
source /opt/ros/jazzy/setup.bash &&
4545
source /root/demo_ws/install/setup.bash &&
46-
ros2 launch sensor_diagnostics_demo demo.launch.py &
47-
sleep 10 &&
48-
curl -sf http://localhost:8080/api/v1/health &&
49-
curl -sf http://localhost:8080/api/v1/apps | jq '.items[] | .id' &&
50-
echo 'CI validation passed!'"
46+
ros2 launch sensor_diagnostics_demo demo.launch.py"

demos/sensor_diagnostics/launch/demo.launch.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ def generate_launch_description():
119119
parameters=[
120120
medkit_params_file,
121121
{"use_sim_time": use_sim_time},
122-
{"manifest_path": manifest_file},
122+
{"discovery.manifest_path": manifest_file},
123123
],
124124
),
125125
# ===== Fault Manager (at root namespace) =====

demos/turtlebot3_integration/config/medkit_params.yaml

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,11 @@ diagnostics:
1717
allow_credentials: false
1818
max_age_seconds: 86400
1919

20-
max_parallel_topic_samples: 10
21-
2220
# Discovery configuration
23-
discovery_mode: "hybrid" # runtime_only, manifest_only, or hybrid
24-
manifest_path: "" # Will be set via launch argument
25-
manifest_strict_validation: true
26-
2721
discovery:
22+
mode: "hybrid" # runtime_only, manifest_only, or hybrid
23+
manifest_path: "" # Will be set via launch argument
24+
manifest_strict_validation: true
2825
runtime:
2926
create_synthetic_components: false # Manifest defines components
3027

0 commit comments

Comments
 (0)