diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index a5d820bd50f0..b838d2d8cff4 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -1094,6 +1094,7 @@ in nextflow = runTestOn [ "x86_64-linux" ] ./nextflow.nix; nextjs-ollama-llm-ui = runTest ./web-apps/nextjs-ollama-llm-ui.nix; nexus = runTest ./nexus.nix; + nezha = runTest ./nezha.nix; # TODO: Test nfsv3 + Kerberos nfs3 = handleTest ./nfs { version = 3; }; nfs4 = handleTest ./nfs { version = 4; }; diff --git a/nixos/tests/nezha.nix b/nixos/tests/nezha.nix new file mode 100644 index 000000000000..924cfc1d8300 --- /dev/null +++ b/nixos/tests/nezha.nix @@ -0,0 +1,114 @@ +{ lib, pkgs, ... }: +let + agent_host = "agent.test"; + dashboard_host = "dashboard.test"; + + agentSecret = pkgs.writeText "fakeagentsecret" "fakeagentsecret"; + + hosts = { + "${agent_host}" = "192.168.0.2"; + "${dashboard_host}" = "192.168.0.1"; + }; + hostsEntries = lib.mapAttrs' (k: v: { + name = v; + value = lib.singleton k; + }) hosts; +in +{ + name = "nezha"; + + meta.maintainers = with lib.maintainers; [ moraxyc ]; + + containers = { + agent = _: { + networking = { + hostName = builtins.elemAt (lib.splitString "." agent_host) 0; + domain = builtins.elemAt (lib.splitString "." agent_host) 1; + firewall.enable = false; + hosts = hostsEntries; + useDHCP = false; + interfaces.eth1.ipv4.addresses = lib.singleton { + address = hosts."${agent_host}"; + prefixLength = 24; + }; + }; + services.nezha-agent = { + enable = true; + debug = true; + genUuid = true; + settings = { + server = hosts."${dashboard_host}" + ":80"; + }; + clientSecretFile = agentSecret; + }; + }; + + dashboard = + { pkgs, ... }: + { + networking = { + firewall.enable = false; + hosts = hostsEntries; + useDHCP = false; + interfaces.eth1.ipv4.addresses = lib.singleton { + address = hosts."${dashboard_host}"; + prefixLength = 24; + }; + }; + services.nezha = { + enable = true; + debug = true; + settings = { + listenhost = "0.0.0.0"; + # Test CAP_NET_BIND_SERVICE + listenport = 80; + }; + mutableConfig = true; + jwtSecretFile = pkgs.writeText "fakejwt" "fakejwt"; + agentSecretFile = agentSecret; + }; + }; + }; + + testScript = '' + import json + + with subtest("Wait for services and network"): + dashboard.wait_for_unit("nezha.service") + agent.wait_for_unit("nezha-agent.service") + dashboard.wait_for_open_port(80) + dashboard.wait_for_unit("network.target") + agent.wait_for_unit("network.target") + agent.succeed("curl --fail --max-time 10 http://dashboard.test/") + + with subtest("Test mutableConfig"): + dashboard.succeed("systemctl stop nezha") + dashboard.succeed(""" + echo '{"sitename": "Nezha on NixOS"}' > /etc/nezha/config.yaml + """) + dashboard.succeed("systemctl start nezha") + dashboard.wait_for_unit("nezha.service") + dashboard.wait_for_open_port(80) + result = json.loads(agent.succeed(""" + curl --fail -X POST --json '{ "username": "admin", "password": "admin"}' \ + 'http://dashboard.test/api/v1/login' + """)) + token = result['data']['token'] + result = json.loads(agent.succeed(f""" + curl --fail -X GET --header 'Authorization: Bearer {token}' \ + 'http://dashboard.test/api/v1/setting' + """)) + assert "Nezha on NixOS" == result['data']['config']['site_name'] + + with subtest("Verify connection and uuid"): + uuid = agent.succeed( + "${lib.getExe' pkgs.util-linux "uuidgen"} --md5 -n @dns -N ${agent_host}" + ) + # remove unprintable characters + uuid = "".join([char for char in uuid if char.isprintable()]) + agent.wait_until_succeeds(f""" + curl --fail -X GET --header 'Authorization: Bearer {token}' \ + 'http://dashboard.test/api/v1/server' | grep {uuid} + """) + ''; +}