1let
2 pgheroPort = 1337;
3 pgheroUser = "pghero";
4 pgheroPass = "pghero";
5in
6{ lib, ... }:
7{
8 name = "pghero";
9 meta.maintainers = [ lib.maintainers.tie ];
10
11 nodes.machine =
12 { config, ... }:
13 {
14 services.postgresql = {
15 enable = true;
16 # This test uses default peer authentication (socket and its directory is
17 # world-readably by default), so we essentially test that we can connect
18 # with DynamicUser= set.
19 ensureUsers = [
20 {
21 name = "pghero";
22 ensureClauses.superuser = true;
23 }
24 ];
25 };
26 services.pghero = {
27 enable = true;
28 listenAddress = "[::]:${toString pgheroPort}";
29 settings = {
30 databases = {
31 postgres.url = "<%= ENV['POSTGRES_DATABASE_URL'] %>";
32 nulldb.url = "nulldb:///";
33 };
34 };
35 environment = {
36 PGHERO_USERNAME = pgheroUser;
37 PGHERO_PASSWORD = pgheroPass;
38 POSTGRES_DATABASE_URL = "postgresql:///postgres?host=/run/postgresql";
39 };
40 };
41 };
42
43 testScript = ''
44 pgheroPort = ${toString pgheroPort}
45 pgheroUser = "${pgheroUser}"
46 pgheroPass = "${pgheroPass}"
47
48 pgheroUnauthorizedURL = f"http://localhost:{pgheroPort}"
49 pgheroBaseURL = f"http://{pgheroUser}:{pgheroPass}@localhost:{pgheroPort}"
50
51 def expect_http_code(node, code, url):
52 http_code = node.succeed(f"curl -s -o /dev/null -w '%{{http_code}}' '{url}'")
53 assert http_code.split("\n")[-1].strip() == code, \
54 f"expected HTTP status code {code} but got {http_code}"
55
56 machine.wait_for_unit("postgresql.target")
57 machine.wait_for_unit("pghero.service")
58
59 with subtest("requires HTTP Basic Auth credentials"):
60 expect_http_code(machine, "401", pgheroUnauthorizedURL)
61
62 with subtest("works with some databases being unavailable"):
63 expect_http_code(machine, "500", pgheroBaseURL + "/nulldb")
64
65 with subtest("connects to the PostgreSQL database"):
66 expect_http_code(machine, "200", pgheroBaseURL + "/postgres")
67 '';
68}