1{
2 name = "zrepl";
3
4 nodes.host =
5 { pkgs, ... }:
6 {
7 config = {
8 # Prerequisites for ZFS and tests.
9 boot.supportedFilesystems = [ "zfs" ];
10 environment.systemPackages = [ pkgs.zrepl ];
11 networking.hostId = "deadbeef";
12 services.zrepl = {
13 enable = true;
14 settings = {
15 # Enable Prometheus output for status assertions.
16 global.monitoring = [
17 {
18 type = "prometheus";
19 listen = ":9811";
20 }
21 ];
22 # Create a periodic snapshot job for an ephemeral zpool.
23 jobs = [
24 {
25 name = "snap_test";
26 type = "snap";
27
28 filesystems."test" = true;
29 snapshotting = {
30 type = "periodic";
31 prefix = "zrepl_";
32 interval = "1s";
33 };
34
35 pruning.keep = [
36 {
37 type = "last_n";
38 count = 8;
39 }
40 ];
41 }
42 ];
43 };
44 };
45 };
46 };
47
48 testScript = ''
49 start_all()
50
51 with subtest("Wait for zrepl and network ready"):
52 host.systemctl("start network-online.target")
53 host.wait_for_unit("network-online.target")
54 host.wait_for_unit("zrepl.service")
55
56 with subtest("Create test zpool"):
57 # ZFS requires 64MiB minimum pool size.
58 host.succeed("fallocate -l 64MiB /root/zpool.img")
59 host.succeed("zpool create test /root/zpool.img")
60
61 with subtest("Check for completed zrepl snapshot"):
62 # zrepl periodic snapshot job creates a snapshot with this prefix.
63 host.wait_until_succeeds("zfs list -t snapshot | grep -q zrepl_")
64
65 with subtest("Verify HTTP monitoring server is configured"):
66 out = host.succeed("curl -f localhost:9811/metrics")
67
68 assert (
69 "zrepl_start_time" in out
70 ), "zrepl start time metric was not found in Prometheus output"
71
72 assert (
73 "zrepl_zfs_snapshot_duration_count{filesystem=\"test\"}" in out
74 ), "zrepl snapshot counter for test was not found in Prometheus output"
75 '';
76}