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