Unified chaos testing infrastructure for PaperTiger.
Consolidates all chaos testing capabilities into a single coordinator:
- Payment chaos (failure rates, decline codes)
- Event chaos (out-of-order delivery, duplicates, delays)
- API chaos (timeouts, rate limits, server errors)
Configuration
PaperTiger.ChaosCoordinator.configure(%{
payment: %{
failure_rate: 0.1,
decline_codes: [:card_declined, :insufficient_funds],
decline_weights: %{card_declined: 0.7, insufficient_funds: 0.3}
},
events: %{
out_of_order: true,
duplicate_rate: 0.05,
buffer_window_ms: 500
},
api: %{
timeout_rate: 0.02,
timeout_ms: 5000,
rate_limit_rate: 0.01,
error_rate: 0.01
}
})Per-Customer Overrides
# Force specific customer to always fail
PaperTiger.ChaosCoordinator.simulate_failure("cus_xxx", :card_declined)
# Clear override
PaperTiger.ChaosCoordinator.clear_simulation("cus_xxx")Namespace Isolation
Uses ETS with namespace isolation for test concurrency. Each test process can have its own chaos state.
Summary
Functions
Returns all available decline codes.
Returns a specification to start this module under a supervisor.
Cleans up after chaos testing.
Clears any payment simulation for a customer.
Configures chaos settings. Merges with existing config.
Returns the default decline codes.
Forces all buffered events to be delivered immediately.
Gets the current chaos configuration.
Gets chaos statistics.
Queues an event for potential chaos processing.
Resets all chaos configuration to defaults and clears all state.
Determines if an API request should fail or return a custom response.
Determines if a payment should fail for the given customer.
Forces payment failures for a specific customer.
Starts the ChaosCoordinator.
Functions
Returns all available decline codes.
Returns a specification to start this module under a supervisor.
See Supervisor.
@spec cleanup() :: :ok
Cleans up after chaos testing.
This resets chaos configuration AND flushes all Paper Tiger stores to remove any test data that was created during chaos testing. Call this after chaos testing to prevent test data from being synced to the host application's database.
Example
# After running chaos tests
PaperTiger.ChaosCoordinator.cleanup()
@spec clear_simulation(String.t()) :: :ok
Clears any payment simulation for a customer.
@spec configure(map()) :: :ok
Configures chaos settings. Merges with existing config.
Examples
# Enable payment chaos
configure(%{payment: %{failure_rate: 0.1}})
# Enable event chaos
configure(%{events: %{out_of_order: true, buffer_window_ms: 500}})
# Enable API chaos
configure(%{api: %{timeout_rate: 0.05}})
Returns the default decline codes.
@spec flush_events() :: :ok
Forces all buffered events to be delivered immediately.
Useful in tests to ensure events are processed before assertions.
@spec get_config() :: map()
Gets the current chaos configuration.
@spec get_stats() :: map()
Gets chaos statistics.
Queues an event for potential chaos processing.
If event chaos is configured, the event may be:
- Buffered and delivered out of order
- Duplicated
- Delayed
If no event chaos is configured, delivers immediately.
@spec reset() :: :ok
Resets all chaos configuration to defaults and clears all state.
@spec should_api_fail?(String.t()) :: :ok | {:timeout, non_neg_integer()} | :rate_limit | :server_error | {:custom_response, pos_integer(), map()}
Determines if an API request should fail or return a custom response.
Returns:
:ok- Request should proceed normally{:timeout, ms}- Request should timeout after sleeping:rate_limit- Request should return 429:server_error- Request should return 500/502/503{:custom_response, status, body}- Return a custom JSON response
Custom Response Example
PaperTiger.ChaosCoordinator.configure(%{
api: %{
endpoint_overrides: %{
"/v1/subscriptions" => {:custom_response, 200, %{"id" => "sub_1", "status" => "past_due"}}
}
}
})
Determines if a payment should fail for the given customer.
Checks customer overrides first, then applies configured chaos rules.
Returns:
{:ok, :succeed}- Payment should succeed{:ok, {:fail, decline_code}}- Payment should fail with the given code
Forces payment failures for a specific customer.
The customer's payments will fail with the given decline code until cleared.
Starts the ChaosCoordinator.