diff --git a/nixos/tests/postgresql/anonymizer.nix b/nixos/tests/postgresql/anonymizer.nix index ec971aa710253..3a5f69086eaac 100644 --- a/nixos/tests/postgresql/anonymizer.nix +++ b/nixos/tests/postgresql/anonymizer.nix @@ -1,24 +1,28 @@ -{ pkgs -, makeTest +{ + pkgs, + makeTest, }: let inherit (pkgs) lib; - makeTestFor = package: + makeTestFor = + package: makeTest { name = "postgresql_anonymizer-${package.name}"; meta.maintainers = lib.teams.flyingcircus.members; - nodes.machine = { pkgs, ... }: { - environment.systemPackages = [ pkgs.pg-dump-anon ]; - services.postgresql = { - inherit package; - enable = true; - extraPlugins = ps: [ ps.anonymizer ]; - settings.shared_preload_libraries = [ "anon" ]; + nodes.machine = + { pkgs, ... }: + { + environment.systemPackages = [ pkgs.pg-dump-anon ]; + services.postgresql = { + inherit package; + enable = true; + extraPlugins = ps: [ ps.anonymizer ]; + settings.shared_preload_libraries = [ "anon" ]; + }; }; - }; testScript = '' start_all() @@ -103,7 +107,9 @@ let }; in lib.recurseIntoAttrs ( - lib.concatMapAttrs (n: p: { ${n} = makeTestFor p; }) (lib.filterAttrs (_: p: !p.pkgs.anonymizer.meta.broken) pkgs.postgresqlVersions) + lib.concatMapAttrs (n: p: { ${n} = makeTestFor p; }) ( + lib.filterAttrs (_: p: !p.pkgs.anonymizer.meta.broken) pkgs.postgresqlVersions + ) // { passthru.override = p: makeTestFor p; } diff --git a/nixos/tests/postgresql/pgjwt.nix b/nixos/tests/postgresql/pgjwt.nix index 2c0b77f180ff8..81e5dac41adae 100644 --- a/nixos/tests/postgresql/pgjwt.nix +++ b/nixos/tests/postgresql/pgjwt.nix @@ -1,43 +1,56 @@ -{ pkgs -, makeTest +{ + pkgs, + makeTest, }: let inherit (pkgs) lib; - makeTestFor = package: + makeTestFor = + package: makeTest { name = "pgjwt-${package.name}"; meta = with lib.maintainers; { - maintainers = [ spinus willibutz ]; + maintainers = [ + spinus + willibutz + ]; }; - nodes.master = { ... }: + nodes.master = + { ... }: { services.postgresql = { inherit package; enable = true; - extraPlugins = ps: with ps; [ pgjwt pgtap ]; + extraPlugins = + ps: with ps; [ + pgjwt + pgtap + ]; }; }; - testScript = { nodes, ... }: - let - sqlSU = "${nodes.master.services.postgresql.superUser}"; - pgProve = "${pkgs.perlPackages.TAPParserSourceHandlerpgTAP}"; - inherit (nodes.master.services.postgresql.package.pkgs) pgjwt; - in - '' - start_all() - master.wait_for_unit("postgresql") - master.succeed( - "${pkgs.sudo}/bin/sudo -u ${sqlSU} ${pgProve}/bin/pg_prove -d postgres -v -f ${pgjwt.src}/test.sql" - ) - ''; + testScript = + { nodes, ... }: + let + sqlSU = "${nodes.master.services.postgresql.superUser}"; + pgProve = "${pkgs.perlPackages.TAPParserSourceHandlerpgTAP}"; + inherit (nodes.master.services.postgresql.package.pkgs) pgjwt; + in + '' + start_all() + master.wait_for_unit("postgresql") + master.succeed( + "${pkgs.sudo}/bin/sudo -u ${sqlSU} ${pgProve}/bin/pg_prove -d postgres -v -f ${pgjwt.src}/test.sql" + ) + ''; }; in lib.recurseIntoAttrs ( - lib.concatMapAttrs (n: p: { ${n} = makeTestFor p; }) (lib.filterAttrs (_: p: !p.pkgs.pgjwt.meta.broken) pkgs.postgresqlVersions) + lib.concatMapAttrs (n: p: { ${n} = makeTestFor p; }) ( + lib.filterAttrs (_: p: !p.pkgs.pgjwt.meta.broken) pkgs.postgresqlVersions + ) // { passthru.override = p: makeTestFor p; } diff --git a/nixos/tests/postgresql/pgvecto-rs.nix b/nixos/tests/postgresql/pgvecto-rs.nix index 8f8c3fdd84368..9d8389eecf99a 100644 --- a/nixos/tests/postgresql/pgvecto-rs.nix +++ b/nixos/tests/postgresql/pgvecto-rs.nix @@ -1,5 +1,6 @@ -{ pkgs -, makeTest +{ + pkgs, + makeTest, }: let @@ -22,52 +23,58 @@ let ('a thin dog sat on a mat and ate a thin rat', '[10, 11, 12]'); ''; - makeTestFor = postgresqlPackage: + makeTestFor = + postgresqlPackage: makeTest { name = "pgvecto-rs-${postgresqlPackage.name}"; meta = with lib.maintainers; { maintainers = [ diogotcorreia ]; }; - nodes.machine = { ... }: + nodes.machine = + { ... }: { services.postgresql = { enable = true; package = postgresqlPackage; - extraPlugins = ps: with ps; [ - pgvecto-rs - ]; + extraPlugins = + ps: with ps; [ + pgvecto-rs + ]; settings.shared_preload_libraries = "vectors"; }; }; - testScript = { nodes, ... }: - let - inherit (nodes.machine.services.postgresql.package.pkgs) pgvecto-rs; - in - '' - def check_count(statement, lines): - return 'test $(sudo -u postgres psql postgres -tAc "{}"|wc -l) -eq {}'.format( - statement, lines - ) + testScript = + { nodes, ... }: + let + inherit (nodes.machine.services.postgresql.package.pkgs) pgvecto-rs; + in + '' + def check_count(statement, lines): + return 'test $(sudo -u postgres psql postgres -tAc "{}"|wc -l) -eq {}'.format( + statement, lines + ) - machine.start() - machine.wait_for_unit("postgresql") + machine.start() + machine.wait_for_unit("postgresql") - with subtest("Postgresql with extension vectors is available just after unit start"): - machine.succeed(check_count("SELECT * FROM pg_available_extensions WHERE name = 'vectors' AND default_version = '${pgvecto-rs.version}';", 1)) + with subtest("Postgresql with extension vectors is available just after unit start"): + machine.succeed(check_count("SELECT * FROM pg_available_extensions WHERE name = 'vectors' AND default_version = '${pgvecto-rs.version}';", 1)) - machine.succeed("sudo -u postgres psql -f ${test-sql}") + machine.succeed("sudo -u postgres psql -f ${test-sql}") - machine.succeed(check_count("SELECT content, embedding FROM items WHERE to_tsvector('english', content) @@ 'cat & rat'::tsquery;", 2)) + machine.succeed(check_count("SELECT content, embedding FROM items WHERE to_tsvector('english', content) @@ 'cat & rat'::tsquery;", 2)) - machine.shutdown() - ''; + machine.shutdown() + ''; }; in lib.recurseIntoAttrs ( - lib.concatMapAttrs (n: p: { ${n} = makeTestFor p; }) (lib.filterAttrs (_: p: !p.pkgs.pgvecto-rs.meta.broken) pkgs.postgresqlVersions) + lib.concatMapAttrs (n: p: { ${n} = makeTestFor p; }) ( + lib.filterAttrs (_: p: !p.pkgs.pgvecto-rs.meta.broken) pkgs.postgresqlVersions + ) // { passthru.override = p: makeTestFor p; } diff --git a/nixos/tests/postgresql/postgresql-jit.nix b/nixos/tests/postgresql/postgresql-jit.nix index 69967f091312b..5d0406062eae3 100644 --- a/nixos/tests/postgresql/postgresql-jit.nix +++ b/nixos/tests/postgresql/postgresql-jit.nix @@ -1,26 +1,30 @@ -{ pkgs -, makeTest +{ + pkgs, + makeTest, }: let inherit (pkgs) lib; - makeTestFor = package: + makeTestFor = + package: makeTest { name = "postgresql-jit-${package.name}"; meta.maintainers = with lib.maintainers; [ ma27 ]; - nodes.machine = { pkgs, ... }: { - services.postgresql = { - inherit package; - enable = true; - enableJIT = true; - initialScript = pkgs.writeText "init.sql" '' - create table demo (id int); - insert into demo (id) select generate_series(1, 5); - ''; + nodes.machine = + { pkgs, ... }: + { + services.postgresql = { + inherit package; + enable = true; + enableJIT = true; + initialScript = pkgs.writeText "init.sql" '' + create table demo (id int); + insert into demo (id) select generate_series(1, 5); + ''; + }; }; - }; testScript = '' machine.start() @@ -45,7 +49,9 @@ let }; in lib.recurseIntoAttrs ( - lib.concatMapAttrs (n: p: { ${n} = makeTestFor p; }) (lib.filterAttrs (n: _: lib.hasSuffix "_jit" n) pkgs.postgresqlVersions) + lib.concatMapAttrs (n: p: { ${n} = makeTestFor p; }) ( + lib.filterAttrs (n: _: lib.hasSuffix "_jit" n) pkgs.postgresqlVersions + ) // { passthru.override = p: makeTestFor p; } diff --git a/nixos/tests/postgresql/postgresql-tls-client-cert.nix b/nixos/tests/postgresql/postgresql-tls-client-cert.nix index 4939c96b2b84d..d7cddb625256c 100644 --- a/nixos/tests/postgresql/postgresql-tls-client-cert.nix +++ b/nixos/tests/postgresql/postgresql-tls-client-cert.nix @@ -1,116 +1,124 @@ -{ pkgs -, makeTest +{ + pkgs, + makeTest, }: let inherit (pkgs) lib; - runWithOpenSSL = file: cmd: pkgs.runCommand file - { + runWithOpenSSL = + file: cmd: + pkgs.runCommand file { buildInputs = [ pkgs.openssl ]; - } - cmd; + } cmd; caKey = runWithOpenSSL "ca.key" "openssl ecparam -name prime256v1 -genkey -noout -out $out"; - caCert = runWithOpenSSL - "ca.crt" - '' - openssl req -new -x509 -sha256 -key ${caKey} -out $out -subj "/CN=test.example" -days 36500 - ''; - serverKey = - runWithOpenSSL "server.key" "openssl ecparam -name prime256v1 -genkey -noout -out $out"; + caCert = runWithOpenSSL "ca.crt" '' + openssl req -new -x509 -sha256 -key ${caKey} -out $out -subj "/CN=test.example" -days 36500 + ''; + serverKey = runWithOpenSSL "server.key" "openssl ecparam -name prime256v1 -genkey -noout -out $out"; serverKeyPath = "/var/lib/postgresql"; - serverCert = - runWithOpenSSL "server.crt" '' - openssl req -new -sha256 -key ${serverKey} -out server.csr -subj "/CN=db.test.example" - openssl x509 -req -in server.csr -CA ${caCert} -CAkey ${caKey} \ - -CAcreateserial -out $out -days 36500 -sha256 - ''; - clientKey = - runWithOpenSSL "client.key" "openssl ecparam -name prime256v1 -genkey -noout -out $out"; - clientCert = - runWithOpenSSL "client.crt" '' - openssl req -new -sha256 -key ${clientKey} -out client.csr -subj "/CN=test" - openssl x509 -req -in client.csr -CA ${caCert} -CAkey ${caKey} \ - -CAcreateserial -out $out -days 36500 -sha256 - ''; + serverCert = runWithOpenSSL "server.crt" '' + openssl req -new -sha256 -key ${serverKey} -out server.csr -subj "/CN=db.test.example" + openssl x509 -req -in server.csr -CA ${caCert} -CAkey ${caKey} \ + -CAcreateserial -out $out -days 36500 -sha256 + ''; + clientKey = runWithOpenSSL "client.key" "openssl ecparam -name prime256v1 -genkey -noout -out $out"; + clientCert = runWithOpenSSL "client.crt" '' + openssl req -new -sha256 -key ${clientKey} -out client.csr -subj "/CN=test" + openssl x509 -req -in client.csr -CA ${caCert} -CAkey ${caKey} \ + -CAcreateserial -out $out -days 36500 -sha256 + ''; clientKeyPath = "/root"; - makeTestFor = package: + makeTestFor = + package: makeTest { name = "postgresql-tls-client-cert-${package.name}"; meta.maintainers = with lib.maintainers; [ erictapen ]; - nodes.server = { ... }: { - system.activationScripts = { - keyPlacement.text = '' - mkdir -p '${serverKeyPath}' - cp '${serverKey}' '${serverKeyPath}/server.key' - chown postgres:postgres '${serverKeyPath}/server.key' - chmod 600 '${serverKeyPath}/server.key' - ''; - }; - services.postgresql = { - inherit package; - enable = true; - enableTCPIP = true; - ensureUsers = [ - { - name = "test"; - ensureDBOwnership = true; - } - ]; - ensureDatabases = [ "test" ]; - settings = { - ssl = "on"; - ssl_ca_file = toString caCert; - ssl_cert_file = toString serverCert; - ssl_key_file = "${serverKeyPath}/server.key"; + nodes.server = + { ... }: + { + system.activationScripts = { + keyPlacement.text = '' + mkdir -p '${serverKeyPath}' + cp '${serverKey}' '${serverKeyPath}/server.key' + chown postgres:postgres '${serverKeyPath}/server.key' + chmod 600 '${serverKeyPath}/server.key' + ''; }; - authentication = '' - hostssl test test ::/0 cert clientcert=verify-full - ''; - }; - networking = { - interfaces.eth1 = { - ipv6.addresses = [ - { address = "fc00::1"; prefixLength = 120; } + services.postgresql = { + inherit package; + enable = true; + enableTCPIP = true; + ensureUsers = [ + { + name = "test"; + ensureDBOwnership = true; + } ]; + ensureDatabases = [ "test" ]; + settings = { + ssl = "on"; + ssl_ca_file = toString caCert; + ssl_cert_file = toString serverCert; + ssl_key_file = "${serverKeyPath}/server.key"; + }; + authentication = '' + hostssl test test ::/0 cert clientcert=verify-full + ''; + }; + networking = { + interfaces.eth1 = { + ipv6.addresses = [ + { + address = "fc00::1"; + prefixLength = 120; + } + ]; + }; + firewall.allowedTCPPorts = [ 5432 ]; }; - firewall.allowedTCPPorts = [ 5432 ]; }; - }; - nodes.client = { ... }: { - system.activationScripts = { - keyPlacement.text = '' - mkdir -p '${clientKeyPath}' - cp '${clientKey}' '${clientKeyPath}/client.key' - chown root:root '${clientKeyPath}/client.key' - chmod 600 '${clientKeyPath}/client.key' - ''; - }; - environment = { - variables = { - PGHOST = "db.test.example"; - PGPORT = "5432"; - PGDATABASE = "test"; - PGUSER = "test"; - PGSSLMODE = "verify-full"; - PGSSLCERT = clientCert; - PGSSLKEY = "${clientKeyPath}/client.key"; - PGSSLROOTCERT = caCert; + nodes.client = + { ... }: + { + system.activationScripts = { + keyPlacement.text = '' + mkdir -p '${clientKeyPath}' + cp '${clientKey}' '${clientKeyPath}/client.key' + chown root:root '${clientKeyPath}/client.key' + chmod 600 '${clientKeyPath}/client.key' + ''; }; - systemPackages = [ package ]; - }; - networking = { - interfaces.eth1 = { - ipv6.addresses = [ - { address = "fc00::2"; prefixLength = 120; } - ]; + environment = { + variables = { + PGHOST = "db.test.example"; + PGPORT = "5432"; + PGDATABASE = "test"; + PGUSER = "test"; + PGSSLMODE = "verify-full"; + PGSSLCERT = clientCert; + PGSSLKEY = "${clientKeyPath}/client.key"; + PGSSLROOTCERT = caCert; + }; + systemPackages = [ package ]; + }; + networking = { + interfaces.eth1 = { + ipv6.addresses = [ + { + address = "fc00::2"; + prefixLength = 120; + } + ]; + }; + hosts = { + "fc00::1" = [ "db.test.example" ]; + }; }; - hosts = { "fc00::1" = [ "db.test.example" ]; }; }; - }; testScript = '' server.wait_for_unit("multi-user.target") diff --git a/nixos/tests/postgresql/postgresql-wal-receiver.nix b/nixos/tests/postgresql/postgresql-wal-receiver.nix index b9d69cf00684d..5c1551c5f2fd2 100644 --- a/nixos/tests/postgresql/postgresql-wal-receiver.nix +++ b/nixos/tests/postgresql/postgresql-wal-receiver.nix @@ -1,11 +1,13 @@ -{ pkgs -, makeTest +{ + pkgs, + makeTest, }: let inherit (pkgs) lib; - makeTestFor = package: + makeTestFor = + package: let postgresqlDataDir = "/var/lib/postgresql/${package.psqlSchema}"; replicationUser = "wal_receiver_user"; @@ -19,41 +21,43 @@ let name = "postgresql-wal-receiver-${package.name}"; meta.maintainers = with lib.maintainers; [ pacien ]; - nodes.machine = { ... }: { - systemd.tmpfiles.rules = [ - "d /var/cache/wals 0750 postgres postgres - -" - ]; + nodes.machine = + { ... }: + { + systemd.tmpfiles.rules = [ + "d /var/cache/wals 0750 postgres postgres - -" + ]; - services.postgresql = { - inherit package; - enable = true; - settings = { - max_replication_slots = 10; - max_wal_senders = 10; - recovery_end_command = "touch recovery.done"; - restore_command = "cp ${walBackupDir}/%f %p"; - wal_level = "archive"; # alias for replica on pg >= 9.6 + services.postgresql = { + inherit package; + enable = true; + settings = { + max_replication_slots = 10; + max_wal_senders = 10; + recovery_end_command = "touch recovery.done"; + restore_command = "cp ${walBackupDir}/%f %p"; + wal_level = "archive"; # alias for replica on pg >= 9.6 + }; + authentication = '' + host replication ${replicationUser} all trust + ''; + initialScript = pkgs.writeText "init.sql" '' + create user ${replicationUser} replication; + select * from pg_create_physical_replication_slot('${replicationSlot}'); + ''; }; - authentication = '' - host replication ${replicationUser} all trust - ''; - initialScript = pkgs.writeText "init.sql" '' - create user ${replicationUser} replication; - select * from pg_create_physical_replication_slot('${replicationSlot}'); - ''; - }; - services.postgresqlWalReceiver.receivers.main = { - postgresqlPackage = package; - connection = replicationConn; - slot = replicationSlot; - directory = walBackupDir; + services.postgresqlWalReceiver.receivers.main = { + postgresqlPackage = package; + connection = replicationConn; + slot = replicationSlot; + directory = walBackupDir; + }; + # This is only to speedup test, it isn't time racing. Service is set to autorestart always, + # default 60sec is fine for real system, but is too much for a test + systemd.services.postgresql-wal-receiver-main.serviceConfig.RestartSec = lib.mkForce 5; + systemd.services.postgresql.serviceConfig.ReadWritePaths = [ "/var/cache/wals" ]; }; - # This is only to speedup test, it isn't time racing. Service is set to autorestart always, - # default 60sec is fine for real system, but is too much for a test - systemd.services.postgresql-wal-receiver-main.serviceConfig.RestartSec = lib.mkForce 5; - systemd.services.postgresql.serviceConfig.ReadWritePaths = [ "/var/cache/wals" ]; - }; testScript = '' # make an initial base backup diff --git a/nixos/tests/postgresql/postgresql.nix b/nixos/tests/postgresql/postgresql.nix index 13a768d9a8a9a..509a14411de9c 100644 --- a/nixos/tests/postgresql/postgresql.nix +++ b/nixos/tests/postgresql/postgresql.nix @@ -1,11 +1,13 @@ -{ pkgs -, makeTest +{ + pkgs, + makeTest, }: let inherit (pkgs) lib; - makeTestFor = package: + makeTestFor = + package: lib.recurseIntoAttrs { postgresql = makeTestForWithBackupAll package false; postgresql-backup-all = makeTestForWithBackupAll package true; @@ -26,17 +28,19 @@ let INSERT INTO xmltest (doc) VALUES ('ok'); -- check if libxml2 enabled ''; - makeTestForWithBackupAll = package: backupAll: + makeTestForWithBackupAll = + package: backupAll: makeTest { name = "postgresql${lib.optionalString backupAll "-backup-all"}-${package.name}"; meta = with lib.maintainers; { maintainers = [ zagy ]; }; - nodes.machine = {...}: + nodes.machine = + { ... }: { services.postgresql = { - inherit (package); + inherit (package) ; enable = true; }; @@ -46,106 +50,110 @@ let }; }; - testScript = let - backupName = if backupAll then "all" else "postgres"; - backupService = if backupAll then "postgresqlBackup" else "postgresqlBackup-postgres"; - backupFileBase = "/var/backup/postgresql/${backupName}"; - in '' - def check_count(statement, lines): - return 'test $(sudo -u postgres psql postgres -tAc "{}"|wc -l) -eq {}'.format( - statement, lines - ) - - - machine.start() - machine.wait_for_unit("postgresql") - - with subtest("Postgresql is available just after unit start"): - machine.succeed( - "cat ${test-sql} | sudo -u postgres psql" - ) - - with subtest("Postgresql survives restart (bug #1735)"): - machine.shutdown() - import time - time.sleep(2) - machine.start() - machine.wait_for_unit("postgresql") - - machine.fail(check_count("SELECT * FROM sth;", 3)) - machine.succeed(check_count("SELECT * FROM sth;", 5)) - machine.fail(check_count("SELECT * FROM sth;", 4)) - machine.succeed(check_count("SELECT xpath('/test/text()', doc) FROM xmltest;", 1)) - - with subtest("Backup service works"): - machine.succeed( - "systemctl start ${backupService}.service", - "zcat ${backupFileBase}.sql.gz | grep 'ok'", - "ls -hal /var/backup/postgresql/ >/dev/console", - "stat -c '%a' ${backupFileBase}.sql.gz | grep 600", - ) - with subtest("Backup service removes prev files"): - machine.succeed( - # Create dummy prev files. - "touch ${backupFileBase}.prev.sql{,.gz,.zstd}", - "chown postgres:postgres ${backupFileBase}.prev.sql{,.gz,.zstd}", - - # Run backup. - "systemctl start ${backupService}.service", - "ls -hal /var/backup/postgresql/ >/dev/console", - - # Since nothing has changed in the database, the cur and prev files - # should match. - "zcat ${backupFileBase}.sql.gz | grep 'ok'", - "cmp ${backupFileBase}.sql.gz ${backupFileBase}.prev.sql.gz", - - # The prev files with unused suffix should be removed. - "[ ! -f '${backupFileBase}.prev.sql' ]", - "[ ! -f '${backupFileBase}.prev.sql.zstd' ]", - - # Both cur and prev file should only be accessible by the postgres user. - "stat -c '%a' ${backupFileBase}.sql.gz | grep 600", - "stat -c '%a' '${backupFileBase}.prev.sql.gz' | grep 600", - ) - with subtest("Backup service fails gracefully"): - # Sabotage the backup process - machine.succeed("rm /run/postgresql/.s.PGSQL.5432") - machine.fail( - "systemctl start ${backupService}.service", - ) - machine.succeed( - "ls -hal /var/backup/postgresql/ >/dev/console", - "zcat ${backupFileBase}.prev.sql.gz | grep 'ok'", - "stat ${backupFileBase}.in-progress.sql.gz", - ) - # In a previous version, the second run would overwrite prev.sql.gz, - # so we test a second run as well. - machine.fail( - "systemctl start ${backupService}.service", - ) - machine.succeed( - "stat ${backupFileBase}.in-progress.sql.gz", - "zcat ${backupFileBase}.prev.sql.gz | grep 'ok'", - ) - - - with subtest("Initdb works"): - machine.succeed("sudo -u postgres initdb -D /tmp/testpostgres2") - - machine.log(machine.execute("systemd-analyze security postgresql.service | grep -v ✓")[1]) - - machine.shutdown() - ''; + testScript = + let + backupName = if backupAll then "all" else "postgres"; + backupService = if backupAll then "postgresqlBackup" else "postgresqlBackup-postgres"; + backupFileBase = "/var/backup/postgresql/${backupName}"; + in + '' + def check_count(statement, lines): + return 'test $(sudo -u postgres psql postgres -tAc "{}"|wc -l) -eq {}'.format( + statement, lines + ) + + + machine.start() + machine.wait_for_unit("postgresql") + + with subtest("Postgresql is available just after unit start"): + machine.succeed( + "cat ${test-sql} | sudo -u postgres psql" + ) + + with subtest("Postgresql survives restart (bug #1735)"): + machine.shutdown() + import time + time.sleep(2) + machine.start() + machine.wait_for_unit("postgresql") + + machine.fail(check_count("SELECT * FROM sth;", 3)) + machine.succeed(check_count("SELECT * FROM sth;", 5)) + machine.fail(check_count("SELECT * FROM sth;", 4)) + machine.succeed(check_count("SELECT xpath('/test/text()', doc) FROM xmltest;", 1)) + + with subtest("Backup service works"): + machine.succeed( + "systemctl start ${backupService}.service", + "zcat ${backupFileBase}.sql.gz | grep 'ok'", + "ls -hal /var/backup/postgresql/ >/dev/console", + "stat -c '%a' ${backupFileBase}.sql.gz | grep 600", + ) + with subtest("Backup service removes prev files"): + machine.succeed( + # Create dummy prev files. + "touch ${backupFileBase}.prev.sql{,.gz,.zstd}", + "chown postgres:postgres ${backupFileBase}.prev.sql{,.gz,.zstd}", + + # Run backup. + "systemctl start ${backupService}.service", + "ls -hal /var/backup/postgresql/ >/dev/console", + + # Since nothing has changed in the database, the cur and prev files + # should match. + "zcat ${backupFileBase}.sql.gz | grep 'ok'", + "cmp ${backupFileBase}.sql.gz ${backupFileBase}.prev.sql.gz", + + # The prev files with unused suffix should be removed. + "[ ! -f '${backupFileBase}.prev.sql' ]", + "[ ! -f '${backupFileBase}.prev.sql.zstd' ]", + + # Both cur and prev file should only be accessible by the postgres user. + "stat -c '%a' ${backupFileBase}.sql.gz | grep 600", + "stat -c '%a' '${backupFileBase}.prev.sql.gz' | grep 600", + ) + with subtest("Backup service fails gracefully"): + # Sabotage the backup process + machine.succeed("rm /run/postgresql/.s.PGSQL.5432") + machine.fail( + "systemctl start ${backupService}.service", + ) + machine.succeed( + "ls -hal /var/backup/postgresql/ >/dev/console", + "zcat ${backupFileBase}.prev.sql.gz | grep 'ok'", + "stat ${backupFileBase}.in-progress.sql.gz", + ) + # In a previous version, the second run would overwrite prev.sql.gz, + # so we test a second run as well. + machine.fail( + "systemctl start ${backupService}.service", + ) + machine.succeed( + "stat ${backupFileBase}.in-progress.sql.gz", + "zcat ${backupFileBase}.prev.sql.gz | grep 'ok'", + ) + + + with subtest("Initdb works"): + machine.succeed("sudo -u postgres initdb -D /tmp/testpostgres2") + + machine.log(machine.execute("systemd-analyze security postgresql.service | grep -v ✓")[1]) + + machine.shutdown() + ''; }; - makeEnsureTestFor = package: + makeEnsureTestFor = + package: makeTest { name = "postgresql-clauses-${package.name}"; meta = with lib.maintainers; { maintainers = [ zagy ]; }; - nodes.machine = {...}: + nodes.machine = + { ... }: { services.postgresql = { inherit package; @@ -170,12 +178,14 @@ let }; }; - testScript = let - getClausesQuery = user: lib.concatStringsSep " " - [ - "SELECT row_to_json(row)" - "FROM (" - "SELECT" + testScript = + let + getClausesQuery = + user: + lib.concatStringsSep " " [ + "SELECT row_to_json(row)" + "FROM (" + "SELECT" "rolsuper," "rolinherit," "rolcreaterole," @@ -183,46 +193,47 @@ let "rolcanlogin," "rolreplication," "rolbypassrls" - "FROM pg_roles" - "WHERE rolname = '${user}'" - ") row;" - ]; - in '' - import json - machine.start() - machine.wait_for_unit("postgresql") - - with subtest("All user permissions are set according to the ensureClauses attr"): - clauses = json.loads( - machine.succeed( - "sudo -u postgres psql -tc \"${getClausesQuery "all-clauses"}\"" + "FROM pg_roles" + "WHERE rolname = '${user}'" + ") row;" + ]; + in + '' + import json + machine.start() + machine.wait_for_unit("postgresql") + + with subtest("All user permissions are set according to the ensureClauses attr"): + clauses = json.loads( + machine.succeed( + "sudo -u postgres psql -tc \"${getClausesQuery "all-clauses"}\"" + ) ) - ) - print(clauses) - assert clauses['rolsuper'], 'expected user with clauses to have superuser clause' - assert clauses['rolinherit'], 'expected user with clauses to have inherit clause' - assert clauses['rolcreaterole'], 'expected user with clauses to have create role clause' - assert clauses['rolcreatedb'], 'expected user with clauses to have create db clause' - assert clauses['rolcanlogin'], 'expected user with clauses to have login clause' - assert clauses['rolreplication'], 'expected user with clauses to have replication clause' - assert clauses['rolbypassrls'], 'expected user with clauses to have bypassrls clause' - - with subtest("All user permissions default when ensureClauses is not provided"): - clauses = json.loads( - machine.succeed( - "sudo -u postgres psql -tc \"${getClausesQuery "default-clauses"}\"" + print(clauses) + assert clauses['rolsuper'], 'expected user with clauses to have superuser clause' + assert clauses['rolinherit'], 'expected user with clauses to have inherit clause' + assert clauses['rolcreaterole'], 'expected user with clauses to have create role clause' + assert clauses['rolcreatedb'], 'expected user with clauses to have create db clause' + assert clauses['rolcanlogin'], 'expected user with clauses to have login clause' + assert clauses['rolreplication'], 'expected user with clauses to have replication clause' + assert clauses['rolbypassrls'], 'expected user with clauses to have bypassrls clause' + + with subtest("All user permissions default when ensureClauses is not provided"): + clauses = json.loads( + machine.succeed( + "sudo -u postgres psql -tc \"${getClausesQuery "default-clauses"}\"" + ) ) - ) - assert not clauses['rolsuper'], 'expected user with no clauses set to have default superuser clause' - assert clauses['rolinherit'], 'expected user with no clauses set to have default inherit clause' - assert not clauses['rolcreaterole'], 'expected user with no clauses set to have default create role clause' - assert not clauses['rolcreatedb'], 'expected user with no clauses set to have default create db clause' - assert clauses['rolcanlogin'], 'expected user with no clauses set to have default login clause' - assert not clauses['rolreplication'], 'expected user with no clauses set to have default replication clause' - assert not clauses['rolbypassrls'], 'expected user with no clauses set to have default bypassrls clause' - - machine.shutdown() - ''; + assert not clauses['rolsuper'], 'expected user with no clauses set to have default superuser clause' + assert clauses['rolinherit'], 'expected user with no clauses set to have default inherit clause' + assert not clauses['rolcreaterole'], 'expected user with no clauses set to have default create role clause' + assert not clauses['rolcreatedb'], 'expected user with no clauses set to have default create db clause' + assert clauses['rolcanlogin'], 'expected user with no clauses set to have default login clause' + assert not clauses['rolreplication'], 'expected user with no clauses set to have default replication clause' + assert not clauses['rolbypassrls'], 'expected user with no clauses set to have default bypassrls clause' + + machine.shutdown() + ''; }; in lib.recurseIntoAttrs ( diff --git a/nixos/tests/postgresql/timescaledb.nix b/nixos/tests/postgresql/timescaledb.nix index a01f890a12c6c..b29d59c744f06 100644 --- a/nixos/tests/postgresql/timescaledb.nix +++ b/nixos/tests/postgresql/timescaledb.nix @@ -1,5 +1,6 @@ -{ pkgs -, makeTest +{ + pkgs, + makeTest, }: let @@ -38,23 +39,28 @@ let SELECT * FROM sth; ''; - makeTestFor = package: + makeTestFor = + package: makeTest { name = "timescaledb-${package.name}"; meta = with lib.maintainers; { maintainers = [ typetetris ]; }; - nodes.machine = { ... }: + nodes.machine = + { ... }: { services.postgresql = { inherit package; enable = true; - extraPlugins = ps: with ps; [ - timescaledb - timescaledb_toolkit - ]; - settings = { shared_preload_libraries = "timescaledb, timescaledb_toolkit"; }; + extraPlugins = + ps: with ps; [ + timescaledb + timescaledb_toolkit + ]; + settings = { + shared_preload_libraries = "timescaledb, timescaledb_toolkit"; + }; }; }; @@ -85,7 +91,9 @@ in # To run these tests: # NIXPKGS_ALLOW_UNFREE=1 nix-build -A nixosTests.postgresql.timescaledb lib.dontRecurseIntoAttrs ( - lib.concatMapAttrs (n: p: { ${n} = makeTestFor p; }) (lib.filterAttrs (_: p: !p.pkgs.timescaledb.meta.broken) pkgs.postgresqlVersions) + lib.concatMapAttrs (n: p: { ${n} = makeTestFor p; }) ( + lib.filterAttrs (_: p: !p.pkgs.timescaledb.meta.broken) pkgs.postgresqlVersions + ) // { passthru.override = p: makeTestFor p; } diff --git a/nixos/tests/postgresql/tsja.nix b/nixos/tests/postgresql/tsja.nix index 8d78093136df7..7c976da21b68f 100644 --- a/nixos/tests/postgresql/tsja.nix +++ b/nixos/tests/postgresql/tsja.nix @@ -1,25 +1,29 @@ -{ pkgs -, makeTest +{ + pkgs, + makeTest, }: let inherit (pkgs) lib; - makeTestFor = package: + makeTestFor = + package: makeTest { name = "tsja-${package.name}"; meta = { maintainers = with lib.maintainers; [ chayleaf ]; }; - nodes.master = { ... }: + nodes.master = + { ... }: { services.postgresql = { inherit package; enable = true; - extraPlugins = ps: with ps; [ - tsja - ]; + extraPlugins = + ps: with ps; [ + tsja + ]; }; }; @@ -37,7 +41,9 @@ let }; in lib.recurseIntoAttrs ( - lib.concatMapAttrs (n: p: { ${n} = makeTestFor p; }) (lib.filterAttrs (_: p: !p.pkgs.tsja.meta.broken) pkgs.postgresqlVersions) + lib.concatMapAttrs (n: p: { ${n} = makeTestFor p; }) ( + lib.filterAttrs (_: p: !p.pkgs.tsja.meta.broken) pkgs.postgresqlVersions + ) // { passthru.override = p: makeTestFor p; } diff --git a/nixos/tests/postgresql/wal2json.nix b/nixos/tests/postgresql/wal2json.nix index 0333369722f0c..551254a68ebda 100644 --- a/nixos/tests/postgresql/wal2json.nix +++ b/nixos/tests/postgresql/wal2json.nix @@ -1,11 +1,13 @@ -{ pkgs -, makeTest +{ + pkgs, + makeTest, }: let inherit (pkgs) lib; - makeTestFor = package: + makeTestFor = + package: makeTest { name = "wal2json-${package.name}"; meta.maintainers = with pkgs.lib.maintainers; [ euank ]; @@ -41,7 +43,9 @@ let }; in lib.recurseIntoAttrs ( - lib.concatMapAttrs (n: p: { ${n} = makeTestFor p; }) (lib.filterAttrs (_: p: !p.pkgs.wal2json.meta.broken) pkgs.postgresqlVersions) + lib.concatMapAttrs (n: p: { ${n} = makeTestFor p; }) ( + lib.filterAttrs (_: p: !p.pkgs.wal2json.meta.broken) pkgs.postgresqlVersions + ) // { passthru.override = p: makeTestFor p; }