xlsynth_test_helpers/
lib.rs

1// SPDX-License-Identifier: Apache-2.0
2
3mod assert_valid_sv;
4mod simulate_sv;
5
6pub use assert_valid_sv::{assert_valid_sv, assert_valid_sv_flist, FlistEntry};
7pub use simulate_sv::{
8    simulate_pipeline_single_pulse, simulate_pipeline_single_pulse_custom, simulate_sv_flist,
9};
10
11use pretty_assertions::assert_eq;
12
13/// Compare arbitrary text against a golden file on disk, with an opt-in
14/// update mechanism controlled by the XLSYNTH_UPDATE_GOLDEN environment
15/// variable. Uses full-string equality (no trimming) for exactness.
16pub fn compare_golden_text(got: &str, relpath: &str) {
17    let golden_path = std::path::Path::new(relpath);
18    if std::env::var("XLSYNTH_UPDATE_GOLDEN").is_ok()
19        || !golden_path.exists()
20        || golden_path.metadata().map(|m| m.len()).unwrap_or(0) == 0
21    {
22        log::info!(
23            "compare_golden_text; writing golden file to {}",
24            golden_path.display()
25        );
26        std::fs::write(golden_path, got).expect("write golden");
27    } else {
28        log::info!(
29            "compare_golden_text; reading golden file from {}",
30            golden_path.display()
31        );
32        let want = std::fs::read_to_string(golden_path).expect("read golden");
33        assert_eq!(
34            got, want,
35            "Golden mismatch; run with XLSYNTH_UPDATE_GOLDEN=1 to update."
36        );
37    }
38}
39
40pub fn compare_golden_sv(got: &str, relpath: &str) {
41    let golden_path = std::path::Path::new(relpath);
42    if std::env::var("XLSYNTH_UPDATE_GOLDEN").is_ok()
43        || !golden_path.exists()
44        || golden_path.metadata().map(|m| m.len()).unwrap_or(0) == 0
45    {
46        log::info!(
47            "compare_golden_sv; writing golden file to {}",
48            golden_path.display()
49        );
50        std::fs::write(golden_path, got).expect("write golden");
51    } else {
52        log::info!(
53            "compare_golden_sv; reading golden file from {}",
54            golden_path.display()
55        );
56        let want = std::fs::read_to_string(golden_path).expect("read golden");
57        assert_eq!(
58            got.trim(),
59            want.trim(),
60            "Golden mismatch; run with XLSYNTH_UPDATE_GOLDEN=1 to update."
61        );
62    }
63
64    // Validate generated Verilog is syntactically correct after golden check.
65    assert_valid_sv(got);
66}
67
68/// Creates a unique temporary directory for tests under the system temp dir,
69/// using the provided base prefix combined with the process id and a nanosecond
70/// timestamp.
71///
72/// The directory is cleaned up automatically when the returned `TempDir` is
73/// dropped.
74pub fn make_test_tmpdir(base_prefix: &str) -> tempfile::TempDir {
75    let pid = std::process::id();
76    let nanos = std::time::SystemTime::now()
77        .duration_since(std::time::UNIX_EPOCH)
78        .unwrap()
79        .as_nanos();
80    let prefix = format!("{base_prefix}_{pid}_{nanos}");
81    tempfile::Builder::new()
82        .prefix(&prefix)
83        .tempdir_in(std::env::temp_dir())
84        .expect("tempdir create")
85}