Merge pull request #183 from olaservo/ruby-smoke-tests
Cover the Ruby examples in the smoke tests
This commit is contained in:
commit
3196b11aae
4 changed files with 59 additions and 9 deletions
7
.github/workflows/ci.yml
vendored
7
.github/workflows/ci.yml
vendored
|
|
@ -41,5 +41,12 @@ jobs:
|
|||
with:
|
||||
go-version: "1.25"
|
||||
|
||||
# 3.4 is the current stable series. 3.3 is supported until March 2027; 3.2
|
||||
# reached end of life in March 2026.
|
||||
- name: Set up Ruby
|
||||
uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
ruby-version: "3.4"
|
||||
|
||||
- name: Run smoke tests
|
||||
run: ./tests/smoke-test.sh
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@ This directory contains smoke tests for the MCP quickstart examples. These tests
|
|||
|
||||
The smoke tests verify:
|
||||
|
||||
- **Servers**: Each weather server (Python, TypeScript, Rust, Go) can start, respond to MCP protocol requests, and honour the output schemas it advertises
|
||||
- **Clients**: The Python and TypeScript MCP clients can connect to a mock server and list tools
|
||||
- **Servers**: Each weather server (Python, TypeScript, Rust, Go, Ruby) can start, respond to MCP protocol requests, and honour the output schemas it advertises
|
||||
- **Clients**: The Python, TypeScript and Ruby MCP clients can connect to a mock server and list tools
|
||||
|
||||
The Go and Rust clients are not covered here: on `main` both abort when no `.env` file is present, so they cannot be driven without credentials. Making them start credential-free is a change in their own directories, so their coverage lands with those changes rather than here. The Ruby examples are not covered either — the `mcp` gem cannot negotiate protocol revision `2026-07-28`.
|
||||
The Go and Rust clients are not covered here: on `main` both abort when no `.env` file is present, so they cannot be driven without credentials. Making them start credential-free is a change in their own directories, so their coverage lands with those changes rather than here.
|
||||
|
||||
## Structured content
|
||||
|
||||
|
|
@ -37,6 +37,8 @@ Tool calls reach the live NWS API. When it is unreachable the tools return an er
|
|||
- **Rust** stable
|
||||
- **Cargo** (for Rust builds)
|
||||
- **Go** 1.25+
|
||||
- **Ruby** 3.4+ (3.2 and 3.3 satisfy the gems, but 3.2 is past end of life)
|
||||
- **Bundler** (ships with Ruby 3.x)
|
||||
|
||||
## How It Works
|
||||
|
||||
|
|
@ -111,6 +113,9 @@ nvm install 24
|
|||
|
||||
# Rust
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
||||
|
||||
# Ruby (via rbenv)
|
||||
rbenv install 3.4
|
||||
```
|
||||
|
||||
## Adding New Tests
|
||||
|
|
|
|||
|
|
@ -84,11 +84,24 @@ test_weather_server_go() {
|
|||
node "${TEST_CLIENT}" "${server_bin}"
|
||||
}
|
||||
|
||||
# Test: Ruby weather server
|
||||
test_weather_server_ruby() {
|
||||
check_dependency ruby || return 1
|
||||
check_dependency bundle || return 1
|
||||
local server_dir="${PROJECT_ROOT}/weather-server-ruby"
|
||||
ensure_bundled "${server_dir}" || return 1
|
||||
(cd "${server_dir}" && node "${TEST_CLIENT}" bundle exec ruby weather.rb)
|
||||
}
|
||||
|
||||
# The client tests drive the no-API-key path, where each client prints a notice
|
||||
# and exits. Empty rather than unset: dotenv skips a name already present in
|
||||
# ENV, so a key in the environment or a local .env would start the chat loop.
|
||||
|
||||
# Test: Python MCP client
|
||||
test_mcp_client_python() {
|
||||
check_dependency uv || return 1
|
||||
local client_dir="${PROJECT_ROOT}/mcp-client-python"
|
||||
uv --directory "${client_dir}" run python "${client_dir}/client.py" "${MOCK_SERVER}" >/dev/null 2>&1
|
||||
ANTHROPIC_API_KEY= uv --directory "${client_dir}" run python "${client_dir}/client.py" "${MOCK_SERVER}" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
# Test: TypeScript MCP client
|
||||
|
|
@ -97,22 +110,34 @@ test_mcp_client_typescript() {
|
|||
check_dependency npm || return 1
|
||||
local client_dir="${PROJECT_ROOT}/mcp-client-typescript"
|
||||
ensure_built "${client_dir}" || return 1
|
||||
node "${client_dir}/build/index.js" "${MOCK_SERVER}" >/dev/null 2>&1
|
||||
ANTHROPIC_API_KEY= node "${client_dir}/build/index.js" "${MOCK_SERVER}" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
# Test: Ruby MCP client
|
||||
test_mcp_client_ruby() {
|
||||
check_dependency ruby || return 1
|
||||
check_dependency bundle || return 1
|
||||
local client_dir="${PROJECT_ROOT}/mcp-client-ruby"
|
||||
ensure_bundled "${client_dir}" || return 1
|
||||
(cd "${client_dir}" && ANTHROPIC_API_KEY= bundle exec ruby client.rb "${MOCK_SERVER}") >/dev/null 2>&1
|
||||
}
|
||||
|
||||
# Run all tests
|
||||
#
|
||||
# All four servers are covered. The Go and Rust clients are not: on main both
|
||||
# abort when no .env file is present, so they cannot be driven without
|
||||
# credentials. Making them start credential-free is a change in their own
|
||||
# directories, so their coverage lands with those changes rather than here.
|
||||
# The Go and Rust clients are not covered: on main both abort when no .env file
|
||||
# is present, so they cannot be driven without credentials. Making them start
|
||||
# credential-free is a change in their own directories, so their coverage lands
|
||||
# with those changes rather than here.
|
||||
|
||||
print_header "Running smoke tests"
|
||||
run_test "weather-server-python" test_weather_server_python
|
||||
run_test "weather-server-typescript" test_weather_server_typescript
|
||||
run_test "weather-server-rust" test_weather_server_rust
|
||||
run_test "weather-server-go" test_weather_server_go
|
||||
run_test "weather-server-ruby" test_weather_server_ruby
|
||||
run_test "mcp-client-python" test_mcp_client_python
|
||||
run_test "mcp-client-typescript" test_mcp_client_typescript
|
||||
run_test "mcp-client-ruby" test_mcp_client_ruby
|
||||
|
||||
# Print summary
|
||||
echo ""
|
||||
|
|
|
|||
|
|
@ -138,3 +138,16 @@ ensure_built() {
|
|||
run_build "go build in ${dir}" go build -o "server$(exe_suffix)" . || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Ensure a Ruby project directory has its gems installed.
|
||||
#
|
||||
# Unlike ensure_built there is no artefact to test for -- a Ruby example has no
|
||||
# build step and Gemfile.lock is gitignored -- so ask Bundler directly.
|
||||
ensure_bundled() {
|
||||
local dir=$1
|
||||
cd "${dir}" || return 1
|
||||
|
||||
if ! bundle check >/dev/null 2>&1; then
|
||||
run_build "bundle install in ${dir}" bundle install || return 1
|
||||
fi
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue