summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobert Hensing <robert@roberthensing.nl>2022-04-16 17:17:46 +0200
committerRobert Hensing <robert@roberthensing.nl>2022-04-16 17:17:46 +0200
commite77e09c5d2d863d5b0500d08ee6afae7895da723 (patch)
treea88b22bda134039d2ff8b6b6ae90ce6fc58d0755
parent2f336f4efdcb4d02e3c5bedb43525e5af271137a (diff)
postgresqlTestHook: init
-rw-r--r--doc/hooks/index.xml10
-rw-r--r--doc/hooks/postgresql-test-hook.section.md59
-rw-r--r--doc/manual.xml1
-rw-r--r--pkgs/build-support/setup-hooks/postgresql-test-hook/default.nix9
-rw-r--r--pkgs/build-support/setup-hooks/postgresql-test-hook/postgresql-test-hook.sh79
-rw-r--r--pkgs/build-support/setup-hooks/postgresql-test-hook/test.nix27
-rw-r--r--pkgs/top-level/all-packages.nix2
7 files changed, 187 insertions, 0 deletions
diff --git a/doc/hooks/index.xml b/doc/hooks/index.xml
new file mode 100644
index 000000000000..dca07819c623
--- /dev/null
+++ b/doc/hooks/index.xml
@@ -0,0 +1,10 @@
+<chapter xmlns="http://docbook.org/ns/docbook"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:xi="http://www.w3.org/2001/XInclude"
+ xml:id="chap-hooks">
+ <title>Hooks reference</title>
+ <para>
+ Nixpkgs has several hook functions that add augment the stdenv phases.
+ </para>
+ <xi:include href="./postgresql-test-hook.section.xml" />
+</chapter>
diff --git a/doc/hooks/postgresql-test-hook.section.md b/doc/hooks/postgresql-test-hook.section.md
new file mode 100644
index 000000000000..077fac14ebbf
--- /dev/null
+++ b/doc/hooks/postgresql-test-hook.section.md
@@ -0,0 +1,59 @@
+
+# `postgresqlTestHook` {#sec-postgresqlTestHook}
+
+This hook starts a PostgreSQL server during the `checkPhase`. Example:
+
+```nix
+{ stdenv, postgresql, postgresqlTestHook }:
+stdenv.mkDerivation {
+
+ # ...
+
+ checkInputs = [
+ postgresql
+ postgresqlTestHook
+ ];
+}
+```
+
+If you use a custom `checkPhase`, remember to add the `runHook` calls:
+```nix
+ checkPhase ''
+ runHook preCheck
+
+ # ... your tests
+
+ runHook postCheck
+ ''
+```
+
+## Variables {#sec-postgresqlTestHook-variables}
+
+The hook logic will read a number of variables and set them to a default value if unset or empty.
+
+Exported variables:
+
+ - `PGDATA`: location of server files.
+ - `PGHOST`: location of UNIX domain socket directory; the default `host` in a connection string.
+ - `PGUSER`: user to create / log in with, default: `test_user`.
+ - `PGDATABASE`: database name, default: `test_db`.
+
+Bash-only variables:
+
+ - `postgresqlTestUserOptions`: SQL options to use when creating the `$PGUSER` role, default: `LOGIN`.
+ - `postgresqlTestSetupSQL`: SQL commands to run as database administrator after startup, default: statements that create `$PGUSER` and `$PGDATABASE`.
+ - `postgresqlTestSetupCommands`: bash commands to run after database start, defaults to running `$postgresqlTestSetupSQL` as database administrator.
+ - `postgresqlEnableTCP`: set to `1` to enable TCP listening. Flaky; not recommended.
+ - `postgresqlStartCommands`: defaults to `pg_ctl start`.
+
+## TCP and the Nix sandbox {#sec-postgresqlTestHook-tcp}
+
+`postgresqlEnableTCP` relies on network sandboxing, which is not available on macOS and some custom Nix installations, resulting in flaky tests.
+For this reason, it is disabled by default.
+
+The preferred solution is to make the test suite use a UNIX domain socket connection. This is the default behavior when no `host` connection parameter is provided.
+Some test suites hardcode a value for `host` though, so a patch may be required. If you can upstream the patch, you can make `host` default to the `PGHOST` environment variable when set. Otherwise, you can patch it locally to omit the `host` connection string parameter altogether.
+
+::: {.note}
+The error `libpq: failed (could not receive data from server: Connection refused` is generally an indication that the test suite is trying to connect through TCP.
+:::
diff --git a/doc/manual.xml b/doc/manual.xml
index b43021d85ca5..e49ae67ec943 100644
--- a/doc/manual.xml
+++ b/doc/manual.xml
@@ -27,6 +27,7 @@
<xi:include href="builders/trivial-builders.chapter.xml" />
<xi:include href="builders/special.xml" />
<xi:include href="builders/images.xml" />
+ <xi:include href="hooks/index.xml" />
<xi:include href="languages-frameworks/index.xml" />
<xi:include href="builders/packages/index.xml" />
</part>
diff --git a/pkgs/build-support/setup-hooks/postgresql-test-hook/default.nix b/pkgs/build-support/setup-hooks/postgresql-test-hook/default.nix
new file mode 100644
index 000000000000..d0031c93c10c
--- /dev/null
+++ b/pkgs/build-support/setup-hooks/postgresql-test-hook/default.nix
@@ -0,0 +1,9 @@
+{ callPackage, makeSetupHook }:
+
+(makeSetupHook {
+ name = "postgresql-test-hook";
+} ./postgresql-test-hook.sh).overrideAttrs (o: {
+ passthru.tests = {
+ simple = callPackage ./test.nix { };
+ };
+})
diff --git a/pkgs/build-support/setup-hooks/postgresql-test-hook/postgresql-test-hook.sh b/pkgs/build-support/setup-hooks/postgresql-test-hook/postgresql-test-hook.sh
new file mode 100644
index 000000000000..041a3f565332
--- /dev/null
+++ b/pkgs/build-support/setup-hooks/postgresql-test-hook/postgresql-test-hook.sh
@@ -0,0 +1,79 @@
+preCheckHooks+=('postgresqlStart')
+postCheckHooks+=('postgresqlStop')
+
+
+postgresqlStart() {
+
+ # Add default environment variable values
+ #
+ # Client variables:
+ # - https://www.postgresql.org/docs/current/libpq-envars.html
+ #
+ # Server variables:
+ # - only PGDATA: https://www.postgresql.org/docs/current/creating-cluster.html
+
+ if [[ "${PGDATA:-}" == "" ]]; then
+ PGDATA="$NIX_BUILD_TOP/postgresql"
+ fi
+ export PGDATA
+
+ if [[ "${PGHOST:-}" == "" ]]; then
+ mkdir -p "$NIX_BUILD_TOP/run/postgresql"
+ PGHOST="$NIX_BUILD_TOP/run/postgresql"
+ fi
+ export PGHOST
+
+ if [[ "${PGUSER:-}" == "" ]]; then
+ PGUSER="test_user"
+ fi
+ export PGUSER
+
+ if [[ "${PGDATABASE:-}" == "" ]]; then
+ PGDATABASE="test_db"
+ fi
+ export PGDATABASE
+
+ if [[ "${postgresqlTestUserOptions:-}" == "" ]]; then
+ postgresqlTestUserOptions="LOGIN"
+ fi
+
+ if [[ "${postgresqlTestSetupSQL:-}" == "" ]]; then
+ postgresqlTestSetupSQL="$(cat <<EOF
+ CREATE ROLE "$PGUSER" $postgresqlTestUserOptions;
+ CREATE DATABASE "$PGDATABASE" OWNER '$PGUSER';
+EOF
+ )"
+ fi
+
+ if [[ "${postgresqlTestSetupCommands:-}" == "" ]]; then
+ postgresqlTestSetupCommands='echo "$postgresqlTestSetupSQL" | PGUSER=postgres psql postgres'
+ fi
+
+ if ! type initdb >/dev/null; then
+ echo >&2 'initdb not found. Did you add postgresql to the checkInputs?'
+ false
+ fi
+ header 'initializing postgresql'
+ initdb -U postgres
+
+ # Move the socket
+ echo "unix_socket_directories = '$NIX_BUILD_TOP/run/postgresql'" >>"$PGDATA/postgresql.conf"
+
+ # TCP ports can be a problem in some sandboxes,
+ # so we disable tcp listening by default
+ if ! [[ "${postgresqlEnableTCP:-}" = 1 ]]; then
+ echo "listen_addresses = ''" >>"$PGDATA/postgresql.conf"
+ fi
+
+ header 'starting postgresql'
+ eval "${postgresqlStartCommands:-pg_ctl start}"
+
+ header 'setting up postgresql'
+ eval "$postgresqlTestSetupCommands"
+
+}
+
+postgresqlStop() {
+ header 'stopping postgresql'
+ pg_ctl stop
+}
diff --git a/pkgs/build-support/setup-hooks/postgresql-test-hook/test.nix b/pkgs/build-support/setup-hooks/postgresql-test-hook/test.nix
new file mode 100644
index 000000000000..6d8ad6c8c7e3
--- /dev/null
+++ b/pkgs/build-support/setup-hooks/postgresql-test-hook/test.nix
@@ -0,0 +1,27 @@
+{ postgresql, postgresqlTestHook, stdenv }:
+
+stdenv.mkDerivation {
+ name = "postgresql-test-hook-test";
+ buildInputs = [ postgresqlTestHook ];
+ checkInputs = [ postgresql ];
+ dontUnpack = true;
+ doCheck = true;
+ passAsFile = ["sql"];
+ sql = ''
+ CREATE TABLE hello (
+ message text
+ );
+ INSERT INTO hello VALUES ('it '||'worked');
+ SELECT * FROM hello;
+ '';
+ checkPhase = ''
+ runHook preCheck
+ psql <$sqlPath | grep 'it worked'
+ TEST_RAN=1
+ runHook postCheck
+ '';
+ installPhase = ''
+ [[ $TEST_RAN == 1 ]]
+ touch $out
+ '';
+}
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index 615bf750169f..12bec9613e6d 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -21965,6 +21965,8 @@ with pkgs;
postgresql_jdbc = callPackage ../development/java-modules/postgresql_jdbc { };
+ postgresqlTestHook = callPackage ../build-support/setup-hooks/postgresql-test-hook { };
+
prom2json = callPackage ../servers/monitoring/prometheus/prom2json.nix { };
prometheus = callPackage ../servers/monitoring/prometheus { };
prometheus-alertmanager = callPackage ../servers/monitoring/prometheus/alertmanager.nix { };