pipecircuit 0.0.23

Correct. Robust. Fast. Portable. Pick four.
Documentation
extern crate std;

use self::std::{env, fs, process::Command};
use super::*;
use alloc::string::{String, ToString};

const ROWS: u32 = 262_144;
const CHILD_CASE: &str = "PIPECIRCUIT_ALLOCATION_REFUSAL_CASE";

fn prlimit(limit: &str) -> Result<(), String> {
    let output = Command::new("prlimit")
        .args([
            "--pid",
            &std::process::id().to_string(),
            &std::format!("--as={limit}:"),
        ])
        .output()
        .map_err(|error| error.to_string())?;
    if output.status.success() {
        Ok(())
    } else {
        Err(String::from_utf8_lossy(&output.stderr).into_owned())
    }
}

fn limited<Output>(additional: usize, run: impl FnOnce() -> Output) -> Result<Output, String> {
    let previous = Command::new("prlimit")
        .args([
            "--pid",
            &std::process::id().to_string(),
            "--as",
            "--output",
            "SOFT",
            "--noheadings",
        ])
        .output()
        .map_err(|error| error.to_string())?;
    if !previous.status.success() {
        return Err("cannot inspect child address-space limit".into());
    }
    let previous = String::from_utf8(previous.stdout).map_err(|error| error.to_string())?;
    let status = fs::read_to_string("/proc/self/status").map_err(|error| error.to_string())?;
    let kib = status
        .lines()
        .find_map(|line| line.strip_prefix("VmSize:"))
        .and_then(|value| value.split_whitespace().next())
        .ok_or("missing process virtual size")?
        .parse::<usize>()
        .map_err(|error| error.to_string())?;
    let limit = kib
        .checked_mul(1024)
        .and_then(|bytes| bytes.checked_add(additional))
        .and_then(|bytes| bytes.checked_add(262_144))
        .ok_or("limit overflow")?;
    prlimit(&limit.to_string())?;
    let result = run();
    prlimit(previous.trim())?;
    Ok(result)
}

#[test]
#[allow(
    clippy::result_large_err,
    reason = "allocation refusal must return the owned table without allocating a box"
)]
fn allocation_refusals_preserve_ownership_and_exact_storage_stage() -> Result<(), String> {
    let case = match env::var(CHILD_CASE) {
        Ok(case) => case,
        Err(env::VarError::NotPresent) => {
            let executable = env::current_exe().map_err(|error| error.to_string())?;
            let name = concat!(
                module_path!(),
                "::allocation_refusals_preserve_ownership_and_exact_storage_stage"
            )
            .strip_prefix("pipecircuit::")
            .ok_or("unexpected test crate")?;
            for case in [
                "incarnations",
                "history",
                "selection",
                "projected",
                "delivery",
            ] {
                let output = Command::new(&executable)
                    .args(["--exact", name, "--nocapture"])
                    .env(CHILD_CASE, case)
                    .env("MALLOC_ARENA_MAX", "1")
                    .env("MALLOC_MMAP_THRESHOLD_", "65536")
                    .env("MALLOC_TRIM_THRESHOLD_", "65536")
                    .output()
                    .map_err(|error| error.to_string())?;
                if !output.status.success() {
                    return Err(std::format!(
                        "{case}: {}\n{}\n{}",
                        output.status,
                        String::from_utf8_lossy(&output.stdout),
                        String::from_utf8_lossy(&output.stderr)
                    ));
                }
            }
            return Ok(());
        }
        Err(env::VarError::NotUnicode(_)) => return Err("invalid allocation case".into()),
    };
    let capacity = Capacity::new(NonZeroU32::new(ROWS).ok_or("zero rows")?);
    let rows = usize::try_from(ROWS).map_err(|error| error.to_string())?;
    let source_id = SourceId::new(NonZeroU64::MIN);
    let view_id = ViewId::new(NonZeroU64::MIN);
    match case.as_str() {
        "incarnations" | "history" | "selection" => {
            let table =
                WarpTable::<Actor>::try_new(capacity).map_err(|error| std::format!("{error:?}"))?;
            let prefix = match case.as_str() {
                "incarnations" => 0,
                "history" => size_of::<u64>(),
                "selection" => {
                    size_of::<u64>().saturating_add(size_of::<super::super::source::Change<u32>>())
                }
                _ => return Err("unknown reserve stage".into()),
            };
            let result = limited(rows.saturating_mul(prefix), || table.observe(source_id))?;
            let Err((table, ObservationCreationError::StorageUnavailable(_))) = result else {
                return Err(std::format!("{case}: expected storage refusal"));
            };
            assert_eq!(table.capacity(), capacity);
            assert!(table.is_empty());
        }
        "projected" => {
            let result = limited(0, || {
                ViewReplica::<u32, u32>::try_new(source_id, view_id, capacity)
            })?;
            assert!(matches!(
                result,
                Err(ViewCreationError::TableUnavailable(
                    super::super::super::WarpTableCreationError::ColumnsUnavailable {
                        source: ViewColumnStorageError {
                            column: "incarnation",
                            ..
                        }
                    }
                ))
            ));
        }
        "delivery" => {
            let source = source(ROWS).map_err(String::from)?;
            let view = view(&source).map_err(String::from)?;
            let result = limited(0, || view.delivery_buffer())?;
            assert!(matches!(
                result,
                Err(ViewCreationError::TableUnavailable(
                    super::super::super::WarpTableCreationError::ColumnsUnavailable {
                        source: ViewColumnStorageError {
                            column: "index",
                            ..
                        }
                    }
                ))
            ));
        }
        _ => return Err("unknown allocation case".into()),
    }
    Ok(())
}