zoobzio December 10, 2025 Edit this page

Testing Reference

The aperture/testing package provides utilities for testing aperture configurations.

Import

import apertesting "github.com/zoobz-io/aperture/testing"

Providers

TestProviders

func TestProviders(
    ctx context.Context,
    serviceName string,
    serviceVersion string,
    otlpEndpoint string,
) (*Providers, error)

Creates OTLP providers configured for testing with insecure connections.

Parameters:

  • ctx - Context for provider creation
  • serviceName - Service name for resource attribute
  • serviceVersion - Service version for resource attribute
  • otlpEndpoint - OTLP collector endpoint (e.g., "localhost:4318")

Returns:

  • *Providers - Log, Meter, and Trace providers
  • error - Validation or connection errors

Example:

pvs, err := apertesting.TestProviders(ctx, "test-service", "v1.0.0", "localhost:4318")
if err != nil {
    t.Skip("collector not available")
}
defer pvs.Shutdown(ctx)

ap, _ := aperture.New(cap, pvs.Log, pvs.Meter, pvs.Trace)

Providers

type Providers struct {
    Log   *sdklog.LoggerProvider
    Meter *sdkmetric.MeterProvider
    Trace *sdktrace.TracerProvider
}

Providers.Shutdown

func (p *Providers) Shutdown(ctx context.Context) error

Shuts down all providers gracefully.

Mock Logger

NewMockLoggerProvider

func NewMockLoggerProvider() *MockLoggerProvider

Creates a mock logger provider that captures log records.

Example:

mockLog := apertesting.NewMockLoggerProvider()
ap, _ := aperture.New(cap, mockLog, noop.NewMeterProvider(), tracenoop.NewTracerProvider())

MockLoggerProvider

type MockLoggerProvider struct {
    // ...
}

Logger

func (p *MockLoggerProvider) Logger(name string, opts ...log.LoggerOption) log.Logger

Returns the mock logger (same instance for all names).

Capture

func (p *MockLoggerProvider) Capture() *LogCapture

Returns the log capture for assertions.

NewMockLogger

func NewMockLogger() *MockLogger

Creates a standalone mock logger.

MockLogger

type MockLogger struct {
    // ...
}

Emit

func (m *MockLogger) Emit(ctx context.Context, record log.Record)

Captures the log record.

Enabled

func (m *MockLogger) Enabled(ctx context.Context, params log.EnabledParameters) bool

Always returns true.

Capture

func (m *MockLogger) Capture() *LogCapture

Returns the log capture.

Log Capture

NewLogCapture

func NewLogCapture() *LogCapture

Creates a new log capture instance.

LogCapture

type LogCapture struct {
    // ...
}

Thread-safe log record storage.

Records

func (lc *LogCapture) Records() []log.Record

Returns a copy of all captured records.

Count

func (lc *LogCapture) Count() int

Returns the number of captured records.

Reset

func (lc *LogCapture) Reset()

Clears all captured records.

WaitForCount

func (lc *LogCapture) WaitForCount(n int, timeout time.Duration) bool

Blocks until at least n records are captured or timeout expires.

Returns: true if count reached, false if timeout.

Example:

if !capture.WaitForCount(5, time.Second) {
    t.Error("timeout waiting for logs")
}

Event Capture

NewEventCapture

func NewEventCapture() *EventCapture

Creates a new event capture instance.

EventCapture

type EventCapture struct {
    // ...
}

Thread-safe capitan event storage.

Handler

func (ec *EventCapture) Handler() capitan.EventCallback

Returns a callback for capitan.Hook().

Example:

capture := apertesting.NewEventCapture()
cap.Hook(sig, capture.Handler())

Events

func (ec *EventCapture) Events() []CapturedEvent

Returns a copy of all captured events.

Count

func (ec *EventCapture) Count() int

Returns the number of captured events.

Reset

func (ec *EventCapture) Reset()

Clears all captured events.

WaitForCount

func (ec *EventCapture) WaitForCount(n int, timeout time.Duration) bool

Blocks until at least n events are captured or timeout expires.

CapturedEvent

type CapturedEvent struct {
    Signal    capitan.Signal
    Timestamp time.Time
    Severity  capitan.Severity
    Fields    []capitan.Field
}

Snapshot of a capitan event.

Usage with Noop Providers

For tests that only verify logging:

import (
    "go.opentelemetry.io/otel/metric/noop"
    tracenoop "go.opentelemetry.io/otel/trace/noop"
)

func TestLogging(t *testing.T) {
    mockLog := apertesting.NewMockLoggerProvider()

    ap, _ := aperture.New(
        cap,
        mockLog,
        noop.NewMeterProvider(),
        tracenoop.NewTracerProvider(),
    )
    // ...
}

Common Test Patterns

Verify Log Count

func TestLogCount(t *testing.T) {
    mockLog := apertesting.NewMockLoggerProvider()
    ap, _ := aperture.New(cap, mockLog, noop.NewMeterProvider(), tracenoop.NewTracerProvider())
    defer ap.Close()

    cap.Emit(ctx, sig)
    cap.Emit(ctx, sig)
    cap.Shutdown()

    if mockLog.Capture().Count() != 2 {
        t.Errorf("expected 2 logs")
    }
}

Verify Whitelist Filtering

func TestWhitelist(t *testing.T) {
    allowed := capitan.NewSignal("allowed", "")
    blocked := capitan.NewSignal("blocked", "")

    schema := aperture.Schema{
        Logs: &aperture.LogSchema{
            Whitelist: []string{"allowed"},
        },
    }

    mockLog := apertesting.NewMockLoggerProvider()
    ap, _ := aperture.New(cap, mockLog, noop.NewMeterProvider(), tracenoop.NewTracerProvider())
    ap.Apply(schema)
    defer ap.Close()

    cap.Emit(ctx, allowed)
    cap.Emit(ctx, blocked)
    cap.Shutdown()

    if mockLog.Capture().Count() != 1 {
        t.Error("whitelist filtering failed")
    }
}

Wait for Async Events

func TestAsync(t *testing.T) {
    mockLog := apertesting.NewMockLoggerProvider()
    // ... setup ...

    go func() {
        for i := 0; i < 10; i++ {
            cap.Emit(ctx, sig)
        }
    }()

    if !mockLog.Capture().WaitForCount(10, 5*time.Second) {
        t.Error("timeout")
    }
}