Loading nixos/tests/akkoma.nix +225 −129 Original line number Diff line number Diff line /* End-to-end test for Akkoma. Based in part on nixos/tests/pleroma. TODO: Test federation. */ import ./make-test-python.nix ( # end‐to‐end test for Akkoma { lib, pkgs, package ? pkgs.akkoma, confined ? false, ... }: let userPassword = "4LKOrGo8SgbPm1a6NclVU5Wb"; inherit ((pkgs.formats.elixirConf { }).lib) mkRaw; provisionUser = pkgs.writers.writeBashBin "provisionUser" '' set -eu -o errtrace -o pipefail pleroma_ctl user new jamy jamy@nixos.test --password '${userPassword}' --moderator --admin -y ''; package = pkgs.akkoma; tlsCert = pkgs.runCommand "selfSignedCerts" names: pkgs.runCommand "certificates-${lib.head names}" { nativeBuildInputs = with pkgs; [ openssl ]; } '' mkdir -p $out openssl req -x509 \ -subj '/CN=akkoma.nixos.test/' -days 49710 \ -addext 'subjectAltName = DNS:akkoma.nixos.test' \ -subj '/CN=${lib.head names}/' -days 49710 \ -addext 'subjectAltName = ${lib.concatStringsSep ", " (map (name: "DNS:${name}") names)}' \ -keyout "$out/key.pem" -newkey ed25519 \ -out "$out/cert.pem" -noenc ''; sendToot = pkgs.writers.writeBashBin "sendToot" '' set -eu -o errtrace -o pipefail export REQUESTS_CA_BUNDLE="/etc/ssl/certs/ca-certificates.crt" tlsCertA = tlsCert [ "akkoma-a.nixos.test" "media.akkoma-a.nixos.test" ]; ${pkgs.toot}/bin/toot login_cli -i "akkoma.nixos.test" -e "jamy@nixos.test" -p '${userPassword}' ${pkgs.toot}/bin/toot post "hello world Jamy here" ${pkgs.toot}/bin/toot timeline -1 | grep -F -q "hello world Jamy here" tlsCertB = tlsCert [ "akkoma-b.nixos.test" "media.akkoma-b.nixos.test" ]; # Test file upload echo "y" | ${pkgs.toot}/bin/toot upload <(dd if=/dev/zero bs=1024 count=1024 status=none) \ | grep -F -q "https://akkoma.nixos.test:443/media" testMedia = pkgs.runCommand "blank.png" { nativeBuildInputs = with pkgs; [ imagemagick ]; } '' magick -size 640x480 canvas:transparent "PNG8:$out" ''; checkFe = pkgs.writers.writeBashBin "checkFe" '' set -eu -o errtrace -o pipefail checkFe = pkgs.writeShellApplication { name = "checkFe"; runtimeInputs = with pkgs; [ curl ]; text = '' paths=( / /static/{config,styles}.json /pleroma/admin/ ) for path in "''${paths[@]}"; do diff \ <(${pkgs.curl}/bin/curl -f -S -s -o /dev/null -w '%{response_code}' "https://akkoma.nixos.test$path") \ <(curl -f -S -s -o /dev/null -w '%{response_code}' "https://$1$path") \ <(echo -n 200) done ''; }; hosts = nodes: '' ${nodes.akkoma.networking.primaryIPAddress} akkoma.nixos.test ${nodes.client.networking.primaryIPAddress} client.nixos.test ''; in { name = "akkoma"; nodes = { client = { nodes, pkgs, config, ... }: commonConfig = { nodes, ... }: { security.pki.certificateFiles = [ "${tlsCert}/cert.pem" ]; networking.extraHosts = hosts nodes; security.pki.certificateFiles = [ "${tlsCertA}/cert.pem" "${tlsCertB}/cert.pem" ]; networking.extraHosts = '' ${nodes.akkoma-a.networking.primaryIPAddress} akkoma-a.nixos.test media.akkoma-a.nixos.test ${nodes.akkoma-b.networking.primaryIPAddress} akkoma-b.nixos.test media.akkoma-b.nixos.test ${nodes.client-a.networking.primaryIPAddress} client-a.nixos.test ${nodes.client-b.networking.primaryIPAddress} client-b.nixos.test ''; }; akkoma = clientConfig = { pkgs, ... }: { nodes, pkgs, config, ... }: environment = { sessionVariables = { REQUESTS_CA_BUNDLE = "/etc/ssl/certs/ca-certificates.crt"; }; systemPackages = with pkgs; [ toot ]; }; }; serverConfig = { config, pkgs, ... }: { networking.extraHosts = hosts nodes; networking.firewall.allowedTCPPorts = [ 443 ]; environment.systemPackages = with pkgs; [ provisionUser ]; networking = { domain = "nixos.test"; firewall.allowedTCPPorts = [ 443 ]; }; systemd.services.akkoma.confinement.enable = confined; services.akkoma = { enable = true; package = package; inherit package; config = { ":pleroma" = { ":instance" = { Loading @@ -112,38 +108,138 @@ import ./make-test-python.nix ( }; "Pleroma.Web.Endpoint" = { url.host = "akkoma.nixos.test"; url.host = config.networking.fqdn; }; "Pleroma.Upload" = { base_url = "https://akkoma.nixos.test:443/media/"; base_url = "https://media.${config.networking.fqdn}/media/"; }; # disable certificate verification until we figure out how to # supply our own certificates ":http".adapter.pools = mkRaw "%{default: [conn_opts: [transport_opts: [verify: :verify_none]]]}"; }; }; nginx = { addSSL = true; sslCertificate = "${tlsCert}/cert.pem"; sslCertificateKey = "${tlsCert}/key.pem"; }; nginx.addSSL = true; }; services.nginx.enable = true; services.postgresql.enable = true; }; in { name = "akkoma"; nodes = { client-a = { ... }: { imports = [ clientConfig commonConfig ]; }; testScript = { nodes, ... }: '' client-b = { ... }: { imports = [ clientConfig commonConfig ]; }; akkoma-a = { ... }: { imports = [ commonConfig serverConfig ]; services.akkoma.nginx = { sslCertificate = "${tlsCertA}/cert.pem"; sslCertificateKey = "${tlsCertA}/key.pem"; }; }; akkoma-b = { ... }: { imports = [ commonConfig serverConfig ]; services.akkoma.nginx = { sslCertificate = "${tlsCertB}/cert.pem"; sslCertificateKey = "${tlsCertB}/key.pem"; }; }; }; testScript = '' import json import random import string from shlex import quote def randomString(len): return "".join(random.choice(string.ascii_letters + string.digits) for _ in range(len)) def registerUser(user, password): return 'pleroma_ctl user new {0} {0}@nixos.test --password {1} -y'.format( quote(user), quote(password)) def loginUser(instance, user, password): return 'toot login_cli -i {}.nixos.test -e {}@nixos.test -p {}'.format( quote(instance), quote(user), quote(password)) userAName = randomString(11) userBName = randomString(11) userAPassword = randomString(22) userBPassword = randomString(22) testMessage = randomString(22) testMedia = '${testMedia}' start_all() akkoma.wait_for_unit('akkoma-initdb.service') akkoma.systemctl('restart akkoma-initdb.service') # test repeated initialisation akkoma.wait_for_unit('akkoma.service') akkoma.wait_for_file('/run/akkoma/socket'); akkoma.succeed('${provisionUser}/bin/provisionUser') akkoma.wait_for_unit('nginx.service') client.succeed('${sendToot}/bin/sendToot') client.succeed('${checkFe}/bin/checkFe') akkoma_a.wait_for_unit('akkoma-initdb.service') akkoma_b.wait_for_unit('akkoma-initdb.service') # test repeated initialisation akkoma_a.systemctl('restart akkoma-initdb.service') akkoma_a.wait_for_unit('akkoma.service') akkoma_b.wait_for_unit('akkoma.service') akkoma_a.wait_for_file('/run/akkoma/socket'); akkoma_b.wait_for_file('/run/akkoma/socket'); akkoma_a.succeed(registerUser(userAName, userAPassword)) akkoma_b.succeed(registerUser(userBName, userBPassword)) akkoma_a.wait_for_unit('nginx.service') akkoma_b.wait_for_unit('nginx.service') client_a.succeed(loginUser('akkoma-a', userAName, userAPassword)) client_b.succeed(loginUser('akkoma-b', userBName, userBPassword)) client_b.succeed('toot follow {}@akkoma-a.nixos.test'.format(userAName)) client_a.wait_until_succeeds('toot followers | grep -F -q {}'.format(quote(userBName))) client_a.succeed('toot post {} --media {} --description "nothing to see here"'.format( quote(testMessage), quote(testMedia))) # verify test message status = json.loads(client_b.wait_until_succeeds( 'toot status --json "$(toot timeline -1 | grep -E -o \'^ID [^ ]+\' | cut -d \' \' -f 2)"')) assert status['content'] == testMessage # compare attachment to original client_b.succeed('cmp {} <(curl -f -S -s {})'.format(quote(testMedia), quote(status['media_attachments'][0]['url']))) client_a.succeed('${lib.getExe checkFe} akkoma-a.nixos.test') client_b.succeed('${lib.getExe checkFe} akkoma-b.nixos.test') ''; } ) nixos/tests/all-tests.nix +8 −2 Original line number Diff line number Diff line Loading @@ -156,8 +156,14 @@ in { age-plugin-tpm-decrypt = runTest ./age-plugin-tpm-decrypt.nix; agorakit = runTest ./web-apps/agorakit.nix; airsonic = runTest ./airsonic.nix; akkoma = handleTestOn [ "x86_64-linux" "aarch64-linux" ] ./akkoma.nix {}; akkoma-confined = handleTestOn [ "x86_64-linux" "aarch64-linux" ] ./akkoma.nix { confined = true; }; akkoma = runTestOn [ "x86_64-linux" "aarch64-linux" ] { imports = [ ./akkoma.nix ]; _module.args.confined = false; }; akkoma-confined = runTestOn [ "x86_64-linux" "aarch64-linux" ] { imports = [ ./akkoma.nix ]; _module.args.confined = true; }; alice-lg = runTest ./alice-lg.nix; alloy = runTest ./alloy.nix; allTerminfo = runTest ./all-terminfo.nix; Loading Loading
nixos/tests/akkoma.nix +225 −129 Original line number Diff line number Diff line /* End-to-end test for Akkoma. Based in part on nixos/tests/pleroma. TODO: Test federation. */ import ./make-test-python.nix ( # end‐to‐end test for Akkoma { lib, pkgs, package ? pkgs.akkoma, confined ? false, ... }: let userPassword = "4LKOrGo8SgbPm1a6NclVU5Wb"; inherit ((pkgs.formats.elixirConf { }).lib) mkRaw; provisionUser = pkgs.writers.writeBashBin "provisionUser" '' set -eu -o errtrace -o pipefail pleroma_ctl user new jamy jamy@nixos.test --password '${userPassword}' --moderator --admin -y ''; package = pkgs.akkoma; tlsCert = pkgs.runCommand "selfSignedCerts" names: pkgs.runCommand "certificates-${lib.head names}" { nativeBuildInputs = with pkgs; [ openssl ]; } '' mkdir -p $out openssl req -x509 \ -subj '/CN=akkoma.nixos.test/' -days 49710 \ -addext 'subjectAltName = DNS:akkoma.nixos.test' \ -subj '/CN=${lib.head names}/' -days 49710 \ -addext 'subjectAltName = ${lib.concatStringsSep ", " (map (name: "DNS:${name}") names)}' \ -keyout "$out/key.pem" -newkey ed25519 \ -out "$out/cert.pem" -noenc ''; sendToot = pkgs.writers.writeBashBin "sendToot" '' set -eu -o errtrace -o pipefail export REQUESTS_CA_BUNDLE="/etc/ssl/certs/ca-certificates.crt" tlsCertA = tlsCert [ "akkoma-a.nixos.test" "media.akkoma-a.nixos.test" ]; ${pkgs.toot}/bin/toot login_cli -i "akkoma.nixos.test" -e "jamy@nixos.test" -p '${userPassword}' ${pkgs.toot}/bin/toot post "hello world Jamy here" ${pkgs.toot}/bin/toot timeline -1 | grep -F -q "hello world Jamy here" tlsCertB = tlsCert [ "akkoma-b.nixos.test" "media.akkoma-b.nixos.test" ]; # Test file upload echo "y" | ${pkgs.toot}/bin/toot upload <(dd if=/dev/zero bs=1024 count=1024 status=none) \ | grep -F -q "https://akkoma.nixos.test:443/media" testMedia = pkgs.runCommand "blank.png" { nativeBuildInputs = with pkgs; [ imagemagick ]; } '' magick -size 640x480 canvas:transparent "PNG8:$out" ''; checkFe = pkgs.writers.writeBashBin "checkFe" '' set -eu -o errtrace -o pipefail checkFe = pkgs.writeShellApplication { name = "checkFe"; runtimeInputs = with pkgs; [ curl ]; text = '' paths=( / /static/{config,styles}.json /pleroma/admin/ ) for path in "''${paths[@]}"; do diff \ <(${pkgs.curl}/bin/curl -f -S -s -o /dev/null -w '%{response_code}' "https://akkoma.nixos.test$path") \ <(curl -f -S -s -o /dev/null -w '%{response_code}' "https://$1$path") \ <(echo -n 200) done ''; }; hosts = nodes: '' ${nodes.akkoma.networking.primaryIPAddress} akkoma.nixos.test ${nodes.client.networking.primaryIPAddress} client.nixos.test ''; in { name = "akkoma"; nodes = { client = { nodes, pkgs, config, ... }: commonConfig = { nodes, ... }: { security.pki.certificateFiles = [ "${tlsCert}/cert.pem" ]; networking.extraHosts = hosts nodes; security.pki.certificateFiles = [ "${tlsCertA}/cert.pem" "${tlsCertB}/cert.pem" ]; networking.extraHosts = '' ${nodes.akkoma-a.networking.primaryIPAddress} akkoma-a.nixos.test media.akkoma-a.nixos.test ${nodes.akkoma-b.networking.primaryIPAddress} akkoma-b.nixos.test media.akkoma-b.nixos.test ${nodes.client-a.networking.primaryIPAddress} client-a.nixos.test ${nodes.client-b.networking.primaryIPAddress} client-b.nixos.test ''; }; akkoma = clientConfig = { pkgs, ... }: { nodes, pkgs, config, ... }: environment = { sessionVariables = { REQUESTS_CA_BUNDLE = "/etc/ssl/certs/ca-certificates.crt"; }; systemPackages = with pkgs; [ toot ]; }; }; serverConfig = { config, pkgs, ... }: { networking.extraHosts = hosts nodes; networking.firewall.allowedTCPPorts = [ 443 ]; environment.systemPackages = with pkgs; [ provisionUser ]; networking = { domain = "nixos.test"; firewall.allowedTCPPorts = [ 443 ]; }; systemd.services.akkoma.confinement.enable = confined; services.akkoma = { enable = true; package = package; inherit package; config = { ":pleroma" = { ":instance" = { Loading @@ -112,38 +108,138 @@ import ./make-test-python.nix ( }; "Pleroma.Web.Endpoint" = { url.host = "akkoma.nixos.test"; url.host = config.networking.fqdn; }; "Pleroma.Upload" = { base_url = "https://akkoma.nixos.test:443/media/"; base_url = "https://media.${config.networking.fqdn}/media/"; }; # disable certificate verification until we figure out how to # supply our own certificates ":http".adapter.pools = mkRaw "%{default: [conn_opts: [transport_opts: [verify: :verify_none]]]}"; }; }; nginx = { addSSL = true; sslCertificate = "${tlsCert}/cert.pem"; sslCertificateKey = "${tlsCert}/key.pem"; }; nginx.addSSL = true; }; services.nginx.enable = true; services.postgresql.enable = true; }; in { name = "akkoma"; nodes = { client-a = { ... }: { imports = [ clientConfig commonConfig ]; }; testScript = { nodes, ... }: '' client-b = { ... }: { imports = [ clientConfig commonConfig ]; }; akkoma-a = { ... }: { imports = [ commonConfig serverConfig ]; services.akkoma.nginx = { sslCertificate = "${tlsCertA}/cert.pem"; sslCertificateKey = "${tlsCertA}/key.pem"; }; }; akkoma-b = { ... }: { imports = [ commonConfig serverConfig ]; services.akkoma.nginx = { sslCertificate = "${tlsCertB}/cert.pem"; sslCertificateKey = "${tlsCertB}/key.pem"; }; }; }; testScript = '' import json import random import string from shlex import quote def randomString(len): return "".join(random.choice(string.ascii_letters + string.digits) for _ in range(len)) def registerUser(user, password): return 'pleroma_ctl user new {0} {0}@nixos.test --password {1} -y'.format( quote(user), quote(password)) def loginUser(instance, user, password): return 'toot login_cli -i {}.nixos.test -e {}@nixos.test -p {}'.format( quote(instance), quote(user), quote(password)) userAName = randomString(11) userBName = randomString(11) userAPassword = randomString(22) userBPassword = randomString(22) testMessage = randomString(22) testMedia = '${testMedia}' start_all() akkoma.wait_for_unit('akkoma-initdb.service') akkoma.systemctl('restart akkoma-initdb.service') # test repeated initialisation akkoma.wait_for_unit('akkoma.service') akkoma.wait_for_file('/run/akkoma/socket'); akkoma.succeed('${provisionUser}/bin/provisionUser') akkoma.wait_for_unit('nginx.service') client.succeed('${sendToot}/bin/sendToot') client.succeed('${checkFe}/bin/checkFe') akkoma_a.wait_for_unit('akkoma-initdb.service') akkoma_b.wait_for_unit('akkoma-initdb.service') # test repeated initialisation akkoma_a.systemctl('restart akkoma-initdb.service') akkoma_a.wait_for_unit('akkoma.service') akkoma_b.wait_for_unit('akkoma.service') akkoma_a.wait_for_file('/run/akkoma/socket'); akkoma_b.wait_for_file('/run/akkoma/socket'); akkoma_a.succeed(registerUser(userAName, userAPassword)) akkoma_b.succeed(registerUser(userBName, userBPassword)) akkoma_a.wait_for_unit('nginx.service') akkoma_b.wait_for_unit('nginx.service') client_a.succeed(loginUser('akkoma-a', userAName, userAPassword)) client_b.succeed(loginUser('akkoma-b', userBName, userBPassword)) client_b.succeed('toot follow {}@akkoma-a.nixos.test'.format(userAName)) client_a.wait_until_succeeds('toot followers | grep -F -q {}'.format(quote(userBName))) client_a.succeed('toot post {} --media {} --description "nothing to see here"'.format( quote(testMessage), quote(testMedia))) # verify test message status = json.loads(client_b.wait_until_succeeds( 'toot status --json "$(toot timeline -1 | grep -E -o \'^ID [^ ]+\' | cut -d \' \' -f 2)"')) assert status['content'] == testMessage # compare attachment to original client_b.succeed('cmp {} <(curl -f -S -s {})'.format(quote(testMedia), quote(status['media_attachments'][0]['url']))) client_a.succeed('${lib.getExe checkFe} akkoma-a.nixos.test') client_b.succeed('${lib.getExe checkFe} akkoma-b.nixos.test') ''; } )
nixos/tests/all-tests.nix +8 −2 Original line number Diff line number Diff line Loading @@ -156,8 +156,14 @@ in { age-plugin-tpm-decrypt = runTest ./age-plugin-tpm-decrypt.nix; agorakit = runTest ./web-apps/agorakit.nix; airsonic = runTest ./airsonic.nix; akkoma = handleTestOn [ "x86_64-linux" "aarch64-linux" ] ./akkoma.nix {}; akkoma-confined = handleTestOn [ "x86_64-linux" "aarch64-linux" ] ./akkoma.nix { confined = true; }; akkoma = runTestOn [ "x86_64-linux" "aarch64-linux" ] { imports = [ ./akkoma.nix ]; _module.args.confined = false; }; akkoma-confined = runTestOn [ "x86_64-linux" "aarch64-linux" ] { imports = [ ./akkoma.nix ]; _module.args.confined = true; }; alice-lg = runTest ./alice-lg.nix; alloy = runTest ./alloy.nix; allTerminfo = runTest ./all-terminfo.nix; Loading