#![allow(clippy::expect_used, clippy::panic, clippy::print_stdout)]
use std::path::PathBuf;
use std::process::Command;
const CASES: [(&str, &str); 8] = [
("primitive-mixed", "plain-cdr2"),
("primitive-mixed", "plain-cdr1"),
("primitive-mixed-descending-alignment", "plain-cdr1"),
("sequence-primitives-nonempty", "plain-cdr2"),
("bitmask-bitbound-32", "plain-cdr2"),
("array-1d-enum", "plain-cdr2"),
("union-discriminator-boolean", "plain-cdr2"),
("primitive-longdouble", "plain-cdr2"),
];
fn repository_root() -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("..")
.join("..")
}
fn java_is_here() -> bool {
for tool in ["javac", "java"] {
match Command::new(tool).arg("-version").output() {
Ok(output) if output.status.success() => {}
Ok(_) | Err(_) => {
println!("SKIPPED: `{tool}` did not answer; the Java column is unmeasured here");
return false;
}
}
}
true
}
#[test]
fn the_java_column_writes_what_the_rust_column_recorded() {
if !java_is_here() {
return;
}
let root = repository_root();
let probe = root.join("tools/wireprobe/wireprobe-zerodds-java");
let mut checked = 0;
let mut failures = Vec::new();
for (case, encoding) in CASES {
let directory = root.join("tests/interop-corpus").join(case);
let recorded = root
.join("tests/interop-results")
.join(case)
.join("zerodds-rust")
.join(format!("{encoding}.le.bin"));
let expected = match std::fs::read(&recorded) {
Ok(bytes) => bytes,
Err(error) => {
failures.push(format!("{case} {encoding}: no recorded octets ({error})"));
continue;
}
};
let type_name = std::fs::read_to_string(directory.join("type"))
.expect("the corpus case names its root")
.trim()
.to_string();
let run = Command::new(&probe)
.current_dir(&root)
.args(["--idl", &directory.join("type.idl").to_string_lossy()])
.args(["--type", &type_name])
.args(["--values", &directory.join("values.json").to_string_lossy()])
.args(["--encoding", encoding, "--endian", "le"])
.output();
let output = match run {
Ok(output) => output,
Err(error) => {
failures.push(format!(
"{case} {encoding}: the probe did not start ({error})"
));
continue;
}
};
if !output.status.success() {
failures.push(format!(
"{case} {encoding}: {}",
String::from_utf8_lossy(&output.stderr)
.lines()
.next()
.unwrap_or("refused")
));
continue;
}
let produced = String::from_utf8_lossy(&output.stdout).trim().to_string();
let want: String = expected.iter().map(|byte| format!("{byte:02x}")).collect();
if produced != want {
failures.push(format!(
"{case} {encoding}:\n java {produced}\n rust {want}"
));
continue;
}
checked += 1;
}
assert!(
failures.is_empty(),
"the Java column disagrees with the recorded octets:\n {}",
failures.join("\n ")
);
assert_eq!(
checked,
CASES.len(),
"every case has to be measured, not skipped into a pass"
);
}