quickstart-resources/tests/smoke-test.sh
Alex Akimov 3844c5b45e
Add smoke tests for Go and Rust clients (#196)
* Add smoke tests for Go and Rush clients

* Add smoke tests for Go and Rush clients
2026-09-15 15:14:06 -07:00

191 lines
5.8 KiB
Shell
Executable file

#!/bin/bash
set -e
# Source utilities
source "$(dirname "$0")/utils.sh"
print_header "MCP Quickstart Smoke Tests"
# Get project root
PROJECT_ROOT=$(get_project_root)
TESTS_DIR="${PROJECT_ROOT}/tests"
# Setup common test variables
TEST_CLIENT="${PROJECT_ROOT}/tests/helpers/build/mcp-test-client.js"
MOCK_SERVER="${PROJECT_ROOT}/tests/helpers/build/mock-mcp-server.js"
# Track test results
FAILED_TESTS=()
PASSED_TESTS=()
# Build test helpers
ensure_helpers_built
# Helper function to run a test and track results
run_test() {
local test_name=$1
echo ""
print_header "Testing ${test_name}"
if "${@:2}"; then
PASSED_TESTS+=("${test_name}")
print_success "${test_name} test passed"
else
FAILED_TESTS+=("${test_name}")
print_error "${test_name} test failed"
fi
}
# Test: Python weather server
test_weather_server_python() {
check_dependency uv || return 1
local server_dir="${PROJECT_ROOT}/weather-server-python"
node "${TEST_CLIENT}" uv --directory "${server_dir}" run weather.py
}
# Test: TypeScript weather server
test_weather_server_typescript() {
check_dependency node || return 1
check_dependency npm || return 1
local server_dir="${PROJECT_ROOT}/weather-server-typescript"
ensure_built "${server_dir}" "" || return 1
node "${TEST_CLIENT}" node "${server_dir}/build/index.js"
}
# Test: Rust weather server
test_weather_server_rust() {
check_dependency cargo || return 1
local server_dir="${PROJECT_ROOT}/weather-server-rust"
ensure_built "${server_dir}" weather || return 1
# Determine which binary to use
local server_bin
server_bin=$(resolve_binary "${server_dir}/target/release/weather" \
|| resolve_binary "${server_dir}/target/debug/weather") || {
print_error "no weather binary found in ${server_dir}/target"
return 1
}
node "${TEST_CLIENT}" "${server_bin}"
}
# Test: Go weather server
test_weather_server_go() {
check_dependency go || return 1
local server_dir="${PROJECT_ROOT}/weather-server-go"
ensure_built "${server_dir}" server || return 1
local server_bin
server_bin=$(resolve_binary "${server_dir}/server") || {
print_error "no server binary found in ${server_dir}"
return 1
}
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"
ANTHROPIC_API_KEY= uv --directory "${client_dir}" run python "${client_dir}/client.py" "${MOCK_SERVER}" >/dev/null 2>&1
}
# Test: TypeScript MCP client
test_mcp_client_typescript() {
check_dependency node || return 1
check_dependency npm || return 1
local client_dir="${PROJECT_ROOT}/mcp-client-typescript"
ensure_built "${client_dir}" "" || return 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
}
# Test: Go MCP client
test_mcp_client_go() {
check_dependency go || return 1
local client_dir="${PROJECT_ROOT}/mcp-client-go"
ensure_built "${client_dir}" mcp-client-go || return 1
local client_bin
client_bin=$(resolve_binary "${client_dir}/mcp-client-go") || {
print_error "no mcp-client-go binary found in ${client_dir}"
return 1
}
ANTHROPIC_API_KEY= "${client_bin}" node "${MOCK_SERVER}" >/dev/null 2>&1
}
# Test: Rust MCP client
test_mcp_client_rust() {
check_dependency cargo || return 1
local client_dir="${PROJECT_ROOT}/mcp-client-rust"
ensure_built "${client_dir}" mcp-client-rust || return 1
local client_bin
client_bin=$(resolve_binary "${client_dir}/target/release/mcp-client-rust" \
|| resolve_binary "${client_dir}/target/debug/mcp-client-rust") || {
print_error "no mcp-client-rust binary found in ${client_dir}/target"
return 1
}
ANTHROPIC_API_KEY= "${client_bin}" node "${MOCK_SERVER}" >/dev/null 2>&1
}
# Run all tests
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
run_test "mcp-client-go" test_mcp_client_go
run_test "mcp-client-rust" test_mcp_client_rust
# Print summary
echo ""
print_header "Test Summary"
echo "Passed: ${#PASSED_TESTS[@]}"
for test in "${PASSED_TESTS[@]}"; do
print_success "${test}"
done
if [ ${#FAILED_TESTS[@]} -gt 0 ]; then
echo ""
echo "Failed: ${#FAILED_TESTS[@]}"
for test in "${FAILED_TESTS[@]}"; do
print_error "${test}"
done
echo ""
print_error "Some tests failed"
exit 1
else
echo ""
print_success "All tests passed!"
exit 0
fi