Cleanroom Testing Framework
A hermetic integration testing framework that executes tests in isolated Docker containers with OpenTelemetry validation. Define tests declaratively using TOML configuration files and validate runtime behavior with Weaver schema validation.
Installation
Homebrew
Cargo
Requirements
- Rust 1.70 or later (for building from source)
- Docker or Podman (for container execution)
Quick Example
Test an API service with database integration. Weaver automatically validates that your telemetry follows OpenTelemetry semantic conventions, ensuring correct instrumentation without manual trace inspection.
# Run the test
[]
= "api_with_database"
= "1.0.0"
= "API service with database - Weaver validates telemetry structure"
# Enable Weaver schema validation
[]
= true
= "registry"
= 0 # Auto-discover available port
= 0 # Auto-discover available port
# Configure OpenTelemetry export to Weaver
[]
= "otlp-http"
= {
"service.name" = "api_service",
= "test"
}
# Multiple services working together
[]
= "generic_container"
= "my-api:latest"
[]
= "generic_container"
= "postgres:15-alpine"
# Scenario that emits rich telemetry
[[]]
= "api_handles_user_request"
= "api"
= "my-api --endpoint /api/v1/users"
= ["spans:default"]
# Validate HTTP server span
[[]]
= "http.server.request"
= "server"
= {
"http.method" = "GET",
= "/api/v1/users"
}
# Validate database query span (must be child of HTTP span)
[[]]
= "db.query"
= "client"
= "http.server.request"
= {
"db.system" = "postgresql",
= "SELECT"
}
# Validate trace graph structure - proves services actually communicated
[]
= [
["http.server.request", "db.query"] # HTTP span must have DB child
]
= true # No cycles allowed (proves correct trace structure)
# Validate temporal ordering - proves operations happened in correct sequence
[]
= [
["http.server.request", "db.query"], # Request must come before query
["db.query", "http.server.response"] # Query must come before response
]
# Ensure no external service leaks - catch accidental production calls
[]
= true
= ["net.peer.name"] # Forbid external hostnames
Why This Matters
This test validates behavior, not just exit codes. Consider what traditional testing misses:
Traditional Testing Problem:
#!/bin/bash
# Fake-green test - passes but does nothing
# ❌ Database never queried
# ❌ API never handled request
# ❌ Services never interacted
# ✅ Traditional testing: PASS (exit code 0)
OTEL-First Validation Solution: Your test fails if:
- ❌ No HTTP server span exists → API never actually ran (just returned exit code 0)
- ❌ No database query span → Database was never accessed (test is fake-green)
- ❌ Graph structure wrong → Services didn't actually communicate (no parent-child edge)
- ❌ Temporal ordering violated → Operations happened in wrong sequence (bug in execution)
- ❌ External service calls detected → Test leaked to production (hermeticity violation)
- ❌ Semantic conventions violated → Instrumentation incorrect (Weaver catches this)
OTEL-first validation requires proof of execution through telemetry:
- ✅ Graph structure proves service interaction happened (HTTP → DB edge exists)
- ✅ Temporal ordering proves operations occurred in correct sequence (request before query)
- ✅ Hermeticity catches accidental external service calls (forbidden attributes)
- ✅ Semantic conventions validated automatically by Weaver (correct attribute names)
Weaver automatically validates all of this against OpenTelemetry schemas—no manual trace inspection needed. The test fails if your code doesn't actually execute correctly, even if it returns exit code 0.
Features
Core Testing
- TOML-based test definitions
- Docker container isolation per test step
- Automatic test discovery
- Template variable support with Tera
OpenTelemetry Integration
- Weaver live-checking - Automatic schema validation during test execution
- OTLP export for telemetry collection (HTTP/gRPC)
- Resource attribute configuration
- Custom headers and propagators (tracecontext, baggage)
- Sample ratio control
Behavior Validation (Not Just Exit Codes) Unlike traditional testing that only checks return codes, clnrm validates actual execution through telemetry:
- Span expectations - Validate name, kind, attributes, events, duration
- Graph structure - Ensure correct parent-child relationships and acyclic traces
- Temporal ordering - Prove operations occur in the correct sequence
- Count/cardinality - Validate span, event, and error counts match expectations
- Temporal windows - Ensure spans occur within expected time boundaries
- Status codes - Validate span status (OK, ERROR, UNSET) across the trace
- Hermeticity - Catch accidental external service calls or forbidden attributes
CLI Commands
clnrm init- Initialize new test projectclnrm run- Execute test files with Weaver validationclnrm validate- Validate TOML configurationclnrm plugins- List available service pluginsclnrm self-test- Run framework self-validation
OpenTelemetry TOML Configuration
Cleanroom supports comprehensive OpenTelemetry configuration directly in TOML test files:
Weaver Live-Checking
Enable automatic schema validation:
[]
= true # Enable Weaver validation
= "registry" # Path to schema registry
= 0 # Auto-discover (0) or fixed port
= 0 # Auto-discover (0) or fixed port
= "./validation_output" # Validation report directory
= false # Streaming output (real-time)
= false # Stop on first violation
OTEL Export Configuration
[]
= "otlp-http" # Export format: stdout, otlp-http, otlp-grpc
= "http://localhost:4318" # OTLP endpoint URL
= "http/protobuf" # Protocol: http/protobuf, grpc, http/json
= 1.0 # Sampling rate (0.0-1.0)
# Resource attributes
= {
"service.name" = "my_service",
= "1.0.0",
= "test"
}
# Custom headers
= {
"Authorization" = "Bearer token"
}
# Context propagators
= ["tracecontext", "baggage"]
Span Expectations
Validate span structure and attributes:
[[]]
= "http.request" # Span name (supports globs)
= "server" # Span kind: internal, client, server, producer, consumer
= "http.server.request" # Parent span name
# Attribute validation
= { All attributes must match
= "GET",
= "/api/users"
}
= { Any attribute must match
= "200"
}
# Event validation
= ["http.request.received", "http.response.sent"]
= ["exception"]
# Duration bounds
= { = 10.0, = 1000.0 }
Graph Structure Validation
Validate trace topology:
[]
# Required edges
= [
["http.server.request", "db.query"],
["db.query", "cache.get"]
]
# Forbidden edges
= [
["external.service", "internal.service"]
]
= true # Ensure no cycles
Count/Cardinality Validation
[]
= { = 1, = 100 } # Total span count bounds
= { = 5 } # Total event count
= { = 0 } # Must have zero errors
# Per-span-name counts
= {
"http.request" = { eq = 10 }, # Exactly 10 http.request spans
= { = 1 } # At least 1 db.query span
}
Temporal Ordering Validation
[]
# First must precede second
= [
["auth.check", "db.query"],
["db.query", "cache.set"]
]
# First must follow second
= [
["response.sent", "request.received"]
]
Temporal Window Validation
[[]]
= "http.server.request" # Outer span defining time window
= [ # Spans that must be within window
"db.query",
"cache.get",
"auth.check"
]
Status Code Validation
[]
= "OK" # All spans must have OK status
# Or per-span-name
= {
"http.request" = "OK",
= "ERROR" # Supports glob patterns
}
Hermeticity Validation
Ensure tests don't leak to external services:
[]
= true # Forbid external service calls
# Resource attributes must match exactly
= {
"service.name" = "my_service",
= "test"
}
# Forbid certain span attributes (e.g., external network calls)
= [
"net.peer.name", # No external hosts
"http.url" # No external URLs
]
Documentation
- Quick Start Guide - Get started in 5 minutes
- Advanced Users Guide - Comprehensive documentation (mdbook)
- TOML Reference - Configuration format
- Weaver TOML Configuration - Weaver live-checking setup
- Documentation Index - Complete navigation hub
Contributing
Contributions are welcome. See CONTRIBUTING.md for guidelines.
License
Licensed under the MIT License. See LICENSE for details.
Repository: github.com/seanchatmangpt/clnrm