Skip to main content

CI Status PyPI package version PyPI python versions

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 netem delay, 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=...), so pg_basebackup can 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)

Source distribution for testgres-exts.pglab 0.1.0
File Size Uploaded Provenance
testgres_exts_pglab-0.1.0.tar.gz 26.2 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for testgres-exts.pglab 0.1.0
File Interpreter ABI Platform
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 log

Release 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 log

Security 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.

Select from 2 files

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 log

A 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.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page