From a6f1bae94614e1efc007bd61ab9e7279cebc3864 Mon Sep 17 00:00:00 2001
From: Mikael Voss <mvs@nyantec.com>
Date: Sat, 24 Sep 2022 15:52:36 +0200
Subject: [PATCH] nixos/tests/akkoma: init

This test is based in part on nixos/tests/pleroma.
---
 nixos/tests/akkoma.nix          | 121 ++++++++++++++++++++++++++++++++
 nixos/tests/all-tests.nix       |   2 +
 pkgs/servers/akkoma/default.nix |   6 ++
 3 files changed, 129 insertions(+)
 create mode 100644 nixos/tests/akkoma.nix

diff --git a/nixos/tests/akkoma.nix b/nixos/tests/akkoma.nix
new file mode 100644
index 000000000000..7115c0beed34
--- /dev/null
+++ b/nixos/tests/akkoma.nix
@@ -0,0 +1,121 @@
+/*
+  End-to-end test for Akkoma.
+
+  Based in part on nixos/tests/pleroma.
+
+  TODO: Test federation.
+*/
+import ./make-test-python.nix ({ pkgs, package ? pkgs.akkoma, confined ? false, ... }:
+let
+  userPassword = "4LKOrGo8SgbPm1a6NclVU5Wb";
+
+  provisionUser = pkgs.writers.writeBashBin "provisionUser" ''
+    set -eu -o errtrace -o pipefail
+
+    pleroma_ctl user new jamy jamy@nixos.test --password '${userPassword}' --moderator --admin -y
+  '';
+
+  tlsCert = pkgs.runCommand "selfSignedCerts" {
+    nativeBuildInputs = with pkgs; [ openssl ];
+  } ''
+    mkdir -p $out
+    openssl req -x509 \
+      -subj '/CN=akkoma.nixos.test/' -days 49710 \
+      -addext 'subjectAltName = DNS:akkoma.nixos.test' \
+      -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"
+
+    echo '${userPassword}' | ${pkgs.toot}/bin/toot login_cli -i "akkoma.nixos.test" -e "jamy@nixos.test"
+    echo "y" | ${pkgs.toot}/bin/toot post "hello world Jamy here"
+    echo "y" | ${pkgs.toot}/bin/toot timeline | grep -F -q "hello world Jamy here"
+
+    # 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/media"
+  '';
+
+  checkFe = pkgs.writers.writeBashBin "checkFe" ''
+    set -eu -o errtrace -o pipefail
+
+    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") \
+        <(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, ... }: {
+      security.pki.certificateFiles = [ "${tlsCert}/cert.pem" ];
+      networking.extraHosts = hosts nodes;
+    };
+
+    akkoma = { nodes, pkgs, config, ... }: {
+      networking.extraHosts = hosts nodes;
+      networking.firewall.allowedTCPPorts = [ 443 ];
+      environment.systemPackages = with pkgs; [ provisionUser ];
+      systemd.services.akkoma.confinement.enable = confined;
+
+      services.akkoma = {
+        enable = true;
+        package = package;
+        config = {
+          ":pleroma" = {
+            ":instance" = {
+              name = "NixOS test Akkoma server";
+              description = "NixOS test Akkoma server";
+              email = "akkoma@nixos.test";
+              notify_email = "akkoma@nixos.test";
+              registration_open = true;
+            };
+
+            ":media_proxy" = {
+              enabled = false;
+            };
+
+            "Pleroma.Web.Endpoint" = {
+              url.host = "akkoma.nixos.test";
+            };
+          };
+        };
+
+        nginx = {
+          addSSL = true;
+          sslCertificate = "${tlsCert}/cert.pem";
+          sslCertificateKey = "${tlsCert}/key.pem";
+        };
+      };
+
+      services.nginx.enable = true;
+      services.postgresql.enable = true;
+    };
+  };
+
+  testScript = { nodes, ... }: ''
+    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')
+  '';
+})
+
diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix
index e577001a3baf..e385dfebebf3 100644
--- a/nixos/tests/all-tests.nix
+++ b/nixos/tests/all-tests.nix
@@ -73,6 +73,8 @@ in {
   agate = runTest ./web-servers/agate.nix;
   agda = handleTest ./agda.nix {};
   airsonic = handleTest ./airsonic.nix {};
+  akkoma = handleTestOn [ "x86_64-linux" "aarch64-linux" ] ./akkoma.nix {};
+  akkoma-confined = handleTestOn [ "x86_64-linux" "aarch64-linux" ] ./akkoma.nix { confined = true; };
   allTerminfo = handleTest ./all-terminfo.nix {};
   alps = handleTest ./alps.nix {};
   amazon-init-shell = handleTest ./amazon-init-shell.nix {};
diff --git a/pkgs/servers/akkoma/default.nix b/pkgs/servers/akkoma/default.nix
index 050d2c64285c..5df95623dad4 100644
--- a/pkgs/servers/akkoma/default.nix
+++ b/pkgs/servers/akkoma/default.nix
@@ -3,6 +3,7 @@
 , fetchFromGitea, fetchFromGitHub, fetchFromGitLab
 , cmake, file, libxcrypt
 , writeText
+, nixosTests
 , ...
 }:
 
@@ -200,6 +201,11 @@ beamPackages.mixRelease rec {
     });
   };
 
+  passthru = {
+    tests = with nixosTests; { inherit akkoma akkoma-confined; };
+    inherit mixNixDeps;
+  };
+
   meta = with lib; {
     description = "ActivityPub microblogging server";
     homepage = "https://akkoma.social";