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; +}