-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
test(refactor): add withToxiproxy* in withTools #4833
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,6 +8,7 @@ | |
| , python3Packages | ||
| , writeText | ||
| , writers | ||
| , toxiproxy | ||
| }: | ||
| let | ||
| withTmpDb = | ||
|
|
@@ -54,16 +55,25 @@ let | |
|
|
||
| export PGDATA="$tmpdir/db" | ||
| export PGHOST="$tmpdir/socket" | ||
| PGPORT=$(${randomPort}) | ||
| export PGPORT | ||
| export PGUSER | ||
| export PGDATABASE | ||
| export PGRST_DB_SCHEMAS | ||
| export PGTZ | ||
| export PGOPTIONS | ||
|
|
||
| HBA_FILE="$tmpdir/pg_hba.conf" | ||
| echo "local $PGDATABASE some_protected_user password" > "$HBA_FILE" | ||
| echo "local $PGDATABASE all trust" >> "$HBA_FILE" | ||
| echo "local replication all trust" >> "$HBA_FILE" | ||
| { | ||
| echo "local $PGDATABASE some_protected_user password" | ||
| echo "local $PGDATABASE all trust" | ||
| echo "local replication all trust" | ||
| echo "host $PGDATABASE some_protected_user localhost password" | ||
| echo "host $PGDATABASE all localhost trust" | ||
| } >> "$HBA_FILE" | ||
|
|
||
| UNIX_PGHOST="$PGHOST" | ||
| export TCP_PGHOST="localhost" | ||
|
|
||
| log "Initializing database cluster..." | ||
| # We try to make the database cluster as independent as possible from the host | ||
|
|
@@ -80,7 +90,7 @@ let | |
| # On MacOS, it's 104 chars | ||
| # See: https://serverfault.com/questions/641347/check-if-a-path-exceeds-maximum-for-unix-domain-socket | ||
|
|
||
| pg_ctl -l "$tmpdir/db.log" -w start -o "-F -c listen_addresses=\"\" -c hba_file=$HBA_FILE -k $PGHOST -c log_statement=\"all\" " \ | ||
| pg_ctl -l "$tmpdir/db.log" -w start -o "-F -c listen_addresses=\"$TCP_PGHOST\" -c hba_file=$HBA_FILE -k $UNIX_PGHOST -c log_statement=\"all\" " \ | ||
| >> "$setuplog" | ||
|
|
||
| log "Creating a minimally privileged $PGUSER connection role..." | ||
|
|
@@ -93,6 +103,7 @@ let | |
| replica_slot="replica_$RANDOM" | ||
| replica_dir="$tmpdir/$replica_slot" | ||
| replica_host="$tmpdir/socket_$replica_slot" | ||
| replica_port=$(${randomPort}) | ||
|
|
||
| mkdir -p "$replica_host" | ||
|
|
||
|
|
@@ -106,15 +117,16 @@ let | |
| log "Starting replica on $replica_host" | ||
|
|
||
| # We set a low max_standby_streaming_delay to make the replication conflict fail faster in tests (otherwise it waits for the default 30s) | ||
| pg_ctl -D "$replica_dir" -l "$replica_dblog" -w start -o "-F -c listen_addresses=\"\" -c hba_file=$HBA_FILE -k $replica_host -c log_statement=\"all\" -c max_standby_streaming_delay=\"3s\" " \ | ||
| pg_ctl -D "$replica_dir" -l "$replica_dblog" -w start -o "-F -c listen_addresses=\"$TCP_PGHOST\" -c port=$replica_port -c hba_file=$HBA_FILE -k $replica_host -c log_statement=\"all\" -c max_standby_streaming_delay=\"3s\" " \ | ||
| >> "$setuplog" | ||
|
|
||
| >&2 echo "${commandName}: Replica enabled. You can connect to it with: psql 'postgres:///$PGDATABASE?host=$replica_host' -U postgres" | ||
| >&2 echo "${commandName}: You can tail the replica logs with: tail -f $replica_dblog" | ||
|
|
||
| export PGREPLICAHOST="$replica_host" | ||
| export PGREPLICAPORT="$replica_port" | ||
| export PGREPLICASLOT="$replica_slot" | ||
| export PGRST_DB_URI="postgres:///$PGDATABASE?host=$PGREPLICAHOST,$PGHOST" | ||
| export PGRST_DB_URI="postgres:///$PGDATABASE?host=$PGREPLICAHOST,$PGHOST&port=$replica_port,$PGPORT" | ||
| fi | ||
|
|
||
| # shellcheck disable=SC2329 | ||
|
|
@@ -372,6 +384,100 @@ let | |
| libraries = [ python3Packages.pandas python3Packages.tabulate python3Packages.psutil ]; | ||
| } | ||
| (builtins.readFile ./monitor_pid.py); | ||
|
|
||
| randomPort = | ||
| writers.writePython3 "postgrest-random-port" | ||
| { } | ||
| '' | ||
| import socket | ||
| s = socket.socket() | ||
| s.bind(("127.0.0.1", 0)) | ||
| print(s.getsockname()[1]) | ||
| s.close() | ||
| ''; | ||
|
|
||
| withToxiproxyProxy = | ||
| checkedShellScript | ||
| { | ||
| name = "postgrest-with-toxiproxy-proxy"; | ||
| docs = "Run <command> with Toxiproxy proxy created."; | ||
| args = | ||
| [ | ||
| "ARG_POSITIONAL_SINGLE([command], [Command to run])" | ||
| "ARG_LEFTOVERS([command arguments])" | ||
| "ARG_OPTIONAL_SINGLE([listen], [l], [Proxy will listen on this address])" | ||
| "ARG_OPTIONAL_SINGLE([upstream], [u], [Proxy will forward to this address])" | ||
| ]; | ||
| positionalCompletion = "_command"; | ||
| workingDir = "/"; | ||
| withPath = [ toxiproxy ]; | ||
| } | ||
| '' | ||
| proxyname="tp$RANDOM" | ||
| toxiproxy-cli create -l "$_arg_listen" -u "$_arg_upstream" "$proxyname" | ||
|
|
||
| # shellcheck disable=SC2329 | ||
| stop () { | ||
|
wolfgangwalther marked this conversation as resolved.
|
||
| toxiproxy-cli delete "$proxyname" || true | ||
| } | ||
| trap stop EXIT | ||
|
|
||
| (TOXI_PROXY_NAME="$proxyname" "$_arg_command" "''${_arg_leftovers[@]}") | ||
| ''; | ||
|
|
||
| withToxiproxyPg = | ||
| checkedShellScript | ||
| { | ||
| name = "postgrest-with-toxiproxy-pg"; | ||
| docs = "Run <command> with a Toxiproxy proxy to PostgreSQL."; | ||
| args = | ||
| [ | ||
| "ARG_POSITIONAL_SINGLE([command], [Command to run])" | ||
| "ARG_LEFTOVERS([command arguments])" | ||
| "ARG_USE_ENV([TCP_PGHOST], [], [PG host name])" | ||
| "ARG_USE_ENV([PGPORT], [], [PG port])" | ||
| ]; | ||
| positionalCompletion = "_command"; | ||
| workingDir = "/"; | ||
| } | ||
| '' | ||
| proxy_port=''$(${randomPort}) | ||
|
|
||
| ${withToxiproxy} ${withToxiproxyProxy} -l "$TCP_PGHOST:$proxy_port" -u "$TCP_PGHOST:$PGPORT" \ | ||
| env "TOXI_PGPORT=$proxy_port" "$_arg_command" "''${_arg_leftovers[@]}" | ||
|
Comment on lines
+444
to
+447
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think a better user-interface would be something where The addition of WDYT?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point - if we don't need unix socket access then I agree. |
||
| ''; | ||
|
|
||
| withToxiproxy = | ||
| checkedShellScript | ||
| { | ||
| name = "postgrest-with-toxiproxy"; | ||
| docs = "Run <command> with toxiproxy-server"; | ||
| args = | ||
| [ | ||
| "ARG_POSITIONAL_SINGLE([command], [Command to run])" | ||
| "ARG_LEFTOVERS([command arguments])" | ||
| ]; | ||
| positionalCompletion = "_command"; | ||
| workingDir = "/"; | ||
| withPath = [ toxiproxy ]; | ||
| } | ||
| '' | ||
| if ! test -v TOXI_PROXY; then | ||
| export TOXI_PROXY="" | ||
| LOG_LEVEL=error toxiproxy-server& | ||
| TOXIPROXY_PID=$! | ||
| sleep 1 # give the server a moment to start | ||
|
|
||
| # shellcheck disable=SC2329 | ||
| stop () { | ||
| kill "$TOXIPROXY_PID" || true | ||
| wait "$TOXIPROXY_PID" || true | ||
| } | ||
| trap stop EXIT | ||
| fi | ||
| ("$_arg_command" "''${_arg_leftovers[@]}") | ||
| ''; | ||
|
|
||
| in | ||
| buildToolbox | ||
| { | ||
|
|
@@ -380,11 +486,12 @@ buildToolbox | |
| inherit | ||
| withGit | ||
| withPgAll | ||
| withPgrst; | ||
| withPgrst | ||
| withToxiproxyPg; | ||
| } // builtins.listToAttrs ( | ||
| # Create a `postgrest-with-pg-` for each PostgreSQL version | ||
| builtins.map (pg: { inherit (pg) name; value = withTmpDb pg; }) postgresqlVersions | ||
| ); | ||
| # make latest withPg available for other nix files | ||
| extra = { inherit withPg; }; | ||
| extra = { inherit withPg withToxiproxyPg; }; | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure whether we still need to keep unix sockets here at all. We originally did this to prevent port-in-use errors during tests. We now need to add the complexity of finding the right port etc. - so there is no point in keeping additional complexity in supporting both unix sockets and tcp.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd agree. The only thing is load tests and the performance impact (if any) of running them with TCP.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why don't we create another dedicated test suite like
postgrest-test-recovery(suggested before here) only focused on TCP? That way we don't have to modify previous test infra?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fine for me.
In #4860 I've extracted a (private) library
test-utilsthat should be shared across different test suites and will make creating additional test suites easier.But I don't think it is relevant to this PR really (see below).
This PR does not really change anything in existing infra (except starting the db server on TCP in addition to unix socket, which required very small adjustments in tests - adding explicit
PGPORT)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That looks like a change, unless if it was gated by bool env var like:
postgrest/nix/tools/withTools.nix
Line 33 in 08ec8d1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Essentially, I conclude the same in #4868. I would not call it "recovery", see my reasoning in that issue. The key thing is: I don't want to run TCP connections on the host system, because that just leads to port conflicts down the road - we've always had these eventually.
See that same issue above why I think what we're currently doing in the
observabilitytest suite is fundamentally wrong - and as such that PR is, too. We can't really use haskell code to "inspect" PostgREST, because we'd always only test the library, not the executable in its entirety. Which is fine for some things, but surely not for listener related things.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's obviously not true, see for example https://github.com/mkleczek/postgrest/blob/9af29496ad943381233d2752ca8f6dd6c10487c4/test/observability/Observation/ToxiSpec.hs#L43
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what the link is supposed to tell me, but it's certainly not a counter point to my argument. Just because you are testing the listener there, doesn't invalidate my point which is:
Your tests are not running the executable, they are using the still-not-split postgrest as a library.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then it is even more important to test the library, isn't it?
I am not sure I understand that. Listener is both a library and in the executable.
I know that, but I don't understand why it would invalidate the tests. There are various kinds of tests necessary to ensure high quality: unit tests, white box tests, black box tests - all with different trade-offs.
You could use the same argument for
postgrest-test-spec- they don't test the whole executable. It does not make them invalid or not useful.And again - there are good arguments for writing tests in Haskell - that already was discussed in #4671.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this discussion is probably better off in #4868, because many of the points you are addressing here, I already did there.