at 23.11-pre 8.5 kB view raw
1{ system ? builtins.currentSystem, 2 config ? {}, 3 pkgs ? import ../.. { inherit system config; } 4}: 5 6with import ../lib/testing-python.nix { inherit system pkgs; }; 7with pkgs.lib; 8 9let 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 13 CREATE TABLE sth ( 14 id int 15 ); 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 23 ''; 24 make-postgresql-test = postgresql-name: postgresql-package: backup-all: makeTest { 25 name = postgresql-name; 26 meta = with pkgs.lib.maintainers; { 27 maintainers = [ zagy ]; 28 }; 29 30 nodes.machine = {...}: 31 { 32 services.postgresql = { 33 enable = true; 34 package = postgresql-package; 35 }; 36 37 services.postgresqlBackup = { 38 enable = true; 39 databases = optional (!backup-all) "postgres"; 40 }; 41 }; 42 43 testScript = let 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}"; 47 in '' 48 def check_count(statement, lines): 49 return 'test $(sudo -u postgres psql postgres -tAc "{}"|wc -l) -eq {}'.format( 50 statement, lines 51 ) 52 53 54 machine.start() 55 machine.wait_for_unit("postgresql") 56 57 with subtest("Postgresql is available just after unit start"): 58 machine.succeed( 59 "cat ${test-sql} | sudo -u postgres psql" 60 ) 61 62 with subtest("Postgresql survives restart (bug #1735)"): 63 machine.shutdown() 64 import time 65 time.sleep(2) 66 machine.start() 67 machine.wait_for_unit("postgresql") 68 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)) 73 74 with subtest("Backup service works"): 75 machine.succeed( 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", 80 ) 81 with subtest("Backup service removes prev files"): 82 machine.succeed( 83 # Create dummy prev files. 84 "touch ${backupFileBase}.prev.sql{,.gz,.zstd}", 85 "chown postgres:postgres ${backupFileBase}.prev.sql{,.gz,.zstd}", 86 87 # Run backup. 88 "systemctl start ${backupService}.service", 89 "ls -hal /var/backup/postgresql/ >/dev/console", 90 91 # Since nothing has changed in the database, the cur and prev files 92 # should match. 93 "zcat ${backupFileBase}.sql.gz | grep '<test>ok</test>'", 94 "cmp ${backupFileBase}.sql.gz ${backupFileBase}.prev.sql.gz", 95 96 # The prev files with unused suffix should be removed. 97 "[ ! -f '${backupFileBase}.prev.sql' ]", 98 "[ ! -f '${backupFileBase}.prev.sql.zstd' ]", 99 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", 103 ) 104 with subtest("Backup service fails gracefully"): 105 # Sabotage the backup process 106 machine.succeed("rm /run/postgresql/.s.PGSQL.5432") 107 machine.fail( 108 "systemctl start ${backupService}.service", 109 ) 110 machine.succeed( 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", 114 ) 115 # In a previous version, the second run would overwrite prev.sql.gz, 116 # so we test a second run as well. 117 machine.fail( 118 "systemctl start ${backupService}.service", 119 ) 120 machine.succeed( 121 "stat ${backupFileBase}.in-progress.sql.gz", 122 "zcat ${backupFileBase}.prev.sql.gz | grep '<test>ok</test>'", 123 ) 124 125 126 with subtest("Initdb works"): 127 machine.succeed("sudo -u postgres initdb -D /tmp/testpostgres2") 128 129 machine.shutdown() 130 ''; 131 132 }; 133 134 mk-ensure-clauses-test = postgresql-name: postgresql-package: makeTest { 135 name = postgresql-name; 136 meta = with pkgs.lib.maintainers; { 137 maintainers = [ zagy ]; 138 }; 139 140 nodes.machine = {...}: 141 { 142 services.postgresql = { 143 enable = true; 144 package = postgresql-package; 145 ensureUsers = [ 146 { 147 name = "all-clauses"; 148 ensureClauses = { 149 superuser = true; 150 createdb = true; 151 createrole = true; 152 "inherit" = true; 153 login = true; 154 replication = true; 155 bypassrls = true; 156 }; 157 } 158 { 159 name = "default-clauses"; 160 } 161 ]; 162 }; 163 }; 164 165 testScript = let 166 getClausesQuery = user: pkgs.lib.concatStringsSep " " 167 [ 168 "SELECT row_to_json(row)" 169 "FROM (" 170 "SELECT" 171 "rolsuper," 172 "rolinherit," 173 "rolcreaterole," 174 "rolcreatedb," 175 "rolcanlogin," 176 "rolreplication," 177 "rolbypassrls" 178 "FROM pg_roles" 179 "WHERE rolname = '${user}'" 180 ") row;" 181 ]; 182 in '' 183 import json 184 machine.start() 185 machine.wait_for_unit("postgresql") 186 187 with subtest("All user permissions are set according to the ensureClauses attr"): 188 clauses = json.loads( 189 machine.succeed( 190 "sudo -u postgres psql -tc \"${getClausesQuery "all-clauses"}\"" 191 ) 192 ) 193 print(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' 201 202 with subtest("All user permissions default when ensureClauses is not provided"): 203 clauses = json.loads( 204 machine.succeed( 205 "sudo -u postgres psql -tc \"${getClausesQuery "default-clauses"}\"" 206 ) 207 ) 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' 215 216 machine.shutdown() 217 ''; 218 }; 219in 220 concatMapAttrs (name: package: { 221 ${name} = make-postgresql-test name package false; 222 ${name + "-clauses"} = mk-ensure-clauses-test name package; 223 }) postgresql-versions 224 // { 225 postgresql_11-backup-all = make-postgresql-test "postgresql_11-backup-all" postgresql-versions.postgresql_11 true; 226 }