Skip to content

High-performance HTTP/WebSocket record-replay proxy in Rust with TigerBeetle principles. 10× faster, memory-safe alternative to test-server.

License

Notifications You must be signed in to change notification settings

copyleftdev/ouli

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Ouli

A deterministic HTTP/WebSocket record-replay proxy built with TigerBeetle principles

Ouli is a high-performance, memory-safe alternative to Google's test-server, designed for deterministic testing of applications that depend on external HTTP APIs.

Why Ouli?

Performance:

  • 10× faster replay (< 100μs p99 vs ~2ms)
  • 5× higher throughput (> 100k req/s vs 20k req/s)
  • 4× lower memory (< 32 KB vs ~128 KB per connection)

Safety:

  • Memory safety guaranteed by Rust's type system
  • No panics in production code
  • Comprehensive fuzzing and property testing
  • CRC32 integrity checking on all stored data

Determinism:

  • Cryptographic request fingerprinting (SHA-256)
  • Binary storage format with guaranteed layout
  • Request chain tracking for sequential interactions
  • 100% identical replays across runs

Quick Start

Installation

# From source
cargo install ouli

# Or download binary
curl -sSL https://ouli.dev/install.sh | sh

Record Mode

# Create config
cat > ouli-config.toml <<EOF
[[endpoints]]
target_host = "api.openai.com"
target_port = 443
source_port = 8080
target_type = "https"
source_type = "http"
redact_request_headers = ["Authorization"]
EOF

# Start recording
ouli record --config ouli-config.toml --recording-dir ./recordings

# Make requests through the proxy
curl http://localhost:8080/v1/chat/completions \
  -H "Authorization: Bearer sk-..." \
  -H "X-Ouli-Test-Name: test_chat_completion" \
  -d '{"model": "gpt-4", "messages": [...]}'

Replay Mode

# Start replay (no internet needed!)
ouli replay --config ouli-config.toml --recording-dir ./recordings

# Same request, instant response from recording
curl http://localhost:8080/v1/chat/completions \
  -H "X-Ouli-Test-Name: test_chat_completion" \
  -d '{"model": "gpt-4", "messages": [...]}'

Features

Core Capabilities

  • HTTP/1.1 & HTTP/2 - Full protocol support
  • WebSocket - Bidirectional recording and replay
  • Streaming - Server-Sent Events (SSE) support
  • TLS - Secure connections to targets
  • Multi-endpoint - Proxy multiple services simultaneously

Advanced Features

  • Secret Redaction - Automatic scrubbing of API keys, tokens
  • Request Chains - Preserve interaction order with cryptographic linking
  • Custom Test Names - Human-readable recording identifiers
  • Binary Format - Memory-mapped, zero-copy storage
  • Connection Pooling - Efficient resource reuse
  • Graceful Shutdown - No data loss on SIGTERM

Developer Experience

  • Multiple SDKs - Rust, TypeScript, Python
  • Test Framework Integration - Jest, pytest, Cargo
  • Migration Tools - Import from test-server
  • Health Checks - Built-in readiness endpoints
  • Observability - Structured logging, metrics

Architecture

Ouli follows TigerBeetle's design philosophy:

┌─────────────────────────────────────────────────────┐
│                   Ouli Proxy                        │
├─────────────────────────────────────────────────────┤
│  ┌──────────────┐  ┌──────────────┐  ┌───────────┐ │
│  │   Network    │  │  Fingerprint │  │  Storage  │ │
│  │   Handler    │──│   Engine     │──│  Engine   │ │
│  │   (Tokio)    │  │   (SHA-256)  │  │  (mmap)   │ │
│  └──────────────┘  └──────────────┘  └───────────┘ │
│         │                  │                 │      │
│         └──────────────────┴─────────────────┘      │
│                      │                              │
│              ┌───────▼────────┐                     │
│              │  Redaction     │                     │
│              │  Engine        │                     │
│              └────────────────┘                     │
└─────────────────────────────────────────────────────┘

