Skip to content

Commit abf5a85

Browse files
committed
First crack
1 parent cac393a commit abf5a85

23 files changed

+714
-0
lines changed

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.terraform*
2+
terraform.tfstate**.json
3+
*.qcow2
4+
terraform.tfstate
5+
terraform.tfstate.backup
6+
results/

Caddyfile

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
:8080 {
2+
handle_path /html {
3+
root static
4+
file_server
5+
}
6+
7+
handle /synthetic {
8+
respond "Hello, world!"
9+
}
10+
}

base.nix

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{ pkgs, ... }: let
2+
sshKey = builtins.readFile ./ssh_pubkey;
3+
in {
4+
# Perf testing tweaks
5+
boot.kernel.sysctl = {
6+
"net.ipv4.ip_local_port_range" = "1024 65535";
7+
"net.ipv4.tcp_tw_reuse" = 1;
8+
"net.ipv4.tcp_timestamps" = 1;
9+
};
10+
security.pam.loginLimits = [{
11+
domain = "*";
12+
type = "soft";
13+
item = "nofile";
14+
value = "250000";
15+
}];
16+
system.stateVersion = "22.05";
17+
users.users.root.openssh.authorizedKeys.keys = [ sshKey ];
18+
}

bench.nix

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
{ lib, pkgs, ... }: {
2+
environment.systemPackages = with pkgs; [
3+
psrecord
4+
];
5+
6+
system.activationScripts.pristine = ''
7+
${pkgs.systemd}/bin/systemctl stop nginx caddy || true
8+
'';
9+
10+
networking.firewall.allowedTCPPorts = [ 8080 ];
11+
12+
services.caddy = {
13+
enable = true;
14+
configFile = pkgs.writeText "Caddyfile" ''
15+
:8080 {
16+
handle_path /html {
17+
root * ${pkgs.static-html}
18+
file_server
19+
}
20+
21+
handle /synthetic {
22+
respond "Hello, world!"
23+
}
24+
}
25+
'';
26+
};
27+
systemd.services.caddy = {
28+
serviceConfig.LimitNOFILE = "250000:250000";
29+
wantedBy = lib.mkForce [];
30+
};
31+
32+
services.nginx = {
33+
enable = true;
34+
logError = "/dev/null";
35+
config = ''
36+
events {
37+
use epoll;
38+
}
39+
40+
http {
41+
access_log off;
42+
43+
server {
44+
server_name localhost;
45+
listen 0.0.0.0:8080;
46+
47+
location = /html {
48+
alias ${pkgs.static-html}/index.html;
49+
}
50+
51+
location = /synthetic {
52+
return 200 "Hello, world!";
53+
}
54+
}
55+
}
56+
'';
57+
};
58+
systemd.services.nginx = {
59+
serviceConfig.LimitNOFILE = "250000:250000";
60+
wantedBy = lib.mkForce [];
61+
};
62+
}

