Skip to content

Commit 6736e0c

Browse files
committed
test: add toxiproxy in front of postgresql in withTmpDb
Having toxiproxy between PostgREST and PostgreSQL in tests opens possibilities of validating behavior of PostgREST under various network conditions: temporary network partitioning, delays etc. This change adds toxiproxy startup and configuration to withTmpDb function in withTools.nix, so that all communication goes through it in tests.
1 parent 78f231c commit 6736e0c

4 files changed

Lines changed: 35 additions & 11 deletions

File tree

nix/tools/withTools.nix

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
, slocat
1010
, writeText
1111
, writers
12+
, toxiproxy
1213
}:
1314
let
1415
withTmpDb =
@@ -35,7 +36,7 @@ let
3536
positionalCompletion = "_command";
3637
workingDir = "/";
3738
redirectTixFiles = false;
38-
withPath = [ postgresql ];
39+
withPath = [ postgresql toxiproxy ];
3940
withTmpDir = true;
4041
}
4142
''
@@ -55,6 +56,7 @@ let
5556
5657
export PGDATA="$tmpdir/db"
5758
export PGHOST="$tmpdir/socket"
59+
export PGPORT=6432
5860
export PGUSER
5961
export PGDATABASE
6062
export PGRST_DB_SCHEMAS
@@ -63,8 +65,16 @@ let
6365
6466
HBA_FILE="$tmpdir/pg_hba.conf"
6567
echo "local $PGDATABASE some_protected_user password" > "$HBA_FILE"
66-
echo "local $PGDATABASE all trust" >> "$HBA_FILE"
67-
echo "local replication all trust" >> "$HBA_FILE"
68+
{
69+
echo "local $PGDATABASE all trust"
70+
echo "local replication all trust"
71+
echo "host $PGDATABASE all localhost trust"
72+
} >> "$HBA_FILE"
73+
74+
UNIX_PGHOST="$PGHOST"
75+
export TCP_PGHOST="localhost"
76+
REAL_PGPORT="$PGPORT"
77+
export TOXI_PGPORT=7432
6878
6979
log "Initializing database cluster..."
7080
# We try to make the database cluster as independent as possible from the host
@@ -81,9 +91,14 @@ let
8191
# On MacOS, it's 104 chars
8292
# See: https://serverfault.com/questions/641347/check-if-a-path-exceeds-maximum-for-unix-domain-socket
8393
84-
pg_ctl -l "$tmpdir/db.log" -w start -o "-F -c listen_addresses=\"\" -c hba_file=$HBA_FILE -k $PGHOST -c log_statement=\"all\" " \
94+
pg_ctl -l "$tmpdir/db.log" -w start -o "-F -c listen_addresses=\"$TCP_PGHOST\" -c port=$REAL_PGPORT -c hba_file=$HBA_FILE -k $UNIX_PGHOST -c log_statement=\"all\" " \
8595
>> "$setuplog"
8696
97+
LOG_LEVEL=error toxiproxy-server&
98+
TOXIPROXY_PID=$!
99+
sleep 1 # give the server a moment to start
100+
toxiproxy-cli create -l "$TCP_PGHOST:$TOXI_PGPORT" -u "$TCP_PGHOST:$REAL_PGPORT" pg
101+
87102
log "Creating a minimally privileged $PGUSER connection role..."
88103
createuser "$PGUSER" -U postgres --host="$tmpdir/socket" --no-createdb --no-inherit --no-superuser --no-createrole --no-replication --login
89104
@@ -94,6 +109,8 @@ let
94109
replica_slot="replica_$RANDOM"
95110
replica_dir="$tmpdir/$replica_slot"
96111
replica_host="$tmpdir/socket_$replica_slot"
112+
replica_port=6433
113+
TOXI_REPLICA_PGPORT=7433
97114
98115
mkdir -p "$replica_host"
99116
@@ -106,15 +123,17 @@ let
106123
107124
log "Starting replica on $replica_host"
108125
109-
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\" " \
126+
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\" " \
110127
>> "$setuplog"
128+
toxiproxy-cli create -l $TCP_PGHOST:$TOXI_REPLICA_PGPORT -u $TCP_PGHOST:$replica_port pg_replica
111129
112130
>&2 echo "${commandName}: Replica enabled. You can connect to it with: psql 'postgres:///$PGDATABASE?host=$replica_host' -U postgres"
113131
>&2 echo "${commandName}: You can tail the replica logs with: tail -f $replica_dblog"
114132
115-
export PGREPLICAHOST="$replica_host"
133+
export PGREPLICAHOST="$TCP_PGHOST"
134+
export PGREPLICAPORT="$TOXI_REPLICA_PGPORT"
116135
export PGREPLICASLOT="$replica_slot"
117-
export PGRST_DB_URI="postgres:///$PGDATABASE?host=$PGREPLICAHOST,$PGHOST"
136+
export PGRST_DB_URI="postgres:///$PGDATABASE?host=$PGREPLICAHOST,$TCP_PGHOST&port=$PGREPLICAPORT,$TOXI_PGPORT"
118137
fi
119138
120139
# shellcheck disable=SC2317
@@ -127,6 +146,8 @@ let
127146
pg_ctl -D "$replica_dir" stop --mode=immediate >> "$setuplog"
128147
rm -rf "$replica_dir"
129148
fi
149+
kill "$TOXIPROXY_PID" || true
150+
wait "$TOXIPROXY_PID" || true
130151
}
131152
trap stop EXIT
132153
fi
@@ -139,7 +160,7 @@ let
139160
>&2 printf " done in %ss. Running command...\n" "$load_end"
140161
fi
141162
142-
("$_arg_command" "''${_arg_leftovers[@]}")
163+
(PGHOST="$TCP_PGHOST" PGPORT="$TOXI_PGPORT" "$_arg_command" "''${_arg_leftovers[@]}")
143164
'';
144165

145166
# Helper script for running a command against all PostgreSQL versions.

test/io/conftest.py

Lines changed: 4 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

@@ -76,6 +78,7 @@ def metapostgrest():
7678
env = {
7779
"PGDATABASE": os.environ["PGDATABASE"],
7880
"PGHOST": os.environ["PGHOST"],
81+
"PGPORT": os.environ["PGPORT"],
7982
"PGUSER": role,
8083
"PGRST_DB_ANON_ROLE": role,
8184
"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
@@ -1653,7 +1653,7 @@ def test_log_listener_connection_start(defaultenv):
16531653
# Check for the listener start message containing host and port
16541654
# Do not check if pg version is displayed properly as it is tricky to test it
16551655
assert any(
1656-
f'"{defaultenv["PGHOST"]}:5432" and listening for database notifications on the "pgrst" channel'
1656+
f'"{defaultenv["PGHOST"]}:{defaultenv["PGPORT"]}" and listening for database notifications on the "pgrst" channel'
16571657
in line
16581658
for line in output
16591659
)

0 commit comments

Comments
 (0)