124 lines
3.7 KiB
Rust
124 lines
3.7 KiB
Rust
|
|
// Copyright 2026 The Fuchsia Authors
|
||
|
|
//
|
||
|
|
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
|
||
|
|
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
|
||
|
|
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
|
||
|
|
// This file may not be copied, modified, or distributed except according to
|
||
|
|
// those terms.
|
||
|
|
|
||
|
|
#![cfg(__ZEROCOPY_INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS)]
|
||
|
|
|
||
|
|
use std::{panic, path::PathBuf, process::Command, thread};
|
||
|
|
|
||
|
|
enum Directive {
|
||
|
|
Asm,
|
||
|
|
Mca,
|
||
|
|
}
|
||
|
|
|
||
|
|
impl Directive {
|
||
|
|
fn arg(&self) -> &'static str {
|
||
|
|
match self {
|
||
|
|
Directive::Asm => "--asm",
|
||
|
|
Directive::Mca => "--mca",
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
fn ext(&self) -> &'static str {
|
||
|
|
match self {
|
||
|
|
Directive::Asm => "",
|
||
|
|
Directive::Mca => ".mca",
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
fn run_codegen_test(bench_name: &str, target_cpu: &str, bless: bool) {
|
||
|
|
println!("Testing {bench_name}.{target_cpu}");
|
||
|
|
|
||
|
|
let manifest_path = env!("CARGO_MANIFEST_PATH");
|
||
|
|
let target_dir = env!("CARGO_TARGET_DIR");
|
||
|
|
|
||
|
|
let cargo_asm = |directive: &Directive| {
|
||
|
|
Command::new("./cargo.sh")
|
||
|
|
.args([
|
||
|
|
"+nightly",
|
||
|
|
"asm",
|
||
|
|
"--quiet",
|
||
|
|
"-p",
|
||
|
|
"zerocopy",
|
||
|
|
"--manifest-path",
|
||
|
|
manifest_path,
|
||
|
|
"--target-dir",
|
||
|
|
target_dir,
|
||
|
|
"--bench",
|
||
|
|
bench_name,
|
||
|
|
"--target-cpu",
|
||
|
|
target_cpu,
|
||
|
|
"--simplify",
|
||
|
|
directive.arg(),
|
||
|
|
&format!("bench_{bench_name}"),
|
||
|
|
])
|
||
|
|
.output()
|
||
|
|
.expect("failed to execute process")
|
||
|
|
};
|
||
|
|
|
||
|
|
let test_directive = |directive: Directive| {
|
||
|
|
let output = cargo_asm(&directive);
|
||
|
|
let actual_result = output.stdout;
|
||
|
|
|
||
|
|
if !(output.status.success()) {
|
||
|
|
panic!(
|
||
|
|
"{}\n{}",
|
||
|
|
String::from_utf8_lossy(&actual_result),
|
||
|
|
String::from_utf8_lossy(&output.stderr)
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
let expected_file_path = {
|
||
|
|
let ext = directive.ext();
|
||
|
|
let mut path: PathBuf = env!("CARGO_MANIFEST_DIR").into();
|
||
|
|
path.push("benches");
|
||
|
|
let file_name = format!("{bench_name}.{target_cpu}{ext}",);
|
||
|
|
path.push(file_name);
|
||
|
|
path
|
||
|
|
};
|
||
|
|
|
||
|
|
if bless {
|
||
|
|
std::fs::write(expected_file_path, &actual_result).unwrap();
|
||
|
|
} else {
|
||
|
|
let expected_result = std::fs::read(expected_file_path).unwrap_or_default();
|
||
|
|
if actual_result != expected_result {
|
||
|
|
let expected = String::from_utf8_lossy(&expected_result[..]);
|
||
|
|
panic!("Bless codegen tests with BLESS=1\nGot unexpected output:\n{}", expected);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
test_directive(Directive::Asm);
|
||
|
|
test_directive(Directive::Mca);
|
||
|
|
}
|
||
|
|
|
||
|
|
#[test]
|
||
|
|
#[cfg_attr(miri, ignore)]
|
||
|
|
fn codegen() {
|
||
|
|
let bless = std::env::var("BLESS").is_ok();
|
||
|
|
let handles: Vec<_> = std::fs::read_dir("benches")
|
||
|
|
.unwrap()
|
||
|
|
.map(|entry| entry.unwrap().path())
|
||
|
|
.filter(|path| path.extension().is_some_and(|ext| ext == "rs"))
|
||
|
|
.map(|path| {
|
||
|
|
let bench_name = path.file_stem().unwrap().to_str().unwrap().to_owned();
|
||
|
|
thread::spawn(move || {
|
||
|
|
panic::catch_unwind(panic::AssertUnwindSafe(|| {
|
||
|
|
run_codegen_test(&bench_name, "x86-64", bless);
|
||
|
|
}))
|
||
|
|
})
|
||
|
|
})
|
||
|
|
.collect();
|
||
|
|
|
||
|
|
let failed = handles.into_iter().any(|handle| handle.join().unwrap().is_err());
|
||
|
|
|
||
|
|
if failed {
|
||
|
|
panic!("One or more codegen tests failed. See thread panics above for details.");
|
||
|
|
}
|
||
|
|
}
|