fn parse_cli_owned(args: Vec<String>) -> Result<Cli, clap::error::Error> {
std::thread::Builder::new()
.stack_size(16 * 1024 * 1024)
.spawn(move || Cli::try_parse_from(args))
.expect("spawn thread")
.join()
.expect("join thread")
}
fn mcp_serve_argv(model: &str, port: u16) -> Vec<String> {
let mut argv = vec!["apr".to_string()];
argv.extend(aprender_mcp::tools::serve::serve_argv(model, port));
argv
}
#[test]
fn falsify_2606_mcp_serve_argv_is_accepted_by_the_cli_parser() {
let model = "/models/qwen2.5-coder-1.5b-instruct-q4_k_m.apr";
let argv = mcp_serve_argv(model, 38621);
let parsed = parse_cli_owned(argv.clone()).unwrap_or_else(|e| {
panic!(
"#2606: the MCP apr.serve tool spawns an argv the CLI REJECTS.\n\
argv: {argv:?}\n\
clap said: {e}\n\
This is the rc=2 the 0.63.0 sweep measured; the tool reported \
{{pid, url}} anyway."
)
});
match *parsed.command {
Commands::Serve {
command: ServeCommands::Run { ref file, port, .. },
} => {
assert_eq!(
file.to_string_lossy(),
model,
"model path must land in the FILE slot, not the subcommand slot"
);
assert_eq!(port, 38621, "--port must reach the server launcher");
}
ref other => panic!(
"#2606: argv parsed, but not into `serve run` — it would never start \
a server. argv: {argv:?}, parsed: {other:?}"
),
}
}
#[test]
fn falsify_2606_the_0_63_0_argv_is_still_rejected_by_clap() {
let model = "/models/qwen2.5-coder-1.5b-instruct-q4_k_m.apr";
let broken = vec![
"apr".to_string(),
"serve".to_string(),
model.to_string(),
"--port".to_string(),
"38621".to_string(),
];
let err = parse_cli_owned(broken.clone())
.err()
.unwrap_or_else(|| panic!("0.63.0's argv {broken:?} unexpectedly parses now"));
let rendered = err.to_string();
assert!(
rendered.contains("subcommand") || rendered.contains("Usage"),
"expected the measured clap rejection, got: {rendered}"
);
}
#[test]
fn falsify_2606_serve_argv_round_trips_port_across_the_range() {
for probe in [1_u16, 80, 8080, 38641, 65535] {
let argv = mcp_serve_argv("/models/m.gguf", probe);
let parsed = parse_cli_owned(argv.clone())
.unwrap_or_else(|e| panic!("argv {argv:?} rejected: {e}"));
match *parsed.command {
Commands::Serve {
command: ServeCommands::Run { port, .. },
} => assert_eq!(port, probe, "port {probe} must round-trip"),
ref other => panic!("argv {argv:?} parsed as {other:?}, not `serve run`"),
}
}
}