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;
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);
}
}
}
fn create_demo_trace() -> UnifiedTrace {
let mut trace = UnifiedTrace::new(12345, "example_api_server".to_string());
let clock = LamportClock::new();
trace.add_syscall(SyscallSpan::new(
1,
Cow::Borrowed("open"),
vec![(Cow::Borrowed("path"), "/var/lib/db.sqlite".to_string())],
3,
0,
5_000_000, None,
&clock,
));
trace.add_syscall(SyscallSpan::new(
1,
Cow::Borrowed("read"),
vec![(Cow::Borrowed("fd"), "3".to_string())],
1024,
5_000_000,
30_000_000, None,
&clock,
));
trace.add_syscall(SyscallSpan::new(
1,
Cow::Borrowed("write"),
vec![(Cow::Borrowed("fd"), "1".to_string())],
512,
35_000_000,
10_000_000, None,
&clock,
));
trace.add_syscall(SyscallSpan::new(
1,
Cow::Borrowed("close"),
vec![(Cow::Borrowed("fd"), "3".to_string())],
0,
45_000_000,
1_000_000, None,
&clock,
));
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);
}
}
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)");
}
}
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, 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);
}
}
}
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!");
}
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();
}