From 5b3ce4f78fe3eef68179a177928b4ee9d63ecb85 Mon Sep 17 00:00:00 2001
From: Florian Brandes <florian.brandes@posteo.de>
Date: Sat, 28 Jan 2023 20:02:15 +0100
Subject: [PATCH] octoprint: add nixosTests

Signed-off-by: Florian Brandes <florian.brandes@posteo.de>
Co-authored-by: Nick Cao <nickcao@nichi.co>
---
 nixos/tests/all-tests.nix                    |  1 +
 nixos/tests/octoprint.nix                    | 61 ++++++++++++++++++++
 pkgs/applications/misc/octoprint/default.nix |  4 ++
 3 files changed, 66 insertions(+)
 create mode 100644 nixos/tests/octoprint.nix

diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix
index b839d539c9f5..12e386f1c2d5 100644
--- a/nixos/tests/all-tests.nix
+++ b/nixos/tests/all-tests.nix
@@ -485,6 +485,7 @@ in {
   opensmtpd = handleTest ./opensmtpd.nix {};
   opensmtpd-rspamd = handleTest ./opensmtpd-rspamd.nix {};
   openssh = handleTest ./openssh.nix {};
+  octoprint = handleTest ./octoprint.nix {};
   openstack-image-metadata = (handleTestOn ["x86_64-linux"] ./openstack-image.nix {}).metadata or {};
   openstack-image-userdata = (handleTestOn ["x86_64-linux"] ./openstack-image.nix {}).userdata or {};
   opentabletdriver = handleTest ./opentabletdriver.nix {};
diff --git a/nixos/tests/octoprint.nix b/nixos/tests/octoprint.nix
new file mode 100644
index 000000000000..15a2d677d4cf
--- /dev/null
+++ b/nixos/tests/octoprint.nix
@@ -0,0 +1,61 @@
+import ./make-test-python.nix ({ pkgs, lib, ... }:
+
+let
+  apikey = "testapikey";
+in
+{
+  name = "octoprint";
+  meta.maintainers = with lib.maintainers; [ gador ];
+
+  nodes.machine = { pkgs, ... }: {
+    environment.systemPackages = with pkgs; [ jq ];
+    services.octoprint = {
+      enable = true;
+      extraConfig = {
+        server = {
+          firstRun = false;
+        };
+        api = {
+          enabled = true;
+          key = apikey;
+        };
+        plugins = {
+          # these need internet access and pollute the output with connection failed errors
+          _disabled = [ "softwareupdate" "announcements" "pluginmanager" ];
+        };
+      };
+    };
+  };
+
+  testScript = ''
+    import json
+
+    @polling_condition
+    def octoprint_running():
+        machine.succeed("pgrep octoprint")
+
+    with subtest("Wait for octoprint service to start"):
+        machine.wait_for_unit("octoprint.service")
+        machine.wait_until_succeeds("pgrep octoprint")
+
+    with subtest("Wait for final boot"):
+        # this appears whe octoprint is almost finished starting
+        machine.wait_for_file("/var/lib/octoprint/uploads")
+
+    # octoprint takes some time to start. This makes sure we'll retry just in case it takes longer
+    # retry-all-errors in necessary, since octoprint will report a 404 error when not yet ready
+    curl_cmd = "curl --retry-all-errors --connect-timeout 5 --max-time 10 --retry 5 --retry-delay 0 \
+                --retry-max-time 40 -X GET --header 'X-API-Key: ${apikey}' "
+
+    # used to fail early, in case octoprint first starts and then crashes
+    with octoprint_running: # type: ignore[union-attr]
+        with subtest("Check for web interface"):
+            machine.wait_until_succeeds("curl -s localhost:5000")
+
+        with subtest("Check API"):
+            version = json.loads(machine.succeed(curl_cmd + "localhost:5000/api/version"))
+            server = json.loads(machine.succeed(curl_cmd + "localhost:5000/api/server"))
+            assert version["server"] == str("${pkgs.octoprint.version}")
+            assert server["safemode"] == None
+  '';
+})
diff --git a/pkgs/applications/misc/octoprint/default.nix b/pkgs/applications/misc/octoprint/default.nix
index b6dcf9056841..4b445c6b3083 100644
--- a/pkgs/applications/misc/octoprint/default.nix
+++ b/pkgs/applications/misc/octoprint/default.nix
@@ -5,6 +5,7 @@
 , python3
 , substituteAll
 , nix-update-script
+, nixosTests
   # To include additional plugins, pass them here as an overlay.
 , packageOverrides ? self: super: { }
 }:
@@ -217,6 +218,9 @@ let
               passthru = {
                 python = self.python;
                 updateScript = nix-update-script { };
+                tests = {
+                  inherit (nixosTests) octoprint;
+                };
               };
 
               meta = with lib; {