-
Notifications
You must be signed in to change notification settings - Fork 176
refactor(topics): migrate to rosapi_service()/rosapi_type(), add tool tests (step3) #281
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
stex2005
wants to merge
13
commits into
develop
Choose a base branch
from
feature/step3
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
d973050
test: add integration tests for node tools (red)
stex2005 7f34706
refactor(nodes): use rosapi_service()/rosapi_type() instead of hardco…
stex2005 470e918
test: add negative tests and run node_details on all distros
stex2005 0c056f9
test: call actual MCP tools in node integration tests
stex2005 6d5ea2f
style: ruff format long assert lines in test_nodes
stex2005 ac802af
fix: surface detection failure warning, fall back to ROS 2 types when…
stex2005 afe6359
refactor(topics): use rosapi_service()/rosapi_type() instead of hardc…
stex2005 2bc26f1
test: integration tests for topic tools via MCP tool functions
stex2005 ae26bc6
ci: add per-module test runner scripts and module filter to run-tests.sh
stex2005 8a04111
ci: rename run-detect_version-tests.sh to run-detect-version-tests.sh
stex2005 e8ee53e
ci: show available distros and modules when run-tests.sh called witho…
stex2005 91f0fbc
test: add publish/subscribe tests, fix type lookup for all distros
stex2005 e635108
fix: correct subscribe_for_duration test to handle ToolResult object
stex2005 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
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
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| #!/bin/bash | ||
| # Run connection integration tests against a specific ROS distro. | ||
| # Usage: ./tests/integration/scripts/run-connection-tests.sh <distro> | ||
| exec "$(dirname "$0")/run-tests.sh" "${1:?Usage: $0 <melodic|noetic|humble|jazzy>}" connection |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| #!/bin/bash | ||
| # Run detect_version integration tests against a specific ROS distro. | ||
| # Usage: ./tests/integration/scripts/run-detect-version-tests.sh <distro> | ||
| exec "$(dirname "$0")/run-tests.sh" "${1:?Usage: $0 <melodic|noetic|humble|jazzy>}" detect_version |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| #!/bin/bash | ||
| # Run nodes integration tests against a specific ROS distro. | ||
| # Usage: ./tests/integration/scripts/run-nodes-tests.sh <distro> | ||
| exec "$(dirname "$0")/run-tests.sh" "${1:?Usage: $0 <melodic|noetic|humble|jazzy>}" nodes |
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| #!/bin/bash | ||
| # Run topics integration tests against a specific ROS distro. | ||
| # Usage: ./tests/integration/scripts/run-topics-tests.sh <distro> | ||
| exec "$(dirname "$0")/run-tests.sh" "${1:?Usage: $0 <melodic|noetic|humble|jazzy>}" topics |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,97 @@ | ||
| """Integration tests for node tools (step 2). | ||
|
|
||
| These tests call the actual MCP tool functions (get_nodes, get_node_details) | ||
| against a live rosbridge container. | ||
|
|
||
| Note: calling get_node_details for nonexistent nodes crashes rosapi_node | ||
| on ROS 2 (#273). Tests only query nodes confirmed to exist. | ||
| """ | ||
|
|
||
| import pytest | ||
|
|
||
| pytestmark = [pytest.mark.integration] | ||
|
|
||
|
|
||
| class TestGetNodes: | ||
| """Verify get_nodes MCP tool returns the running node list.""" | ||
|
|
||
| def test_returns_nodes(self, tools): | ||
| """get_nodes should return nodes and node_count.""" | ||
| result = tools["get_nodes"]() | ||
| assert "nodes" in result | ||
| assert "node_count" in result | ||
| assert result["node_count"] > 0 | ||
| assert result["node_count"] == len(result["nodes"]) | ||
|
|
||
| def test_includes_turtlesim(self, tools): | ||
| """turtlesim node should be present (launched by Docker container).""" | ||
| result = tools["get_nodes"]() | ||
| nodes = result["nodes"] | ||
| assert any("/turtlesim" in n for n in nodes), f"turtlesim not in {nodes}" | ||
|
|
||
| def test_includes_rosbridge(self, tools): | ||
| """rosbridge node should be present.""" | ||
| result = tools["get_nodes"]() | ||
| nodes = result["nodes"] | ||
| assert any("rosbridge" in n for n in nodes), f"rosbridge not in {nodes}" | ||
|
|
||
| def test_node_count_at_least_three(self, tools): | ||
| """Should have at least 3 nodes: turtlesim, rosbridge, rosapi.""" | ||
| result = tools["get_nodes"]() | ||
| assert result["node_count"] >= 3, ( | ||
| f"Expected >= 3, got {result['node_count']}: {result['nodes']}" | ||
| ) | ||
|
|
||
| def test_all_nodes_are_ros_names(self, tools): | ||
| """Every node name should be a string starting with /.""" | ||
| result = tools["get_nodes"]() | ||
| for node in result["nodes"]: | ||
| assert isinstance(node, str), f"Expected string, got {type(node)}: {node}" | ||
| assert node.startswith("/"), f"Node name should start with /: {node}" | ||
|
|
||
|
|
||
| class TestGetNodeDetails: | ||
| """Verify get_node_details MCP tool returns publishers/subscribers/services. | ||
|
|
||
| Only queries nodes confirmed to exist — calling get_node_details for | ||
| nonexistent nodes crashes rosapi_node on ROS 2 (#273). | ||
| """ | ||
|
|
||
| def test_turtlesim_details(self, tools): | ||
| """get_node_details for /turtlesim should return publishers and subscribers.""" | ||
| result = tools["get_node_details"](node="/turtlesim") | ||
| assert result["node"] == "/turtlesim" | ||
| assert result["publisher_count"] > 0, "turtlesim should have publishers" | ||
| assert result["subscriber_count"] > 0, "turtlesim should have subscribers" | ||
| assert any("pose" in p for p in result["publishers"]), f"No pose in {result['publishers']}" | ||
| assert any("cmd_vel" in s for s in result["subscribers"]), ( | ||
| f"No cmd_vel in {result['subscribers']}" | ||
| ) | ||
|
|
||
| def test_rosbridge_has_services(self, tools): | ||
| """get_node_details for rosbridge should return services.""" | ||
| # Find rosbridge node name dynamically (varies by distro) | ||
| nodes_result = tools["get_nodes"]() | ||
| rosbridge = next((n for n in nodes_result["nodes"] if "rosbridge" in n), None) | ||
| assert rosbridge is not None | ||
|
|
||
| result = tools["get_node_details"](node=rosbridge) | ||
| assert result["node"] == rosbridge | ||
| assert result["service_count"] > 0, "rosbridge should have services" | ||
|
|
||
| def test_detail_counts_match_lists(self, tools): | ||
| """publisher_count/subscriber_count/service_count should match list lengths.""" | ||
| result = tools["get_node_details"](node="/turtlesim") | ||
| assert result["publisher_count"] == len(result["publishers"]) | ||
| assert result["subscriber_count"] == len(result["subscribers"]) | ||
| assert result["service_count"] == len(result["services"]) | ||
|
|
||
| def test_empty_node_name_returns_error(self, tools): | ||
| """get_node_details with empty string should return error dict.""" | ||
| result = tools["get_node_details"](node="") | ||
| assert "error" in result | ||
|
|
||
| def test_whitespace_node_name_returns_error(self, tools): | ||
| """get_node_details with whitespace should return error dict.""" | ||
| result = tools["get_node_details"](node=" ") | ||
| assert "error" in result |
Oops, something went wrong.
Oops, something went wrong.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR inherits the same
DetectionErrorcrash path flagged on #280. If detection fails silently inconnect_to_robot, all 6 topic tool functions will crash with an unhandledDetectionErrorwhen they callrosapi_type(). This is a regression from the hardcoded strings that always worked regardless of detection state.See the detailed comment on #280: #280 (review)
This will be resolved once the fix lands in step 2 — no action needed here, just flagging the dependency.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed. Step2 fixes should be already in this branch via rebase.
get_type()should now fall back to ROS 2 format andconnect_to_robotsurfaces a warning.