import sys import pytest import testinfra import os import shutil import subprocess import textwrap from pathlib import Path THIS_COOKBOOK_DIR = Path(__file__).parent.parent COOKBOOKS_DIR = THIS_COOKBOOK_DIR.parent TOP_LEVEL_DIR = COOKBOOKS_DIR.parent THIS_COOKBOOK_NAME = THIS_COOKBOOK_DIR.name # Add directories to the path so we can import Python modules from the top level "tests" directory and current directory. sys.path.insert(0, str(Path(__file__).parent)) sys.path.insert(0, str(TOP_LEVEL_DIR / "tests")) import helpers # noqa: E402 from fcos_vm import FCOSVirtualMachine, ensure_fcos_ign # noqa: E402 # Major version of PostgreSQL to install by default on a fresh VM boot. PG_MAJOR_DEFAULT = 18 # PostgreSQL VM are kept for the duration of a test module, backed with a persistent Virtiofs directory. @pytest.fixture(scope="module") def fcos_vm( request, keep_vm: bool, test_ssh_key: Path, test_ssh_pubkey: str, virtiofs_dirs: list[tuple[Path, str]], tmp_path_factory: pytest.TempPathFactory, ) -> FCOSVirtualMachine: """Running CoreOS VM with Quadlets installed. With --keep-vm the VM is reused across runs: it is created only if it does not already exist and is never destroyed on teardown. """ module_name = request.module.__name__.split(".")[-1].replace("test_", "").replace("_", "-") vm = FCOSVirtualMachine( cookbook_name=THIS_COOKBOOK_NAME, instance_name=module_name, keep=keep_vm, virtiofs_dirs=virtiofs_dirs, ) if not (keep_vm and vm.exists()): fcos_ign = ensure_fcos_ign(THIS_COOKBOOK_DIR) vm.ignition.ignition_files.append(fcos_ign) vm.ignition.extra_files.update({ "/etc/quadlets/postgresql/config.env": ( textwrap.dedent(f""" # This file is generated by conftest.py for testing purposes. POSTGRES_USER=postgres POSTGRES_PASSWORD=postgres POSTGRES_DB=postgres POSTGRES_HOST_AUTH_METHOD=scram-sha-256 POSTGRES_INITDB_ARGS=--auth-host=scram-sha-256 POSTGRES_ARGS=-h 127.0.0.1 PGPORT=5432 PG_MAJOR={PG_MAJOR_DEFAULT} POSTGRES_BACKUP_RETENTION=7 """), 0, 0, 0o600, ), }) vm.ignition.ssh_key = test_ssh_pubkey vm.create() vm.wait_ssh(ssh_key=test_ssh_key, timeout=300) yield vm # <-- tests run here with access to the VM instance if not keep_vm: vm.destroy() """ Verify that the postgresql Quadlet correctly restores a database from a backup. """ class TestPostgresqlQuadletRestore(helpers.TestPostgresqlQuadlet): expected_pg_major = PG_MAJOR_DEFAULT def test_data_is_still_there_after_restore(self, fcos_host): """Data created before the restore must still be there after the restore.""" # Check that the old data is still there after the restore output = self._run_sql(fcos_host, "SELECT datname FROM pg_database WHERE datname = 'upgrade_path_db'") assert output == "upgrade_path_db", f"Unexpected output from SQL query: {output}" output = self._run_sql(fcos_host, "SELECT datname FROM pg_database WHERE datname = 'testdb'") assert output == "testdb", f"Unexpected output from SQL query: {output}" result = fcos_host.run( "podman exec postgresql-server psql -U test -d testdb --csv -t -c %s", "SELECT 1 AS probe" ) assert result.exit_status == 0, f"SQL query failed with exit code {result.exit_status}: {result.stderr}" # Check that the upgrade_path table contains the initial postgresql version (14) output = self._run_sql(fcos_host, "SELECT version FROM upgrade_path ORDER BY version ASC LIMIT 1", database="upgrade_path_db") assert output.startswith("14."), f"Unexpected output from SQL query: {output}"