1import ./make-test-python.nix ({ pkgs, lib, ... }:
2
3let
4 apikey = "testapikey";
5in
6{
7 name = "octoprint";
8 meta.maintainers = with lib.maintainers; [ gador ];
9
10 nodes.machine = { pkgs, ... }: {
11 environment.systemPackages = with pkgs; [ jq ];
12 services.octoprint = {
13 enable = true;
14 extraConfig = {
15 server = {
16 firstRun = false;
17 };
18 api = {
19 enabled = true;
20 key = apikey;
21 };
22 plugins = {
23 # these need internet access and pollute the output with connection failed errors
24 _disabled = [ "softwareupdate" "announcements" "pluginmanager" ];
25 };
26 };
27 };
28 };
29
30 testScript = ''
31 import json
32
33 @polling_condition
34 def octoprint_running():
35 machine.succeed("pgrep octoprint")
36
37 with subtest("Wait for octoprint service to start"):
38 machine.wait_for_unit("octoprint.service")
39 machine.wait_until_succeeds("pgrep octoprint")
40
41 with subtest("Wait for final boot"):
42 # this appears whe octoprint is almost finished starting
43 machine.wait_for_file("/var/lib/octoprint/uploads")
44
45 # octoprint takes some time to start. This makes sure we'll retry just in case it takes longer
46 # retry-all-errors in necessary, since octoprint will report a 404 error when not yet ready
47 curl_cmd = "curl --retry-all-errors --connect-timeout 5 --max-time 10 --retry 5 --retry-delay 0 \
48 --retry-max-time 40 -X GET --header 'X-API-Key: ${apikey}' "
49
50 # used to fail early, in case octoprint first starts and then crashes
51 with octoprint_running: # type: ignore[union-attr]
52 with subtest("Check for web interface"):
53 machine.wait_until_succeeds("curl -s localhost:5000")
54
55 with subtest("Check API"):
56 version = json.loads(machine.succeed(curl_cmd + "localhost:5000/api/version"))
57 server = json.loads(machine.succeed(curl_cmd + "localhost:5000/api/server"))
58 assert version["server"] == str("${pkgs.octoprint.version}")
59 assert server["safemode"] == None
60 '';
61})