nixos/zrepl: Improve tests (#416118)

nixos/zrepl: Improve tests to:

* Use a block device for zpool
* Have two virtual machines so that source->target replication works
This commit is contained in:
Jonathan Davies 2025-06-12 17:00:47 +00:00 committed by GitHub
parent 03dd44737a
commit d50e8abe7e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,76 +1,178 @@
{
name = "zrepl";
nodes.host =
{ pkgs, ... }:
{
config = {
# Prerequisites for ZFS and tests.
boot.supportedFilesystems = [ "zfs" ];
environment.systemPackages = [ pkgs.zrepl ];
networking.hostId = "deadbeef";
services.zrepl = {
enable = true;
settings = {
# Enable Prometheus output for status assertions.
global.monitoring = [
{
type = "prometheus";
listen = ":9811";
}
];
# Create a periodic snapshot job for an ephemeral zpool.
jobs = [
{
name = "snap_test";
type = "snap";
nodes = {
source =
{ nodes, pkgs, ... }:
{
config = {
# Prerequisites for ZFS and tests.
virtualisation.emptyDiskImages = [
2048
];
filesystems."test" = true;
snapshotting = {
type = "periodic";
prefix = "zrepl_";
interval = "1s";
};
boot.supportedFilesystems = [ "zfs" ];
environment.systemPackages = [
pkgs.parted
pkgs.zrepl
];
networking.firewall.allowedTCPPorts = [ 8888 ];
networking.hostId = "deadbeef";
services.zrepl = {
enable = true;
settings = {
# Enable Prometheus output for status assertions.
global.monitoring = [
{
type = "prometheus";
listen = ":9811";
}
];
# Create a periodic snapshot job for an ephemeral zpool.
jobs = [
{
name = "snapshots";
type = "snap";
pruning.keep = [
{
type = "last_n";
count = 8;
}
];
}
];
filesystems."tank/data" = true;
snapshotting = {
type = "periodic";
prefix = "zrepl_";
interval = "10s";
};
pruning.keep = [
{
type = "last_n";
count = 8;
}
];
}
{
name = "backup-target";
type = "source";
serve = {
type = "tcp";
listen = ":8888";
clients = {
"${nodes.target.networking.primaryIPAddress}" = "${nodes.target.networking.hostName}";
"${nodes.target.networking.primaryIPv6Address}" = "${nodes.target.networking.hostName}";
};
};
filesystems."tank/data" = true;
# Snapshots are handled by the separate snap job
snapshotting = {
type = "manual";
};
}
];
};
};
};
};
};
target =
{ pkgs, ... }:
{
config = {
# Prerequisites for ZFS and tests.
virtualisation.emptyDiskImages = [
2048
];
boot.supportedFilesystems = [ "zfs" ];
environment.systemPackages = [
pkgs.parted
pkgs.zrepl
];
networking.hostId = "deadd0d0";
services.zrepl = {
enable = true;
settings = {
# Enable Prometheus output for status assertions.
global.monitoring = [
{
type = "prometheus";
listen = ":9811";
}
];
jobs = [
{
name = "source-pull";
type = "pull";
connect = {
type = "tcp";
address = "source:8888";
};
root_fs = "tank/zrepl/source";
interval = "15s";
recv = {
placeholder = {
encryption = "off";
};
};
pruning = {
keep_sender = [
{
type = "regex";
regex = ".*";
}
];
keep_receiver = [
{
type = "grid";
grid = "1x1h(keep=all) | 24x1h";
regex = "^zrepl_";
}
];
};
}
];
};
};
};
};
};
testScript = ''
start_all()
with subtest("Wait for zrepl and network ready"):
host.systemctl("start network-online.target")
host.wait_for_unit("network-online.target")
host.wait_for_unit("zrepl.service")
for machine in source, target:
machine.systemctl("start network-online.target")
machine.wait_for_unit("network-online.target")
machine.wait_for_unit("zrepl.service")
with subtest("Create test zpool"):
# ZFS requires 64MiB minimum pool size.
host.succeed("fallocate -l 64MiB /root/zpool.img")
host.succeed("zpool create test /root/zpool.img")
with subtest("Create tank zpool"):
for machine in source, target:
machine.succeed(
"parted --script /dev/vdb mklabel gpt",
"zpool create tank /dev/vdb",
)
with subtest("Check for completed zrepl snapshot"):
# Create ZFS datasets
source.succeed("zfs create tank/data")
target.succeed("zfs create -p tank/zrepl/source")
with subtest("Check for completed zrepl snapshot on target"):
# zrepl periodic snapshot job creates a snapshot with this prefix.
host.wait_until_succeeds("zfs list -t snapshot | grep -q zrepl_")
target.wait_until_succeeds("zfs list -t snapshot | grep -q tank/zrepl/source/tank/data@zrepl_")
with subtest("Check for completed zrepl bookmark on source"):
source.wait_until_succeeds("zfs list -t bookmark | grep -q tank/data#zrepl_")
with subtest("Verify HTTP monitoring server is configured"):
out = host.succeed("curl -f localhost:9811/metrics")
out = source.succeed("curl -f localhost:9811/metrics")
assert (
"zrepl_start_time" in out
), "zrepl start time metric was not found in Prometheus output"
assert (
"zrepl_zfs_snapshot_duration_count{filesystem=\"test\"}" in out
), "zrepl snapshot counter for test was not found in Prometheus output"
"zrepl_zfs_snapshot_duration_count{filesystem=\"tank/data\"}" in out
), "zrepl snapshot counter for tank/data was not found in Prometheus output"
'';
}