bench.sh

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
#!/usr/bin/env bash
2+
3+
set -euo pipefail
4+
IFS=$'\n\t'
5+
6+
test_duration=30
7+
test_concurrency=${VUS:-200}
8+
tests=(synthetic html)
9+
proxies=(caddy nginx)
10+
11+
function ssh_ { ssh -F ssh_config $@; }
12+
function scp_ { scp -F ssh_config $@; }
13+
function config {
14+
NIX_SSHOPTS="-F ssh_config" \
15+
nixos-rebuild \
16+
--flake ".#$1" \
17+
--target-host root@$2 \
18+
--build-host localhost \
19+
test
20+
}
21+
22+
function run_tests {
23+
terraform apply -auto-approve
24+
dns=$(terraform output -json dns)
25+
sut_pri=$(echo $dns | jq -r '.[0][0]')
26+
dri_pri=$(echo $dns | jq -r '.[0][1]')
27+
sut_pub=$(echo $dns | jq -r '.[1][0]')
28+
dri_pub=$(echo $dns | jq -r '.[1][1]')
29+
30+
echo -n "Waiting for ssh..."
31+
for h in $dri_pub $sut_pub
32+
do
33+
until ssh_ $h id &>/dev/null ; do
34+
printf .
35+
sleep 1
36+
done
37+
done
38+
39+
config aws-bench $sut_pub
40+
config aws-driver $dri_pub
41+
ssh_ $sut_pub systemctl stop nginx caddy || true
42+
43+
scp_ test.js $dri_pub:~/
44+
45+
for svc in ${proxies[@]}
46+
do
47+
for test_uri in ${tests[@]}
48+
do
49+
ssh_ $sut_pub systemctl start $svc
50+
sleep 3
51+
pid=$(ssh_ $sut_pub systemctl show $svc --property=MainPID --value)
52+
ssh_ $sut_pub "psrecord $pid \
53+
--include-children \
54+
--interval 0.1 \
55+
--duration $(( $test_duration + 15 )) \
56+
--log $svc-$test_uri-$test_concurrency.txt" &
57+
record=$!
58+
ssh_ $dri_pub \
59+
"TEST_TARGET=http://${sut_pri}:8080/${test_uri} \
60+
k6 run \
61+
--vus $test_concurrency \
62+
--duration ${test_duration}s \
63+
test.js"
64+
ssh_ $sut_pub systemctl stop $svc
65+
scp_ $dri_pub:~/summary.json results/$svc-$test_uri-$test_concurrency.json
66+
wait $record
67+
scp_ $sut_pub:~/$svc-$test_uri-$test_concurrency.txt results/
68+
done
69+
done
70+
71+
terraform apply -destroy -auto-approve
72+
}
73+
74+
function postprocess_resources {
75+
cleanup=()
76+
for test_type in ${tests[@]}
77+
do
78+
for svc in ${proxies[@]}
79+
do
80+
raw=results/$svc-$test_type-$test_concurrency.txt
81+
ready=results/$svc-$test_type-$test_concurrency-formatted.txt
82+
cleanup+=($ready)
83+
84+
sed 1d $raw \
85+
| choose 0:2 \
86+
| sed '1i Time "'$svc' CPU %" "'$svc' Memory"' \
87+
> $ready
88+
done
89+
90+
gnuplot \
91+
-e "test_type='${test_type}'" \
92+
-e "par='${test_concurrency}'" \
93+
-e "caddy='results/caddy-$test_type-$test_concurrency-formatted.txt'" \
94+
-e "nginx='results/nginx-$test_type-$test_concurrency-formatted.txt'" \
95+
resources.gp \
96+
> results/resources-${test_type}-${test_concurrency}c-$(date +%s).svg
97+
done
98+
rm ${cleanup[@]}
99+
}
100+
101+
function postprocess_metrics {
102+
plots=()
103+
for test_type in ${tests[@]}
104+
do
105+
to_join=()
106+
for svc in ${proxies[@]}
107+
do
108+
raw=results/$svc-$test_type-$test_concurrency.json
109+
processed=results/$svc-$test_type-duration-$test_concurrency.tsv
110+
jq --arg var http_req_duration -r -f metric.jq $raw \
111+
| sed "1i metric ${svc}-${test_type}" \
112+
> $processed
113+
to_join+=($processed)
114+
done
115+
plot=results/$test_type-duration-plot.txt
116+
join ${to_join[@]} > $plot
117+
rm ${to_join[@]}
118+
plots+=($plot)
119+
done
120+
121+
join ${plots[@]} > results/plot.txt
122+
rm ${plots[@]}
123+
gnuplot \
124+
-e "data='results/plot.txt'" \
125+
-e "test_type='duration'" \
126+
metrics.gp > results/metrics-duration-${test_concurrency}c-$(date +%s).svg
127+
rm results/plot.txt
128+
}
129+
130+
function postprocess_tests {
131+
postprocess_resources
132+
postprocess_metrics
133+
}
134+
135+
run_tests
136+
postprocess_tests

cloud-init.nix

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
### https://nixos.org/channels/nixos-22.05 nixos
2+
3+
{ modulesPath, ... }:
4+
{
5+
imports = [ "$${modulesPath}/virtualisation/amazon-image.nix" ];
6+
7+
users.users.root.openssh.authorizedKeys.keys = [
8+
"${deploy-key}"
9+
];
10+
}

driver.nix

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{ pkgs, ... }: {
2+
environment.systemPackages = with pkgs; [
3+
k6
4+
];
5+
}

flake.lock

Lines changed: 128 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)