diff --git a/.github/workflows/test-bsd.yml b/.github/workflows/test-bsd.yml index e82b92820..e3408accf 100644 --- a/.github/workflows/test-bsd.yml +++ b/.github/workflows/test-bsd.yml @@ -1,5 +1,5 @@ -# Selected unit tests on BSD-derived operating systems. MacOS runs directly on the runner while FreeBSD runs in a VM hosted on a -# Linux runner. +# Selected unit tests and the smoke test on BSD-derived operating systems. MacOS runs directly on the runner while FreeBSD runs in a +# VM hosted on a Linux runner. name: bsd on: workflow_call @@ -9,7 +9,7 @@ permissions: contents: read jobs: - # Selected unit tests on MacOS + # Selected unit tests and the smoke test on MacOS macos: runs-on: macos-26 env: @@ -42,6 +42,25 @@ jobs: brew install -q pkg-config openssl@3 libpq libxml2 libyaml meson + # The PostgreSQL versions supported by pgBackRest, oldest first, read from the generated header so the list never needs to + # be updated here + pgSupport=$(sed -n 's/^#define PG_VERSION_[0-9_]*_Z *"\([0-9.]*\)".*/postgresql@\1/p' \ + ${GITHUB_WORKSPACE?}/src/postgres/version.auto.h) + + # The PostgreSQL formulae that are safe to test against, i.e. keg-only and neither deprecated nor disabled. The binaries + # in a formula that is not keg-only load libpq from the linked prefix rather than the keg and fail unless the formula is + # linked, and a deprecated formula is eventually disabled and can no longer be installed. Homebrew packages only released + # versions so betas never appear here. + pgSafe=$(brew info --json=v2 --formula $(brew search --formula '/^postgresql@[0-9.]*$/' | grep '^postgresql@') | \ + jq -r '.formulae[] | select(.keg_only and (.deprecated | not) and (.disabled | not)) | .name') + + # Install the oldest and newest version that is both supported and safe. The order comes from the supported list since + # these do not sort naturally, e.g. postgresql@9.6 is not greater than postgresql@10. + pgInstall=$(echo "${pgSupport}" | grep -xF "${pgSafe}") + echo "postgresql available: $(echo ${pgInstall})" + + brew install -q $(echo "${pgInstall}" | head -1) $(echo "${pgInstall}" | tail -1) + - name: Debug run: | pwd @@ -52,7 +71,16 @@ jobs: - name: Run Test run: cd .. && ${GITHUB_WORKSPACE?}/test/test.pl --vm-max=2 --no-coverage --no-valgrind --module=command --test=backup --test=info --test=archive-push - # Selected unit tests on FreeBSD + # The integration tests cannot run here because there are no containers, but the smoke test drives a backup/restore cycle + # against each PostgreSQL installed above, which covers the basics + - name: Run Smoke Test + run: | + cd .. + meson setup build ${GITHUB_WORKSPACE?} + ninja -C build src/pgbackrest + meson test -C build --suite smoke -v + + # Selected unit tests and the smoke test on FreeBSD freebsd: runs-on: ubuntu-24.04 strategy: @@ -60,9 +88,15 @@ jobs: fail-fast: false matrix: + # The PostgreSQL ports all install into the same prefix and conflict with each other, so only one version can be installed + # at a time. Test the oldest supported version on the oldest FreeBSD and the newest on the newest FreeBSD, which covers both + # without doubling the number of jobs. The versions are discovered during install rather than named here. os: - version: '14.4' + pg: oldest + - version: '15.1' + pg: newest steps: - uses: actions/checkout@v6 @@ -75,9 +109,45 @@ jobs: # The custom shell runs the commands in the VM started above. Do not set this as a job default since the checkout step must # run on the host. - - name: Run Test + - name: Install shell: cpa.sh {0} run: | uname -a - sudo pkg update && sudo pkg upgrade -y libiconv && sudo pkg install -y bash git postgresql-libpqxx pkgconf libxml2 gmake perl5 libyaml p5-YAML-LibYAML rsync meson - cd .. && perl ${GITHUB_WORKSPACE?}/test/test.pl --vm-max=2 --no-coverage --no-valgrind --module=command --test=backup --test=info --test=archive-push + sudo pkg update && sudo pkg upgrade -y libiconv + + # The PostgreSQL versions supported by pgBackRest, oldest first, read from the generated header so the list never needs to + # be updated here. FreeBSD leaves the dot out of the package name, e.g. 9.6 is postgresql96-server. + pgSupport=$(sed -n 's/^#define PG_VERSION_[0-9_]*_Z *"\([0-9.]*\)".*/\1/p' \ + ${GITHUB_WORKSPACE?}/src/postgres/version.auto.h | tr -d . | sed 's/^/postgresql/;s/$/-server/') + + # The versions that are both supported and available. FreeBSD removes a version once it is end-of-life and does not + # package betas, so everything available is safe to test. The order comes from the supported list since these do not sort + # naturally, e.g. postgresql96-server is not greater than postgresql10-server. + pgAvail=$(echo "${pgSupport}" | grep -xF "$(pkg rquery -x '%n' '^postgresql[0-9]*-server$')") + echo "postgresql available: $(echo ${pgAvail})" + + # Only one version can be installed at a time so the matrix selects either the oldest or the newest + if [ ${{matrix.os.pg}} = oldest ]; then + pgServer=$(echo "${pgAvail}" | head -1) + else + pgServer=$(echo "${pgAvail}" | tail -1) + fi + + # postgresql*-client provides the libpq to build against and postgresql*-server provides the tooling the smoke test needs + # to create a cluster + sudo pkg install -y bash git ${pgServer%-server}-client ${pgServer} pkgconf libxml2 gmake perl5 libyaml \ + p5-YAML-LibYAML rsync meson + + - name: Run Test + shell: cpa.sh {0} + run: cd .. && perl ${GITHUB_WORKSPACE?}/test/test.pl --vm-max=2 --no-coverage --no-valgrind --module=command --test=backup --test=info --test=archive-push + + # The integration tests cannot run here because there are no containers, but the smoke test drives a backup/restore cycle + # against the PostgreSQL installed above, which covers the basics + - name: Run Smoke Test + shell: cpa.sh {0} + run: | + cd .. + meson setup build ${GITHUB_WORKSPACE?} + ninja -C build src/pgbackrest + meson test -C build --suite smoke -v diff --git a/test/smoke.py b/test/smoke.py index 22d563b9e..7a30231b0 100755 --- a/test/smoke.py +++ b/test/smoke.py @@ -3,8 +3,7 @@ # pgBackRest Smoke Test # # A minimal, dependency-free (Python standard library only) sanity check that a built pgbackrest binary actually works. It finds -# every PostgreSQL installation on the system, using the same path list as the test harness (test/src/harness/host.c), and drives -# pgbackrest through a full backup/restore cycle against each version found: +# every PostgreSQL installation on the system and drives pgbackrest through a full backup/restore cycle against each version found: # # initdb -> configure -> stanza-create -> check -> full backup -> load data -> incr backup -> wipe -> restore -> verify # @@ -127,12 +126,16 @@ class Runner: #################################################################################################################################### # Discover PostgreSQL installations #################################################################################################################################### -# Candidate bin directories, mirroring the list in test/src/harness/host.c +# Candidate bin directories. This is a superset of the list in test/src/harness/host.c since the smoke test also runs where the +# integration tests cannot, i.e. MacOS and FreeBSD. def pg_bin_candidates(extra_dirs): candidates = [] candidates += sorted(glob.glob("/usr/lib/postgresql/*/bin")) # Debian candidates += sorted(glob.glob("/usr/pgsql-*/bin")) # RHEL (PGDG) candidates += sorted(glob.glob("/usr/libexec/postgresql*")) # Alpine + candidates += sorted(glob.glob("/opt/homebrew/opt/postgresql@*/bin")) # MacOS (Homebrew on ARM) + candidates += sorted(glob.glob("/usr/local/opt/postgresql@*/bin")) # MacOS (Homebrew on Intel) + candidates += ["/usr/local/bin"] # FreeBSD candidates += ["/usr/bin"] # Native (e.g. RHEL application stream) candidates += list(extra_dirs)