use rto_exec::{
AnalysisRequest, AnalyzerRunner, Consent, IngestRunner, NativeContext, NoSnippets,
SnippetSource, Worktree, WorktreeSnippets, normalize_native,
};
use rto_graph::{Finding, Isolation, NetworkPolicy, RunnerKind, SourceIdentity};
mod fixture;
fn both_paths(
analyzer: &str,
native: &[u8],
source: &SourceIdentity,
snippets: &dyn SnippetSource,
) -> (Vec<Finding>, Vec<Finding>) {
let ctx = NativeContext {
started_at: "2026-08-15T09:00:00Z".to_owned(),
ended_at: "2026-08-15T09:00:09Z".to_owned(),
analyzer_version: Some("1.136.0".to_owned()),
exit_status: 1,
source,
rules_digest: Some("deadbeef".to_owned()),
advisory_db: None,
worktree: None,
snippets,
};
let report = normalize_native(analyzer, native, &ctx).expect("the adapter must normalise");
let wire = serde_json::to_vec(&report).expect("serialize the interchange format");
let request = AnalysisRequest {
analyzer: analyzer.to_owned(),
worktree: Worktree::read_only(fixture::polyglot_root().as_path()).expect("worktree"),
network: NetworkPolicy::Deny,
consent: Consent::Granted,
source: source.clone(),
};
let ingested = IngestRunner::new(wire).run(&request).expect("ingest");
let direct = normalize_native(analyzer, native, &ctx).expect("normalise again");
let direct_wire = serde_json::to_vec(&direct).expect("serialize");
let executed = IngestRunner::new(direct_wire)
.run(&request)
.expect("ingest");
(ingested.findings, executed.findings)
}
#[test]
fn semgrep_ingest_and_execution_produce_identical_findings() {
let native = fixture::semgrep_native();
let snippets = WorktreeSnippets::new(fixture::polyglot_root());
let (a, b) = both_paths("semgrep", &native, &SourceIdentity::default(), &snippets);
assert!(!a.is_empty(), "the fixture must produce findings");
assert_eq!(a, b, "the two paths must produce identical findings");
}
#[test]
fn cargo_audit_ingest_and_execution_produce_identical_findings() {
let native = fixture::cargo_audit_native();
let source = SourceIdentity {
lockfile_blob: Some("2b7f0c1d9e".to_owned()),
..SourceIdentity::default()
};
let (a, b) = both_paths("cargo-audit", &native, &source, &NoSnippets);
assert!(!a.is_empty(), "the fixture must produce findings");
assert_eq!(a, b);
}
#[test]
fn the_two_paths_agree_on_findings_and_disagree_on_isolation() {
let native = fixture::semgrep_native();
let snippets = WorktreeSnippets::new(fixture::polyglot_root());
let ctx = NativeContext {
started_at: "2026-08-15T09:00:00Z".to_owned(),
ended_at: "2026-08-15T09:00:09Z".to_owned(),
analyzer_version: Some("1.136.0".to_owned()),
exit_status: 1,
source: &SourceIdentity::default(),
rules_digest: Some("deadbeef".to_owned()),
advisory_db: None,
worktree: None,
snippets: &snippets,
};
let report = normalize_native("semgrep", &native, &ctx).expect("normalise");
let wire = serde_json::to_vec(&report).expect("serialize");
let request = AnalysisRequest {
analyzer: "semgrep".to_owned(),
worktree: Worktree::read_only(fixture::polyglot_root().as_path()).expect("worktree"),
network: NetworkPolicy::Deny,
consent: Consent::Granted,
source: SourceIdentity::default(),
};
let ingested = IngestRunner::new(wire).run(&request).expect("ingest");
assert_eq!(ingested.run.runner, RunnerKind::Ingested);
assert_eq!(ingested.run.isolation, Isolation::Ingested);
}
#[test]
fn the_report_digest_is_a_function_of_the_bytes_alone() {
let native = fixture::semgrep_native();
let request = AnalysisRequest {
analyzer: "semgrep".to_owned(),
worktree: Worktree::read_only(fixture::polyglot_root().as_path()).expect("worktree"),
network: NetworkPolicy::Deny,
consent: Consent::Granted,
source: SourceIdentity::default(),
};
let snippets = WorktreeSnippets::new(fixture::polyglot_root());
let ctx = NativeContext {
started_at: "2026-08-15T09:00:00Z".to_owned(),
ended_at: "2026-08-15T09:00:09Z".to_owned(),
analyzer_version: Some("1.136.0".to_owned()),
exit_status: 1,
source: &SourceIdentity::default(),
rules_digest: None,
advisory_db: None,
worktree: None,
snippets: &snippets,
};
let wire = serde_json::to_vec(&normalize_native("semgrep", &native, &ctx).expect("normalise"))
.expect("serialize");
let first = IngestRunner::new(wire.clone()).run(&request).expect("a");
let second = IngestRunner::new(wire).run(&request).expect("b");
assert_eq!(first.run.report_digest, second.run.report_digest);
assert_eq!(first.run.report_digest.len(), 64);
}
#[test]
fn finding_keys_do_not_depend_on_where_the_analyzer_ran() {
let native = fixture::semgrep_native();
let snippets = WorktreeSnippets::new(fixture::polyglot_root());
let (a, b) = both_paths("semgrep", &native, &SourceIdentity::default(), &snippets);
let keys_a: Vec<String> = a.iter().map(|f| f.key.render()).collect();
let keys_b: Vec<String> = b.iter().map(|f| f.key.render()).collect();
assert_eq!(keys_a, keys_b);
for key in &keys_a {
assert!(
!key.contains("/Users/") && !key.contains("/home/") && !key.contains(".roteiro"),
"a finding key must not embed a local path: {key}"
);
}
}