1 { system ? builtins.currentSystem,
3 pkgs ? import ../.. { inherit system config; }
6 with import ../lib/testing-python.nix { inherit system pkgs; };
10 postgresql-versions = import ../../pkgs/servers/sql/postgresql pkgs;
11 test-sql = pkgs.writeText "postgresql-test" ''
12 CREATE EXTENSION pgcrypto; -- just to check if lib loading works
16 INSERT INTO sth (id) VALUES (1);
17 INSERT INTO sth (id) VALUES (1);
18 INSERT INTO sth (id) VALUES (1);
19 INSERT INTO sth (id) VALUES (1);
20 INSERT INTO sth (id) VALUES (1);
21 CREATE TABLE xmltest ( doc xml );
22 INSERT INTO xmltest (doc) VALUES ('<test>ok</test>'); -- check if libxml2 enabled
24 make-postgresql-test = postgresql-name: postgresql-package: backup-all: makeTest {
25 name = postgresql-name;
26 meta = with pkgs.lib.maintainers; {
27 maintainers = [ zagy ];
30 nodes.machine = {...}:
32 services.postgresql = {
34 package = postgresql-package;
37 services.postgresqlBackup = {
39 databases = optional (!backup-all) "postgres";
44 backupName = if backup-all then "all" else "postgres";
45 backupService = if backup-all then "postgresqlBackup" else "postgresqlBackup-postgres";
46 backupFileBase = "/var/backup/postgresql/${backupName}";
48 def check_count(statement, lines):
49 return 'test $(sudo -u postgres psql postgres -tAc "{}"|wc -l) -eq {}'.format(
55 machine.wait_for_unit("postgresql")
57 with subtest("Postgresql is available just after unit start"):
59 "cat ${test-sql} | sudo -u postgres psql"
62 with subtest("Postgresql survives restart (bug #1735)"):
67 machine.wait_for_unit("postgresql")
69 machine.fail(check_count("SELECT * FROM sth;", 3))
70 machine.succeed(check_count("SELECT * FROM sth;", 5))
71 machine.fail(check_count("SELECT * FROM sth;", 4))
72 machine.succeed(check_count("SELECT xpath('/test/text()', doc) FROM xmltest;", 1))
74 with subtest("Backup service works"):
76 "systemctl start ${backupService}.service",
77 "zcat ${backupFileBase}.sql.gz | grep '<test>ok</test>'",
78 "ls -hal /var/backup/postgresql/ >/dev/console",
79 "stat -c '%a' ${backupFileBase}.sql.gz | grep 600",
81 with subtest("Backup service removes prev files"):
83 # Create dummy prev files.
84 "touch ${backupFileBase}.prev.sql{,.gz,.zstd}",
85 "chown postgres:postgres ${backupFileBase}.prev.sql{,.gz,.zstd}",
88 "systemctl start ${backupService}.service",
89 "ls -hal /var/backup/postgresql/ >/dev/console",
91 # Since nothing has changed in the database, the cur and prev files
93 "zcat ${backupFileBase}.sql.gz | grep '<test>ok</test>'",
94 "cmp ${backupFileBase}.sql.gz ${backupFileBase}.prev.sql.gz",
96 # The prev files with unused suffix should be removed.
97 "[ ! -f '${backupFileBase}.prev.sql' ]",
98 "[ ! -f '${backupFileBase}.prev.sql.zstd' ]",
100 # Both cur and prev file should only be accessible by the postgres user.
101 "stat -c '%a' ${backupFileBase}.sql.gz | grep 600",
102 "stat -c '%a' '${backupFileBase}.prev.sql.gz' | grep 600",
104 with subtest("Backup service fails gracefully"):
105 # Sabotage the backup process
106 machine.succeed("rm /run/postgresql/.s.PGSQL.5432")
108 "systemctl start ${backupService}.service",
111 "ls -hal /var/backup/postgresql/ >/dev/console",
112 "zcat ${backupFileBase}.prev.sql.gz | grep '<test>ok</test>'",
113 "stat ${backupFileBase}.in-progress.sql.gz",
115 # In a previous version, the second run would overwrite prev.sql.gz,
116 # so we test a second run as well.
118 "systemctl start ${backupService}.service",
121 "stat ${backupFileBase}.in-progress.sql.gz",
122 "zcat ${backupFileBase}.prev.sql.gz | grep '<test>ok</test>'",
126 with subtest("Initdb works"):
127 machine.succeed("sudo -u postgres initdb -D /tmp/testpostgres2")
134 mk-ensure-clauses-test = postgresql-name: postgresql-package: makeTest {
135 name = postgresql-name;
136 meta = with pkgs.lib.maintainers; {
137 maintainers = [ zagy ];
140 nodes.machine = {...}:
142 services.postgresql = {
144 package = postgresql-package;
147 name = "all-clauses";
159 name = "default-clauses";
166 getClausesQuery = user: pkgs.lib.concatStringsSep " "
168 "SELECT row_to_json(row)"
179 "WHERE rolname = '${user}'"
185 machine.wait_for_unit("postgresql")
187 with subtest("All user permissions are set according to the ensureClauses attr"):
188 clauses = json.loads(
190 "sudo -u postgres psql -tc \"${getClausesQuery "all-clauses"}\""
194 assert clauses['rolsuper'], 'expected user with clauses to have superuser clause'
195 assert clauses['rolinherit'], 'expected user with clauses to have inherit clause'
196 assert clauses['rolcreaterole'], 'expected user with clauses to have create role clause'
197 assert clauses['rolcreatedb'], 'expected user with clauses to have create db clause'
198 assert clauses['rolcanlogin'], 'expected user with clauses to have login clause'
199 assert clauses['rolreplication'], 'expected user with clauses to have replication clause'
200 assert clauses['rolbypassrls'], 'expected user with clauses to have bypassrls clause'
202 with subtest("All user permissions default when ensureClauses is not provided"):
203 clauses = json.loads(
205 "sudo -u postgres psql -tc \"${getClausesQuery "default-clauses"}\""
208 assert not clauses['rolsuper'], 'expected user with no clauses set to have default superuser clause'
209 assert clauses['rolinherit'], 'expected user with no clauses set to have default inherit clause'
210 assert not clauses['rolcreaterole'], 'expected user with no clauses set to have default create role clause'
211 assert not clauses['rolcreatedb'], 'expected user with no clauses set to have default create db clause'
212 assert clauses['rolcanlogin'], 'expected user with no clauses set to have default login clause'
213 assert not clauses['rolreplication'], 'expected user with no clauses set to have default replication clause'
214 assert not clauses['rolbypassrls'], 'expected user with no clauses set to have default bypassrls clause'
220 concatMapAttrs (name: package: {
221 ${name} = make-postgresql-test name package false;
222 ${name + "-backup-all"} = make-postgresql-test "${name + "-backup-all"}" package true;
223 ${name + "-clauses"} = mk-ensure-clauses-test name package;
224 }) postgresql-versions