Open-Source Wikis

/

Pingora

/

How to contribute

/

Testing

cloudflare/pingora

Testing

Pingora's tests are mostly Rust's normal #[cfg(test)] plus integration tests that spin up real listeners on loopback. There's no custom test framework.

Running tests

cargo test --workspace                             # everything
cargo test -p pingora-cache                         # one crate
cargo test --workspace --features "openssl proxy"   # with TLS + proxy on
cargo test test_h2_                                 # tests by name pattern

The --features flag is important when changing TLS-adjacent code: many tests are gated behind cargo features and silently skipped if the feature is off.

Test layout

Each crate puts unit tests inside the file under test, in a mod tests { } block guarded by #[cfg(test)]. Integration tests that need a listener live in crate/tests/:

  • pingora-core/tests/headers.rs, pingora-core/tests/utils/, pingora-core/tests/v1.rs, pingora-core/tests/v2.rs, pingora-core/tests/tls.rs
  • pingora-proxy/tests/test_basic.rs, pingora-proxy/tests/utils/ (a small in-process backend reused across tests)

The tests/utils/ crates often expose a mock_server helper that binds to 127.0.0.1:0 to dodge port collisions.

Flakes

A few tests are known to be flaky in CI. The pattern is "real network on loopback + small timeouts":

  • test_tls_psk, test_conn_timeout, test_1xx_caching — fixed in commit 542129f (Mar 2026)
  • A slate of caching stall tests was marked #[ignore] in commit c0adfd3 (Apr 2026)

If you hit flakes locally, re-run with a single thread:

cargo test -- --test-threads=1

What good test coverage looks like here

The crates with the most test mass are the ones that benefit most: pingora-cache, pingora-proxy, pingora-load-balancing, and pingora-pool. Smaller utility crates (pingora-error, pingora-runtime, pingora-timeout) tend to have shorter unit-test sections.

When adding a feature to the proxy, look at how pingora-proxy/tests/test_basic.rs exercises a request end-to-end and follow the same pattern: spin up a backend, spin up the proxy, send a request with reqwest, assert on the response.

Benchmarks

Benchmarks use criterion and live under benches/:

  • pingora-ketama/benches/ — hash-ring ops
  • pingora-lru/benches/ — LRU operations
  • tinyufo/benches/ — TinyUFO algorithm
  • pingora-cache/benches/ — cache operations

Run them with:

cargo bench -p tinyufo

The [profile.bench] section in the root Cargo.toml keeps debug info on for benchmarks (debug = true).

CI

.github/workflows/build.yml is the main test workflow. It runs the matrix described in Development workflow — stable, beta, and MSRV; with and without TLS features.

.github/workflows/audit.yml runs cargo audit against the lockfile.

.github/workflows/semgrep.yml (new in Apr 2026) runs Semgrep OSS rules across the codebase. This was added to surface security smells beyond what cargo audit catches.

Testing TLS code

The TLS-backend crates (pingora-openssl, pingora-boringssl, pingora-rustls, pingora-s2n) each ship a small lib.rs of glue plus an ext.rs of helpers. End-to-end TLS tests live in pingora-core/tests/utils/ so they can exercise listeners and connectors together. The --features openssl run is the most reliable; rustls and s2n have fewer integration tests because they're newer.

Testing graceful upgrade

There's no automated test for the full SIGQUIT-+---upgrade dance. The pingora-core/src/server/transfer_fd/ module has unit tests for the FD-passing socket protocol, but the end-to-end "old binary hands sockets to new binary" flow is exercised manually using the recipe in docs/user_guide/graceful.md.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Testing – Pingora wiki | Factory