weirflow 0.1.0

GPU-first dataflow analysis primitives for Vyre and Santh compiler pipelines.
Documentation
//! Integration test that compiles every Weir example.
//!
//! Each example is built with `cargo build --example <name>`. A separate
//! target directory is used to avoid deadlocking with the outer `cargo test`
//! invocation. Every build is capped at 120 seconds.

use std::process::{Command, Stdio};
use std::sync::mpsc;
use std::thread;
use std::time::Duration;

const TIMEOUT_SECS: u64 = 120;

fn cargo_example(name: &str, features: &[&str]) -> (Command, String) {
    let manifest_dir = env!("CARGO_MANIFEST_DIR");
    let target_dir = format!("{manifest_dir}/target/examples_build_test");

    let mut cmd = Command::new("cargo");
    cmd.arg("build")
        .arg("--example")
        .arg(name)
        .arg("-p")
        .arg("weir")
        .env("CARGO_TARGET_DIR", &target_dir)
        .current_dir(manifest_dir)
        .stdout(Stdio::piped())
        .stderr(Stdio::piped());

    for f in features {
        cmd.arg("--features").arg(f);
    }

    (cmd, target_dir)
}

fn run_example(name: &str, features: &[&str]) {
    let (mut cmd, _target_dir) = cargo_example(name, features);

    let child = cmd.spawn().expect("cargo should spawn");
    let pid = child.id();

    let (tx, rx) = mpsc::channel();
    thread::spawn(move || {
        let result = child.wait_with_output();
        let _ = tx.send(result);
    });

    let output = match rx.recv_timeout(Duration::from_secs(TIMEOUT_SECS)) {
        Ok(Ok(output)) => output,
        Ok(Err(e)) => panic!("cargo build --example {name} failed to execute: {e}"),
        Err(_) => {
            let _ = Command::new("kill").args(["-9", &pid.to_string()]).status();
            panic!("cargo build --example {name} timed out after {TIMEOUT_SECS}s");
        }
    };

    assert!(
        output.status.success(),
        "example {name} build failed:\nstdout: {}\nstderr: {}",
        String::from_utf8_lossy(&output.stdout),
        String::from_utf8_lossy(&output.stderr)
    );
}

#[test]
fn example_ifds_to_witness_builds_and_runs() {
    run_example("ifds_to_witness", &[]);
}

#[test]
fn example_serde_evidence_builds_and_runs() {
    run_example("serde_evidence", &["serde"]);
}

#[test]
fn example_witness_many_builds_and_runs() {
    run_example("witness_many", &[]);
}