Skip to content

Commit 06c01cb

Browse files
authored
nixos/tests/akkoma: re‐write end‐to‐end test (NixOS#388766)
2 parents c410b02 + 73e6832 commit 06c01cb

File tree

2 files changed

+233
-131
lines changed

2 files changed

+233
-131
lines changed

nixos/tests/akkoma.nix

Lines changed: 225 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -1,149 +1,245 @@
1-
/*
2-
End-to-end test for Akkoma.
3-
4-
Based in part on nixos/tests/pleroma.
5-
6-
TODO: Test federation.
7-
*/
8-
import ./make-test-python.nix (
9-
{
10-
pkgs,
11-
package ? pkgs.akkoma,
12-
confined ? false,
13-
...
14-
}:
15-
let
16-
userPassword = "4LKOrGo8SgbPm1a6NclVU5Wb";
17-
18-
provisionUser = pkgs.writers.writeBashBin "provisionUser" ''
19-
set -eu -o errtrace -o pipefail
20-
21-
pleroma_ctl user new jamy [email protected] --password '${userPassword}' --moderator --admin -y
22-
'';
1+
# end‐to‐end test for Akkoma
2+
{
3+
lib,
4+
pkgs,
5+
confined ? false,
6+
...
7+
}:
8+
let
9+
inherit ((pkgs.formats.elixirConf { }).lib) mkRaw;
10+
11+
package = pkgs.akkoma;
12+
13+
tlsCert =
14+
names:
15+
pkgs.runCommand "certificates-${lib.head names}"
16+
{
17+
nativeBuildInputs = with pkgs; [ openssl ];
18+
}
19+
''
20+
mkdir -p $out
21+
openssl req -x509 \
22+
-subj '/CN=${lib.head names}/' -days 49710 \
23+
-addext 'subjectAltName = ${lib.concatStringsSep ", " (map (name: "DNS:${name}") names)}' \
24+
-keyout "$out/key.pem" -newkey ed25519 \
25+
-out "$out/cert.pem" -noenc
26+
'';
2327

24-
tlsCert =
25-
pkgs.runCommand "selfSignedCerts"
26-
{
27-
nativeBuildInputs = with pkgs; [ openssl ];
28-
}
29-
''
30-
mkdir -p $out
31-
openssl req -x509 \
32-
-subj '/CN=akkoma.nixos.test/' -days 49710 \
33-
-addext 'subjectAltName = DNS:akkoma.nixos.test' \
34-
-keyout "$out/key.pem" -newkey ed25519 \
35-
-out "$out/cert.pem" -noenc
36-
'';
37-
38-
sendToot = pkgs.writers.writeBashBin "sendToot" ''
39-
set -eu -o errtrace -o pipefail
40-
41-
export REQUESTS_CA_BUNDLE="/etc/ssl/certs/ca-certificates.crt"
42-
43-
${pkgs.toot}/bin/toot login_cli -i "akkoma.nixos.test" -e "[email protected]" -p '${userPassword}'
44-
${pkgs.toot}/bin/toot post "hello world Jamy here"
45-
${pkgs.toot}/bin/toot timeline -1 | grep -F -q "hello world Jamy here"
46-
47-
# Test file upload
48-
echo "y" | ${pkgs.toot}/bin/toot upload <(dd if=/dev/zero bs=1024 count=1024 status=none) \
49-
| grep -F -q "https://akkoma.nixos.test:443/media"
50-
'';
28+
tlsCertA = tlsCert [
29+
"akkoma-a.nixos.test"
30+
"media.akkoma-a.nixos.test"
31+
];
32+
33+
tlsCertB = tlsCert [
34+
"akkoma-b.nixos.test"
35+
"media.akkoma-b.nixos.test"
36+
];
5137

52-
checkFe = pkgs.writers.writeBashBin "checkFe" ''
53-
set -eu -o errtrace -o pipefail
38+
testMedia = pkgs.runCommand "blank.png" { nativeBuildInputs = with pkgs; [ imagemagick ]; } ''
39+
magick -size 640x480 canvas:transparent "PNG8:$out"
40+
'';
5441

42+
checkFe = pkgs.writeShellApplication {
43+
name = "checkFe";
44+
runtimeInputs = with pkgs; [ curl ];
45+
text = ''
5546
paths=( / /static/{config,styles}.json /pleroma/admin/ )
5647
5748
for path in "''${paths[@]}"; do
5849
diff \
59-
<(${pkgs.curl}/bin/curl -f -S -s -o /dev/null -w '%{response_code}' "https://akkoma.nixos.test$path") \
50+
<(curl -f -S -s -o /dev/null -w '%{response_code}' "https://$1$path") \
6051
<(echo -n 200)
6152
done
6253
'';
54+
};
55+
56+
commonConfig =
57+
{ nodes, ... }:
58+
{
59+
security.pki.certificateFiles = [
60+
"${tlsCertA}/cert.pem"
61+
"${tlsCertB}/cert.pem"
62+
];
63+
64+
networking.extraHosts = ''
65+
${nodes.akkoma-a.networking.primaryIPAddress} akkoma-a.nixos.test media.akkoma-a.nixos.test
66+
${nodes.akkoma-b.networking.primaryIPAddress} akkoma-b.nixos.test media.akkoma-b.nixos.test
67+
${nodes.client-a.networking.primaryIPAddress} client-a.nixos.test
68+
${nodes.client-b.networking.primaryIPAddress} client-b.nixos.test
69+
'';
70+
};
6371

64-
hosts = nodes: ''
65-
${nodes.akkoma.networking.primaryIPAddress} akkoma.nixos.test
66-
${nodes.client.networking.primaryIPAddress} client.nixos.test
67-
'';
68-
in
69-
{
70-
name = "akkoma";
71-
nodes = {
72-
client =
73-
{
74-
nodes,
75-
pkgs,
76-
config,
77-
...
78-
}:
79-
{
80-
security.pki.certificateFiles = [ "${tlsCert}/cert.pem" ];
81-
networking.extraHosts = hosts nodes;
72+
clientConfig =
73+
{ pkgs, ... }:
74+
{
75+
environment = {
76+
sessionVariables = {
77+
REQUESTS_CA_BUNDLE = "/etc/ssl/certs/ca-certificates.crt";
8278
};
79+
systemPackages = with pkgs; [ toot ];
80+
};
81+
};
8382

84-
akkoma =
85-
{
86-
nodes,
87-
pkgs,
88-
config,
89-
...
90-
}:
91-
{
92-
networking.extraHosts = hosts nodes;
93-
networking.firewall.allowedTCPPorts = [ 443 ];
94-
environment.systemPackages = with pkgs; [ provisionUser ];
95-
systemd.services.akkoma.confinement.enable = confined;
96-
97-
services.akkoma = {
98-
enable = true;
99-
package = package;
100-
config = {
101-
":pleroma" = {
102-
":instance" = {
103-
name = "NixOS test Akkoma server";
104-
description = "NixOS test Akkoma server";
105-
email = "[email protected]";
106-
notify_email = "[email protected]";
107-
registration_open = true;
108-
};
109-
110-
":media_proxy" = {
111-
enabled = false;
112-
};
113-
114-
"Pleroma.Web.Endpoint" = {
115-
url.host = "akkoma.nixos.test";
116-
};
117-
"Pleroma.Upload" = {
118-
base_url = "https://akkoma.nixos.test:443/media/";
119-
};
120-
};
83+
serverConfig =
84+
{ config, pkgs, ... }:
85+
{
86+
networking = {
87+
domain = "nixos.test";
88+
firewall.allowedTCPPorts = [ 443 ];
89+
};
90+
91+
systemd.services.akkoma.confinement.enable = confined;
92+
93+
services.akkoma = {
94+
enable = true;
95+
inherit package;
96+
config = {
97+
":pleroma" = {
98+
":instance" = {
99+
name = "NixOS test Akkoma server";
100+
description = "NixOS test Akkoma server";
101+
email = "[email protected]";
102+
notify_email = "[email protected]";
103+
registration_open = true;
121104
};
122105

123-
nginx = {
124-
addSSL = true;
125-
sslCertificate = "${tlsCert}/cert.pem";
126-
sslCertificateKey = "${tlsCert}/key.pem";
106+
":media_proxy" = {
107+
enabled = false;
127108
};
128-
};
129109

130-
services.nginx.enable = true;
131-
services.postgresql.enable = true;
110+
"Pleroma.Web.Endpoint" = {
111+
url.host = config.networking.fqdn;
112+
};
113+
114+
"Pleroma.Upload" = {
115+
base_url = "https://media.${config.networking.fqdn}/media/";
116+
};
117+
118+
# disable certificate verification until we figure out how to
119+
# supply our own certificates
120+
":http".adapter.pools = mkRaw "%{default: [conn_opts: [transport_opts: [verify: :verify_none]]]}";
121+
};
132122
};
123+
124+
nginx.addSSL = true;
125+
};
126+
127+
services.nginx.enable = true;
128+
services.postgresql.enable = true;
133129
};
130+
in
131+
{
132+
name = "akkoma";
133+
nodes = {
134+
client-a =
135+
{ ... }:
136+
{
137+
imports = [
138+
clientConfig
139+
commonConfig
140+
];
141+
};
142+
143+
client-b =
144+
{ ... }:
145+
{
146+
imports = [
147+
clientConfig
148+
commonConfig
149+
];
150+
};
151+
152+
akkoma-a =
153+
{ ... }:
154+
{
155+
imports = [
156+
commonConfig
157+
serverConfig
158+
];
159+
160+
services.akkoma.nginx = {
161+
sslCertificate = "${tlsCertA}/cert.pem";
162+
sslCertificateKey = "${tlsCertA}/key.pem";
163+
};
164+
};
165+
166+
akkoma-b =
167+
{ ... }:
168+
{
169+
imports = [
170+
commonConfig
171+
serverConfig
172+
];
173+
174+
services.akkoma.nginx = {
175+
sslCertificate = "${tlsCertB}/cert.pem";
176+
sslCertificateKey = "${tlsCertB}/key.pem";
177+
};
178+
};
179+
};
134180

135-
testScript =
136-
{ nodes, ... }:
137-
''
138-
start_all()
139-
akkoma.wait_for_unit('akkoma-initdb.service')
140-
akkoma.systemctl('restart akkoma-initdb.service') # test repeated initialisation
141-
akkoma.wait_for_unit('akkoma.service')
142-
akkoma.wait_for_file('/run/akkoma/socket');
143-
akkoma.succeed('${provisionUser}/bin/provisionUser')
144-
akkoma.wait_for_unit('nginx.service')
145-
client.succeed('${sendToot}/bin/sendToot')
146-
client.succeed('${checkFe}/bin/checkFe')
147-
'';
148-
}
149-
)
181+
testScript = ''
182+
import json
183+
import random
184+
import string
185+
from shlex import quote
186+
187+
def randomString(len):
188+
return "".join(random.choice(string.ascii_letters + string.digits) for _ in range(len))
189+
190+
def registerUser(user, password):
191+
return 'pleroma_ctl user new {0} {0}@nixos.test --password {1} -y'.format(
192+
quote(user), quote(password))
193+
194+
def loginUser(instance, user, password):
195+
return 'toot login_cli -i {}.nixos.test -e {}@nixos.test -p {}'.format(
196+
quote(instance), quote(user), quote(password))
197+
198+
userAName = randomString(11)
199+
userBName = randomString(11)
200+
userAPassword = randomString(22)
201+
userBPassword = randomString(22)
202+
203+
testMessage = randomString(22)
204+
testMedia = '${testMedia}'
205+
206+
start_all()
207+
akkoma_a.wait_for_unit('akkoma-initdb.service')
208+
akkoma_b.wait_for_unit('akkoma-initdb.service')
209+
210+
# test repeated initialisation
211+
akkoma_a.systemctl('restart akkoma-initdb.service')
212+
213+
akkoma_a.wait_for_unit('akkoma.service')
214+
akkoma_b.wait_for_unit('akkoma.service')
215+
akkoma_a.wait_for_file('/run/akkoma/socket');
216+
akkoma_b.wait_for_file('/run/akkoma/socket');
217+
218+
akkoma_a.succeed(registerUser(userAName, userAPassword))
219+
akkoma_b.succeed(registerUser(userBName, userBPassword))
220+
221+
akkoma_a.wait_for_unit('nginx.service')
222+
akkoma_b.wait_for_unit('nginx.service')
223+
224+
client_a.succeed(loginUser('akkoma-a', userAName, userAPassword))
225+
client_b.succeed(loginUser('akkoma-b', userBName, userBPassword))
226+
227+
client_b.succeed('toot follow {}@akkoma-a.nixos.test'.format(userAName))
228+
client_a.wait_until_succeeds('toot followers | grep -F -q {}'.format(quote(userBName)))
229+
230+
client_a.succeed('toot post {} --media {} --description "nothing to see here"'.format(
231+
quote(testMessage), quote(testMedia)))
232+
233+
# verify test message
234+
status = json.loads(client_b.wait_until_succeeds(
235+
'toot status --json "$(toot timeline -1 | grep -E -o \'^ID [^ ]+\' | cut -d \' \' -f 2)"'))
236+
assert status['content'] == testMessage
237+
238+
# compare attachment to original
239+
client_b.succeed('cmp {} <(curl -f -S -s {})'.format(quote(testMedia),
240+
quote(status['media_attachments'][0]['url'])))
241+
242+
client_a.succeed('${lib.getExe checkFe} akkoma-a.nixos.test')
243+
client_b.succeed('${lib.getExe checkFe} akkoma-b.nixos.test')
244+
'';
245+
}

nixos/tests/all-tests.nix

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,14 @@ in {
156156
age-plugin-tpm-decrypt = runTest ./age-plugin-tpm-decrypt.nix;
157157
agorakit = runTest ./web-apps/agorakit.nix;
158158
airsonic = runTest ./airsonic.nix;
159-
akkoma = handleTestOn [ "x86_64-linux" "aarch64-linux" ] ./akkoma.nix {};
160-
akkoma-confined = handleTestOn [ "x86_64-linux" "aarch64-linux" ] ./akkoma.nix { confined = true; };
159+
akkoma = runTestOn [ "x86_64-linux" "aarch64-linux" ] {
160+
imports = [ ./akkoma.nix ];
161+
_module.args.confined = false;
162+
};
163+
akkoma-confined = runTestOn [ "x86_64-linux" "aarch64-linux" ] {
164+
imports = [ ./akkoma.nix ];
165+
_module.args.confined = true;
166+
};
161167
alice-lg = runTest ./alice-lg.nix;
162168
alloy = runTest ./alloy.nix;
163169
allTerminfo = runTest ./all-terminfo.nix;

0 commit comments

Comments
 (0)