From aa01fb4e175b5c7c77c47e8e526af0c93cd8e140 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliv=C3=A9r=20Falvai?= Date: Wed, 15 Jan 2025 21:14:31 +0100 Subject: [PATCH] redisTestHook: init --- doc/hooks/redis-test-hook.section.md | 60 +++++++++++++++++++ pkgs/by-name/re/redisTestHook/package.nix | 17 ++++++ .../re/redisTestHook/redis-test-hook.sh | 33 ++++++++++ pkgs/by-name/re/redisTestHook/test.nix | 47 +++++++++++++++ 4 files changed, 157 insertions(+) create mode 100644 doc/hooks/redis-test-hook.section.md create mode 100644 pkgs/by-name/re/redisTestHook/package.nix create mode 100644 pkgs/by-name/re/redisTestHook/redis-test-hook.sh create mode 100644 pkgs/by-name/re/redisTestHook/test.nix diff --git a/doc/hooks/redis-test-hook.section.md b/doc/hooks/redis-test-hook.section.md new file mode 100644 index 000000000000..b14d29801a0e --- /dev/null +++ b/doc/hooks/redis-test-hook.section.md @@ -0,0 +1,60 @@ + +# `redisTestHook` {#sec-redisTestHook} + +This hook starts a Redis server during `checkPhase`. Example: + +```nix +{ + stdenv, + redis, + redisTestHook +}: +stdenv.mkDerivation { + + # ... + + nativeCheckInputs = [ + redisTestHook + ]; +} +``` + +If you use a custom `checkPhase`, remember to add the `runHook` calls: +```nix + checkPhase '' + runHook preCheck + + # ... your tests + + runHook postCheck + '' +``` + +## Variables {#sec-redisTestHook-variables} + +The hook logic will read the following variables and set them to a default value if unset or empty. + +Exported variables: + +- `REDIS_SOCKET`: UNIX domain socket path + +Bash-only variables: + + - `redisTestPort`: Port to use by Redis. Defaults to `6379` + +Example usage: + +```nix +{ stdenv, redis, redisTestHook }: +stdenv.mkDerivation { + + # ... + + nativeCheckInputs = [ + redisTestHook + ]; + + preCheck = '' + redisTestPort=6390 + '' +} diff --git a/pkgs/by-name/re/redisTestHook/package.nix b/pkgs/by-name/re/redisTestHook/package.nix new file mode 100644 index 000000000000..3cf244bd436a --- /dev/null +++ b/pkgs/by-name/re/redisTestHook/package.nix @@ -0,0 +1,17 @@ +{ + lib, + callPackage, + makeSetupHook, + redis, +}: + +makeSetupHook { + name = "redis-test-hook"; + substitutions = { + cli = lib.getExe' redis "redis-cli"; + server = lib.getExe' redis "redis-server"; + }; + passthru.tests = { + simple = callPackage ./test.nix { }; + }; +} ./redis-test-hook.sh diff --git a/pkgs/by-name/re/redisTestHook/redis-test-hook.sh b/pkgs/by-name/re/redisTestHook/redis-test-hook.sh new file mode 100644 index 000000000000..58496021760c --- /dev/null +++ b/pkgs/by-name/re/redisTestHook/redis-test-hook.sh @@ -0,0 +1,33 @@ +preCheckHooks+=('redisStart') +postCheckHooks+=('redisStop') + + +redisStart() { + if [[ "${redisTestPort:-}" == "" ]]; then + redisTestPort=6379 + fi + + if [[ "${REDIS_SOCKET:-}" == "" ]]; then + mkdir -p "$NIX_BUILD_TOP/run/" + REDIS_SOCKET="$NIX_BUILD_TOP/run/redis.sock" + fi + export REDIS_SOCKET + + echo 'starting redis' + + # Note about Darwin: unless the output is redirected, the parent process becomes launchd instead of bash. + # This would leave the Redis process running in case of a test failure (the postCheckHook would not be executed), + # hanging the Nix build forever. + @server@ --unixsocket "$REDIS_SOCKET" --port "$redisTestPort" > /dev/null 2>&1 & + REDIS_PID=$! + + echo 'waiting for redis to be ready' + while ! @cli@ --scan -s "$REDIS_SOCKET" ; do + sleep 1 + done +} + +redisStop() { + echo 'stopping redis' + kill "$REDIS_PID" +} diff --git a/pkgs/by-name/re/redisTestHook/test.nix b/pkgs/by-name/re/redisTestHook/test.nix new file mode 100644 index 000000000000..d3b5ac33ff4e --- /dev/null +++ b/pkgs/by-name/re/redisTestHook/test.nix @@ -0,0 +1,47 @@ +{ + redis, + redisTestHook, + stdenv, +}: + +stdenv.mkDerivation { + name = "redis-test-hook-test"; + + nativeCheckInputs = [ + redis + redisTestHook + ]; + + dontUnpack = true; + doCheck = true; + + preCheck = '' + redisTestPort=6380 + REDIS_SOCKET=/tmp/customredis.sock + ''; + + checkPhase = '' + runHook preCheck + + echo "running test" + if redis-cli --scan -p $redisTestPort; then + echo "connected to redis via localhost" + PORT_TEST_RAN=1 + fi + + if redis-cli --scan -s $REDIS_SOCKET; then + echo "connected to redis via domain socket" + SOCKET_TEST_RAN=1 + fi + + runHook postCheck + ''; + + installPhase = '' + [[ $PORT_TEST_RAN == 1 && $SOCKET_TEST_RAN == 1 ]] + echo "test passed" + touch $out + ''; + + __darwinAllowLocalNetworking = true; +}