aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--tests/by-name/at/atuin-sync/test.nix102
-rw-r--r--tests/by-name/ba/back/test.nix46
-rw-r--r--tests/by-name/em/email-dns/test.nix3
-rw-r--r--tests/by-name/em/email-http/test.nix3
-rw-r--r--tests/by-name/em/email-ip/test.nix3
-rw-r--r--tests/by-name/gi/git-server/test.nix49
-rw-r--r--tests/by-name/mo/monitoring-basic/test.nix75
-rw-r--r--tests/by-name/mo/monitoring-federation/test.nix109
-rw-r--r--tests/by-name/ro/rocie/test.nix89
-rw-r--r--tests/by-name/ru/rust-motd/test.nix47
-rw-r--r--tests/by-name/sh/sharkey-cpu/test.nix57
-rw-r--r--tests/by-name/sh/sharkey/test.nix87
-rw-r--r--tests/by-name/ta/taskchampion-sync/test.nix66
-rw-r--r--tests/common/acme/default.nix7
-rw-r--r--tests/default.nix258
15 files changed, 585 insertions, 416 deletions
diff --git a/tests/by-name/at/atuin-sync/test.nix b/tests/by-name/at/atuin-sync/test.nix
index d65c216..627e89e 100644
--- a/tests/by-name/at/atuin-sync/test.nix
+++ b/tests/by-name/at/atuin-sync/test.nix
@@ -6,62 +6,27 @@
pkgs,
extraModules,
nixLib,
+ turtle,
+ vhack,
...
}:
-nixos-lib.runTest {
- hostPkgs = pkgs;
+vhack.runTest {
name = "atuin-sync";
-
- node = {
- specialArgs = {inherit pkgsUnstable vhackPackages nixpkgs-unstable nixLib;};
-
- # Use the nixpkgs as constructed by the `nixpkgs.*` options
- pkgs = null;
- };
+ serverDomains = [
+ {
+ server = "atuin-sync.server";
+ }
+ ];
nodes = let
atuinSession = "01969ec6b8d07e30a9d2df0911fbfe2a";
+ atuin = turtle.packages."${pkgs.stdenv.hostPlatform.system}".default;
in {
- acme = {
- imports = [
- ../../../common/acme/server.nix
- ../../../common/dns/client.nix
- ];
- };
- name_server = {nodes, ...}: {
- imports =
- extraModules
- ++ [
- ../../../common/acme/client.nix
- ../../../common/dns/server.nix
- ];
-
- vhack.dns.zones = {
- "atuin-sync.server" = {
- SOA = {
- nameServer = "ns";
- adminEmail = "admin@server.com";
- serial = 2025012301;
- };
- useOrigin = false;
-
- A = [
- nodes.server.networking.primaryIPAddress
- ];
- AAAA = [
- nodes.server.networking.primaryIPv6Address
- ];
- };
- };
- };
-
server = {config, ...}: {
imports =
extraModules
++ [
../../../../modules
- ../../../common/acme/client.nix
- ../../../common/dns/client.nix
];
vhack = {
@@ -75,50 +40,37 @@ nixos-lib.runTest {
};
client1 = {config, ...}: {
- imports = [
- ../../../common/acme/client.nix
- ../../../common/dns/client.nix
- ];
-
environment.sessionVariables.ATUIN_SESSION = atuinSession;
environment.systemPackages = [
- pkgs.atuin
+ atuin
pkgs.sqlite-interactive
];
};
client2 = {config, ...}: {
- imports = [
- ../../../common/acme/client.nix
- ../../../common/dns/client.nix
- ];
-
environment.sessionVariables.ATUIN_SESSION = atuinSession;
environment.systemPackages = [
- pkgs.atuin
+ atuin
pkgs.sqlite-interactive
];
};
};
- testScript = {nodes, ...}: let
- syncLogin = pkgs.writeShellScript "login-atuin-sync-account" ''
- atuin login --username syncy --password password1234 --key "$1"
- '';
-
- syncRegister = pkgs.writeShellScript "register-atuin-sync-account" ''
- atuin register --username syncy --email syncy@email.com --password password1234
- '';
+ services = [
+ {server = "turtle.service";}
+ ];
+ testScript = {nodes, ...}: let
mkSyncConfig = pkgs.writeShellScript "register-atuin-sync-account" ''
mkdir --parents ~/.config/atuin/
+
cat << EOF > ~/.config/atuin/config.toml
- sync_address = "https://atuin-sync.server"
- # Use the v2 sync
[sync]
- records = true
+ address = "https://atuin-sync.server"
+ user_id_path = "${pkgs.writeText "user-id" "019eb88a-6b51-7e52-b12c-7d30bd8e5928"}"
+ encryption_key_path = "${pkgs.writeText "encryption-key" "3AAgbWsDzL7M00/Mq0LMjsyOCy3MnsypBsyQzKbMywNGzNnMrUBozIINAxdbIiDMhQ=="}"
EOF
'';
@@ -141,13 +93,9 @@ nixos-lib.runTest {
run_and_record_in_atuin "$@"
'';
-
- acme = import ../../../common/acme {inherit pkgs;};
in
- acme.prepare ["server" "client1" "client2"]
# Python
''
- server.wait_for_unit("atuin.service")
server.wait_for_open_port(443)
# Wait for the server to acquire the acme certificate
@@ -158,8 +106,12 @@ nixos-lib.runTest {
for client in [client1, client2]:
client.succeed("${mkSyncConfig}")
- client1.succeed("${syncRegister}")
- client2.succeed(f"${syncLogin} '{client1.succeed("atuin key")}'")
+ with subtest("Start atuin daemons"):
+ for client in [client1, client2]:
+ client.succeed("systemd-run atuin daemon start")
+
+ for client in [client1, client2]:
+ client.wait_until_succeeds("atuin daemon status")
with subtest("Can import shell history"):
client1.succeed("${runCommandAndRecordInAtuin} echo hi - client 1")
@@ -167,8 +119,8 @@ nixos-lib.runTest {
with subtest("Can sync tasks"):
for client in [client1, client2]:
- client.succeed("atuin sync --force")
- client1.succeed("atuin sync --force")
+ client.succeed("atuin sync perform --force")
+ client1.succeed("atuin sync perform --force")
with subtest("Have correct tasks"):
diff --git a/tests/by-name/ba/back/test.nix b/tests/by-name/ba/back/test.nix
index 41d6c8e..b1d908d 100644
--- a/tests/by-name/ba/back/test.nix
+++ b/tests/by-name/ba/back/test.nix
@@ -1,11 +1,7 @@
{
- nixos-lib,
- pkgsUnstable,
- nixpkgs-unstable,
- vhackPackages,
pkgs,
extraModules,
- nixLib,
+ vhack,
...
}: let
domain = "server";
@@ -22,17 +18,15 @@
option user-configs = cgit\.owner cgit\.desc cgit\.section cgit\.homepage
'';
in
- nixos-lib.runTest {
- hostPkgs = pkgs; # the Nixpkgs package set used outside the VMs
-
+ vhack.runTest {
name = "back";
- node = {
- specialArgs = {inherit pkgsUnstable vhackPackages nixpkgs-unstable nixLib;};
+ ignore = "We are not using back currently.";
- # Use the nixpkgs as constructed by the `nixpkgs.*` options
- pkgs = null;
- };
+ serverDomains = [
+ {server = "git.${domain}";}
+ {server = "issues.${domain}";}
+ ];
nodes = {
server = {config, ...}: {
@@ -49,7 +43,6 @@ in
openssh.enable = true;
nginx = {
enable = true;
- selfsign = true;
};
git-server = {
enable = true;
@@ -73,23 +66,17 @@ in
PreferredAuthentications publickey
'';
users.users.alice = {isNormalUser = true;};
- networking.hosts = {
- "${nodes.server.networking.primaryIPAddress}" = [
- "git.${domain}"
- "issues.${domain}"
- "${domain}"
- ];
- };
};
};
+ services = [
+ {server = "gitolite-init.service";}
+ {server = "sshd.service";}
+ ];
+
testScript = {nodes, ...}:
- /*
- python
- */
+ # Python
''
- start_all()
-
with subtest("can setup ssh keys on client"):
client.succeed(
"mkdir -p ~root/.ssh",
@@ -103,11 +90,8 @@ in
)
with subtest("gitolite server starts"):
- server.wait_for_unit("gitolite-init.service")
- server.wait_for_unit("sshd.service")
client.succeed("ssh -n git@git.${domain} info")
-
with subtest("admin can clone and configure gitolite-admin.git"):
server.succeed("sudo -u git ${pkgs.writeShellScript "delete_main_branch_on_server" ''
set -xe
@@ -188,10 +172,10 @@ in
client.succeed("${pkgs.writeShellScript "curl-back" ''
set -xe
- curl --insecure --fail --show-error "https://issues.${domain}/alice/repo1/issues/?query=status:open" --output /root/issues.html
+ curl --fail --show-error "https://issues.${domain}/alice/repo1/issues/?query=status:open" --output /root/issues.html
grep -- 'Second bug title' /root/issues.html
- curl --insecure --fail --show-error "https://issues.${domain}/" --output /root/repos.html
+ curl --fail --show-error "https://issues.${domain}/" --output /root/repos.html
grep -- 'repo' /root/repos.html
grep -- "&lt;No description&gt;" /root/repos.html
grep -- '<span class="user-name">Alice</span>' /root/repos.html
diff --git a/tests/by-name/em/email-dns/test.nix b/tests/by-name/em/email-dns/test.nix
index c7ba3b3..33955d8 100644
--- a/tests/by-name/em/email-dns/test.nix
+++ b/tests/by-name/em/email-dns/test.nix
@@ -14,6 +14,9 @@
inherit (user) mkUser;
in
nixos-lib.runTest {
+ # Wait until we actually use stalwart again
+ meta.broken = true;
+
hostPkgs = pkgs; # the Nixpkgs package set used outside the VMs
name = "email-dns";
diff --git a/tests/by-name/em/email-http/test.nix b/tests/by-name/em/email-http/test.nix
index 82b4c45..42fd22b 100644
--- a/tests/by-name/em/email-http/test.nix
+++ b/tests/by-name/em/email-http/test.nix
@@ -14,6 +14,9 @@
inherit (user) mkUser;
in
nixos-lib.runTest {
+ # Wait until we actually use stalwart again
+ meta.broken = true;
+
hostPkgs = pkgs; # the Nixpkgs package set used outside the VMs
name = "email-http";
diff --git a/tests/by-name/em/email-ip/test.nix b/tests/by-name/em/email-ip/test.nix
index dabc404..c0b2d7e 100644
--- a/tests/by-name/em/email-ip/test.nix
+++ b/tests/by-name/em/email-ip/test.nix
@@ -78,6 +78,9 @@
};
in
nixos-lib.runTest {
+ # Wait until we actually use stalwart again
+ meta.broken = true;
+
hostPkgs = pkgs; # the Nixpkgs package set used outside the VMs
name = "email";
diff --git a/tests/by-name/gi/git-server/test.nix b/tests/by-name/gi/git-server/test.nix
index 4e503b6..6fc3685 100644
--- a/tests/by-name/gi/git-server/test.nix
+++ b/tests/by-name/gi/git-server/test.nix
@@ -5,6 +5,7 @@
pkgs,
extraModules,
nixLib,
+ vhack,
...
}: let
sshKeys =
@@ -35,24 +36,16 @@
option user-configs = cgit\.owner cgit\.desc cgit\.section cgit\.homepage
'';
- expectedHtmlReadme = pkgs.writeText "expectedHtmlReadme" ''
- <h1>Alice's Repo</h1>
- '';
expectedMdReadme = pkgs.writeText "expectedMdReadme" ''
# Alice's Repo
'';
in
- nixos-lib.runTest {
- hostPkgs = pkgs; # the Nixpkgs package set used outside the VMs
-
+ vhack.runTest {
name = "git-server";
- node = {
- specialArgs = {inherit pkgsUnstable nixpkgs-unstable nixLib;};
-
- # Use the nixpkgs as constructed by the `nixpkgs.*` options
- pkgs = null;
- };
+ serverDomains = [
+ {server = gitServerDomain;}
+ ];
nodes = {
server = {config, ...}: {
@@ -67,7 +60,6 @@ in
openssh.enable = true;
nginx = {
enable = true;
- selfsign = true;
};
git-server = {
enable = true;
@@ -91,13 +83,14 @@ in
};
};
- testScript = {nodes, ...}:
- /*
- python
- */
- ''
- start_all()
+ services = [
+ {server = "gitolite-init.service";}
+ {server = "sshd.service";}
+ ];
+ testScript = {...}:
+ # Python
+ ''
with subtest("can setup ssh keys on client"):
client.succeed(
"mkdir -p ~root/.ssh",
@@ -116,8 +109,6 @@ in
)
with subtest("gitolite server starts"):
- server.wait_for_unit("gitolite-init.service")
- server.wait_for_unit("sshd.service")
client.succeed("ssh -n git@server info")
@@ -224,15 +215,13 @@ in
}
''}")
+ with subtest("Bob can see alice's README"):
+ client.succeed("sudo -u bob ${pkgs.writeShellScript "bob-alice-readme" ''
+ set -xe
- # He can't see the readme (FIXME: find out why this does not work. <2024-08-13> )
- # with subtest("Bob can see alice's README"):
- # client.succeed("sudo -u bob ${pkgs.writeShellScript "bob-alice-readme" ''
- # set -xe
- #
- # curl --insecure --silent --fail --show-error 'https://server/alice/alice-project/about' > readme.html
- # cat readme.html
- # diff --side-by-side ${expectedHtmlReadme} readme.html
- # ''}")
+ curl --fail --show-error 'https://server/alice/alice-project/about/' > readme.html
+ grep 'alice-project - My nice project.' ./readme.html
+ grep 'My nice project.' ./readme.html
+ ''}")
'';
}
diff --git a/tests/by-name/mo/monitoring-basic/test.nix b/tests/by-name/mo/monitoring-basic/test.nix
new file mode 100644
index 0000000..a00331f
--- /dev/null
+++ b/tests/by-name/mo/monitoring-basic/test.nix
@@ -0,0 +1,75 @@
+{
+ extraModules,
+ vhack,
+ ...
+}: let
+ grafanaDomain = "grafana.server.org";
+ scrutinyDomain = "scrutiny.server.org";
+in
+ vhack.runTest {
+ name = "monitoring";
+
+ serverDomains = [
+ {server = grafanaDomain;}
+ {server = scrutinyDomain;}
+ ];
+
+ nodes = {
+ client = {};
+
+ server = {config, ...}: {
+ imports =
+ extraModules
+ ++ [
+ ../../../../modules
+ ];
+
+ # there are no SMART available disk in the VM, so this service always fails.
+ systemd.services."smartd".enable = false;
+
+ age.identityPaths = ["${../../../common/email/hostKey}"];
+
+ vhack = {
+ monitoring = {
+ grafana = {
+ enable = true;
+ contactPoints = ["me@example.com"];
+ fqdn = grafanaDomain;
+
+ adminPassword = ../../../common/email/dkim/alice.com/private.age;
+ secretKey = ../../../common/email/dkim/bob.com/private.age;
+
+ # TODO: Add a test for that <2026-07-19>
+ smtp = null;
+ };
+
+ loki = {
+ enable = true;
+ };
+
+ prometheus = {
+ enable = true;
+ };
+
+ scrutiny = {
+ enable = true;
+ fqdn = scrutinyDomain;
+ };
+ };
+ };
+ };
+ };
+
+ services = [
+ {server = "grafana.service";}
+ {server = "fluent-bit.service";}
+ {server = "loki.service";}
+ {server = "netdata.service";}
+ ];
+
+ testScript = {...}:
+ # Python
+ ''
+ # TODO: We should probably query some of the prometheus metrics here? <2026-07-19>
+ '';
+ }
diff --git a/tests/by-name/mo/monitoring-federation/test.nix b/tests/by-name/mo/monitoring-federation/test.nix
new file mode 100644
index 0000000..a64577d
--- /dev/null
+++ b/tests/by-name/mo/monitoring-federation/test.nix
@@ -0,0 +1,109 @@
+{
+ extraModules,
+ pkgs,
+ vhack,
+ ...
+}: let
+ prometheusMain = "prometheus.server2.server.org";
+ remoteWriteTo = {
+ url = "https://${prometheusMain}";
+ };
+ promPort = 3001;
+in
+ vhack.runTest {
+ name = "monitoring";
+
+ serverDomains = [
+ {server2 = prometheusMain;}
+ ];
+
+ nodes = {
+ server2 = {config, ...}: {
+ imports =
+ extraModules
+ ++ [
+ ../../../../modules
+ ];
+
+ environment.systemPackages = [
+ pkgs.curl
+ ];
+
+ vhack = {
+ monitoring = {
+ prometheus = {
+ enable = true;
+ port = promPort;
+ remoteWriteReceiver = prometheusMain;
+ };
+ };
+ };
+ };
+ server3 = {config, ...}: {
+ imports =
+ extraModules
+ ++ [
+ ../../../../modules
+ ];
+
+ vhack = {
+ monitoring = {
+ prometheus = {
+ enable = true;
+ port = promPort;
+ inherit remoteWriteTo;
+ };
+ };
+ };
+ };
+ server4 = {config, ...}: {
+ imports =
+ extraModules
+ ++ [
+ ../../../../modules
+ ];
+
+ vhack = {
+ monitoring = {
+ prometheus = {
+ enable = true;
+ port = promPort;
+ inherit remoteWriteTo;
+ };
+ };
+ };
+ };
+ };
+
+ services = [
+ {server2 = "prometheus.service";}
+ {server3 = "prometheus.service";}
+ {server4 = "prometheus.service";}
+ ];
+
+ testScript = {...}:
+ # Python
+ ''
+ import json, time
+
+ # Give the Prometheus servers some time to generate metrics and sync with the main
+ # one.
+ time.sleep(1)
+
+ metrics = server2.succeed("${pkgs.writeShellScript "query-metrics" ''
+ curl --silent \
+ http://127.0.0.1:${toString promPort}/api/v1/query?query="go_gc_cleanups_queued_cleanups_total"
+ ''}")
+
+ metrics = json.loads(metrics)
+
+ hosts = []
+ for result in metrics["data"]["result"]:
+ server2.log(json.dumps(result,indent=4))
+ hosts.append(result["metric"]["hostname"])
+
+ hosts.sort()
+
+ assert hosts == ["server2", "server3", "server4"], f"Not all hosts used the remote write (got {hosts})"
+ '';
+ }
diff --git a/tests/by-name/ro/rocie/test.nix b/tests/by-name/ro/rocie/test.nix
index c2ba97a..1f0fccb 100644
--- a/tests/by-name/ro/rocie/test.nix
+++ b/tests/by-name/ro/rocie/test.nix
@@ -1,66 +1,21 @@
{
- nixos-lib,
- pkgsUnstable,
- nixpkgs-unstable,
- vhackPackages,
- pkgs,
extraModules,
- nixLib,
+ vhack,
...
}:
-nixos-lib.runTest {
- hostPkgs = pkgs; # the Nixpkgs package set used outside the VMs
-
+vhack.runTest {
name = "rocie";
- node = {
- specialArgs = {inherit pkgsUnstable extraModules vhackPackages nixpkgs-unstable nixLib;};
-
- # Use the nixpkgs as constructed by the `nixpkgs.*` options
- pkgs = null;
- };
+ serverDomains = [
+ {server = "rocie.server";}
+ ];
nodes = {
- acme = {...}: {
- imports = [
- ../../../common/acme/server.nix
- ../../../common/dns/client.nix
- ];
- };
- name_server = {nodes, ...}: {
- imports =
- extraModules
- ++ [
- ../../../common/acme/client.nix
- ../../../common/dns/server.nix
- ];
-
- vhack.dns.zones = {
- "rocie.server" = {
- SOA = {
- nameServer = "ns";
- adminEmail = "admin@server.com";
- serial = 2025012301;
- };
- useOrigin = false;
-
- A = [
- nodes.server.networking.primaryIPAddress
- ];
- AAAA = [
- nodes.server.networking.primaryIPv6Address
- ];
- };
- };
- };
-
server = {config, ...}: {
imports =
extraModules
++ [
../../../../modules
- ../../../common/acme/client.nix
- ../../../common/dns/client.nix
];
age.identityPaths = ["${../../../common/email/hostKey}"];
@@ -76,31 +31,17 @@ nixos-lib.runTest {
};
};
- client = {...}: {
- imports = [
- ../../../common/acme/client.nix
- ../../../common/dns/client.nix
- ];
- };
+ client = {_, ...}: {};
};
- testScript = {nodes, ...}: let
- acme = import ../../../common/acme {inherit pkgs;};
- in
- acme.prepare ["server" "client"]
- # Python
- ''
- server.wait_for_unit("rocie.service")
-
- with subtest("All services running"):
- import json
- def all_services_running(host):
- (status, output) = host.systemctl("list-units --state=failed --plain --no-pager --output=json")
- host_failed = json.loads(output)
- assert len(host_failed) == 0, f"Expected zero failing services, but found: {json.dumps(host_failed, indent=4)}"
- all_services_running(server)
+ services = [
+ {server = "rocie.service";}
+ ];
- client.wait_until_succeeds("curl --verbose https://rocie.server/api/can-be-provisioned > out.file")
- client.copy_from_vm("out.file")
- '';
+ testScript = {...}:
+ # Python
+ ''
+ client.wait_until_succeeds("curl --verbose https://rocie.server/api/can-be-provisioned > out.file")
+ client.copy_from_vm("out.file")
+ '';
}
diff --git a/tests/by-name/ru/rust-motd/test.nix b/tests/by-name/ru/rust-motd/test.nix
index 6623c0c..43a905d 100644
--- a/tests/by-name/ru/rust-motd/test.nix
+++ b/tests/by-name/ru/rust-motd/test.nix
@@ -1,25 +1,11 @@
{
- nixos-lib,
- pkgsUnstable,
- nixpkgs-unstable,
- vhackPackages,
- pkgs,
extraModules,
- nixLib,
+ vhack,
...
}:
-nixos-lib.runTest {
- hostPkgs = pkgs;
-
+vhack.runTest {
name = "rust-motd";
- node = {
- specialArgs = {inherit pkgsUnstable extraModules vhackPackages nixpkgs-unstable nixLib;};
-
- # Use the nixpkgs as constructed by the `nixpkgs.*` options
- pkgs = null;
- };
-
nodes = {
server = {config, ...}: {
imports =
@@ -34,29 +20,18 @@ nixos-lib.runTest {
};
};
+ services = [
+ {
+ server = "rust-motd.service";
+ start = true;
+ }
+ ];
+
testScript = {nodes, ...}:
- /*
- python
- */
+ # Python
''
- from time import sleep
-
- start_all()
-
- # Give the service time to run.
- sleep(3)
-
- with subtest("All services running"):
- import json
- def all_services_running(host):
- (status, output) = host.systemctl("list-units --state=failed --plain --no-pager --output=json")
- host_failed = json.loads(output)
- assert len(host_failed) == 0, f"Expected zero failing services, but found: {json.dumps(host_failed, indent=4)}"
- all_services_running(server)
-
with subtest("Motd generated"):
- sleep(1)
- server.succeed("cat /var/lib/rust-motd/motd | tee /dev/stderr | grep --invert-match Error")
+ server.succeed("cat /var/lib/rust-motd/motd | tee /dev/stderr | grep --invert-match --ignore-case Error")
server.copy_from_vm("/var/lib/rust-motd/motd")
'';
diff --git a/tests/by-name/sh/sharkey-cpu/test.nix b/tests/by-name/sh/sharkey-cpu/test.nix
index 47c16ff..d648429 100644
--- a/tests/by-name/sh/sharkey-cpu/test.nix
+++ b/tests/by-name/sh/sharkey-cpu/test.nix
@@ -1,25 +1,12 @@
{
- nixos-lib,
- pkgsUnstable,
- nixpkgs-unstable,
- vhackPackages,
pkgs,
extraModules,
- nixLib,
+ vhack,
...
}:
-nixos-lib.runTest {
- hostPkgs = pkgs; # the Nixpkgs package set used outside the VMs
-
+vhack.runTest {
name = "sharkey-cpu";
- node = {
- specialArgs = {inherit pkgsUnstable extraModules vhackPackages nixpkgs-unstable nixLib;};
-
- # Use the nixpkgs as constructed by the `nixpkgs.*` options
- pkgs = null;
- };
-
nodes = {
server = {config, ...}: {
imports =
@@ -45,12 +32,22 @@ nixos-lib.runTest {
nodejs = pkgs.lib.getExe pkgs.nodejs;
script = pkgs.writeTextFile {
name = "script.js";
- text = ''
- import * as os from 'node:os';
+ text =
+ # js
+ ''
+ import * as os from 'node:os';
+
+ var cpus = os.cpus()
- console.log(os.cpus()[0].model)
- console.log(os.cpus().length)
- '';
+ if (cpus.length != 0) {
+ console.log(cpus[0].model)
+ } else {
+ // Fail?
+ }
+
+ while (true) {
+ }
+ '';
};
in
pkgs.lib.mkForce "${nodejs} ${script}";
@@ -58,24 +55,16 @@ nixos-lib.runTest {
};
};
- testScript = {nodes, ...}:
- /*
- python
- */
+ services = [
+ {server = "sharkey.service";}
+ ];
+
+ testScript = {...}:
+ # Python
''
from time import sleep
- start_all()
-
# Give the service time to run.
sleep(3)
-
- with subtest("All services running"):
- import json
- def all_services_running(host):
- (status, output) = host.systemctl("list-units --state=failed --plain --no-pager --output=json")
- host_failed = json.loads(output)
- assert len(host_failed) == 0, f"Expected zero failing services, but found: {json.dumps(host_failed, indent=4)}"
- all_services_running(server)
'';
}
diff --git a/tests/by-name/sh/sharkey/test.nix b/tests/by-name/sh/sharkey/test.nix
index 0d79cd2..7b6f537 100644
--- a/tests/by-name/sh/sharkey/test.nix
+++ b/tests/by-name/sh/sharkey/test.nix
@@ -1,66 +1,21 @@
{
- nixos-lib,
- pkgsUnstable,
- nixpkgs-unstable,
- vhackPackages,
- pkgs,
extraModules,
- nixLib,
+ vhack,
...
}:
-nixos-lib.runTest {
- hostPkgs = pkgs; # the Nixpkgs package set used outside the VMs
-
+vhack.runTest {
name = "sharkey";
- node = {
- specialArgs = {inherit pkgsUnstable extraModules vhackPackages nixpkgs-unstable nixLib;};
-
- # Use the nixpkgs as constructed by the `nixpkgs.*` options
- pkgs = null;
- };
+ serverDomains = [
+ {server = "sharkey.server";}
+ ];
nodes = {
- acme = {...}: {
- imports = [
- ../../../common/acme/server.nix
- ../../../common/dns/client.nix
- ];
- };
- name_server = {nodes, ...}: {
- imports =
- extraModules
- ++ [
- ../../../common/acme/client.nix
- ../../../common/dns/server.nix
- ];
-
- vhack.dns.zones = {
- "sharkey.server" = {
- SOA = {
- nameServer = "ns";
- adminEmail = "admin@server.com";
- serial = 2025012301;
- };
- useOrigin = false;
-
- A = [
- nodes.server.networking.primaryIPAddress
- ];
- AAAA = [
- nodes.server.networking.primaryIPv6Address
- ];
- };
- };
- };
-
server = {config, ...}: {
imports =
extraModules
++ [
../../../../modules
- ../../../common/acme/client.nix
- ../../../common/dns/client.nix
];
vhack = {
@@ -73,30 +28,16 @@ nixos-lib.runTest {
};
};
- client = {...}: {
- imports = [
- ../../../common/acme/client.nix
- ../../../common/dns/client.nix
- ];
- };
+ client = {...}: {};
};
- testScript = {nodes, ...}: let
- acme = import ../../../common/acme {inherit pkgs;};
- in
- acme.prepare ["server" "client"]
- # Python
- ''
- server.wait_for_unit("sharkey.service")
-
- with subtest("All services running"):
- import json
- def all_services_running(host):
- (status, output) = host.systemctl("list-units --state=failed --plain --no-pager --output=json")
- host_failed = json.loads(output)
- assert len(host_failed) == 0, f"Expected zero failing services, but found: {json.dumps(host_failed, indent=4)}"
- all_services_running(server)
+ services = [
+ {server = "sharkey.service";}
+ ];
- client.wait_until_succeeds("curl --silent https://sharkey.server | grep 'Thank you for using Sharkey!'")
- '';
+ testScript = {...}:
+ # Python
+ ''
+ client.wait_until_succeeds("curl --verbose https://sharkey.server | grep 'Thank you for using Sharkey!'")
+ '';
}
diff --git a/tests/by-name/ta/taskchampion-sync/test.nix b/tests/by-name/ta/taskchampion-sync/test.nix
index 4bca4e0..3878167 100644
--- a/tests/by-name/ta/taskchampion-sync/test.nix
+++ b/tests/by-name/ta/taskchampion-sync/test.nix
@@ -6,64 +6,26 @@
pkgs,
extraModules,
nixLib,
+ vhack,
...
}:
-nixos-lib.runTest {
- hostPkgs = pkgs;
+vhack.runTest {
name = "taskchampion-sync";
- node = {
- specialArgs = {inherit pkgsUnstable vhackPackages nixpkgs-unstable nixLib;};
-
- # Use the nixpkgs as constructed by the `nixpkgs.*` options
- pkgs = null;
- };
+ serverDomains = [
+ {server = "taskchampion.server";}
+ ];
nodes = let
taskwarriorPackage = pkgs.taskwarrior3.overrideAttrs (final: prev: {
cmakeFlags = (prev.cmakeFlags or []) ++ ["-DENABLE_TLS_NATIVE_ROOTS=true"];
});
in {
- acme = {
- imports = [
- ../../../common/acme/server.nix
- ../../../common/dns/client.nix
- ];
- };
- name_server = {nodes, ...}: {
- imports =
- extraModules
- ++ [
- ../../../common/acme/client.nix
- ../../../common/dns/server.nix
- ];
-
- vhack.dns.zones = {
- "taskchampion.server" = {
- SOA = {
- nameServer = "ns";
- adminEmail = "admin@server.com";
- serial = 2025012301;
- };
- useOrigin = false;
-
- A = [
- nodes.server.networking.primaryIPAddress
- ];
- AAAA = [
- nodes.server.networking.primaryIPv6Address
- ];
- };
- };
- };
-
server = {config, ...}: {
imports =
extraModules
++ [
../../../../modules
- ../../../common/acme/client.nix
- ../../../common/dns/client.nix
];
vhack = {
@@ -77,27 +39,21 @@ nixos-lib.runTest {
};
task_client1 = {config, ...}: {
- imports = [
- ../../../common/acme/client.nix
- ../../../common/dns/client.nix
- ];
-
environment.systemPackages = [
taskwarriorPackage
];
};
task_client2 = {config, ...}: {
- imports = [
- ../../../common/acme/client.nix
- ../../../common/dns/client.nix
- ];
-
environment.systemPackages = [
taskwarriorPackage
];
};
};
+ services = [
+ {server = "taskchampion-sync-server.service";}
+ ];
+
testScript = {nodes, ...}: let
# Generated with uuidgen
uuid = "bf01376e-04a4-435a-9263-608567531af3";
@@ -112,13 +68,9 @@ nixos-lib.runTest {
echo 'sync.server.client_id=${uuid}' >> "${path}"
echo 'sync.encryption_secret=${password}' >> "${path}"
'';
-
- acme = import ../../../common/acme {inherit pkgs;};
in
- acme.prepare ["server" "task_client1" "task_client2"]
# Python
''
- server.wait_for_unit("taskchampion-sync-server.service")
server.wait_for_open_port(443)
with subtest("Setup task syncing"):
diff --git a/tests/common/acme/default.nix b/tests/common/acme/default.nix
index c756a4f..e7869c2 100644
--- a/tests/common/acme/default.nix
+++ b/tests/common/acme/default.nix
@@ -29,14 +29,11 @@ in {
( # python
''
# Start dependencies for the other services
- acme.start()
+ start_all()
+
acme.wait_for_unit("pebble.service")
- name_server.start()
name_server.wait_for_unit("nsd.service")
- # Start actual test
- start_all()
-
with subtest("Add pebble ca key to all services"):
for node in [name_server, ${builtins.concatStringsSep "," clients}]:
node.wait_until_succeeds("curl https://acme.test:15000/roots/0")
diff --git a/tests/default.nix b/tests/default.nix
index d9b354a..9bab516 100644
--- a/tests/default.nix
+++ b/tests/default.nix
@@ -3,11 +3,267 @@
nixLib,
pkgs,
}: let
+ splitAttr = attr: let
+ name = builtins.elemAt (builtins.attrNames attr) 0;
+ in {
+ inherit name;
+ value = attr.${name};
+ };
+
+ vhack.runTest = {
+ name,
+ nodes ? {},
+ serverDomains ? [],
+ testScript ? {_, ...}: "",
+ services ? [],
+ ignore ? null,
+ }: let
+ # Apparently the default's (e.g. `serivces ? []`), are not applied for the `@args`
+ # syntax.
+ args = {
+ inherit name nodes serverDomains testScript services ignore;
+ };
+ in
+ specialArgs.nixos-lib.runTest {
+ hostPkgs = pkgs;
+ inherit (args) name;
+
+ meta.broken = pkgs.lib.mkIf (args.ignore != null) true;
+
+ node = {
+ specialArgs = {
+ inherit
+ (specialArgs)
+ pkgsUnstable
+ vhackPackages
+ nixpkgs-unstable
+ ;
+ inherit nixLib;
+ };
+
+ # Use the nixpkgs as constructed by the `nixpkgs.*` options
+ pkgs = null;
+ };
+
+ nodes = pkgs.lib.mkMerge [
+ {
+ acme = {
+ imports = [
+ ./common/acme/server.nix
+ ./common/dns/client.nix
+ ];
+ };
+ name_server = {nodes, ...}: {
+ imports =
+ specialArgs.extraModules
+ ++ [
+ ./common/acme/client.nix
+ ./common/dns/server.nix
+ ];
+
+ vhack.dns.zones = let
+ mkDomain = attr: let
+ split = splitAttr attr;
+ in {
+ name = "${split.value}";
+ value = {
+ SOA = {
+ nameServer = "ns";
+ adminEmail = "admin@server.com";
+ serial = 2025012301;
+ };
+ useOrigin = false;
+
+ A = [
+ nodes.${split.name}.networking.primaryIPAddress
+ ];
+ AAAA = [
+ nodes.${split.name}.networking.primaryIPv6Address
+ ];
+ };
+ };
+ in
+ builtins.listToAttrs (builtins.map mkDomain args.serverDomains);
+ };
+ }
+ args.nodes
+ (builtins.mapAttrs (_: _: {
+ imports = [
+ ./common/acme/client.nix
+ ./common/dns/client.nix
+ ];
+ })
+ args.nodes)
+ ];
+
+ testScript = {nodes, ...} @ testScriptInput: let
+ acme = import ./common/acme {inherit pkgs;};
+
+ waitFor = builtins.concatStringsSep "\n" (
+ builtins.map (attr: let
+ split = splitAttr attr;
+ in " maybe_wait(${split.name},\"${split.value}\", ${
+ if (builtins.hasAttr "start" attr && attr.start)
+ then "True"
+ else "False"
+ })")
+ args.services
+ );
+
+ acmeOnline = builtins.concatStringsSep "\n" (builtins.map (attr: let
+ split = splitAttr attr;
+ in " status.append(acme_online(${split.name}, \"${split.value}\", renewRan.get(\"acme-order-renew-${split.value}.service\", False)))")
+ args.serverDomains);
+
+ allRunning =
+ builtins.concatStringsSep "\n" (builtins.map (name: " all_services_running(${name})")
+ (builtins.attrNames args.nodes));
+
+ optional = condition: value:
+ if condition
+ then value
+ else "";
+ in
+ acme.prepare (builtins.attrNames args.nodes)
+ # The acme code runs `start_all` before it hands execution back to us.
+ # So we don't need to run it.
+ (
+ optional (args.services != [] || args.serverDomains != [])
+ # Python
+ ''
+ def unit_exists(host, unitName: str) -> bool:
+ (status, _) = host.execute(f"test -f '/etc/systemd/system/{unitName}'")
+ return status == 0
+
+ wasAlive: bool
+ deadCounter: int
+ def run_and_wait(host, unit: str):
+ global wasAlive
+ global deadCounter
+
+ wasAlive = False
+ deadCounter = 0
+
+ def wait_state(_last_try: bool) -> bool:
+ global wasAlive
+ global deadCounter
+
+ state = host.get_unit_property(unit, "SubState")
+ host.log(f"(waiting) {unit} -> {state}")
+
+ match state:
+ case "failed":
+ assert False, f'Unit "{unit}" reached state "{state}"'
+ case "start" | "active" | "running":
+ wasAlive = True
+ case "dead":
+ if wasAlive:
+ return True
+ else:
+ if deadCounter >= 5:
+ return True
+
+ deadCounter = deadCounter + 1
+ return False
+
+ return False
+
+ with host.nested(f"Waiting for unit {unit}"):
+ retry(wait_state)
+ ''
+ + optional (args.serverDomains != [])
+ # Python
+ ''
+ def acme_online(host, domain, renewRan):
+ from typing import assert_never
+
+ unitMain = f"acme-{domain}.service"
+ unitRenew = f"acme-order-renew-{domain}.service"
+
+ infoMain = host.get_unit_property(unitMain, "SubState")
+ infoRenew = host.get_unit_property(unitRenew, "SubState")
+
+ match (infoMain, infoRenew):
+ case ("exited", "dead") | ("dead", "dead") if not renewRan:
+ # The unit might not exist, because we use the DNS values for
+ # generating this code (there is no needed mapping between DNS -> acme
+ # host). So we check, if it is an actual unit.
+ if unit_exists(host, unitMain):
+ host.start_job(f"acme-{domain}")
+ return ("Wait", unitRenew, host)
+ else:
+ return ("Done", None, None)
+
+ case ("exited", "dead") | ("exited", "dead") if renewRan:
+ # The unit is done, so it should be good?
+ host.require_unit_state(unitMain, "active")
+ host.succeed(f"${pkgs.lib.getExe pkgs.openssl} s_client -connect {domain}:443 -verify_return_error </dev/null")
+ return ("Done", None, None)
+
+ case (_, "running") | (_, "start"):
+ # It's currently running, let's wait
+ return ("Wait", unitRenew, host)
+
+ case other:
+ assert False, f"Wrong unit sub-states for ({unitMain},{unitRenew}): {other}"
+ assert_never() # i.e. unreachable
+
+ with subtest("Ensure, that all acme certificates have been fetched"):
+ renewRan = {}
+ while True:
+ status = []
+ ${acmeOnline}
+ done = True
+ for (state, unit, host) in status:
+ if state == "Wait":
+ run_and_wait(host, unit)
+ renewRan[unit] = True
+ if state != "Done":
+ done = False
+ if done:
+ break
+ ''
+ + optional (args.services != [])
+ # Python
+ ''
+ def maybe_wait(host, unit: str, should_start: bool):
+ if unit_exists(host, unit):
+ if should_start:
+ host.start_job(unit.removesuffix(".service"))
+ run_and_wait(host, unit)
+ else:
+ host.wait_for_unit(unit)
+ else:
+ assert False, f"Unit '{unit}' does not exist, test misconfigured"
+
+ with subtest("Waiting for units"):
+ ${waitFor}
+ ''
+ +
+ # Python
+ ''
+ def all_services_running(host):
+ import json
+ (status, output) = host.systemctl("list-units --state=failed --plain --no-pager --output=json")
+ host_failed = json.loads(output)
+ assert len(host_failed) == 0, f"Expected zero failing services, but found: {json.dumps(host_failed, indent=4)}"
+
+ with subtest("All services running"):
+ ${allRunning}
+
+ ${(args.testScript testScriptInput)}
+
+ with subtest("All services running"):
+ ${allRunning}
+ ''
+ );
+ };
+
tests = nixLib.mkByName {
baseDirectory = ./by-name;
fileName = "test.nix";
finalizeFunction = name: value:
- import value (nixLib.warnMerge specialArgs {inherit pkgs;} "the test args set");
+ import value (nixLib.warnMerge specialArgs {inherit pkgs vhack;} "the test args set");
};
in
tests