From 568ae43832cd432eed3f7f5c97e41f8c91075ff9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 14 Sep 2026 05:52:24 +0000 Subject: [PATCH] test: add CLI coverage for ado-aw trace --step flag Adds two end-to-end assertions to audit_pipeline_artifact_layouts_are_equivalent_end_to_end covering the previously-untested --step flag on the trace CLI subcommand: - trace --step succeeds, returns a populated step/location/ upstream/downstream JSON section, and does not warn. - trace --step still exits 0, prints the "requested step was not found in the local IR graph" warning on stderr, and omits the step section from JSON. Previously src/inspect/trace.rs only had unit-level coverage for the step-filtering path (build_trace_report(..., Some(step))); no test exercised the full CLI (dispatch_trace -> build_trace -> trace::render/JSON) with --step set. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- tests/audit_it.rs | 81 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/tests/audit_it.rs b/tests/audit_it.rs index e6412cef8..4f7620d4d 100644 --- a/tests/audit_it.rs +++ b/tests/audit_it.rs @@ -892,6 +892,87 @@ async fn audit_pipeline_artifact_layouts_are_equivalent_end_to_end() { let trace: Value = serde_json::from_slice(&trace.stdout).expect("trace JSON"); assert_eq!(trace["build_id"], 630125); + let step_trace_cache = TempDir::new().expect("create step trace cache"); + let step_trace = Command::new(binary()) + .current_dir(workspace.path()) + .env("CI", "1") + .env("TMPDIR", step_trace_cache.path()) + .env("ADO_AW_TEST_ORG_URL", flat_server.uri()) + .args([ + "trace", + "630125", + "--step", + "threatAnalysis", + "--json", + "--org", + "test-org", + "--project", + "test-project", + "--pat", + "test-pat", + ]) + .output() + .await + .expect("run trace --step"); + assert!( + step_trace.status.success(), + "trace --step should succeed: stdout={} stderr={}", + String::from_utf8_lossy(&step_trace.stdout), + String::from_utf8_lossy(&step_trace.stderr) + ); + assert!( + !String::from_utf8_lossy(&step_trace.stderr) + .contains("requested step was not found in the local IR graph"), + "trace --step for a step present in the local IR graph should not warn: stderr={}", + String::from_utf8_lossy(&step_trace.stderr) + ); + let step_trace: Value = + serde_json::from_slice(&step_trace.stdout).expect("trace --step JSON"); + assert_eq!(step_trace["build_id"], 630125); + assert_eq!(step_trace["step"]["step"], "threatAnalysis"); + assert_eq!(step_trace["step"]["location"]["job"], "Detection"); + + let missing_step_cache = TempDir::new().expect("create missing-step trace cache"); + let missing_step_trace = Command::new(binary()) + .current_dir(workspace.path()) + .env("CI", "1") + .env("TMPDIR", missing_step_cache.path()) + .env("ADO_AW_TEST_ORG_URL", flat_server.uri()) + .args([ + "trace", + "630125", + "--step", + "does-not-exist", + "--json", + "--org", + "test-org", + "--project", + "test-project", + "--pat", + "test-pat", + ]) + .output() + .await + .expect("run trace --step for a missing step"); + assert!( + missing_step_trace.status.success(), + "trace --step for an unknown step id should still exit 0: stdout={} stderr={}", + String::from_utf8_lossy(&missing_step_trace.stdout), + String::from_utf8_lossy(&missing_step_trace.stderr) + ); + assert!( + String::from_utf8_lossy(&missing_step_trace.stderr) + .contains("requested step was not found in the local IR graph"), + "trace --step for an unknown step id should warn on stderr: stderr={}", + String::from_utf8_lossy(&missing_step_trace.stderr) + ); + let missing_step_trace: Value = serde_json::from_slice(&missing_step_trace.stdout) + .expect("trace --step (missing) JSON"); + assert!( + missing_step_trace["step"].is_null(), + "trace --step for an unknown step id should omit the step section: {missing_step_trace}" + ); + let mcp_cache = TempDir::new().expect("create MCP cache"); let responses = run_mcp_author(workspace.path(), mcp_cache.path(), &flat_server).await; let audit_build = responses