Skip to content

narrow-feature cargo test invocations fail to compile due to under-gated test files #7

Description

@bug-ops

Description

crates/rmcp/tests/ has 81 *.rs files but only 39 are declared as [[test]] targets with required-features in crates/rmcp/Cargo.toml. The other 42 are auto-discovered by Cargo and always get compiled by cargo test -p rmcp regardless of which --features are passed, unless the file itself carries a complete internal #![cfg(feature = "...")] gate. This breaks the exact "filter by test name" workflow this repo's own .claude/CLAUDE.md documents as the way to run a feature-scoped test subset:

cargo test -p rmcp --features "<feat1>,<feat2>" test_name_substring

Two files are confirmed broken by live reproduction:

  • test_cancelled_response.rs — no internal cfg gate at all; references RoleServer, ServiceExt, service::RequestContext (server-feature-gated).
  • test_stdio_response_concurrency.rs — has #![cfg(not(feature = "local"))], but that gate is incomplete: it calls rmcp::transport::stdio(), gated behind transport-io, which the existing cfg doesn't cover.

A broader audit found 21 of the 42 undeclared files have no internal cfg gate at all, and the remaining 21 have a gate whose completeness hasn't been individually verified (only test_stdio_response_concurrency.rs's incompleteness is confirmed). Full inventory in the linked spec.

Reproduction Steps

  1. On main @ 02c62ae (v3.1.2, no drift as of this cycle):
    cargo test -p rmcp --features "server,client" test_mrtr_behavior
    
  2. Observe a compile error instead of the expected test run:
    error[E0425]: cannot find function `stdio` in module `rmcp::transport`
       --> crates/rmcp/tests/test_stdio_response_concurrency.rs:106:61
        |
    106 |     let server = LargeResponseServer.serve(rmcp::transport::stdio()).await?;
        |                                                             ^^^^^ not found in `rmcp::transport`
    note: found an item that was configured out
       --> crates/rmcp/src/transport.rs:94:13
     93 | #[cfg(feature = "transport-io")]
     94 | pub use io::stdio;
    error: could not compile `rmcp` (test "test_stdio_response_concurrency") due to 1 previous error
    
  3. A second run with --features request-state independently fails on both test_stdio_response_concurrency (same error) and test_cancelled_response (unresolved server-feature-gated symbols) — confirms the pattern, not a one-off.

Expected Behavior

cargo test -p rmcp --features "<any valid combo>" <test_name_substring> should either run the matching tests or report 0 matched — never fail to compile because of an unrelated test file outside the requested scope. Every file under crates/rmcp/tests/ should have either a [[test]]/required-features declaration in Cargo.toml (like the other 39 files) or a complete internal cfg gate covering every feature-gated API it references.

Actual Behavior

The documented "filter by test name" workflow fails to compile on an unrelated file whenever the passed --features set doesn't happen to satisfy every undeclared/under-gated test file's real requirements.

Environment

  • Version: v3.1.2, commit 02c62ae
  • Features: reproduced with server,client and separately with request-state

Upstream

No exact duplicate found. modelcontextprotocol/rust-sdk#1067 ("Rationalize feature flags for v3.0", open) covers feature-flag naming/design problems (a reqwest TLS trap, local's additivity violation, internal flags leaking to docs.rs) but does not mention the tests/ directory's undeclared-file/under-gated-cfg compile-break described here — different root cause, filed locally as a distinct issue.

Spec

.local/specs/003-test-feature-gate-compile-break/spec.md

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2High: degraded UX, incorrect non-destructive behaviorbugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions