aprender-profile 0.32.0

Pure Rust system call tracer with source-aware correlation for Rust binaries
//! Build-Time Assertions Example (Sprint 44)
//!
//! This example demonstrates how to use renacer's build-time assertion system
//! to validate performance constraints during cargo test.
//!
//! Run with: cargo run --example build_time_assertions

use renacer::assertion_dsl::AssertionConfig;
use renacer::assertion_engine::AssertionEngine;
use renacer::assertion_types::{
    Assertion, AssertionType, CriticalPathAssertion, SpanCountAssertion,
};
use renacer::trace_context::LamportClock;
use renacer::unified_trace::{SyscallSpan, UnifiedTrace};
use std::borrow::Cow;

/// Demo 1: Parse renacer.toml configuration
fn demo_parse_config() {
    println!("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
    println!("Demo 1: Parsing renacer.toml Configuration");
    println!("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n");

    let toml_config = r#"
        [[assertion]]
        name = "api_max_latency"
        type = "critical_path"
        max_duration_ms = 100
        fail_on_violation = true

        [[assertion]]
        name = "max_syscalls"
        type = "span_count"
        max_spans = 1000
        fail_on_violation = true

        [[assertion]]
        name = "disabled_check"
        type = "critical_path"
        max_duration_ms = 10
        enabled = false
    "#;

    match AssertionConfig::from_toml_str(toml_config) {
        Ok(config) => {
            println!("Parsed {} assertions from TOML", config.assertion.len());
            for assertion in &config.assertion {
                println!(
                    "   - {} ({:?}) [enabled: {}]",
                    assertion.name,
                    match &assertion.assertion_type {
                        AssertionType::CriticalPath(_) => "CriticalPath",
                        AssertionType::SpanCount(_) => "SpanCount",
                        _ => "Other",
                    },
                    assertion.enabled
                );
            }

            println!("\n   Enabled assertions: {}", config.enabled_assertions().len());
            println!(
                "   Fail-on-violation assertions: {}",
                config.fail_on_violation_assertions().len()
            );
        }
        Err(e) => {
            eprintln!("Failed to parse TOML: {}", e);
        }
    }
}

/// Create a synthetic trace for demo purposes
fn create_demo_trace() -> UnifiedTrace {
    let mut trace = UnifiedTrace::new(12345, "example_api_server".to_string());
    let clock = LamportClock::new();

    // 1. Open database connection
    trace.add_syscall(SyscallSpan::new(
        1,
        Cow::Borrowed("open"),
        vec![(Cow::Borrowed("path"), "/var/lib/db.sqlite".to_string())],
        3,
        0,
        5_000_000, // 5ms
        None,
        &clock,
    ));

    // 2. Query database
    trace.add_syscall(SyscallSpan::new(
        1,
        Cow::Borrowed("read"),
        vec![(Cow::Borrowed("fd"), "3".to_string())],
        1024,
        5_000_000,
        30_000_000, // 30ms (database query)
        None,
        &clock,
    ));

    // 3. Write response
    trace.add_syscall(SyscallSpan::new(
        1,
        Cow::Borrowed("write"),
        vec![(Cow::Borrowed("fd"), "1".to_string())],
        512,
        35_000_000,
        10_000_000, // 10ms
        None,
        &clock,
    ));

    // 4. Close connection
    trace.add_syscall(SyscallSpan::new(
        1,
        Cow::Borrowed("close"),
        vec![(Cow::Borrowed("fd"), "3".to_string())],
        0,
        45_000_000,
        1_000_000, // 1ms
        None,
        &clock,
    ));

    trace
}

/// Demo 2: Generate and display a synthetic trace
fn demo_synthetic_trace(trace: &UnifiedTrace) {
    println!("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
    println!("Demo 2: Generating Synthetic Trace");
    println!("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n");

    let total_duration_ms =
        trace.syscall_spans.iter().map(|s| s.duration_nanos).sum::<u64>() / 1_000_000;

    println!("Generated trace with {} syscalls", trace.syscall_spans.len());
    println!("   Process: {} (PID {})", trace.process_span.name, trace.process_span.pid);
    println!("   Total duration: {}ms", total_duration_ms);
    for (i, span) in trace.syscall_spans.iter().enumerate() {
        println!("   {}. {} - {}ms", i + 1, span.name, span.duration_nanos / 1_000_000);
    }
}

/// Demo 3: Evaluate assertions (PASS scenario)
fn demo_pass_scenario(trace: &UnifiedTrace) {
    println!("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
    println!("Demo 3: Evaluating Assertions (PASS Scenario)");
    println!("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n");

    let assertions = vec![
        Assertion {
            name: "api_max_latency".to_string(),
            assertion_type: AssertionType::CriticalPath(CriticalPathAssertion {
                max_duration_ms: 100,
                trace_name_pattern: None,
            }),
            fail_on_violation: true,
            enabled: true,
        },
        Assertion {
            name: "max_syscalls".to_string(),
            assertion_type: AssertionType::SpanCount(SpanCountAssertion {
                max_spans: 10,
                span_name_pattern: None,
            }),
            fail_on_violation: true,
            enabled: true,
        },
    ];

    let engine = AssertionEngine::new();
    let results = engine.evaluate_all(&assertions, trace);

    for result in &results {
        if result.passed {
            println!("PASS: {} - {}", result.name, result.message);
        } else {
            println!("FAIL: {} - {}", result.name, result.message);
        }
    }

    if AssertionEngine::has_failures(&results, &assertions) {
        println!("\nAssertion failures detected! (Would fail cargo test)");
    } else {
        println!("\nAll assertions passed! (cargo test would succeed)");
    }
}

/// Demo 4: Evaluate assertions (FAIL scenario)
fn demo_fail_scenario() {
    println!("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
    println!("Demo 4: Evaluating Assertions (FAIL Scenario)");
    println!("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n");

    let mut slow_trace = UnifiedTrace::new(99999, "slow_api_server".to_string());
    let slow_clock = LamportClock::new();

    slow_trace.add_syscall(SyscallSpan::new(
        1,
        Cow::Borrowed("read"),
        vec![],
        1024,
        0,
        120_000_000, // 120ms - exceeds 100ms limit!
        None,
        &slow_clock,
    ));

    let slow_duration_ms =
        slow_trace.syscall_spans.iter().map(|s| s.duration_nanos).sum::<u64>() / 1_000_000;

    println!("Generated slow trace:");
    println!("   Total duration: {}ms (exceeds 100ms limit!)", slow_duration_ms);

    let strict_assertion = Assertion {
        name: "strict_latency_check".to_string(),
        assertion_type: AssertionType::CriticalPath(CriticalPathAssertion {
            max_duration_ms: 100,
            trace_name_pattern: None,
        }),
        fail_on_violation: true,
        enabled: true,
    };

    let engine = AssertionEngine::new();
    let result = engine.evaluate(&strict_assertion, &slow_trace);

    println!("\nAssertion result:");
    if result.passed {
        println!("PASS: {}", result.message);
    } else {
        println!("FAIL: {}", result.message);
        if let (Some(actual), Some(expected)) = (&result.actual_value, &result.expected_value) {
            println!("   Actual:   {}", actual);
            println!("   Expected: {}", expected);
        }
    }
}

/// Demo 5: Integration with cargo test
fn demo_integration() {
    println!("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
    println!("Demo 5: Integration with cargo test");
    println!("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n");

    println!("Example test code:");
    println!(
        r#"
    #[test]
    fn test_api_performance() {{
        // Load assertions from renacer.toml
        let config = AssertionConfig::from_file("renacer.toml").expect("test");

        // Run your API endpoint and capture trace
        let trace = run_api_endpoint();

        // Evaluate assertions
        let engine = AssertionEngine::new();
        let results = engine.evaluate_all(&config.assertion, &trace);

        // Fail test if any assertion fails
        if AssertionEngine::has_failures(&results, &config.assertion) {{
            for (result, assertion) in results.iter().zip(&config.assertion) {{
                if !result.passed && assertion.fail_on_violation {{
                    panic!("Assertion '{{}}' failed: {{}}",
                           result.name, result.message);
                }}
            }}
        }}
    }}
    "#
    );

    println!("\nUsage:");
    println!("1. Create renacer.toml with your assertions");
    println!("2. Add integration test like above");
    println!("3. Run: cargo test");
    println!("4. If performance degrades -> test fails -> CI fails");
    println!("5. Regression prevented!");
}

/// Print final summary
fn demo_summary() {
    println!("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
    println!("Summary: Build-Time Assertions (Sprint 44)");
    println!("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n");

    println!("Key Features:");
    println!("   - Declarative TOML DSL for performance constraints");
    println!("   - 5 assertion types: CriticalPath, AntiPattern, SpanCount, Memory, Custom");
    println!("   - Zero runtime overhead (build-time only)");
    println!("   - CI/CD integration (fail builds on regression)");
    println!("   - Toyota Way: Andon principle (stop the line)");

    println!("\nSprint 44 Deliverables:");
    println!("   - assertion_types.rs (390 lines, 10 tests)");
    println!("   - assertion_dsl.rs (302 lines, 11 tests)");
    println!("   - assertion_engine.rs (512 lines, 8 tests)");
    println!("   - examples/renacer.toml (example configuration)");
    println!("   - Total: 29 tests passing");

    println!("\nGOLDEN-001 Epic Complete (Sprints 40-44):");
    println!("   - Sprint 40: Ring Buffer + Lamport Clocks");
    println!("   - Sprint 41: Causal Graph + RLE Compression");
    println!("   - Sprint 42: Trace Context + Semantic Equivalence");
    println!("   - Sprint 43: Query Optimization + Predicate Pushdown");
    println!("   - Sprint 44: Build-Time Assertions + CI Integration");

    println!("\nGolden Thread OpenTelemetry Integration: 100% Complete!\n");
}

fn main() {
    println!("Renacer Build-Time Assertions Demo (Sprint 44)\n");
    println!("Toyota Way Principle: Andon (Stop the line when defects detected)\n");

    demo_parse_config();
    let trace = create_demo_trace();
    demo_synthetic_trace(&trace);
    demo_pass_scenario(&trace);
    demo_fail_scenario();
    demo_integration();
    demo_summary();
}