base16-schemes: unstable-2024-06-21 -> unstable-2024-11-12
[NixPkgs.git] / nixos / tests / postgresql / postgresql-wal-receiver.nix
blob579a56153386ea72821769267153dfbf1689deb1
2   pkgs,
3   makeTest,
4 }:
6 let
7   inherit (pkgs) lib;
9   makeTestFor =
10     package:
11     let
12       postgresqlDataDir = "/var/lib/postgresql/${package.psqlSchema}";
13       replicationUser = "wal_receiver_user";
14       replicationSlot = "wal_receiver_slot";
15       replicationConn = "postgresql://${replicationUser}@localhost";
16       baseBackupDir = "/var/cache/wals/pg_basebackup";
17       walBackupDir = "/var/cache/wals/pg_wal";
18       recoveryFile = pkgs.writeTextDir "recovery.signal" "";
19     in
20     makeTest {
21       name = "postgresql-wal-receiver-${package.name}";
22       meta.maintainers = with lib.maintainers; [ pacien ];
24       nodes.machine =
25         { ... }:
26         {
27           systemd.tmpfiles.rules = [
28             "d /var/cache/wals 0750 postgres postgres - -"
29           ];
31           services.postgresql = {
32             inherit package;
33             enable = true;
34             enableJIT = lib.hasInfix "-jit-" package.name;
35             settings = {
36               max_replication_slots = 10;
37               max_wal_senders = 10;
38               recovery_end_command = "touch recovery.done";
39               restore_command = "cp ${walBackupDir}/%f %p";
40               wal_level = "archive"; # alias for replica on pg >= 9.6
41             };
42             authentication = ''
43               host replication ${replicationUser} all trust
44             '';
45             initialScript = pkgs.writeText "init.sql" ''
46               create user ${replicationUser} replication;
47               select * from pg_create_physical_replication_slot('${replicationSlot}');
48             '';
49           };
51           services.postgresqlWalReceiver.receivers.main = {
52             postgresqlPackage = package;
53             connection = replicationConn;
54             slot = replicationSlot;
55             directory = walBackupDir;
56           };
57           # This is only to speedup test, it isn't time racing. Service is set to autorestart always,
58           # default 60sec is fine for real system, but is too much for a test
59           systemd.services.postgresql-wal-receiver-main.serviceConfig.RestartSec = lib.mkForce 5;
60           systemd.services.postgresql.serviceConfig.ReadWritePaths = [ "/var/cache/wals" ];
61         };
63       testScript = ''
64         # make an initial base backup
65         machine.wait_for_unit("postgresql")
66         machine.wait_for_unit("postgresql-wal-receiver-main")
67         # WAL receiver healthchecks PG every 5 seconds, so let's be sure they have connected each other
68         # required only for 9.4
69         machine.sleep(5)
70         machine.succeed(
71             "${package}/bin/pg_basebackup --dbname=${replicationConn} --pgdata=${baseBackupDir}"
72         )
74         # create a dummy table with 100 records
75         machine.succeed(
76             "sudo -u postgres psql --command='create table dummy as select * from generate_series(1, 100) as val;'"
77         )
79         # stop postgres and destroy data
80         machine.systemctl("stop postgresql")
81         machine.systemctl("stop postgresql-wal-receiver-main")
82         machine.succeed("rm -r ${postgresqlDataDir}/{base,global,pg_*}")
84         # restore the base backup
85         machine.succeed(
86             "cp -r ${baseBackupDir}/* ${postgresqlDataDir} && chown postgres:postgres -R ${postgresqlDataDir}"
87         )
89         # prepare WAL and recovery
90         machine.succeed("chmod a+rX -R ${walBackupDir}")
91         machine.execute(
92             "for part in ${walBackupDir}/*.partial; do mv $part ''${part%%.*}; done"
93         )  # make use of partial segments too
94         machine.succeed(
95             "cp ${recoveryFile}/* ${postgresqlDataDir}/ && chmod 666 ${postgresqlDataDir}/recovery*"
96         )
98         # replay WAL
99         machine.systemctl("start postgresql")
100         machine.wait_for_file("${postgresqlDataDir}/recovery.done")
101         machine.systemctl("restart postgresql")
102         machine.wait_for_unit("postgresql")
104         # check that our records have been restored
105         machine.succeed(
106             "test $(sudo -u postgres psql --pset='pager=off' --tuples-only --command='select count(distinct val) from dummy;') -eq 100"
107         )
108       '';
109     };
111 lib.recurseIntoAttrs (
112   lib.concatMapAttrs (n: p: { ${n} = makeTestFor p; }) pkgs.postgresqlVersions
113   // {
114     passthru.override = p: makeTestFor p;
115   }