Skip to content

test: add integration tests for MCP server mode #248 - #761

Open
eajajhossain wants to merge 1 commit into
stakpak:mainfrom
eajajhossain:test/mcp-server-integration-tests
Open

test: add integration tests for MCP server mode #248#761
eajajhossain wants to merge 1 commit into
stakpak:mainfrom
eajajhossain:test/mcp-server-integration-tests

Conversation

@eajajhossain

Copy link
Copy Markdown

Description

Adds a comprehensive integration test suite for the MCP server (stakpak-mcp-server) to validate server functionality across different tool modes (local, remote, combined), mTLS configurations, tool execution, and error handling.

Related Issues

Closes #248

Changes Made

  • New Test Suite: Created libs/mcp/server/tests/mcp_server_integration.rs containing 12 integration tests.
  • Tool Mode Tests: Added test cases for LocalOnly, RemoteOnly, and Combined tool modes to ensure tool routers expose only the expected tool signatures for each mode.
  • mTLS Security Tests: Tested successful mTLS handshake with matching CertificateChain, rejection when client cert is missing, and rejection when client cert is signed by an untrusted CA.
  • End-to-End Execution: Verified calling the view tool via real stakpak-mcp-client on a temporary file.
  • Server Lifecycle & Auth: Verified graceful shutdown signal handling, port unbinding, and running LocalOnly mode without an API key.
  • Dependencies: Added stakpak-mcp-client, stakpak-shared, tokio, reqwest, and rustls to libs/mcp/server/Cargo.toml [dev-dependencies].

Testing

  • All tests pass locally (cargo test -p stakpak-mcp-server --test mcp_server_integration) — 12 passed.
  • Added tests for new functionality.
  • Tested on Windows/Linux/macOS compatible code path (127.0.0.1:0 dynamic port allocation).
  • cargo clippy -p stakpak-mcp-server --all-targets passed cleanly.
  • cargo fmt --check passed cleanly.

Breaking Changes

None

- Add integration test suite covering local, remote, and combined tool modes
- Test mTLS authentication success, missing client cert, and wrong CA rejection
- Test end-to-end local tool execution (view tool)
- Test graceful shutdown and server behavior without API key

Closes stakpak#248
Copilot AI lite review requested due to automatic review settings August 22, 2026 09:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds 12 integration tests for stakpak-mcp-server, covering tool modes, mTLS, execution, lifecycle, and API-key scenarios.

Changes:

  • Added server integration tests for local, remote, and combined modes.
  • Added mTLS, tool execution, shutdown, and authentication coverage.
  • Added required test-only dependencies.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.

File Description Final review comments
libs/mcp/server/tests/mcp_server_integration.rs Integration tests for server modes and lifecycle behavior 5 moderate findings: strengthen RemoteOnly assertions using LOCAL_TOOL_NAMES (2 votes); assert actual TLS/MCP handshake failure in both mTLS rejection tests (3 votes); ensure the wrong client trusts the server CA (3 votes); assert cleanup timeout, join, and inner results (3 votes); inject a mock provider and test the missing-client path (2 votes).
libs/mcp/server/Cargo.toml Test dependency configuration No final comments.
Suppressed comments (3)

libs/mcp/server/tests/mcp_server_integration.rs:517

  • As in the no-client-certificate test, this raw GET /mcp only proves that the HTTP request was not successful, not that the TLS handshake rejected the client certificate. If the server accepts the wrong certificate but rejects the non-MCP GET at the application layer, this assertion still passes. Exercise MCP initialization and assert the transport error instead.
    let result = timeout(
        Duration::from_secs(5),
        wrong_client
            .get(format!("https://127.0.0.1:{}/mcp", server.port))
            .send(),

libs/mcp/server/tests/mcp_server_integration.rs:560

  • result.is_ok() checks only that the timeout completed; it is also true when the server task panics or returns Err. This can report a failed server as a successful graceful shutdown. Unwrap the timeout and join result, then assert the inner anyhow::Result.
    let result = timeout(Duration::from_secs(10), server.server_handle).await;
    assert!(result.is_ok(), "server should shut down within the timeout");

libs/mcp/server/tests/mcp_server_integration.rs:567

  • rebind_result.is_ok() only checks that the outer timeout did not elapse. Ok(Err(bind_error)) is also considered a pass, so an occupied port or any other bind failure can satisfy this assertion. Check the inner bind result before claiming that shutdown released the port.
    let rebind_result = timeout(
        Duration::from_secs(2),
        TcpListener::bind(format!("127.0.0.1:{port}")),
    )
    .await;

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +290 to +298
// Local-only tools (like run_command) should NOT be present
assert!(
!tool_names.contains(&"run_command".to_string()),
"RemoteOnly mode should NOT include local tool 'run_command', got: {tool_names:?}"
);
assert!(
!tool_names.contains(&"view".to_string()),
"RemoteOnly mode should NOT include local tool 'view', got: {tool_names:?}"
);
Comment on lines +464 to +468
let result = timeout(
Duration::from_secs(5),
plain_client
.get(format!("https://127.0.0.1:{}/mcp", server.port))
.send(),
Comment on lines +497 to +499
let wrong_client_tls = wrong_chain
.create_client_config()
.expect("should create wrong client TLS config");
async fn shutdown(self) {
let _ = self.shutdown_tx.send(());
// Give the server a moment to exit gracefully.
let _ = timeout(Duration::from_secs(5), self.server_handle).await;
Comment on lines +80 to +83
client: None,
bind_address: format!("127.0.0.1:{port}"),
enabled_tools: EnabledToolsConfig::default(),
tool_mode: opts.tool_mode,
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Integration Tests for MCP Server Mode

2 participants