vuls: init at 0.27.0
[NixPkgs.git] / nixos / tests / lemmy.nix
blob66bdaffbe29e35745a3524ad0e3522e3b2cfbc42
1 import ./make-test-python.nix ({ pkgs, lib, ... }:
2 let
3   uiPort = 1234;
4   backendPort = 5678;
5   lemmyNodeName = "server";
6 in
8   name = "lemmy";
9   meta = with lib.maintainers; { maintainers = [ mightyiam ]; };
11   nodes = {
12     client = { };
14     "${lemmyNodeName}" = {
15       services.lemmy = {
16         enable = true;
17         ui.port = uiPort;
18         database.createLocally = true;
19         settings = {
20           hostname = "http://${lemmyNodeName}";
21           port = backendPort;
22           # Without setup, the /feeds/* and /nodeinfo/* API endpoints won't return 200
23           setup = {
24             admin_username = "mightyiam";
25             site_name = "Lemmy FTW";
26             admin_email = "mightyiam@example.com";
27           };
28         };
29         adminPasswordFile = /etc/lemmy-admin-password.txt;
30         caddy.enable = true;
31       };
33       environment.etc."lemmy-admin-password.txt".text = "ThisIsWhatIUseEverywhereTryIt";
35       networking.firewall.allowedTCPPorts = [ 80 ];
37       # pict-rs seems to need more than 1025114112 bytes
38       virtualisation.memorySize = 2000;
39     };
40   };
42   testScript = ''
43     server = ${lemmyNodeName}
45     with subtest("the merged config is secure"):
46         server.wait_for_unit("lemmy.service")
47         config_permissions = server.succeed("stat --format %A /run/lemmy/config.hjson").rstrip()
48         assert config_permissions == "-rw-------", f"merged config permissions {config_permissions} are insecure"
49         directory_permissions = server.succeed("stat --format %A /run/lemmy").rstrip()
50         assert directory_permissions[5] == directory_permissions[8] == "-", "merged config can be replaced"
52     with subtest("the backend starts and responds"):
53         server.wait_for_open_port(${toString backendPort})
54         # wait until succeeds, it just needs few seconds for migrations, but lets give it 50s max
55         server.wait_until_succeeds("curl --fail localhost:${toString backendPort}/api/v3/site", 50)
57     with subtest("the UI starts and responds"):
58         server.wait_for_unit("lemmy-ui.service")
59         server.wait_for_open_port(${toString uiPort})
60         server.succeed("curl --fail localhost:${toString uiPort}")
62     with subtest("Lemmy-UI responds through the caddy reverse proxy"):
63         server.systemctl("start network-online.target")
64         server.wait_for_unit("network-online.target")
65         server.wait_for_unit("caddy.service")
66         server.wait_for_open_port(80)
67         body = server.execute("curl --fail --location ${lemmyNodeName}")[1]
68         assert "Lemmy" in body, f"String Lemmy not found in response for ${lemmyNodeName}: \n{body}"
70     with subtest("the server is exposed externally"):
71         client.systemctl("start network-online.target")
72         client.wait_for_unit("network-online.target")
73         client.succeed("curl -v --fail ${lemmyNodeName}")
75     with subtest("caddy correctly routes backend requests"):
76         # Make sure we are not hitting frontend
77         server.execute("systemctl stop lemmy-ui.service")
79         def assert_http_code(url, expected_http_code, extra_curl_args=""):
80             _, http_code = server.execute(f'curl --location --silent -o /dev/null {extra_curl_args} --fail --write-out "%{{http_code}}" {url}')
81             assert http_code == str(expected_http_code), f"expected http code {expected_http_code}, got {http_code}"
83         # Caddy responds with HTTP code 502 if it cannot handle the requested path
84         assert_http_code("${lemmyNodeName}/obviously-wrong-path/", 502)
86         assert_http_code("${lemmyNodeName}/static/js/client.js", 200)
87         assert_http_code("${lemmyNodeName}/api/v3/site", 200)
89         # A 404 confirms that the request goes to the backend
90         # No path can return 200 until after we upload an image to pict-rs
91         assert_http_code("${lemmyNodeName}/pictrs/", 404)
93         assert_http_code("${lemmyNodeName}/feeds/all.xml", 200)
94         assert_http_code("${lemmyNodeName}/nodeinfo/2.0.json", 200)
96         assert_http_code("${lemmyNodeName}/some-other-made-up-path/", 404, "-X POST")
97         assert_http_code("${lemmyNodeName}/some-other-path", 404, "-H 'Accept: application/activity+json'")
98         assert_http_code("${lemmyNodeName}/some-other-path", 404, "-H 'Accept: application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"'")
99   '';