Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions nixos/tests/all-tests.nix
Original file line number Diff line number Diff line change
Expand Up @@ -1003,6 +1003,7 @@ in {
zammad = handleTest ./zammad.nix {};
zeronet-conservancy = handleTest ./zeronet-conservancy.nix {};
zfs = handleTest ./zfs.nix {};
zfs-tests = discoverTests (import ./zfs-tests.nix);
zigbee2mqtt = handleTest ./zigbee2mqtt.nix {};
zoneminder = handleTest ./zoneminder.nix {};
zookeeper = handleTest ./zookeeper.nix {};
Expand Down
193 changes: 193 additions & 0 deletions nixos/tests/zfs-tests.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
let
# Running all tests takes very long (multiple hours) and doesn't work properly.
# We'll just do a quick smoke-test.

# test run results (no extra text means PASS):
# - chattr
# - checksum
# - deadman
# - devices
# - fallocate
# - snapshot
# - tmpfile
# - upgrade
# - userquota
# - zdb
# - zfs
# - zfs_sysfs
# - zpool_add
# - zpool_reopen
# - compression (4 FAIL)
# - compression/l2arc_compressed_arc
# - compression/l2arc_compressed_arc_disabled
# - compression/l2arc_encrypted
# - compression/l2arc_encrypted_no_compressed_arc
# - events (3 FAIL)
# - events/events_001_pos
# - events/events_002_pos
# - events/zed_rc_filter
# - exec (1 FAIL)
# - exec/exec_001_pos
# - fault (takes very long, doesn't terminate?)
# - large_dnode (1 FAIL)
# - features/large_dnode/large_dnode_006_pos
# - misc (1 FAIL)
# - cli_user/misc/arc_summary_001_pos
# - mmp (14 SKIP)
# - rsend (takes very long, errors out with ENOSPC)
# - user_namespace (1 FAIL)
# - zfs_mount (2 FAIL)
# - cli_root/zfs_mount/zfs_mount_013_pos
# - cli_root/zfs_mount/zfs_multi_mount
# - zfs_share (2 FAIL, 13 SKIP)
# - cli_root/zfs_share/setup
# - zpool_create (1 FAIL)
# - cli_root/zpool_create/zpool_create_014_neg
# - zpool_expand (1 FAIL)
# - cli_root/zpool_expand/zpool_expand_001_pos
# - zpool_split (1 SKIP)
# - cli_root/zpool_split/zpool_split_props

# TODO
# - io (broken? fio)
# - pool_checkpoint (takes > 15 minutes)
# - cache (fio)
# - trim (fio)
# - l2arc (fio)
# - pam (pamtester)

tests = [
# 00:07
"chattr"
# 01:47
"checksum"
"compression"
# 01:00
"deadman"
# 00:04
"devices"
"events"
"exec"
# 00:02
"fallocate"
# 01:03
"snapshot"
# 00:02
"tmpfile"
# 00:22
"upgrade"
# 00:58
"userquota"
# 04:51
"zdb"
# 00:43
"zfs"
# 00:04
"zfs_sysfs"
# 04:54
"zpool_add"
"zpool_create"
# 03:06
"zpool_reopen"
];

mkTest = testname: (

import ./make-test-python.nix ({ lib, pkgs, ... }:
let
zfsForTesting = pkgs.zfs;
in
{
name = "zfs-tests-${testname}";
meta = with lib.maintainers; {
maintainers = [ mindavi ];
};

nodes.machine =
{ lib, pkgs, config, ... }:
with lib;
{
imports = [ ./common/user-account.nix ];
# User must be in wheel group, without requiring password entry.
users.users.alice = { isNormalUser = true; group = "wheel"; };
security.sudo.wheelNeedsPassword = false;

# The default size of 512 MB was not enough, so bump it to be safe.
# E.g. functional/pool_checkpoint/setup uses quite a bit of harddrive space.
virtualisation.diskSize = 8192;
# ZFS uses quite a bit of RAM.
# This seems like a generous enough amount of memory.
virtualisation.memorySize = 4096;
# TODO(mindavi): Does it help to assign multiple cores?
virtualisation.cores = 6;

# This prevents that grub is rebuild / included in closure.
# It doesn't seem to be used anyway, because disabling helps :).
boot.loader.grub.enable = false;

boot.kernelModules = [ "zfs" ];
boot.supportedFilesystems = [ "zfs" ];
environment.systemPackages = [
pkgs.gcc
zfsForTesting
pkgs.ksh
pkgs.util-linux
pkgs.coreutils
pkgs.sudo
pkgs.lvm2
pkgs.gawk
pkgs.e2fsprogs # mkfs.ext4
pkgs.gzip # gzip, gunzip
pkgs.procps
pkgs.acl # setfacl, getfacl
pkgs.python3
pkgs.openssl
pkgs.bc
pkgs.nfs-utils
pkgs.dmidecode
pkgs.lsscsi
pkgs.file
pkgs.sysstat # iostat
pkgs.pax
pkgs.binutils # strings
pkgs.parted
pkgs.linuxPackages.perf
pkgs.samba # net
#pkgs.fio # disable because of kernel crashes... / hangs
# exportfs -> nfs-utils?
pkgs.tree

pkgs.lvm2
];
networking.hostId = "abcdef01";
};

testScript = ''
start_all()
machine.wait_for_unit("multi-user.target")
print(machine.succeed("modprobe zfs", "zfs version", "id"))

machine.execute(
"su - alice -- ${zfsForTesting.zfs_tests}/share/zfs/zfs-tests.sh -T ${testname} >> test-results.log",
)
# Show the last lines of the test results log.
print(machine.execute("tail -n30 test-results.log")[1])

print(machine.execute("cat test-results.log")[1])
print(machine.execute("grep 'Results Summary' -A 8 test-results.log")[1])

# These tools are still missing:
# Missing util(s): devname2devid mmap_libaio fio pamtester quotaon umask wait setenforce
print(machine.execute("grep 'Missing util' test-results.log")[1])

print(machine.succeed("tree /var/tmp/test_results/"))
print(machine.succeed("cat /var/tmp/test_results/current/**"))
# Test results can be found in /var/tmp/test_results/<DATETIME>
machine.succeed("grep 'Percent passed.*100' test-results.log")
'';
})
);
lib = (import ../../. { }).lib;
in
lib.genAttrs tests mkTest

41 changes: 38 additions & 3 deletions pkgs/os-specific/linux/zfs/generic.nix
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ let
, perl
, configFile ? "all"

# Test dependencies
, ksh
, lvm2
, gzip
, e2fsprogs

# Userspace dependencies
, zlib, libuuid, python3, attr, openssl
, libtirpc
Expand Down Expand Up @@ -73,6 +79,33 @@ let
--replace '"/usr/bin/env", "umount"' '"${util-linux}/bin/umount", "-n"' \
--replace '"/usr/bin/env", "mount"' '"${util-linux}/bin/mount", "-n"'
'' + optionalString buildUser ''
# TODO(Mindavi): Is overriding with /run/current-system/sw/bin acceptable?
substituteInPlace scripts/zfs-tests.sh \
--replace '$STF_PATH/ksh' ${ksh}/bin/ksh \
--replace 'LOSETUP=' 'LOSETUP=${util-linux}/bin/losetup #' \
--replace 'export PATH=$STF_PATH' '#' \
--replace 'DMSETUP=' 'DMSETUP=${lvm2}/bin/dmsetup #' \
--replace '$STF_PATH/gzip' '${gzip}/bin/gzip' \
--replace '$STF_PATH/gunzip' '${gzip}/bin/gunzip' \
--replace '/sbin/fsck.ext4' '${e2fsprogs}/bin/fsck.ext4' \
--replace '/sbin/mkfs.ext4' '${e2fsprogs}/bin/mkfs.ext4' \
--replace '$STF_PATH/awk' '${gawk}/bin/awk' \
--replace 'SYSTEM_DIRS="/usr/local/bin /usr/local/sbin"' 'SYSTEM_DIRS="/run/current-system/sw/bin"'
substituteInPlace scripts/common.sh.in \
--replace 'export ZTS_DIR=' 'export ZTS_DIR=${placeholder "zfs_tests"}/share/zfs #' \
--replace 'export SCRIPT_DIR=' 'export SCRIPT_DIR=${placeholder "zfs_tests"}/share/zfs #' \
--replace 'export ZDB=' 'export ZDB=${placeholder "out"}/bin/zdb #' \
--replace 'export ZFS=' 'export ZFS=${placeholder "out"}/bin/zfs #' \
--replace 'export ZPOOL=' 'export ZPOOL=${placeholder "out"}/bin/zpool #' \
--replace 'export ZTEST=' 'export ZTEST=${placeholder "out"}/bin/ztest #' \
--replace 'export ZFS_SH=' 'export ZFS_SH=${placeholder "zfs_tests"}/share/zfs/zfs.sh #'
# Fix ksh paths in test suite.
# patchShebangs doesn't work due to the scripts not being executable.
# It doesn't seem logical to make them executable either.
find -name "*.ksh" -exec sed -i 's,/bin/ksh,${ksh}/bin/ksh,' {} \;
# Patching maybe required for more binaries
# Maybe FHS environment would be better?

substituteInPlace ./lib/libshare/os/linux/nfs.c --replace "/usr/sbin/exportfs" "${
# We don't *need* python support, but we set it like this to minimize closure size:
# If it's disabled by default, no need to enable it, even if we have python enabled
Expand Down Expand Up @@ -181,10 +214,12 @@ let
done

# Remove tests because they add a runtime dependency on gcc
rm -rf $out/share/zfs/zfs-tests
# TODO(mindavi): Should we optionally remove these? How does that work?
mkdir -p ${placeholder "zfs_tests"}/share/zfs/
mv ${placeholder "out"}/share/zfs/ ${placeholder "zfs_tests"}/share/

# Add Bash completions.
install -v -m444 -D -t $out/share/bash-completion/completions contrib/bash_completion.d/zfs
install -v -m444 -D -t ${placeholder "out"}/share/bash-completion/completions contrib/bash_completion.d/zfs
(cd $out/share/bash-completion/completions; ln -s zfs zpool)
'';

Expand All @@ -196,7 +231,7 @@ let
done
'';

outputs = [ "out" ] ++ optionals buildUser [ "dev" ];
outputs = [ "out" ] ++ optionals buildUser [ "dev" "zfs_tests" ];

passthru = {
inherit enableMail latestCompatibleLinuxPackages kernelModuleAttribute;
Expand Down