fix: enumerate conformance client scenarios (#1008)
fixes #1001. Restores explicit dispatch arms for the ten client scenarios orphaned by #991: standard auth flow: - `auth/iss-*` - `auth/offline-access-*` - `auth/metadata-issuer-mismatch` - `auth/authorization-server-migration` plain connect/list client: `json-schema-ref-no-deref` `run_auth_client` now negotiates via `ClientLifecycleMode::Discover` — `auth/authorization-server-migration` tracked in #879
This commit is contained in:
parent
8efc142e51
commit
61b40afdca
1 changed files with 52 additions and 6 deletions
|
|
@ -286,7 +286,17 @@ async fn run_auth_client(server_url: &str, ctx: &ConformanceContext) -> anyhow::
|
|||
StreamableHttpClientTransportConfig::with_uri(server_url),
|
||||
);
|
||||
|
||||
let client = BasicClientHandler.serve(transport).await?;
|
||||
// The 2026-07-28 auth mocks require the modern per-request lifecycle
|
||||
// (MCP-Protocol-Version header on every request), so negotiate via the
|
||||
// discover lifecycle rather than the legacy initialize handshake.
|
||||
let client = BasicClientHandler
|
||||
.serve_with_lifecycle(
|
||||
transport,
|
||||
ClientLifecycleMode::Discover {
|
||||
preferred_versions: preferred_protocol_versions(),
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
tracing::debug!("Connected (authenticated)");
|
||||
|
||||
let tools = client.list_tools(Default::default()).await?;
|
||||
|
|
@ -899,15 +909,22 @@ fn conformance_protocol_version() -> ProtocolVersion {
|
|||
.unwrap_or(ProtocolVersion::V_2026_07_28)
|
||||
}
|
||||
|
||||
/// Runs draft stateless scenarios through the public discover lifecycle and
|
||||
/// Streamable HTTP transport.
|
||||
async fn run_discover_client(server_url: &str) -> anyhow::Result<()> {
|
||||
/// Preferred protocol versions for discover-lifecycle negotiation: the
|
||||
/// runner-provided version first, then all other known versions newest-first.
|
||||
fn preferred_protocol_versions() -> Vec<ProtocolVersion> {
|
||||
let mut preferred_versions = vec![conformance_protocol_version()];
|
||||
for version in ProtocolVersion::KNOWN_VERSIONS.iter().rev() {
|
||||
if !preferred_versions.contains(version) {
|
||||
preferred_versions.push(version.clone());
|
||||
}
|
||||
}
|
||||
preferred_versions
|
||||
}
|
||||
|
||||
/// Runs draft stateless scenarios through the public discover lifecycle and
|
||||
/// Streamable HTTP transport.
|
||||
async fn run_discover_client(server_url: &str) -> anyhow::Result<()> {
|
||||
let preferred_versions = preferred_protocol_versions();
|
||||
let transport = StreamableHttpClientTransport::from_uri(server_url);
|
||||
let client = FullClientHandler
|
||||
.serve_with_lifecycle(
|
||||
|
|
@ -968,7 +985,12 @@ async fn main() -> anyhow::Result<()> {
|
|||
match scenario.as_str() {
|
||||
// Non-auth scenarios
|
||||
"initialize" => run_basic_client(&server_url).await?,
|
||||
"json-schema-ref-no-deref" => run_discover_client(&server_url).await?,
|
||||
// SEP-2106: the scenario serves a tool whose schema carries a network
|
||||
// `$ref`; the check passes when the client lists tools without
|
||||
// dereferencing (fetching) that URL. A plain connect → list_tools →
|
||||
// close is sufficient; the scenario's mock server does not implement
|
||||
// the discover lifecycle, so `run_discover_client` hangs against it.
|
||||
"json-schema-ref-no-deref" => run_basic_client(&server_url).await?,
|
||||
"tools_call" => run_tools_call_client(&server_url, &ctx).await?,
|
||||
"elicitation-sep1034-client-defaults" => {
|
||||
run_elicitation_defaults_client(&server_url).await?
|
||||
|
|
@ -994,7 +1016,31 @@ async fn main() -> anyhow::Result<()> {
|
|||
| "auth/token-endpoint-auth-post"
|
||||
| "auth/token-endpoint-auth-none"
|
||||
| "auth/2025-03-26-oauth-metadata-backcompat"
|
||||
| "auth/2025-03-26-oauth-endpoint-fallback" => run_auth_client(&server_url, &ctx).await?,
|
||||
| "auth/2025-03-26-oauth-endpoint-fallback"
|
||||
// Offline access scope handling: positive/negative variants both run
|
||||
// the well-behaved flow; the referee inspects the requested scopes.
|
||||
| "auth/offline-access-scope"
|
||||
| "auth/offline-access-not-supported"
|
||||
// SEP-2468 (RFC 9207 iss / RFC 8414 §3.3 issuer-echo). The client
|
||||
// captures `iss` from the authorization redirect and passes it to the
|
||||
// callback handler; the SDK validates internally. Positive scenarios
|
||||
// proceed to the token endpoint; negative scenarios error out (the
|
||||
// referee sets `allowClientError`).
|
||||
| "auth/iss-supported"
|
||||
| "auth/iss-not-advertised"
|
||||
| "auth/iss-supported-missing"
|
||||
| "auth/iss-wrong-issuer"
|
||||
| "auth/iss-unexpected"
|
||||
| "auth/iss-normalized"
|
||||
| "auth/metadata-issuer-mismatch"
|
||||
| "auth/metadata-issuer-mismatch"
|
||||
// SEP-2352: PRM `authorization_servers` switches between calls; a
|
||||
// compliant client re-registers at the new AS. Known partial failure:
|
||||
// the SDK lacks issuer-stamped credential storage (#879), so the
|
||||
// `sep-2352-reregister-on-as-change` check fails. Left on the standard
|
||||
// flow rather than fixture-orchestrated re-registration so the
|
||||
// conformance result reflects real SDK behavior.
|
||||
| "auth/authorization-server-migration" => run_auth_client(&server_url, &ctx).await?,
|
||||
|
||||
// Auth - scope step-up
|
||||
"auth/scope-step-up" => run_auth_scope_step_up_client(&server_url, &ctx).await?,
|
||||
|
|
|
|||
Loading…
Reference in a new issue