Compare commits

..

11 Commits

Author SHA1 Message Date
Marco Nenciarini
2518deff63 test: tighten WAL restore assertions and fix a misleading comment
Assert the actual exit code on the end-of-wal-stream fast-fail path
instead of just HaveOccurred(), which would pass for any error. Also
correct a comment claiming ExecuteInContainer folds command output
into the returned error; it only carries the exit code, so forging a
WAL segment fails with no indication of the underlying aws CLI error.
Drop an unnecessary var declaration and note the real bound on the
forged segment numbering.

Signed-off-by: Marco Nenciarini <marco.nenciarini@enterprisedb.com>
2026-07-09 11:00:33 +02:00
Marco Nenciarini
9b2097f2b6 test: pin aws-cli image by digest
Every other e2e fixture pins its image by digest with a companion
Version comment; the s3-client image was the only one still pinned by
a mutable tag.

Note this doesn't yet restore renovate parity with those fixtures:
renovate.json5's ignorePaths still excludes anything under
test/e2e/internal/tests/**, which is where every Ginkgo test package in
this suite (including this one) lives, so the digest won't be bumped
automatically until that gap is closed separately. The digest pin is
still worth having on its own for reproducibility.

Signed-off-by: Marco Nenciarini <marco.nenciarini@enterprisedb.com>
2026-07-09 11:00:33 +02:00
Niccolò Fei
d2a87965cf test: remove redundant primary/standby picking logic
If pod-1 is not the primary we'd fail anyway because a timeline
bump would make all assertions about the walLogDir fail.
Also there's no reason why there should have been a switchover,
so we should not hide a failure if that happens.

Signed-off-by: Niccolò Fei <niccolo.fei@enterprisedb.com>
2026-07-09 11:00:33 +02:00
Niccolò Fei
aeb0aa169c chore: bump aws-cli to 2.35.11
Signed-off-by: Niccolò Fei <niccolo.fei@enterprisedb.com>
2026-07-09 11:00:33 +02:00
Armando Ruocco
41238d7df5 test(e2e): cover parallel WAL restore via the plugin
Recreate the parallel WAL-restore coverage in the plugin repo: a 2-instance
cluster archiving to minio with wal.maxParallel=3, forged WAL segments on the
object store, and assertions on the plugin's prefetch/spool/end-of-wal-stream
state machine driven through `/controller/manager wal-restore` on the standby.

Part of cloudnative-pg/cloudnative-pg#10954.

Signed-off-by: Armando Ruocco <armando.ruocco@enterprisedb.com>
2026-07-09 11:00:33 +02:00
Marco Nenciarini
b0e4538147
chore(renovate): stop ignoring test/e2e/internal/tests/** (#996)
ignorePaths still had '**/tests/**' left over from the recommended
preset, even though a comment right above documents removing
'**/test/**' specifically to let renovate scan test/e2e for emulator
image dependencies. Every e2e Ginkgo package lives under
test/e2e/internal/tests/**, so the plural pattern was silently excluding
all of them; any image pinned by digest in those packages (e.g. minio,
aws-cli) was never going to get a bump PR.

No other tracked path in the repo matches '**/tests/**' once
node_modules is excluded by its own rule, so this narrows nothing else.

Signed-off-by: Marco Nenciarini <marco.nenciarini@enterprisedb.com>
2026-07-09 11:00:04 +02:00
Niccolò Fei
bf955430cb
fix: reduce startupProbe periodSeconds without losing failure tolerance (#992)
The startup probe for the injected plugin-barman-cloud sidecar
previously left `periodSeconds` unset, so the API server defaulted it to
10s. Because the sidecar is a native init container that gates the main
postgres container on reaching `Started`, this added roughly one full
period to every pod's startup, even though the probe itself (a local
unix-socket health check) normally succeeds in milliseconds.

`periodSeconds` is now 1s, so the probe reports success almost
immediately in the common case. To avoid trading away failure tolerance
for that faster common case, `failureThreshold` is raised to 30 and
`timeoutSeconds` is lowered to 5s: a unix-socket call essentially never
times out under mere load, so hitting the timeout means the sidecar is
genuinely unresponsive rather than just slow, and it's fine to give that
rare case more attempts before restarting the container.

Closes #991

Signed-off-by: Niccolò Fei <niccolo.fei@enterprisedb.com>
Signed-off-by: Marco Nenciarini <marco.nenciarini@enterprisedb.com>
Co-authored-by: Marco Nenciarini <marco.nenciarini@enterprisedb.com>
2026-07-09 10:36:09 +02:00
renovate[bot]
3cc6a882c8
chore(deps): refresh pip-compile outputs (#977)
This PR contains the following updates:

| Update | Change |
|---|---|
| lockFileMaintenance | All locks refreshed |

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yMzEuMSIsInVwZGF0ZWRJblZlciI6IjQzLjI0Mi4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJhdXRvbWF0ZWQiLCJuby1pc3N1ZSJdfQ==-->

Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-06-26 12:18:39 +02:00
renovate[bot]
f4fa18e592
chore(deps): update dependency cert-manager/cert-manager to v1.20.3 (#985)
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
|
[cert-manager/cert-manager](https://redirect.github.com/cert-manager/cert-manager)
| patch | `v1.20.2` → `v1.20.3` |

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yNDIuMiIsInVwZGF0ZWRJblZlciI6IjQzLjI0Mi4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJhdXRvbWF0ZWQiLCJuby1pc3N1ZSJdfQ==-->

Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-06-26 12:18:05 +02:00
renovate[bot]
26de2dadaf
chore(deps): update all cloudnative-pg daggerverse dependencies to 7a53f0b (#984)
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| commitlint | digest | `679d505` → `7a53f0b` |
| controller-gen | digest | `679d505` → `7a53f0b` |
| crd-gen-refs | digest | `679d505` → `7a53f0b` |
| spellcheck | digest | `679d505` → `7a53f0b` |
| uncommitted | digest | `679d505` → `7a53f0b` |

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yNDIuMiIsInVwZGF0ZWRJblZlciI6IjQzLjI0Mi4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJhdXRvbWF0ZWQiLCJuby1pc3N1ZSJdfQ==-->

Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-06-26 12:17:30 +02:00
Marco Nenciarini
f3b4934faf
chore(deps): drop setuptools dependency (#983)
Barman 3.19 dropped its runtime dependency on setuptools, so we no
longer need to pin it in the sidecar requirements or install it in the
image build. A Python 3.13 venv no longer seeds setuptools by default,
so removing it from the pip upgrade keeps it out of the runtime image
entirely.

Signed-off-by: Marco Nenciarini <marco.nenciarini@enterprisedb.com>
2026-06-26 11:07:15 +02:00
9 changed files with 38 additions and 39 deletions

View File

@ -46,7 +46,7 @@ tasks:
- wordlist-ordered - wordlist-ordered
env: env:
# renovate: datasource=git-refs depName=spellcheck lookupName=https://github.com/cloudnative-pg/daggerverse currentValue=main # renovate: datasource=git-refs depName=spellcheck lookupName=https://github.com/cloudnative-pg/daggerverse currentValue=main
DAGGER_SPELLCHECK_SHA: 679d5056358d3cd838ec226333decff673602937 DAGGER_SPELLCHECK_SHA: 7a53f0b7f36c786389a6f72714d5875b9a63e9c1
cmds: cmds:
- > - >
GITHUB_REF= dagger -s call -m github.com/cloudnative-pg/daggerverse/spellcheck@${DAGGER_SPELLCHECK_SHA} GITHUB_REF= dagger -s call -m github.com/cloudnative-pg/daggerverse/spellcheck@${DAGGER_SPELLCHECK_SHA}
@ -60,7 +60,7 @@ tasks:
desc: Check for conventional commits desc: Check for conventional commits
env: env:
# renovate: datasource=git-refs depName=commitlint lookupName=https://github.com/cloudnative-pg/daggerverse currentValue=main # renovate: datasource=git-refs depName=commitlint lookupName=https://github.com/cloudnative-pg/daggerverse currentValue=main
DAGGER_COMMITLINT_SHA: 679d5056358d3cd838ec226333decff673602937 DAGGER_COMMITLINT_SHA: 7a53f0b7f36c786389a6f72714d5875b9a63e9c1
cmds: cmds:
- > - >
GITHUB_REF= dagger -s call -m github.com/cloudnative-pg/daggerverse/commitlint@${DAGGER_COMMITLINT_SHA} GITHUB_REF= dagger -s call -m github.com/cloudnative-pg/daggerverse/commitlint@${DAGGER_COMMITLINT_SHA}
@ -74,7 +74,7 @@ tasks:
- wordlist-ordered - wordlist-ordered
env: env:
# renovate: datasource=git-refs depName=uncommitted lookupName=https://github.com/cloudnative-pg/daggerverse currentValue=main # renovate: datasource=git-refs depName=uncommitted lookupName=https://github.com/cloudnative-pg/daggerverse currentValue=main
DAGGER_UNCOMMITTED_SHA: 679d5056358d3cd838ec226333decff673602937 DAGGER_UNCOMMITTED_SHA: 7a53f0b7f36c786389a6f72714d5875b9a63e9c1
cmds: cmds:
- GITHUB_REF= dagger -s call -m github.com/cloudnative-pg/daggerverse/uncommitted@${DAGGER_UNCOMMITTED_SHA} check-uncommitted --source . stdout - GITHUB_REF= dagger -s call -m github.com/cloudnative-pg/daggerverse/uncommitted@${DAGGER_UNCOMMITTED_SHA} check-uncommitted --source . stdout
sources: sources:
@ -86,7 +86,7 @@ tasks:
- controller-gen - controller-gen
env: env:
# renovate: datasource=git-refs depName=crd-gen-refs lookupName=https://github.com/cloudnative-pg/daggerverse currentValue=main # renovate: datasource=git-refs depName=crd-gen-refs lookupName=https://github.com/cloudnative-pg/daggerverse currentValue=main
DAGGER_CRDGENREF_SHA: 679d5056358d3cd838ec226333decff673602937 DAGGER_CRDGENREF_SHA: 7a53f0b7f36c786389a6f72714d5875b9a63e9c1
# renovate: datasource=go depName=github.com/elastic/crd-ref-docs # renovate: datasource=go depName=github.com/elastic/crd-ref-docs
CRDREFDOCS_VERSION: v0.3.0 CRDREFDOCS_VERSION: v0.3.0
cmds: cmds:
@ -381,7 +381,7 @@ tasks:
run: once run: once
env: env:
# renovate: datasource=git-refs depName=controller-gen lookupName=https://github.com/cloudnative-pg/daggerverse currentValue=main # renovate: datasource=git-refs depName=controller-gen lookupName=https://github.com/cloudnative-pg/daggerverse currentValue=main
DAGGER_CONTROLLER_GEN_SHA: 679d5056358d3cd838ec226333decff673602937 DAGGER_CONTROLLER_GEN_SHA: 7a53f0b7f36c786389a6f72714d5875b9a63e9c1
cmds: cmds:
- > - >
GITHUB_REF= dagger -s call -m github.com/cloudnative-pg/daggerverse/controller-gen@${DAGGER_CONTROLLER_GEN_SHA} GITHUB_REF= dagger -s call -m github.com/cloudnative-pg/daggerverse/controller-gen@${DAGGER_CONTROLLER_GEN_SHA}

View File

@ -55,7 +55,7 @@ COPY containers/sidecar-requirements.txt .
# Create virtualenv and install dependencies # Create virtualenv and install dependencies
RUN python3 -m venv /venv && \ RUN python3 -m venv /venv && \
/venv/bin/pip install --upgrade pip setuptools wheel && \ /venv/bin/pip install --upgrade pip wheel && \
/venv/bin/pip install --no-cache-dir -r sidecar-requirements.txt /venv/bin/pip install --no-cache-dir -r sidecar-requirements.txt
# Download and extract runtime library packages and their dependencies # Download and extract runtime library packages and their dependencies

View File

@ -1,3 +1,2 @@
barman[azure,cloud,google,snappy,zstandard,lz4]==3.19.1 barman[azure,cloud,google,snappy,zstandard,lz4]==3.19.1
setuptools==82.0.1
zipp>=3.19.1 # not directly required, pinned by Snyk to avoid a vulnerability zipp>=3.19.1 # not directly required, pinned by Snyk to avoid a vulnerability

View File

@ -22,19 +22,19 @@ barman==3.19.1 \
--hash=sha256:0a6a9e1babf97687732d8b2a3eb79ea95d55246a5257b9433865cb6e755221c0 \ --hash=sha256:0a6a9e1babf97687732d8b2a3eb79ea95d55246a5257b9433865cb6e755221c0 \
--hash=sha256:2f71c4a1f1ba53f694cbdf838bb9906d8ba02b97d1fd3041196e8999bec7a1ee --hash=sha256:2f71c4a1f1ba53f694cbdf838bb9906d8ba02b97d1fd3041196e8999bec7a1ee
# via -r sidecar-requirements.in # via -r sidecar-requirements.in
boto3==1.43.30 \ boto3==1.43.36 \
--hash=sha256:6b1ee360f363a457f67a8f5702f522043d8a32d67a97c362ad12075d8b5b531e \ --hash=sha256:42942dde254673abcbc9e6e60017c88341a4f49d99d24e1f2e290fb38138c26f \
--hash=sha256:89e982463d94773136ccf69be77cccd54ff1ce351a6aadd1d3437fcb693681b5 --hash=sha256:587d7ee92a12e440ad12b0e7f11f3358f0c4d65b19f64726efc94aaf194aff28
# via barman # via barman
botocore==1.43.30 \ botocore==1.43.36 \
--hash=sha256:19ed560cb35ae43bf010d37da429a553c07063bf7efea0f2cb53be8a78d3e3d5 \ --hash=sha256:3c65fdc39ed01d8dfde1e961b34038aed03c459f8ddf80717a12ac006475e49d \
--hash=sha256:26b1dded84d89b396180916f56900bd2ab1c0d545a66d1d2c3eeb40f772935b2 --hash=sha256:4cae47d1b2d426316b85a0087d9e69e048f13bc003b5177d74639fe9dfd28205
# via # via
# boto3 # boto3
# s3transfer # s3transfer
certifi==2026.5.20 \ certifi==2026.6.17 \
--hash=sha256:3c52e209ba0a4ad7aebe60436a4ab349c39e1e602e8c134221e546902ad25897 \ --hash=sha256:024c88eeec92ca068db80f02b8b07c9cef7b9fe261d1d535abfd5abd6f6af432 \
--hash=sha256:69dea482ab64caa7b9f6aba1c6bf48bb6a5448d1c0f1b17ab42ad8c763a5344d --hash=sha256:2227dcbaafe0d2f59279d1762ddddc37783ed4354594f194ffc31d20f41fc3db
# via requests # via requests
cffi==2.0.0 \ cffi==2.0.0 \
--hash=sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb \ --hash=sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb \
@ -654,9 +654,9 @@ requests==2.34.2 \
# google-api-core # google-api-core
# google-cloud-storage # google-cloud-storage
# msal # msal
s3transfer==0.18.0 \ s3transfer==0.19.0 \
--hash=sha256:239c13b09e65ad0346e1be7348b8a202dcad44ac7ea7c6eb858fc881dce739b6 \ --hash=sha256:777cc2415536f1debadb5c2ef7779275d0fc0fe0e042411cdd6caebeb2685262 \
--hash=sha256:3760b8b7ec1315da54048b2d626276732bee4300d054d492d4e1d43e20d4ecbd --hash=sha256:ce436931687addc4c1712d52d40b32f53e88315723f107ffa20ba82b05a0f685
# via boto3 # via boto3
six==1.17.0 \ six==1.17.0 \
--hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \ --hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \
@ -780,9 +780,3 @@ zstandard==0.25.0 \
--hash=sha256:fd7a5004eb1980d3cefe26b2685bcb0b17989901a70a1040d1ac86f1d898c551 \ --hash=sha256:fd7a5004eb1980d3cefe26b2685bcb0b17989901a70a1040d1ac86f1d898c551 \
--hash=sha256:ffef5a74088f1e09947aecf91011136665152e0b4b359c42be3373897fb39b01 --hash=sha256:ffef5a74088f1e09947aecf91011136665152e0b4b359c42be3373897fb39b01
# via barman # via barman
# The following packages are considered to be unsafe in a requirements file:
setuptools==82.0.1 \
--hash=sha256:7d872682c5d01cfde07da7bccc7b65469d3dca203318515ada1de5eda35efbf9 \
--hash=sha256:a59e362652f08dcd477c78bb6e7bd9d80a7995bc73ce773050228a348ce2e5bb
# via -r sidecar-requirements.in

View File

@ -403,8 +403,9 @@ func reconcilePodSpec(
envs = append(envs, config.env...) envs = append(envs, config.env...)
baseProbe := &corev1.Probe{ baseProbe := &corev1.Probe{
FailureThreshold: 10, PeriodSeconds: 1,
TimeoutSeconds: 10, FailureThreshold: 30,
TimeoutSeconds: 5,
ProbeHandler: corev1.ProbeHandler{ ProbeHandler: corev1.ProbeHandler{
Exec: &corev1.ExecAction{ Exec: &corev1.ExecAction{
Command: []string{"/manager", "healthcheck", "unix"}, Command: []string{"/manager", "healthcheck", "unix"},

View File

@ -12,14 +12,14 @@
rebaseWhen: 'never', rebaseWhen: 'never',
prConcurrentLimit: 5, prConcurrentLimit: 5,
// Override default ignorePaths to scan test/e2e for emulator image dependencies // Override default ignorePaths to scan test/e2e for emulator image dependencies
// Removed: '**/test/**' // Removed: '**/test/**', '**/tests/**' (this repo's e2e Ginkgo packages live
// under test/e2e/internal/tests/**, which the plural pattern was excluding)
ignorePaths: [ ignorePaths: [
'**/node_modules/**', '**/node_modules/**',
'**/bower_components/**', '**/bower_components/**',
'**/vendor/**', '**/vendor/**',
'**/examples/**', '**/examples/**',
'**/__tests__/**', '**/__tests__/**',
'**/tests/**',
'**/__fixtures__/**', '**/__fixtures__/**',
], ],
lockFileMaintenance: { lockFileMaintenance: {

View File

@ -58,7 +58,7 @@ func WithIgnoreExistingResources(ignore bool) InstallOption {
// DefaultVersion is the default version of cert-manager to install. // DefaultVersion is the default version of cert-manager to install.
// //
// renovate: datasource=github-releases depName=cert-manager/cert-manager // renovate: datasource=github-releases depName=cert-manager/cert-manager
const DefaultVersion = "v1.20.2" const DefaultVersion = "v1.20.3"
// Install installs cert-manager using kubectl. // Install installs cert-manager using kubectl.
func Install(ctx context.Context, cl client.Client, opts ...InstallOption) error { func Install(ctx context.Context, cl client.Client, opts ...InstallOption) error {

View File

@ -121,7 +121,8 @@ func newS3ClientDeployment(namespace string) *appsv1.Deployment {
{ {
Name: s3ClientName, Name: s3ClientName,
// renovate: datasource=docker depName=amazon/aws-cli versioning=docker // renovate: datasource=docker depName=amazon/aws-cli versioning=docker
Image: "docker.io/amazon/aws-cli:2.35.11", // Version: 2.35.11
Image: "docker.io/amazon/aws-cli@sha256:749bfaf91d690b9a1768083822d620f96c19defdf9ca2dc227eb3695281fda5b",
Command: []string{"sleep", "infinity"}, Command: []string{"sleep", "infinity"},
Env: []corev1.EnvVar{ Env: []corev1.EnvVar{
{ {

View File

@ -21,6 +21,7 @@ package walrestore
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"strconv" "strconv"
"strings" "strings"
@ -30,6 +31,7 @@ import (
apitypes "k8s.io/apimachinery/pkg/types" apitypes "k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest" "k8s.io/client-go/rest"
executil "k8s.io/client-go/util/exec"
"sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client"
internalClient "github.com/cloudnative-pg/plugin-barman-cloud/test/e2e/internal/client" internalClient "github.com/cloudnative-pg/plugin-barman-cloud/test/e2e/internal/client"
@ -67,9 +69,8 @@ const (
) )
// walFile returns the name of the n-th forged WAL segment (segment 0xF0+n on // walFile returns the name of the n-th forged WAL segment (segment 0xF0+n on
// timeline 1, log 0). The high segment number keeps it out of the range an idle // timeline 1, log 0, for n <= 15). The high segment number keeps it out of the
// PostgreSQL would archive on its own. Hex formatting keeps the name a valid // range an idle PostgreSQL would archive on its own.
// 24-character segment for any small n.
func walFile(n int) string { func walFile(n int) string {
return fmt.Sprintf("0000000100000000%08X", 0xF0+n) return fmt.Sprintf("0000000100000000%08X", 0xF0+n)
} }
@ -199,8 +200,8 @@ var _ = Describe("Parallel WAL restore", func() {
"sh", "-c", "rm -f "+spoolDirectory+"/* 2>/dev/null; true") "sh", "-c", "rm -f "+spoolDirectory+"/* 2>/dev/null; true")
} }
forge := func(src, dst string) { forge := func(src, dst string) {
// ExecuteInContainer folds a non-zero exit (and its output) into the // ExecuteInContainer drops stdout/stderr on a non-zero exit, so on
// returned error, so we surface that rather than the empty stderr. // failure this only reports the exit code, not the aws CLI's error text.
_, _, err := execInPod(ctx, clientSet, cfg, ns, s3Client, s3ClientName, _, _, err := execInPod(ctx, clientSet, cfg, ns, s3Client, s3ClientName,
"aws", "s3", "cp", walObjectURI(src), walObjectURI(dst)) "aws", "s3", "cp", walObjectURI(src), walObjectURI(dst))
Expect(err).NotTo(HaveOccurred(), "forging %s -> %s", src, dst) Expect(err).NotTo(HaveOccurred(), "forging %s -> %s", src, dst)
@ -211,7 +212,6 @@ var _ = Describe("Parallel WAL restore", func() {
return err == nil && strings.TrimSpace(out) != "" return err == nil && strings.TrimSpace(out) != ""
} }
var latestWAL string
By("archiving a real WAL on the primary and learning its name") By("archiving a real WAL on the primary and learning its name")
_, _, err := execInPod(ctx, clientSet, cfg, ns, primary, postgresContainer, _, _, err := execInPod(ctx, clientSet, cfg, ns, primary, postgresContainer,
"psql", "-tAc", "CHECKPOINT") "psql", "-tAc", "CHECKPOINT")
@ -219,7 +219,7 @@ var _ = Describe("Parallel WAL restore", func() {
out, _, err := execInPod(ctx, clientSet, cfg, ns, primary, postgresContainer, out, _, err := execInPod(ctx, clientSet, cfg, ns, primary, postgresContainer,
"psql", "-tAc", "SELECT pg_walfile_name(pg_switch_wal())") "psql", "-tAc", "SELECT pg_walfile_name(pg_switch_wal())")
Expect(err).NotTo(HaveOccurred(), "switching WAL on the primary failed") Expect(err).NotTo(HaveOccurred(), "switching WAL on the primary failed")
latestWAL = strings.TrimSpace(out) latestWAL := strings.TrimSpace(out)
Expect(latestWAL).To(HavePrefix(walLogDir), Expect(latestWAL).To(HavePrefix(walLogDir),
"the freshly bootstrapped cluster should still be on the first WAL log") "the freshly bootstrapped cluster should still be on the first WAL log")
@ -288,7 +288,11 @@ var _ = Describe("Parallel WAL restore", func() {
// #6 (first): flag is set, so the request fails fast (exit 1) and the // #6 (first): flag is set, so the request fails fast (exit 1) and the
// flag is consumed, leaving an empty spool. // flag is consumed, leaving an empty spool.
By("requesting WAL #6: fails fast on the end-of-wal-stream flag, spool cleared") By("requesting WAL #6: fails fast on the end-of-wal-stream flag, spool cleared")
Expect(restore(walFile(6))).To(HaveOccurred(), "exit code should be 1") restoreErr := restore(walFile(6))
var exitErr executil.CodeExitError
Expect(errors.As(restoreErr, &exitErr)).To(BeTrue(),
"expected a CodeExitError, got %T: %v", restoreErr, restoreErr)
Expect(exitErr.ExitStatus()).To(Equal(1), "exit code should be 1")
Eventually(func(g Gomega) { Eventually(func(g Gomega) {
g.Expect(existsIn(pgWalPath, walFile(6))).To(BeFalse(), "#6 not restored") g.Expect(existsIn(pgWalPath, walFile(6))).To(BeFalse(), "#6 not restored")
g.Expect(spoolSegments()).To(Equal(0), "no WAL segments in spool") g.Expect(spoolSegments()).To(Equal(0), "no WAL segments in spool")