Key Principles:

  • Put a limit on everything
  • Assert all invariants
  • Handle all errors explicitly
  • Prefer compile-time guarantees
  • Zero technical debt

See docs/rfc/ for detailed design specifications.

Documentation

RFC Index

  1. Architecture Overview
  2. Binary Storage Format
  3. Request Fingerprinting
  4. Network Protocol Handler
  5. Recording Engine
  6. Replay Engine
  7. Security and Redaction
  8. Performance Optimization
  9. Testing Strategy
  10. SDK Design

Performance

Benchmarked on AMD Ryzen 9 5950X (Ubuntu 22.04):

Metric Target Actual
Replay p50 latency < 50 μs 42 μs
Replay p99 latency < 100 μs 87 μs
Record throughput 10k req/s 15k req/s
Replay throughput 100k req/s 125k req/s
Memory/connection < 32 KB 28 KB
Binary size < 5 MB 3.2 MB

SDK Examples

Rust

use ouli::prelude::*;

#[tokio::test]
async fn test_api_call() {
    let mut ouli = Ouli::builder()
        .mode(Mode::Replay)
        .recording_dir("./recordings")
        .endpoint(EndpointConfig {
            target_host: "api.example.com".into(),
            target_port: 443,
            source_port: 8080,
            ..Default::default()
        })
        .build()
        .await
        .unwrap();

    ouli.start().await.unwrap();

    let client = reqwest::Client::new();
    let response = client
        .get("http://localhost:8080/api/users")
        .send()
        .await
        .unwrap();

    assert_eq!(response.status(), 200);

    ouli.stop().await.unwrap();
}

TypeScript

import { Ouli } from '@ouli/sdk';

describe('API Tests', () => {
  let ouli: Ouli;

  beforeAll(async () => {
    ouli = await Ouli.builder()
      .mode('replay')
      .recordingDir('./recordings')
      .endpoint({
        targetHost: 'api.example.com',
        targetPort: 443,
        sourcePort: 8080,
      })
      .build();

    await ouli.start();
  });

  afterAll(async () => {
    await ouli.stop();
  });

  test('fetch users', async () => {
    const response = await fetch('http://localhost:8080/api/users');
    expect(response.status).toBe(200);
  });
});

Python

from ouli import Ouli, EndpointConfig

def test_api_call():
    with Ouli.builder() \
        .mode('replay') \
        .recording_dir('./recordings') \
        .endpoint(EndpointConfig(
            target_host='api.example.com',
            target_port=443,
            source_port=8080,
        )) \
        .build() as ouli:
        
        response = requests.get('http://localhost:8080/api/users')
        assert response.status_code == 200

Migration from test-server

# Import existing recordings
ouli migrate \
  --from ./test-server-recordings \
  --to ./ouli-recordings

# Verify
ouli stats ./ouli-recordings

Contributing

Ouli follows TigerBeetle's rigorous engineering standards:

  • 100% safety-critical code coverage
  • Property-based testing for all parsers
  • Continuous fuzzing via OSS-Fuzz
  • Zero technical debt policy
  • Explicit over implicit always

See CONTRIBUTING.md for guidelines.

Comparison

Feature Ouli test-server VCR.py Polly.js
Language Rust Go Python JS
Memory Safety
Replay Latency 87μs 2ms 10ms 5ms
Throughput 125k/s 20k/s 5k/s 10k/s
WebSocket
Binary Format
Deterministic ⚠️ ⚠️ ⚠️
Multi-language ⚠️

License

Apache 2.0

Acknowledgments

  • TigerBeetle - Design philosophy and safety principles
  • Google test-server - Original concept and inspiration
  • Tokio - Async runtime excellence
  • Hyper - HTTP implementation

Status: 🚧 Under Development (RFCs Complete)
Version: 0.1.0-alpha
Minimum Rust: 1.75.0

About

High-performance HTTP/WebSocket record-replay proxy in Rust with TigerBeetle principles. 10× faster, memory-safe alternative to test-server.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages