Skip to content

Commit d50e8ab

Browse files
authored
nixos/zrepl: Improve tests (NixOS#416118)
nixos/zrepl: Improve tests to: * Use a block device for zpool * Have two virtual machines so that source->target replication works
1 parent 03dd447 commit d50e8ab

1 file changed

Lines changed: 154 additions & 52 deletions

File tree

nixos/tests/zrepl.nix

Lines changed: 154 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,76 +1,178 @@
11
{
22
name = "zrepl";
33

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-
];
4+
nodes = {
5+
source =
6+
{ nodes, pkgs, ... }:
7+
{
8+
config = {
9+
# Prerequisites for ZFS and tests.
10+
virtualisation.emptyDiskImages = [
11+
2048
12+
];
13+
14+
boot.supportedFilesystems = [ "zfs" ];
15+
environment.systemPackages = [
16+
pkgs.parted
17+
pkgs.zrepl
18+
];
19+
networking.firewall.allowedTCPPorts = [ 8888 ];
20+
networking.hostId = "deadbeef";
21+
services.zrepl = {
22+
enable = true;
23+
settings = {
24+
# Enable Prometheus output for status assertions.
25+
global.monitoring = [
26+
{
27+
type = "prometheus";
28+
listen = ":9811";
29+
}
30+
];
31+
# Create a periodic snapshot job for an ephemeral zpool.
32+
jobs = [
33+
{
34+
name = "snapshots";
35+
type = "snap";
36+
37+
filesystems."tank/data" = true;
38+
snapshotting = {
39+
type = "periodic";
40+
prefix = "zrepl_";
41+
interval = "10s";
42+
};
43+
44+
pruning.keep = [
45+
{
46+
type = "last_n";
47+
count = 8;
48+
}
49+
];
50+
}
51+
{
52+
name = "backup-target";
53+
type = "source";
54+
55+
serve = {
56+
type = "tcp";
57+
listen = ":8888";
58+
59+
clients = {
60+
"${nodes.target.networking.primaryIPAddress}" = "${nodes.target.networking.hostName}";
61+
"${nodes.target.networking.primaryIPv6Address}" = "${nodes.target.networking.hostName}";
62+
};
63+
};
64+
filesystems."tank/data" = true;
65+
# Snapshots are handled by the separate snap job
66+
snapshotting = {
67+
type = "manual";
68+
};
69+
}
70+
];
71+
};
4372
};
4473
};
4574
};
46-
};
75+
76+
target =
77+
{ pkgs, ... }:
78+
{
79+
config = {
80+
# Prerequisites for ZFS and tests.
81+
virtualisation.emptyDiskImages = [
82+
2048
83+
];
84+
85+
boot.supportedFilesystems = [ "zfs" ];
86+
environment.systemPackages = [
87+
pkgs.parted
88+
pkgs.zrepl
89+
];
90+
networking.hostId = "deadd0d0";
91+
services.zrepl = {
92+
enable = true;
93+
settings = {
94+
# Enable Prometheus output for status assertions.
95+
global.monitoring = [
96+
{
97+
type = "prometheus";
98+
listen = ":9811";
99+
}
100+
];
101+
jobs = [
102+
{
103+
name = "source-pull";
104+
type = "pull";
105+
106+
connect = {
107+
type = "tcp";
108+
address = "source:8888";
109+
};
110+
root_fs = "tank/zrepl/source";
111+
interval = "15s";
112+
recv = {
113+
placeholder = {
114+
encryption = "off";
115+
};
116+
};
117+
pruning = {
118+
keep_sender = [
119+
{
120+
type = "regex";
121+
regex = ".*";
122+
}
123+
];
124+
keep_receiver = [
125+
{
126+
type = "grid";
127+
grid = "1x1h(keep=all) | 24x1h";
128+
regex = "^zrepl_";
129+
}
130+
];
131+
};
132+
}
133+
];
134+
};
135+
};
136+
};
137+
};
138+
};
47139

48140
testScript = ''
49141
start_all()
50142
51143
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")
144+
for machine in source, target:
145+
machine.systemctl("start network-online.target")
146+
machine.wait_for_unit("network-online.target")
147+
machine.wait_for_unit("zrepl.service")
148+
149+
with subtest("Create tank zpool"):
150+
for machine in source, target:
151+
machine.succeed(
152+
"parted --script /dev/vdb mklabel gpt",
153+
"zpool create tank /dev/vdb",
154+
)
55155
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")
156+
# Create ZFS datasets
157+
source.succeed("zfs create tank/data")
158+
target.succeed("zfs create -p tank/zrepl/source")
60159
61-
with subtest("Check for completed zrepl snapshot"):
160+
with subtest("Check for completed zrepl snapshot on target"):
62161
# zrepl periodic snapshot job creates a snapshot with this prefix.
63-
host.wait_until_succeeds("zfs list -t snapshot | grep -q zrepl_")
162+
target.wait_until_succeeds("zfs list -t snapshot | grep -q tank/zrepl/source/tank/data@zrepl_")
163+
164+
with subtest("Check for completed zrepl bookmark on source"):
165+
source.wait_until_succeeds("zfs list -t bookmark | grep -q tank/data#zrepl_")
64166
65167
with subtest("Verify HTTP monitoring server is configured"):
66-
out = host.succeed("curl -f localhost:9811/metrics")
168+
out = source.succeed("curl -f localhost:9811/metrics")
67169
68170
assert (
69171
"zrepl_start_time" in out
70172
), "zrepl start time metric was not found in Prometheus output"
71173
72174
assert (
73-
"zrepl_zfs_snapshot_duration_count{filesystem=\"test\"}" in out
74-
), "zrepl snapshot counter for test was not found in Prometheus output"
175+
"zrepl_zfs_snapshot_duration_count{filesystem=\"tank/data\"}" in out
176+
), "zrepl snapshot counter for tank/data was not found in Prometheus output"
75177
'';
76178
}

0 commit comments

Comments
 (0)