Skip to content

Commit 4edd002

Browse files
committed
test(refactor): add withToxiproxy* in withTools
This commit introduces toxiproxy in withTools adding the following helpers: * withToxiproxyServer * withToxiproxyProxy * withToxiproxyPgProxy
1 parent de4ad62 commit 4edd002

4 files changed

Lines changed: 119 additions & 10 deletions

File tree

nix/tools/withTools.nix

Lines changed: 112 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
, python3Packages
99
, writeText
1010
, writers
11+
, toxiproxy
1112
}:
1213
let
1314
withTmpDb =
@@ -54,16 +55,25 @@ let
5455
5556
export PGDATA="$tmpdir/db"
5657
export PGHOST="$tmpdir/socket"
58+
PGPORT=$(${randomPort})
59+
export PGPORT
5760
export PGUSER
5861
export PGDATABASE
5962
export PGRST_DB_SCHEMAS
6063
export PGTZ
6164
export PGOPTIONS
6265
6366
HBA_FILE="$tmpdir/pg_hba.conf"
64-
echo "local $PGDATABASE some_protected_user password" > "$HBA_FILE"
65-
echo "local $PGDATABASE all trust" >> "$HBA_FILE"
66-
echo "local replication all trust" >> "$HBA_FILE"
67+
{
68+
echo "local $PGDATABASE some_protected_user password"
69+
echo "local $PGDATABASE all trust"
70+
echo "local replication all trust"
71+
echo "host $PGDATABASE some_protected_user localhost password"
72+
echo "host $PGDATABASE all localhost trust"
73+
} >> "$HBA_FILE"
74+
75+
UNIX_PGHOST="$PGHOST"
76+
export TCP_PGHOST="localhost"
6777
6878
log "Initializing database cluster..."
6979
# We try to make the database cluster as independent as possible from the host
@@ -80,7 +90,7 @@ let
8090
# On MacOS, it's 104 chars
8191
# See: https://serverfault.com/questions/641347/check-if-a-path-exceeds-maximum-for-unix-domain-socket
8292
83-
pg_ctl -l "$tmpdir/db.log" -w start -o "-F -c listen_addresses=\"\" -c hba_file=$HBA_FILE -k $PGHOST -c log_statement=\"all\" " \
93+
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\" " \
8494
>> "$setuplog"
8595
8696
log "Creating a minimally privileged $PGUSER connection role..."
@@ -93,6 +103,7 @@ let
93103
replica_slot="replica_$RANDOM"
94104
replica_dir="$tmpdir/$replica_slot"
95105
replica_host="$tmpdir/socket_$replica_slot"
106+
replica_port=$(${randomPort})
96107
97108
mkdir -p "$replica_host"
98109
@@ -105,15 +116,16 @@ let
105116
106117
log "Starting replica on $replica_host"
107118
108-
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\" " \
119+
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\" " \
109120
>> "$setuplog"
110121
111122
>&2 echo "${commandName}: Replica enabled. You can connect to it with: psql 'postgres:///$PGDATABASE?host=$replica_host' -U postgres"
112123
>&2 echo "${commandName}: You can tail the replica logs with: tail -f $replica_dblog"
113124
114125
export PGREPLICAHOST="$replica_host"
126+
export PGREPLICAPORT="$replica_port"
115127
export PGREPLICASLOT="$replica_slot"
116-
export PGRST_DB_URI="postgres:///$PGDATABASE?host=$PGREPLICAHOST,$PGHOST"
128+
export PGRST_DB_URI="postgres:///$PGDATABASE?host=$PGREPLICAHOST,$PGHOST&port=$replica_port,$PGPORT"
117129
fi
118130
119131
# shellcheck disable=SC2329
@@ -371,6 +383,99 @@ let
371383
libraries = [ python3Packages.pandas python3Packages.tabulate python3Packages.psutil ];
372384
}
373385
(builtins.readFile ./monitor_pid.py);
386+
387+
randomPort =
388+
writers.writePython3 "postgrest-random-port"
389+
{
390+
# Quick one-liner: ignore linting errors
391+
flakeIgnore = [ "E702" "W292" "E501" ];
392+
}
393+
''import socket; s = socket.socket(); s.bind(("127.0.0.1", 0)); print(s.getsockname()[1]); s.close()'';
394+
395+
withToxiproxyProxy =
396+
checkedShellScript
397+
{
398+
name = "postgrest-with-toxiproxy-proxy";
399+
docs = "Run <command> with Toxiproxy proxy created. Proxy name passed as TOXI_PROXY_NAME env variable.";
400+
args =
401+
[
402+
"ARG_POSITIONAL_SINGLE([command], [Command to run])"
403+
"ARG_LEFTOVERS([command arguments])"
404+
"ARG_OPTIONAL_SINGLE([listen], [l], [Proxy will listen on this address])"
405+
"ARG_OPTIONAL_SINGLE([upstream], [u], [Proxy will forward to this address])"
406+
];
407+
positionalCompletion = "_command";
408+
workingDir = "/";
409+
withPath = [ toxiproxy ];
410+
}
411+
''
412+
proxyname="tp$RANDOM"
413+
toxiproxy-cli create -l "$_arg_listen" -u "$_arg_upstream" "$proxyname"
414+
415+
# shellcheck disable=SC2317
416+
# shellcheck disable=SC2329
417+
stop () {
418+
toxiproxy-cli delete "$proxyname" || true
419+
}
420+
trap stop EXIT
421+
422+
(TOXI_PROXY_NAME="$proxyname" "$_arg_command" "''${_arg_leftovers[@]}")
423+
'';
424+
425+
withToxiproxyPgProxy =
426+
checkedShellScript
427+
{
428+
name = "postgrest-with-toxiproxy-pg-proxy";
429+
docs = "Run <command> with a Toxiproxy proxy to PosgreSQL.";
430+
args =
431+
[
432+
"ARG_POSITIONAL_SINGLE([command], [Command to run])"
433+
"ARG_LEFTOVERS([command arguments])"
434+
"ARG_USE_ENV([TCP_PGHOST], [], [PG host name])"
435+
"ARG_USE_ENV([PGPORT], [], [PG port])"
436+
];
437+
positionalCompletion = "_command";
438+
workingDir = "/";
439+
}
440+
''
441+
proxy_port=''$(${randomPort})
442+
443+
${withToxiproxyServer} ${withToxiproxyProxy} -l "$TCP_PGHOST:$proxy_port" -u "$TCP_PGHOST:$PGPORT" \
444+
env "TOXI_PGPORT=$proxy_port" "$_arg_command" "''${_arg_leftovers[@]}"
445+
'';
446+
447+
withToxiproxyServer =
448+
checkedShellScript
449+
{
450+
name = "postgrest-with-toxiproxy-server";
451+
docs = "Run <command> with toxiproxy-server";
452+
args =
453+
[
454+
"ARG_POSITIONAL_SINGLE([command], [Command to run])"
455+
"ARG_LEFTOVERS([command arguments])"
456+
];
457+
positionalCompletion = "_command";
458+
workingDir = "/";
459+
withPath = [ toxiproxy ];
460+
}
461+
''
462+
if ! test -v TOXI_PROXY; then
463+
export TOXI_PROXY=""
464+
LOG_LEVEL=error toxiproxy-server&
465+
TOXIPROXY_PID=$!
466+
sleep 1 # give the server a moment to start
467+
468+
# shellcheck disable=SC2317
469+
# shellcheck disable=SC2329
470+
stop () {
471+
kill "$TOXIPROXY_PID" || true
472+
wait "$TOXIPROXY_PID" || true
473+
}
474+
trap stop EXIT
475+
fi
476+
("$_arg_command" "''${_arg_leftovers[@]}")
477+
'';
478+
374479
in
375480
buildToolbox
376481
{
@@ -385,5 +490,5 @@ buildToolbox
385490
builtins.map (pg: { inherit (pg) name; value = withTmpDb pg; }) postgresqlVersions
386491
);
387492
# make latest withPg available for other nix files
388-
extra = { inherit withPg; };
493+
extra = { inherit withPg withToxiproxyPgProxy; };
389494
}

