PgLab
PgLab is a Linux fault-injection layer for PostgreSQL tests built on top of Testgres.
Testgres owns PostgreSQL lifecycle, SQL access, backups and physical replication. PgLab owns Linux isolation and faults:
- network namespaces, veth pairs and a bridge;
- cgroup v1/v2 I/O throttling;
- network partitions;
tc netemdelay, jitter, loss, duplication, corruption, reordering and rate limits;- freeze/unfreeze of a PostgreSQL process group;
- cleanup of namespaces, cgroups, qdiscs and temporary firewall rules.
PgLab currently requires Linux and root privileges because it creates network namespaces, interfaces and cgroups. PostgreSQL itself runs as a configurable unprivileged Unix account.
Why this needed changes in Testgres
Each PgLab node has a different OsOperations execution context: PostgreSQL
commands for a replica must run inside that replica's network namespace, and
server-starting commands must also enter its cgroup. A replica therefore cannot
simply inherit the primary node's os_ops, host and port-management context.
The Testgres target execution-context API lets PgLab keep the proper separation
of responsibilities: Testgres still owns pg_basebackup, physical replication
and PostgresNode lifecycle; PgLab only supplies the target execution context
and Linux fault injection.
See docs/why-testgres-execution-context.md for the concrete primary/replica flow and the reason behind the upstream Testgres changes.
Testgres compatibility
PgLab uses the target execution-context API in current Testgres:
primary.replicate(
target_os_ops=replica_ops,
target_host=replica_ip,
target_port=5432,
)
The compatible Testgres tree must provide:
PostgresNode.replicate(target_os_ops=..., target_host=..., target_port=...);NodeBackup(..., os_ops=...), sopg_basebackupcan run in the target context;- target execution-context support in node cloning.
The current development target is Testgres 1.17.0 with that API. Until those changes are present in a released Testgres build, install Testgres from the compatible checkout and install PgLab editable beside it.
Development install
With a compatible Testgres checkout in ../testgres:
./setup.sh --testgres-dir ../testgres
Or manually:
python3 -m venv .venv
.venv/bin/python -m pip install -U pip setuptools wheel
.venv/bin/python -m pip install -e ../testgres
.venv/bin/python -m pip install -e '.[test]'
.venv/bin/python tools/verify_install.py
When the required Testgres API is available from PyPI, a normal editable install is enough:
python3 -m venv .venv
.venv/bin/python -m pip install -e '.[test]'
No setup.py is required. Packaging metadata lives in pyproject.toml.
PostgreSQL environment
Point PgLab at the PostgreSQL build you want to test:
export PG_BIN=/home/user/build/postgres/bin
export PGLAB_OS_USER=user
export PGLAB_DB_USER=postgres
export PGLAB_TEST_ROOT=/var/tmp
PGLAB_TEST_ROOT should live on a block-backed filesystem for cgroup I/O tests.
A tmpfs or overlay filesystem is fine for networking-only tests but cannot be
mapped reliably to a block device for io.max/blkio throttling.
Check the host:
./scripts/doctor.sh
Example
from pglab import PgLab
with PgLab(
pg_bin="/home/user/build/postgres/bin",
base_dir="/var/tmp/pglab-demo",
subnet="10.203.0.0/24",
os_user="user",
db_superuser="postgres",
) as lab:
primary = lab.create_primary("p1", "10.203.0.10", port=5432)
primary.init().start()
replica = lab.create_replica("p1", "r1", "10.203.0.11", port=5432)
replica.start()
replica.catchup()
replica.netem(delay_ms=100, loss_pct=1)
replica.clear_netem()
lab.partition("p1", "r1")
lab.heal_partition("p1", "r1")
replica.freeze()
replica.unfreeze()
The same TCP port may be used by several nodes because each PostgreSQL server runs in its own network namespace. PgLab disables Unix-domain PostgreSQL sockets to avoid collisions in the shared mount namespace.
Tests
Smoke test:
./scripts/run-smoke.sh
Full integration suite:
./scripts/run-tests.sh
One file or test can be selected normally:
./scripts/run-tests.sh tests/test_pglab_netem_effects.py
The integration suite covers primary/replica lifecycle, same-port replicas, partitions and recovery, cgroup I/O controls, cleanup after failures, netem latency/loss/rate effects, freeze/unfreeze, replication lag and an unrecoverable WAL-gap scenario.
Project layout
pglab.py PgLab implementation
pyproject.toml Python package metadata
example.py small usage example
smoke.py end-to-end smoke test
tests/ integration and compatibility tests
scripts/doctor.sh environment diagnostics
scripts/run-tests.sh privileged test runner
scripts/run-smoke.sh privileged smoke runner
scripts/install-system-deps.sh host package helper
tools/verify_install.py Testgres API compatibility check
docs/why-testgres-execution-context.md
rationale for the Testgres target-context API
PgLab is still experimental. The public API and packaging may change while the corresponding Testgres execution-context API is being reviewed upstream.
License
PgLab is distributed under the PostgreSQL License. See LICENSE.
Metadata
Release files for testgres-exts.pglab 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| testgres_exts_pglab-0.1.0.tar.gz | 26.2 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| testgres_exts_pglab-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 41.5 kB
Release files / testgres_exts_pglab-0.1.0.tar.gz
| Download URL | testgres_exts_pglab-0.1.0.tar.gz |
|---|---|
| Size | 26.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
91d15398385221fec509b39fbc81a1fb96c955492ddc03988c3fd8ac99d4451e
|
|
BLAKE2b-256 checksum How to use checksums |
eaebd76b7a67ef59271eeeb677d47add0a1abacfa828fe9a32cc6cf8dc24ec5f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.
Transparency logRelease files / testgres_exts_pglab-0.1.0-py3-none-any.whl
| Download URL | testgres_exts_pglab-0.1.0-py3-none-any.whl |
|---|---|
| Size | 15.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b0c2d7c29b4943ac4c5b8b62f4351bdaef80a4b0bddbf83896b2ad92a9a17bf3
|
|
BLAKE2b-256 checksum How to use checksums |
6a7ace0d09f49c3d6229f6791224d7031698c786d4bd3f0060b9177da1e9fd18
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.
Transparency logSecurity for testgres-exts.pglab 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for testgres_exts_pglab-0.1.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.