Skip to content

Commit 16a7f47

Browse files
committed
test: add cloud test for reproducing timeouts
This uses NixOps wrapper scripts to reproduce #86. The steps are: ``` $ net-cloud-deploy $ net-cloud-reproduce-timeouts net-cloud-reproduce-timeouts NOTICE: Waiting until 10000 requests complete NOTICE: Stats: {"request_successes":8882,"request_failures":1118,"last_failure_error":"Timeout was reached"} NOTICE: Time taken: 00:01:44.341157 ``` Then destroy the cloud setup with `net-cloud-destroy`
1 parent 0debca9 commit 16a7f47

File tree

4 files changed

+117
-24
lines changed

4 files changed

+117
-24
lines changed

docs/contributing.md

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -72,28 +72,19 @@ $ sudo with-gdb -p 1145879
7272

7373
## Load Testing
7474

75-
This will deploy a client and server on t3a.nano. You must have `default` setup in `.aws/credentials`.
75+
These are scripts that wrap NixOps to deploy an AWS cloud setup. You must have `default` setup in `.aws/credentials`.
7676

7777
```bash
78-
cd nix
79-
80-
nixops create -d pg_net
81-
82-
# will take a while
83-
nixops deploy -k -d pg_net --allow-reboot --confirm
78+
net-cloud-deploy
8479
```
8580

8681
Then you can connect on the client instance and do requests to the server instance through `pg_net`.
8782

