From 216dc833fdb9045add9504df2f9fae29ee9f6f4c Mon Sep 17 00:00:00 2001 From: Robert Vollmert Date: Fri, 24 Feb 2023 20:40:46 +0100 Subject: [PATCH] test: add optional latency to postgrest-loadtest This pipes data between client/postgrest and between postgrest/database through a proxy that adds delay (github.com/robx/slocat). --- default.nix | 1 + nix/README.md | 3 ++ nix/overlays/default.nix | 1 + nix/overlays/slocat.nix | 13 +++++++ nix/tools/loadtest.nix | 2 + nix/tools/withTools.nix | 80 +++++++++++++++++++++++++++++++++++++++- 6 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 nix/overlays/slocat.nix diff --git a/default.nix b/default.nix index ebad92df2..be3cb7382 100644 --- a/default.nix +++ b/default.nix @@ -41,6 +41,7 @@ let allOverlays.postgresql-legacy allOverlays.postgresql-future (allOverlays.haskell-packages { inherit compiler; }) + allOverlays.slocat ]; # Evaluated expression of the Nixpkgs repository. diff --git a/nix/README.md b/nix/README.md index de7018caf..2f67d90b7 100644 --- a/nix/README.md +++ b/nix/README.md @@ -204,6 +204,9 @@ postgrest-loadtest # You can loadtest comparing to a different branch postgrest-loadtest-against master +# You can simulate latency client/postgrest and postgrest/database +PGRST_DELAY=5ms PGDELAY=5ms postgrest-loadtest + # Produce a markdown report to be used on CI postgrest-loadtest-report ``` diff --git a/nix/overlays/default.nix b/nix/overlays/default.nix index 43d154868..8b0b3af4f 100644 --- a/nix/overlays/default.nix +++ b/nix/overlays/default.nix @@ -7,4 +7,5 @@ postgresql-default = import ./postgresql-default.nix; postgresql-legacy = import ./postgresql-legacy.nix; postgresql-future = import ./postgresql-future.nix; + slocat = import ./slocat.nix; } diff --git a/nix/overlays/slocat.nix b/nix/overlays/slocat.nix new file mode 100644 index 000000000..cb17963c0 --- /dev/null +++ b/nix/overlays/slocat.nix @@ -0,0 +1,13 @@ +final: prev: +{ + slocat = prev.buildGoModule { + name = "slocat"; + src = prev.fetchFromGitHub { + owner = "robx"; + repo = "slocat"; + rev = "52e7512c6029fd00483e41ccce260a3b4b9b3b64"; + sha256 = "sha256-qn6luuh5wqREu3s8RfuMCP5PKdS2WdwPrujRYTpfzQ8="; + }; + vendorSha256 = "sha256-pQpattmS9VmO3ZIQUFn66az8GSmB4IvYhTTCFn6SUmo="; + }; +} diff --git a/nix/tools/loadtest.nix b/nix/tools/loadtest.nix index 4c9e964e6..444499904 100644 --- a/nix/tools/loadtest.nix +++ b/nix/tools/loadtest.nix @@ -60,7 +60,9 @@ let # shellcheck disable=SC2145 ${withTools.withPg} --fixtures "$_arg_testdir"/fixtures.sql \ + ${withTools.withSlowPg} \ ${withTools.withPgrst} \ + ${withTools.withSlowPgrst} \ sh -c "cd \"$_arg_testdir\" && ${runner} -targets targets.http -output \"$abs_output\" \"''${_arg_leftovers[@]}\"" ${vegeta}/bin/vegeta report -type=text "$_arg_output" ''; diff --git a/nix/tools/withTools.nix b/nix/tools/withTools.nix index 7c7b2753e..c7dceb49b 100644 --- a/nix/tools/withTools.nix +++ b/nix/tools/withTools.nix @@ -8,6 +8,7 @@ , lib , postgresqlVersions , postgrest +, slocat , writeText }: let @@ -137,6 +138,81 @@ let withPg = builtins.head withPgVersions; + withSlowPg = + checkedShellScript + { + name = "postgrest-with-slow-pg"; + docs = "Run the given command with simulated high latency postgresql"; + args = + [ + "ARG_POSITIONAL_SINGLE([command], [Command to run])" + "ARG_LEFTOVERS([command arguments])" + "ARG_USE_ENV([PGHOST], [], [PG host (socket name)])" + "ARG_USE_ENV([PGDELAY], [0ms], [extra PG latency (duration)])" + ]; + positionalCompletion = "_command"; + inRootDir = true; + redirectTixFiles = false; + withTmpDir = true; + } + '' + delay="''${PGDELAY:-0ms}" + echo "delaying data to/from postgres by $delay" + + REALPGHOST="$PGHOST" + export PGHOST="$tmpdir/socket" + mkdir -p "$PGHOST" + + ${slocat}/bin/slocat -delay "$delay" -src "$PGHOST/.s.PGSQL.5432" -dst "$REALPGHOST/.s.PGSQL.5432" & + SLOCAT_PID=$! + # shellcheck disable=SC2317 + stop_slocat() { + kill "$SLOCAT_PID" || true + wait "$SLOCAT_PID" || true + } + trap stop_slocat EXIT + sleep 1 # should wait for socket file to appear instead + + ("$_arg_command" "''${_arg_leftovers[@]}") + ''; + + withSlowPgrst = + checkedShellScript + { + name = "postgrest-with-slow-postgrest"; + docs = "Run the given command with simulated high latency postgrest"; + args = + [ + "ARG_POSITIONAL_SINGLE([command], [Command to run])" + "ARG_LEFTOVERS([command arguments])" + "ARG_USE_ENV([PGRST_SERVER_UNIX_SOCKET], [], [PostgREST host (socket name)])" + "ARG_USE_ENV([PGRST_DELAY], [0ms], [extra PostgREST latency (duration)])" + ]; + positionalCompletion = "_command"; + inRootDir = true; + redirectTixFiles = false; + withTmpDir = true; + } + '' + delay="''${PGRST_DELAY:-0ms}" + echo "delaying data to/from PostgREST by $delay" + + REAL_PGRST_SERVER_UNIX_SOCKET="$PGRST_SERVER_UNIX_SOCKET" + export PGRST_SERVER_UNIX_SOCKET="$tmpdir/postgrest.socket" + + ${slocat}/bin/slocat -delay "$delay" -src "$PGRST_SERVER_UNIX_SOCKET" -dst "$REAL_PGRST_SERVER_UNIX_SOCKET" & + SLOCAT_PID=$! + # shellcheck disable=SC2317 + stop_slocat() { + kill "$SLOCAT_PID" || true + wait "$SLOCAT_PID" || true + } + trap stop_slocat EXIT + sleep 1 # should wait for socket file to appear instead + + ("$_arg_command" "''${_arg_leftovers[@]}") + ''; + withGit = let name = "postgrest-with-git"; @@ -288,7 +364,7 @@ in buildToolbox { name = "postgrest-with"; - tools = [ withPgAll withGit withPgrst ] ++ withPgVersions; + tools = [ withPgAll withGit withPgrst withSlowPg withSlowPgrst ] ++ withPgVersions; # make withTools available for other nix files - extra = { inherit withGit withPg withPgAll withPgrst; }; + extra = { inherit withGit withPg withPgAll withPgrst withSlowPg withSlowPgrst; }; }