|
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 | + ''; |
23 | 27 |
|
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 | + ]; |
51 | 37 |
|
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 | + ''; |
54 | 41 |
|
| 42 | + checkFe = pkgs.writeShellApplication { |
| 43 | + name = "checkFe"; |
| 44 | + runtimeInputs = with pkgs; [ curl ]; |
| 45 | + text = '' |
55 | 46 | paths=( / /static/{config,styles}.json /pleroma/admin/ ) |
56 | 47 |
|
57 | 48 | for path in "''${paths[@]}"; do |
58 | 49 | 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") \ |
60 | 51 | <(echo -n 200) |
61 | 52 | done |
62 | 53 | ''; |
| 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 | + }; |
63 | 71 |
|
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"; |
82 | 78 | }; |
| 79 | + systemPackages = with pkgs; [ toot ]; |
| 80 | + }; |
| 81 | + }; |
83 | 82 |
|
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 | | - |
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 | + |
| 102 | + notify_email = "[email protected]"; |
| 103 | + registration_open = true; |
121 | 104 | }; |
122 | 105 |
|
123 | | - nginx = { |
124 | | - addSSL = true; |
125 | | - sslCertificate = "${tlsCert}/cert.pem"; |
126 | | - sslCertificateKey = "${tlsCert}/key.pem"; |
| 106 | + ":media_proxy" = { |
| 107 | + enabled = false; |
127 | 108 | }; |
128 | | - }; |
129 | 109 |
|
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 | + }; |
132 | 122 | }; |
| 123 | + |
| 124 | + nginx.addSSL = true; |
| 125 | + }; |
| 126 | + |
| 127 | + services.nginx.enable = true; |
| 128 | + services.postgresql.enable = true; |
133 | 129 | }; |
| 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 | + }; |
134 | 180 |
|
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 | +} |
0 commit comments