pipecircuit-cli 0.0.2

Command-line architectural tools for Pipecircuit programs
use std::process::Command;

#[test]
fn native_installation_routes_additions_and_a_final_snapshot() -> std::io::Result<()> {
    let output = Command::new(env!("CARGO_BIN_EXE___PROJECT__"))
        .args(["3", "4"])
        .output()?;
    assert!(output.status.success(), "{:?}", output);
    assert_eq!(
        output.stdout,
        b"count: 3 (was 0)\ncount: 7 (was 3)\nsnapshot: 7\n"
    );
    assert!(output.stderr.is_empty());
    Ok(())
}

#[test]
fn overflow_is_a_reply_and_does_not_corrupt_the_next_read() -> std::io::Result<()> {
    let output = Command::new(env!("CARGO_BIN_EXE___PROJECT__"))
        .args(["18446744073709551615", "1"])
        .output()?;
    assert!(output.status.success(), "{:?}", output);
    assert_eq!(output.stdout, b"count: 18446744073709551615 (was 0)\noverflow: 18446744073709551615 + 1; count unchanged\nsnapshot: 18446744073709551615\n");
    Ok(())
}

#[test]
fn empty_input_reads_zero_and_invalid_input_is_refused_before_work() -> std::io::Result<()> {
    let empty = Command::new(env!("CARGO_BIN_EXE___PROJECT__")).output()?;
    assert!(empty.status.success());
    assert_eq!(empty.stdout, b"snapshot: 0\n");
    for invalid in ["0", "-1", "text", "18446744073709551616"] {
        let output = Command::new(env!("CARGO_BIN_EXE___PROJECT__"))
            .args(["3", invalid])
            .output()?;
        assert!(!output.status.success());
        assert!(output.stdout.is_empty());
        assert!(!output.stderr.is_empty());
    }
    Ok(())
}

#[test]
fn many_requests_reuse_capacity_and_exit_cleanly() -> std::io::Result<()> {
    let output = Command::new(env!("CARGO_BIN_EXE___PROJECT__"))
        .args(core::iter::repeat_n("1", 1000))
        .output()?;
    assert!(output.status.success(), "{:?}", output.stderr);
    assert!(output.stdout.ends_with(b"snapshot: 1000\n"));
    assert_eq!(
        output.stdout.iter().filter(|byte| **byte == b'\n').count(),
        1001
    );
    Ok(())
}

#[cfg(unix)]
#[test]
fn non_utf8_input_is_refused_without_starting_work() -> std::io::Result<()> {
    use std::os::unix::ffi::OsStringExt as _;
    let output = Command::new(env!("CARGO_BIN_EXE___PROJECT__"))
        .arg(std::ffi::OsString::from_vec(vec![0xff]))
        .output()?;
    assert!(!output.status.success());
    assert!(output.stdout.is_empty());
    assert!(String::from_utf8_lossy(&output.stderr).contains("Expected a UTF-8 integer"));
    Ok(())
}

#[cfg(target_os = "linux")]
#[test]
fn failed_output_closes_the_peer_and_joins_the_worker() -> std::io::Result<()> {
    let output = Command::new(env!("CARGO_BIN_EXE___PROJECT__"))
        .args(["3", "4"])
        .stdout(std::fs::OpenOptions::new().write(true).open("/dev/full")?)
        .output()?;
    assert!(!output.status.success());
    assert!(String::from_utf8_lossy(&output.stderr).contains("Output("));
    Ok(())
}