test/io/conftest.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@ def dburi():
99
"Postgres database connection URI."
1010
dbname = os.environ["PGDATABASE"]
1111
host = os.environ["PGHOST"]
12+
port = os.environ["PGPORT"]
1213
user = os.environ["PGUSER"]
13-
return f"postgresql://?dbname={dbname}&host={host}&user={user}".encode()
14+
return f"postgresql://?dbname={dbname}&host={host}&port={port}&user={user}".encode()
1415

1516

1617
@pytest.fixture
@@ -19,6 +20,7 @@ def baseenv():
1920
return {
2021
"PGDATABASE": os.environ["PGDATABASE"],
2122
"PGHOST": os.environ["PGHOST"],
23+
"PGPORT": os.environ["PGPORT"],
2224
"PGUSER": os.environ["PGUSER"],
2325
}
2426

@@ -51,6 +53,7 @@ def replicaenv(defaultenv):
5153
**defaultenv,
5254
**conf,
5355
"PGHOST": os.environ["PGREPLICAHOST"] + "," + os.environ["PGHOST"],
56+
"PGPORT": os.environ["PGREPLICAPORT"] + "," + os.environ["PGPORT"],
5457
"PGREPLICASLOT": os.environ["PGREPLICASLOT"],
5558
},
5659
}
@@ -76,6 +79,7 @@ def metapostgrest():
7679
env = {
7780
"PGDATABASE": os.environ["PGDATABASE"],
7881
"PGHOST": os.environ["PGHOST"],
82+
"PGPORT": os.environ["PGPORT"],
7983
"PGUSER": role,
8084
"PGRST_DB_ANON_ROLE": role,
8185
"PGRST_DB_CONFIG": "true",

test/io/test_auth.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ def relativeSeconds(sec):
165165

166166
def test_fail_with_invalid_password(defaultenv):
167167
"Connecting with an invalid password should fail without retries."
168-
uri = f'postgresql://?dbname={defaultenv["PGDATABASE"]}&host={defaultenv["PGHOST"]}&user=some_protected_user&password=invalid_pass'
168+
uri = f'postgresql://?dbname={defaultenv["PGDATABASE"]}&host={defaultenv["PGHOST"]}&port={defaultenv["PGPORT"]}&user=some_protected_user&password=invalid_pass'
169169
env = {**defaultenv, "PGRST_DB_URI": uri}
170170
with run(env=env, wait_for_readiness=False) as postgrest:
171171
exitCode = wait_until_exit(postgrest)

test/io/test_io.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1849,7 +1849,7 @@ def test_log_listener_connection_start(defaultenv):
18491849
# Check for the listener start message containing host and port
18501850
# Do not check if pg version is displayed properly as it is tricky to test it
18511851
assert any(
1852-
f'"{defaultenv["PGHOST"]}:5432" and listening for database notifications on the "pgrst" channel'
1852+
f'"{defaultenv["PGHOST"]}:{defaultenv["PGPORT"]}" and listening for database notifications on the "pgrst" channel'
18531853
in line
18541854
for line in output
18551855
)

0 commit comments

Comments
 (0)