Why Chaos Injection Uses a CSPRNG (and Rolls Fresh Every Request)
Real APIs fail sometimes — a flaky upstream, a timeout, a 500 under load. If your client code has never seen that happen, you don't actually know how it behaves when it does. Chaos injection makes MockBase fail on purpose, at a rate you choose, so you can find out before production does.
The mechanism is one line
Each route has a configurable error rate. On every request to that route, MockBase decides independently whether this particular call fails:
secrets.randbelow(10_000) < int(error_rate * 10_000)
error_rate is a float between 0 and 1. Scaling it to an integer out of 10,000 rather than checking random() < error_rate directly gives the roll two extra decimal digits of precision — you can dial in 0.1% as accurately as 10%, not just whole percentages.
The secrets module — not random — is the meaningful choice here. random.random() is a Mersenne Twister: fast, statistically fine for simulations, but seeded and reproducible if you know the state. secrets.randbelow() is cryptographically secure, which matters because chaos injection is a security-adjacent testing feature — people use it to test retry logic, circuit breakers, and failover behavior, and a predictable "random" failure pattern would make those tests less honest than they look.
Independent per request, not a schedule
There's no state carried between requests — no "fail every 10th call," no counter. Each request gets its own fresh roll against the configured rate. Set it to 20% and roughly 1 in 5 calls fails, but which ones is genuinely unpredictable, including runs where three failures land in a row or thirty successes pass before one failure shows up. That's closer to how real intermittent failures actually distribute than a fixed pattern would be — and a fixed pattern is exactly the kind of thing a client could accidentally learn to work around without truly handling the failure case.
What a failed request actually returns
When the roll triggers, MockBase skips your configured response entirely and returns a fixed error shape instead — a configurable status code (so you can test how your client handles a 500 differently from a 503) with a body of {"error": "chaos_injection", "detail": "Injected failure for chaos testing."}. It's unambiguous on purpose: you should never wonder whether a failure during testing was chaos injection or an actual bug in your mock configuration.
Picking a rate
10-20% is usually enough to prove your retry and error-handling paths actually run without making every test run painfully flaky. Save 100% for a deliberate "this endpoint is down" test — verifying a hard dependency failure, not just an intermittent one.
Xerat02
Building MockBase.
More from the blog
Your Mock's Access Token Is Shown to You Exactly Once
Turn on token protection and MockBase generates a token, shows it to you, and then — by design — never shows it to you again. Not in the UI, not through the API. If you didn't copy it, your only move is to rotate: generate a new one and invalidate the old.
Custom Subdomains Match Exactly One Label, on Purpose
Claim a slug and your mock also answers at `<slug>.mockbase.org` instead of only `mockbase.org/mock/<id>`. The routing behind that is a single Host-header check, and it's stricter than it might look — deliberately.