Luigit
repositories / smith

smith

There are many coding harnesses - but this one is fast

owned by admin

smith-harness/tests/alloc_bounds.rs

Raw
//! Allocation-count bounds on one agent turn (`SMH-SPEC-SPEC0001`, memory
//! accounting). Bounds only tighten.

use smith_alloc::{Counting, Scope, measure};
use smith_harness::{RuntimeConfig, build_agent, mock_text_reply};
use std::sync::mpsc;
use std::time::Duration;

#[global_allocator]
static ALLOC: Counting = Counting;

/// One mock text turn on a fresh session: request build (one decode of the
/// user message), stream consumption, two recorded entries encoded once into
/// the arena, one worker request + bounded acknowledgement per entry.
/// Worker ownership adds two channels and two owned frame transfers per turn.
const MOCK_TURN_ALLOCATIONS: u64 = 47;

/// Initialize std MPMC's per-thread wait context before turn accounting.
///
/// `sync_channel().recv()` allocates its `Context` only when it blocks.
/// A worker acknowledgement can race between immediate delivery and that path,
/// so this bounded deadline fixes the lazy-state boundary explicitly.
fn initialize_mpsc_wait_context() {
    let (_sender, receiver) = mpsc::sync_channel::<()>(1);
    assert_eq!(
        receiver.recv_timeout(Duration::from_secs(1)),
        Err(mpsc::RecvTimeoutError::Timeout)
    );
}

fn mock_turn(tag: &str) -> (u64, u64) {
    let dir = std::env::temp_dir().join(format!("smith_alloc_{tag}_{}", std::process::id()));
    let _ = std::fs::remove_dir_all(&dir);
    std::fs::create_dir_all(&dir).unwrap();
    let mut agent = build_agent(&RuntimeConfig::mock(&dir, vec![mock_text_reply("hi")])).unwrap();
    let (outcome, cost) = measure(Scope::Turn, || agent.run_turn("hello"));
    assert_eq!(outcome.unwrap().text, "hi");
    drop(agent);
    let _ = std::fs::remove_dir_all(&dir);
    (cost.allocations, cost.bytes)
}

#[test]
fn provider_effect_channel_moves_records_without_allocating() {
    use smith::provider::{ProviderEffectOutcome, ProviderEffectRecord, record_channel};
    let (sender, receiver) = record_channel();
    let record = ProviderEffectRecord::Outcome {
        status: 200,
        response_bytes: 12,
        outcome: ProviderEffectOutcome::Completed,
    };
    let (received, cost) = measure(Scope::IoRequest, || {
        sender.try_send(record).unwrap();
        receiver.try_recv().unwrap()
    });
    assert!(matches!(
        received,
        ProviderEffectRecord::Outcome {
            response_bytes: 12,
            ..
        }
    ));
    assert_eq!(cost.allocations, 0);
    assert_eq!(cost.peak, 0);
}

#[test]
fn mock_turn_is_bounded_and_reproducible() {
    // SMH-SPEC-SPEC0001: turn accounting excludes process initialization.
    initialize_mpsc_wait_context();
    let _warmup = mock_turn("warmup");
    let first = mock_turn("a");
    let second = mock_turn("b");
    assert_eq!(first, second);
    assert_eq!(
        first.0, MOCK_TURN_ALLOCATIONS,
        "turn allocated {} times, bound is {MOCK_TURN_ALLOCATIONS}",
        first.0
    );
}