Skip to content

Refactor BDD tests: split monolithic extended.rs into modules #471

Refactor BDD tests: split monolithic extended.rs into modules

Refactor BDD tests: split monolithic extended.rs into modules #471

Workflow file for this run

name: BDD Tests
permissions:
contents: read
on:
pull_request:
branches:
- master
push:
branches:
- master
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}/test-runner
DEBUG: 1
jobs:
# Job 0: Check if image needs to be rebuilt
check-image:
name: Check Image Cache
runs-on: ubuntu-latest
permissions:
contents: read
packages: read
outputs:
image-tag: ${{ steps.compute-tag.outputs.tag }}
image-exists: ${{ steps.check-exists.outputs.exists }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Compute image tag from flake files
id: compute-tag
run: |
# Create a hash based on flake.nix and flake.lock content
FLAKE_HASH=$(cat tests/nix/flake.nix tests/nix/flake.lock | sha256sum | cut -c1-16)
echo "tag=flake-${FLAKE_HASH}" >> $GITHUB_OUTPUT
echo "Computed image tag: flake-${FLAKE_HASH}"
- name: Log in to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Check if image exists in registry
id: check-exists
run: |
IMAGE="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.compute-tag.outputs.tag }}"
echo "Checking for image: ${IMAGE}"
# Try to pull the manifest (without downloading the image)
if docker manifest inspect "${IMAGE}" > /dev/null 2>&1; then
echo "exists=true" >> $GITHUB_OUTPUT
echo "✅ Image already exists in registry, skipping build"
else
echo "exists=false" >> $GITHUB_OUTPUT
echo "📦 Image not found, will build"
fi
env:
DOCKER_CLI_EXPERIMENTAL: enabled
# Job 1: Build and push multi-arch Nix image to GHCR
build-and-push-image:
name: Build and Push Test Image
needs: check-image
if: needs.check-image.outputs.image-exists != 'true'
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
strategy:
matrix:
include:
- arch: x86_64-linux
platform: linux/amd64
- arch: aarch64-linux
platform: linux/arm64
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up QEMU for multi-arch builds
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Install Nix
uses: cachix/install-nix-action@v27
with:
nix_path: nixpkgs=channel:nixos-unstable
extra_nix_config: |
experimental-features = nix-command flakes
max-jobs = auto
cores = 0
extra-platforms = aarch64-linux
- name: Setup magic-nix-cache for ultra-fast builds
uses: DeterminateSystems/magic-nix-cache-action@v7
- name: Setup Cachix for Nix packages
uses: cachix/cachix-action@v15
with:
name: nix-community
skipPush: true
- name: Cache Nix store paths
uses: actions/cache@v4
with:
path: |
/nix/store
~/.cache/nix
key: ${{ runner.os }}-${{ matrix.arch }}-nix-${{ hashFiles('tests/nix/flake.lock') }}
restore-keys: |
${{ runner.os }}-${{ matrix.arch }}-nix-
- name: Build test-runner image with Nix for ${{ matrix.arch }}
run: |
cd tests/nix
# Build for specific architecture using Nix cross-compilation
nix build .#packages.${{ matrix.arch }}.dockerImage --out-link result --print-build-logs
echo "Image built successfully for ${{ matrix.arch }}"
- name: Log in to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Load and push arch-specific image
run: |
docker load < tests/nix/result
ARCH_TAG="${{ needs.check-image.outputs.image-tag }}-${{ matrix.arch }}"
docker tag pg_doorman-test-env:latest ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${ARCH_TAG}
docker push ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${ARCH_TAG}
echo "Pushed: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${ARCH_TAG}"
# Job 2: Create multi-arch manifest
create-manifest:
name: Create Multi-Arch Manifest
needs: [ check-image, build-and-push-image ]
if: needs.check-image.outputs.image-exists != 'true'
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Log in to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Create and push multi-arch manifest
run: |
IMAGE_TAG="${{ needs.check-image.outputs.image-tag }}"
BASE_IMAGE="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}"
# Create manifest combining both architectures
docker manifest create ${BASE_IMAGE}:${IMAGE_TAG} \
${BASE_IMAGE}:${IMAGE_TAG}-x86_64-linux \
${BASE_IMAGE}:${IMAGE_TAG}-aarch64-linux
docker manifest annotate ${BASE_IMAGE}:${IMAGE_TAG} \
${BASE_IMAGE}:${IMAGE_TAG}-x86_64-linux --os linux --arch amd64
docker manifest annotate ${BASE_IMAGE}:${IMAGE_TAG} \
${BASE_IMAGE}:${IMAGE_TAG}-aarch64-linux --os linux --arch arm64
docker manifest push ${BASE_IMAGE}:${IMAGE_TAG}
# Also tag as latest
docker manifest create ${BASE_IMAGE}:latest \
${BASE_IMAGE}:${IMAGE_TAG}-x86_64-linux \
${BASE_IMAGE}:${IMAGE_TAG}-aarch64-linux
docker manifest annotate ${BASE_IMAGE}:latest \
${BASE_IMAGE}:${IMAGE_TAG}-x86_64-linux --os linux --arch amd64
docker manifest annotate ${BASE_IMAGE}:latest \
${BASE_IMAGE}:${IMAGE_TAG}-aarch64-linux --os linux --arch arm64
docker manifest push ${BASE_IMAGE}:latest
echo "✅ Multi-arch manifest created and pushed"
echo "Image: ${BASE_IMAGE}:${IMAGE_TAG}" >> $GITHUB_STEP_SUMMARY
echo "Architectures: linux/amd64, linux/arm64" >> $GITHUB_STEP_SUMMARY
# Job 3: Prepare image tag for test jobs (waits for build if needed, or proceeds if image exists)
prepare-tests:
name: Prepare Test Image
needs: [ check-image, create-manifest ]
# Run when check-image succeeded AND either:
# - image already exists in registry (create-manifest was skipped), OR
# - image was just built (create-manifest succeeded)
if: >-
always() &&
needs.check-image.result == 'success' &&
(needs.check-image.outputs.image-exists == 'true' || needs.create-manifest.result == 'success')
runs-on: ubuntu-latest
outputs:
image-tag: ${{ needs.check-image.outputs.image-tag }}
steps:
- name: Output image tag for tests
run: |
if [ "${{ needs.check-image.outputs.image-exists }}" == "true" ]; then
echo "✅ Using cached image: ${{ needs.check-image.outputs.image-tag }}"
else
echo "✅ Using freshly built image: ${{ needs.check-image.outputs.image-tag }}"
fi
# Job 4: Run BDD tests with Go client
go-tests:
name: Go BDD Tests
needs: prepare-tests
if: always() && needs.prepare-tests.result == 'success'
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Pull test image from GHCR
run: |
docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.prepare-tests.outputs.image-tag }}
- name: Run BDD tests for Go
uses: nick-fields/retry@v3
with:
timeout_minutes: 30
max_attempts: 2
command: |
docker run --rm \
-v ${{ github.workspace }}:/workspace \
-w /workspace \
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.prepare-tests.outputs.image-tag }} \
cargo test --test bdd -- --tags @go
# Job 5: Run BDD tests with Python client
python-tests:
name: Python BDD Tests
needs: prepare-tests
if: always() && needs.prepare-tests.result == 'success'
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Pull test image from GHCR
run: |
docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.prepare-tests.outputs.image-tag }}
- name: Run BDD tests for Python
uses: nick-fields/retry@v3
with:
timeout_minutes: 30
max_attempts: 2
command: |
docker run --rm \
-v ${{ github.workspace }}:/workspace \
-w /workspace \
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.prepare-tests.outputs.image-tag }} \
cargo test --test bdd -- --tags @python
# Job 6: Run BDD tests with Node.js client
nodejs-tests:
name: Node.js BDD Tests
needs: prepare-tests
if: always() && needs.prepare-tests.result == 'success'
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Pull test image from GHCR
run: |
docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.prepare-tests.outputs.image-tag }}
- name: Run BDD tests for Node.js
uses: nick-fields/retry@v3
with:
timeout_minutes: 30
max_attempts: 2
command: |
docker run --rm \
-v ${{ github.workspace }}:/workspace \
-w /workspace \
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.prepare-tests.outputs.image-tag }} \
cargo test --test bdd -- --tags @nodejs
# Job 7: Run BDD tests with .NET client
dotnet-tests:
name: .NET BDD Tests
needs: prepare-tests
if: always() && needs.prepare-tests.result == 'success'
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Pull test image from GHCR
run: |
docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.prepare-tests.outputs.image-tag }}
- name: Run BDD tests for .NET
uses: nick-fields/retry@v3
with:
timeout_minutes: 30
max_attempts: 2
command: |
docker run --rm \
-v ${{ github.workspace }}:/workspace \
-w /workspace \
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.prepare-tests.outputs.image-tag }} \
cargo test --test bdd -- --tags @dotnet
# Job 8: Run BDD tests with Java client
java-tests:
name: Java BDD Tests
needs: prepare-tests
if: always() && needs.prepare-tests.result == 'success'
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Pull test image from GHCR
run: |
docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.prepare-tests.outputs.image-tag }}
- name: Run BDD tests for Java
uses: nick-fields/retry@v3
with:
timeout_minutes: 30
max_attempts: 2
command: |
docker run --rm \
-v ${{ github.workspace }}:/workspace \
-w /workspace \
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.prepare-tests.outputs.image-tag }} \
cargo test --test bdd -- --tags @java
# Job 9: Run BDD tests with Rust client (split into 3 parallel jobs)
rust-tests-1:
name: Rust BDD Tests (Part 1)
needs: prepare-tests
if: always() && needs.prepare-tests.result == 'success'
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Pull test image from GHCR
run: |
docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.prepare-tests.outputs.image-tag }}
- name: Run BDD tests for Rust (Part 1)
uses: nick-fields/retry@v3
with:
timeout_minutes: 30
max_attempts: 2
command: |
docker run --rm \
-v ${{ github.workspace }}:/workspace \
-w /workspace \
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.prepare-tests.outputs.image-tag }} \
cargo test --test bdd -- --tags @rust-1
# Job 8b: Run BDD tests with Rust client (Part 2)
rust-tests-2:
name: Rust BDD Tests (Part 2)
needs: prepare-tests
if: always() && needs.prepare-tests.result == 'success'
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Pull test image from GHCR
run: |
docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.prepare-tests.outputs.image-tag }}
- name: Run BDD tests for Rust (Part 2)
uses: nick-fields/retry@v3
with:
timeout_minutes: 30
max_attempts: 2
command: |
docker run --rm \
-v ${{ github.workspace }}:/workspace \
-w /workspace \
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.prepare-tests.outputs.image-tag }} \
cargo test --test bdd -- --tags @rust-2
# Job 8c: Run BDD tests with Rust client (Part 3)
rust-tests-3:
name: Rust BDD Tests (Part 3)
needs: prepare-tests
if: always() && needs.prepare-tests.result == 'success'
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Pull test image from GHCR
run: |
docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.prepare-tests.outputs.image-tag }}
- name: Run BDD tests for Rust (Part 3)
uses: nick-fields/retry@v3
with:
timeout_minutes: 30
max_attempts: 2
command: |
docker run --rm \
-v ${{ github.workspace }}:/workspace \
-w /workspace \
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.prepare-tests.outputs.image-tag }} \
cargo test --test bdd -- --tags @rust-3
# Job 8d: Run BDD tests with Rust client (Part 4) — sleep-heavy pool lifecycle tests
rust-tests-4:
name: Rust BDD Tests (Part 4)
needs: prepare-tests
if: always() && needs.prepare-tests.result == 'success'
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Pull test image from GHCR
run: |
docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.prepare-tests.outputs.image-tag }}
- name: Run BDD tests for Rust (Part 4)
uses: nick-fields/retry@v3
with:
timeout_minutes: 30
max_attempts: 2
command: |
docker run --rm \
-v ${{ github.workspace }}:/workspace \
-w /workspace \
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.prepare-tests.outputs.image-tag }} \
cargo test --test bdd -- --tags @rust-4
# Job 9: Run Binary Upgrade Graceful Shutdown BDD tests
binary-upgrade-grac-shutdown-tests:
name: Binary Upgrade Graceful Shutdown BDD Tests
needs: prepare-tests
if: always() && needs.prepare-tests.result == 'success'
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Pull test image from GHCR
run: |
docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.prepare-tests.outputs.image-tag }}
- name: Run BDD tests for Binary Upgrade Graceful Shutdown
uses: nick-fields/retry@v3
with:
timeout_minutes: 30
max_attempts: 2
command: |
docker run --rm \
-v ${{ github.workspace }}:/workspace \
-w /workspace \
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.prepare-tests.outputs.image-tag }} \
cargo test --test bdd -- --tags @binary-upgrade-grac-shutdown
# Job 10: Run Fuzz BDD tests (no retries - fuzz tests should not be flaky)
fuzz-tests:
name: Fuzz BDD Tests
needs: prepare-tests
if: always() && needs.prepare-tests.result == 'success'
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Pull test image from GHCR
run: |
docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.prepare-tests.outputs.image-tag }}
- name: Run Fuzz BDD tests
run: |
docker run --rm \
-v ${{ github.workspace }}:/workspace \
-w /workspace \
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.prepare-tests.outputs.image-tag }} \
cargo test --test bdd -- --tags @fuzz
# Job: Run Generate BDD tests
generate-tests:
name: Generate BDD Tests
needs: prepare-tests
if: always() && needs.prepare-tests.result == 'success'
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Pull test image from GHCR
run: |
docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.prepare-tests.outputs.image-tag }}
- name: Run Generate BDD tests
uses: nick-fields/retry@v3
with:
timeout_minutes: 30
max_attempts: 2
command: |
docker run --rm \
-v ${{ github.workspace }}:/workspace \
-w /workspace \
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.prepare-tests.outputs.image-tag }} \
cargo test --test bdd -- --tags @generate
# Job 10: Run BDD tests for patroni_proxy
patroni-proxy-tests:
name: Patroni Proxy BDD Tests
needs: prepare-tests
if: always() && needs.prepare-tests.result == 'success'
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Pull test image from GHCR
run: |
docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.prepare-tests.outputs.image-tag }}
- name: Run BDD tests for patroni_proxy
uses: nick-fields/retry@v3
with:
timeout_minutes: 30
max_attempts: 2
command: |
docker run --rm \
-v ${{ github.workspace }}:/workspace \
-w /workspace \
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.prepare-tests.outputs.image-tag }} \
cargo test --test patroni_proxy_bdd
# Job 11: Run Rollback BDD tests
rollback-tests:
name: Rollback BDD Tests
needs: prepare-tests
if: always() && needs.prepare-tests.result == 'success'
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Pull test image from GHCR
run: |
docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.prepare-tests.outputs.image-tag }}
- name: Run Rollback BDD tests
uses: nick-fields/retry@v3
with:
timeout_minutes: 30
max_attempts: 2
command: |
docker run --rm \
-v ${{ github.workspace }}:/workspace \
-w /workspace \
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.prepare-tests.outputs.image-tag }} \
cargo test --test bdd -- --tags @rollback
# Job 12: Run Auth Query BDD tests
auth-query-tests:
name: Auth Query BDD Tests
needs: prepare-tests
if: always() && needs.prepare-tests.result == 'success'
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Pull test image from GHCR
run: |
docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.prepare-tests.outputs.image-tag }}
- name: Run Auth Query BDD tests
uses: nick-fields/retry@v3
with:
timeout_minutes: 30
max_attempts: 2
command: |
docker run --rm \
-v ${{ github.workspace }}:/workspace \
-w /workspace \
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.prepare-tests.outputs.image-tag }} \
cargo test --test bdd -- --tags @auth-query
# Job 13: Run Static Passthrough BDD tests
static-passthrough-tests:
name: Static Passthrough BDD Tests
needs: prepare-tests
if: always() && needs.prepare-tests.result == 'success'
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Pull test image from GHCR
run: |
docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.prepare-tests.outputs.image-tag }}
- name: Run Static Passthrough BDD tests
uses: nick-fields/retry@v3
with:
timeout_minutes: 30
max_attempts: 2
command: |
docker run --rm \
-v ${{ github.workspace }}:/workspace \
-w /workspace \
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.prepare-tests.outputs.image-tag }} \
cargo test --test bdd -- --tags @static-passthrough