use serde_json::Value; use std::fs; use std::process::Command; use tempfile::TempDir; fn fixture_root() -> std::path::PathBuf { std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures/p4c") } #[test] fn build_imports_a_qualified_p4c_envelope() { let directory = TempDir::new().unwrap(); let graph = directory.path().join("graph.json"); let html = directory.path().join("graph.html"); let report = fixture_root().join("reports/p4c-1.2.5.16-duplicate-state.json"); let output = Command::new(env!("CARGO_BIN_EXE_brick")) .args([ "build", fixture_root().to_str().unwrap(), "--p4c-report", report.to_str().unwrap(), "--json", graph.to_str().unwrap(), "--html", html.to_str().unwrap(), ]) .output() .unwrap(); assert!( output.status.success(), "{}", String::from_utf8_lossy(&output.stderr) ); assert!(String::from_utf8_lossy(&output.stdout).contains("1 p4c diagnostics")); let model: Value = serde_json::from_slice(&fs::read(graph).unwrap()).unwrap(); assert_eq!(model.get("schema_version"), Some(&Value::from(4))); assert_eq!( model.pointer("/metrics/p4/parser_state_count"), Some(&Value::from(2)) ); let findings = model .get("nodes") .and_then(Value::as_array) .unwrap() .iter() .filter(|node| node.get("kind").and_then(Value::as_str) == Some("finding")) .collect::>(); assert_eq!(findings.len(), 1); assert_eq!( findings[0].pointer("/attributes/tool.version"), Some(&Value::String("1.2.5.16".into())) ); } #[test] fn build_rejects_a_malformed_p4c_envelope() { let directory = TempDir::new().unwrap(); let report = directory.path().join("malformed.json"); fs::write(&report, b"{not-json").unwrap(); let output = Command::new(env!("CARGO_BIN_EXE_brick")) .args([ "build", fixture_root().to_str().unwrap(), "--p4c-report", report.to_str().unwrap(), "--json", directory.path().join("graph.json").to_str().unwrap(), "--html", directory.path().join("graph.html").to_str().unwrap(), ]) .output() .unwrap(); assert!(!output.status.success()); assert!(String::from_utf8_lossy(&output.stderr).contains("invalid P4 evidence report")); }