8883
```bash
89-
cd nix
90-
91-
nixops ssh -d pg_net client
84+
net-cloud-ssh
9285

9386
psql -U postgres
9487

95-
create extension pg_net;
96-
9788
select net.http_get('http://server');
9889
# this the default welcome page of nginx on the server instance
9990
# "server" is already included to /etc/hosts, so `curl http://server` will give the same result
@@ -103,13 +94,10 @@ select net.http_get('http://server') from generate_series(1,1000);
10394
# run `top` on another shell(another `nixops ssh -d pg_net client`) to check the worker behavior
10495
```
10596
106-
To destroy the instances:
97+
To destroy the cloud setup:
10798
10899
```bash
109-
cd nix
110-
111-
nixops destroy -d pg_net --confirm
112-
nixops delete -d pg_net
100+
net-cloud-destroy
113101
```
114102
115103
## Documentation

nix/nixops.nix

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -115,16 +115,44 @@ in {
115115
initialScript = pkgs.writeText "init-sql-script" ''
116116
create extension pg_net;
117117
118-
alter system set pg_net.batch_size to 32000;
119-
120-
select net.worker_restart();
121-
122118
create view pg_net_stats as
123119
select
124120
count(*) filter (where error_msg is null) as request_successes,
125121
count(*) filter (where error_msg is not null) as request_failures,
126122
(select error_msg from net._http_response where error_msg is not null order by id desc limit 1) as last_failure_error
127123
from net._http_response;
124+
125+
create or replace procedure repro_timeouts(number_of_requests int default 10000, url text default 'http://server/post') as ''$''$
126+
declare
127+
last_id bigint;
128+
first_time timestamptz;
129+
second_time timestamptz;
130+
time_taken interval;
131+
begin
132+
delete from net._http_response;
133+
134+
with do_requests as (
135+
select
136+
net.http_post(url, jsonb_build_object('id', x, 'message', 'payload ' || x), headers:=jsonb_build_object('Content-Type', 'application/json')) as id
137+
from generate_series (1, number_of_requests) x
138+
)
139+
select id, clock_timestamp() into last_id, first_time from do_requests offset number_of_requests - 1;
140+
141+
commit;
142+
143+
raise notice 'Waiting until % requests complete', number_of_requests;
144+
145+
perform net._await_response(last_id);
146+
147+
select clock_timestamp() into second_time;
148+
149+
select age(second_time, first_time) into time_taken;
150+
151+
raise notice 'Stats: %', (select to_json(x) from pg_net_stats x limit 1);
152+
153+
raise notice 'Time taken: %', time_taken;
154+
end;
155+
''$''$ language plpgsql;
128156
'';
129157
};
130158

@@ -136,22 +164,40 @@ in {
136164
pkgs.vegeta
137165
(
138166
pkgs.writeShellScriptBin "vegeta-bench" ''
167+
set -euo pipefail
168+
139169
# rate=0 means maximum rate subject to max-workers
140170
echo "GET http://server/pathological?status=200" | vegeta attack -rate=0 -duration=1s -max-workers=1 | tee results.bin | vegeta report
141171
''
142172
)
143173
(
144174
pkgs.writeShellScriptBin "vegeta-bench-max-requests" ''
175+
set -euo pipefail
176+
145177
# rate=0 means maximum rate subject to max-workers
146178
echo "GET http://server/pathological?status=200" | vegeta attack -rate=0 -duration=10s -max-workers=50 | tee results.bin | vegeta report
147179
''
148180
)
149181
(
150-
pkgs.writeShellScriptBin "net-bench" ''
182+
pkgs.writeShellScriptBin "psql-net-bench" ''
183+
set -euo pipefail
184+
185+
psql -U postgres -c "TRUNCATE net._http_response; TRUNCATE net.http_request_queue;"
186+
psql -U postgres -c "alter system set pg_net.batch_size to 32000;" # this just a high number
187+
psql -U postgres -c "select net.worker_restart();"
151188
psql -U postgres -c "truncate net._http_response;"
152189
psql -U postgres -c "select net.http_get('http://server/pathological?status=200') from generate_series(1, 400);" > /dev/null
153190
sleep 2
154191
psql -U postgres -c "select * from pg_net_stats;"
192+
psql -U postgres -c "alter system reset pg_net.batch_size;"
193+
psql -U postgres -c "select net.worker_restart();"
194+
''
195+
)
196+
(
197+
pkgs.writeShellScriptBin "psql-reproduce-timeouts" ''
198+
set -euo pipefail
199+
200+
psql -U postgres -c "call repro_timeouts();"
155201
''
156202
)
157203
];

nix/nixopsScripts.nix

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
{ nixops_unstable_minimal, writeShellScriptBin } :
2+
3+
let
4+
nixops = nixops_unstable_minimal.withPlugins (ps: [ ps.nixops-aws ]);
5+
nixopsBin = "${nixops}/bin/nixops";
6+
nixopsDeploy =
7+
writeShellScriptBin "net-cloud-deploy"
8+
''
9+
set -euo pipefail
10+
11+
cd nix
12+
13+
set +e && ${nixopsBin} info -d pg_net > /dev/null 2> /dev/null
14+
info=$? && set -e
15+
16+
if test $info -eq 1
17+
then
18+
echo "Creating deployment..."
19+
${nixopsBin} create -d pg_net
20+
fi
21+
22+
${nixopsBin} deploy -k -d pg_net --allow-reboot --confirm
23+
'';
24+
nixopsSSH =
25+
writeShellScriptBin ("net-cloud-ssh")
26+
''
27+
set -euo pipefail
28+
29+
cd nix
30+
31+
${nixopsBin} ssh -d pg_net client
32+
'';
33+
nixopsReproTimeouts =
34+
writeShellScriptBin ("net-cloud-reproduce-timeouts")
35+
''
36+
set -euo pipefail
37+
38+
cd nix
39+
40+
${nixopsBin} ssh -d pg_net client psql-reproduce-timeouts
41+
'';
42+
nixopsDestroy =
43+
writeShellScriptBin ("net-cloud-destroy")
44+
''
45+
set -euo pipefail
46+
47+
cd nix
48+
49+
${nixopsBin} destroy -d pg_net --confirm
50+
51+
${nixopsBin} delete -d pg_net
52+
'';
53+
in
54+
[
55+
nixopsDeploy
56+
nixopsSSH
57+
nixopsReproTimeouts
58+
nixopsDestroy
59+
]

shell.nix

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ mkShell {
1717
extAll = map (x: callPackage ./nix/pgScript.nix { postgresql = pgWithExt { pg = x;}; }) supportedPgVersions;
1818
nginxCustom = callPackage ./nix/nginxCustom.nix {};
1919
gdbScript = callPackage ./nix/gdbScript.nix {};
20+
nixopsScripts = callPackage ./nix/nixopsScripts.nix {};
2021
pythonDeps = with python3Packages; [
2122
pytest
2223
psycopg2
@@ -30,8 +31,7 @@ mkShell {
3031
format.do format.doCheck
3132
nginxCustom.nginxScript
3233
gdbScript
33-
(pkgs.nixops_unstable_minimal.withPlugins (ps: [ ps.nixops-aws ]))
34-
];
34+
] ++ nixopsScripts;
3535
shellHook = ''
3636
export HISTFILE=.history
3737
'';

0 commit comments

Comments
 (0)