Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nixos tests #299

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
1 change: 0 additions & 1 deletion .github/workflows/nix-flake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,3 @@ jobs:
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
- run: nix flake show
- run: nix flake check --print-build-logs
- run: nix build --print-build-logs
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,20 @@ Build and install

Refer to [INSTALL.md](./INSTALL.md)

Testing
-------

Besides manual testing, which is also encouraged, there are also a number of
checks defined that are used for CI (e.g. github actions).

These checks can be listed using `nix flake show`. You can, for example, test
the current state of the repo or test every patch before publishing them.

```console
$ nix flake check
$ git rev-list origin/master.. | xargs -I{} nix flake check "git+file://$(pwd)?rev={}"
```

Bug reports and contributions
-----------------------------

Expand Down
72 changes: 72 additions & 0 deletions checks/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# NixOS tests

Any `*.sh` file in this directory will be run in a NixOS VM for basic
functionality testing as part of CI. To list all outputs, including the checks,
you can use this command:

```console
$ nix flake show
```

You can also run these tests locally by running `nix flake check`. To run one
specific test you can use `nix build` like this:

```console
$ nix build ".#checks.x86_64-linux.subvolume"
```

With the flag `-L`/`--print-build-logs` outputs are shown fully as checks are
executing. Additionally, if the specific check has already been run locally, you
can view the log for the check or force another run with the following:

```console
$ nix log .#checks.x86_64-linux.subvolume
$ nix build --rebuild .#checks.x86_64-linux.subvolume
```

If you need any more packages inside of the VM for a test, you can add them to
`environment.systemPackages` in `default.nix`. If you're unsure about the
package you need, [NixOS package search] may be able to help.

For more information about the NixOS testing library see the
[testing wiki article].

## Kernel version inside VM

By default `linuxPackages_latest` from nixpkgs is used in the testing VM. This
is the latest stable kernel version available in the nixpkgs revision. Updating
the nixpkgs flake input may update the used kernel. A custom-built kernel can be
used as well but with added build times in CI.

## Adding new tests

The easiest way to add new tests is of course to copy an existing test and adapt
it accordingly. Importantly, for nix to see a file as part of the sources, the
file needs to be in the git index. It doesn't have to be committed to the repo
just yet but you need to `git add` it. If `git ls-files` lists the file, nix
will also see it.

## Interactive debugging of tests

When writing a new test or experiencing a difficult to understand test failure,
an interactive login can be very handy. This can be achieved by building the
`driverInteractive` attribute of the check, for example like this:

```console
$ nix build .#checks.x86_64-linux.subvolume.driverInteractive
```

The `nix build` will create a symlink in your working directory called `result`
which leads to a script that launches the VM interactively:

```console
$ ./result/bin/nixos-test-driver
```

There is more information about this in the NixOS manual under
[running tests interactively].

[Linux wiki article]: https://wiki.nixos.org/wiki/Linux_kernel
[NixOS package search]: https://search.nixos.org
[running tests interactively]: https://nixos.org/manual/nixos/stable/#sec-running-nixos-tests-interactively
[testing wiki article]: https://wiki.nixos.org/wiki/NixOS_Testing_library
52 changes: 52 additions & 0 deletions checks/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{ pkgs }:
let
inherit (builtins) baseNameOf readDir;
inherit (pkgs.lib)
filterAttrs
genAttrs
hasSuffix
mapAttrsToList
removeSuffix
;

scriptName = shFile: removeSuffix ".sh" (baseNameOf shFile);

scriptNames = mapAttrsToList (n: v: scriptName n) (
filterAttrs (n: v: v == "regular" && hasSuffix ".sh" n) (readDir ./.)
);

mkTest =
name:
pkgs.testers.runNixOSTest {
inherit name;

nodes.machine =
{ pkgs, ... }:
{
virtualisation.emptyDiskImages = [
4096
1024
];
boot.supportedFilesystems = [ "bcachefs" ];
boot.kernelPackages = pkgs.linuxPackages_latest;

# Add any packages you need inside test scripts here
environment.systemPackages = with pkgs; [
f3
genpass
keyutils
];

environment.variables = {
BCACHEFS_LOG = "trace";
RUST_BACKTRACE = "full";
};
};

testScript = ''
machine.succeed("modprobe bcachefs")
machine.succeed("${./${name}.sh} 1>&2")
'';
};
in
genAttrs scriptNames mkTest
45 changes: 45 additions & 0 deletions checks/encrypted-multidev.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/usr/bin/env bash
set -euxo pipefail

blkdev="/dev/vdb"
blkdev2="/dev/vdc"
mnt=$(mktemp -d)
pw=$(genpass)
uuid=$(uuidgen)

# link user and session keyrings so that the key can be found by the kernel
keyctl link @u @s

sfdisk "$blkdev" <<EOF
label: gpt
type=linux, size=1G
type=linux, size=1G
type=linux
EOF

udevadm settle

echo "$pw" | bcachefs format \
--verbose \
--encrypted \
--replicas=2 \
--uuid "$uuid" \
--fs_label test-fs \
"${blkdev}"{1,2}

udevadm settle

echo "$pw" | bcachefs mount "UUID=$uuid" "$mnt"

bcachefs device add "$mnt" "${blkdev}3"
bcachefs device add "$mnt" "$blkdev2"

udevadm settle

blkid

keyctl search @u user "bcachefs:$uuid"

umount "$mnt"

bcachefs mount "UUID=$uuid" "$mnt"
55 changes: 55 additions & 0 deletions checks/encrypted-unlock.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/usr/bin/env bash
set -euxo pipefail

blkdev="/dev/vdb"
mnt=$(mktemp -d)
pw=$(genpass)
uuid=$(uuidgen)

# link user and session keyrings so that the key can be found by the kernel
keyctl link @u @s

echo "$pw" | bcachefs format \
--verbose \
--encrypted \
--uuid "$uuid" \
--fs_label test-fs \
"$blkdev"

udevadm settle

bcachefs unlock -c "$blkdev"

echo "$pw" | bcachefs unlock "$blkdev"
key_id=$(keyctl search @u user "bcachefs:$uuid")

bcachefs mount "$blkdev" "$mnt"
umount "$mnt"

keyctl unlink "$key_id"

echo "$pw" | bcachefs unlock -k session "$blkdev"
key_id=$(keyctl search @s user "bcachefs:$uuid")

mount -t bcachefs "$blkdev" "$mnt"
umount "$mnt"

keyctl unlink "$key_id"

bcachefs mount -f <(echo "$pw") "$blkdev" "$mnt"
key_id=$(keyctl search @u user "bcachefs:$uuid")
umount "$mnt"
keyctl unlink "$key_id"

echo "$pw" | bcachefs mount -k stdin "$blkdev" "$mnt"
key_id=$(keyctl search @u user "bcachefs:$uuid")
umount "$mnt"
keyctl unlink "$key_id"

echo "$pw" | bcachefs mount "$blkdev" "$mnt"
key_id=$(keyctl search @u user "bcachefs:$uuid")
umount "$mnt"
bcachefs mount -k fail "$blkdev"
bcachefs mount -k wait "$blkdev" "$mnt"
umount "$mnt"
keyctl unlink "$key_id"
40 changes: 40 additions & 0 deletions checks/nested.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/usr/bin/env bash
set -euxo pipefail

blkdev="/dev/vdb"
mnt1=$(mktemp -d)
mnt2=$(mktemp -d)
pw=$(genpass)
uuid=$(uuidgen)

# link user and session keyrings so that the key can be found by the kernel
keyctl link @u @s

echo "$pw" | bcachefs format \
--verbose \
--encrypted \
--uuid "$uuid" \
--fs_label test-fs \
"$blkdev"

udevadm settle

echo "$pw" | bcachefs mount "UUID=$uuid" "$mnt1"

fallocate --length 2G "$mnt1/fs.img"

bcachefs format \
--verbose \
"$mnt1/fs.img"

loopdev=$(losetup --find --show "$mnt1/fs.img")

udevadm settle

mount "$loopdev" "$mnt2"

f3write "$mnt1"
f3write "$mnt2"

f3read "$mnt1"
f3read "$mnt2"
19 changes: 19 additions & 0 deletions checks/outputs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/usr/bin/env bash
set -euxo pipefail

blkdev="/dev/vdb"
mnt=$(mktemp -d)
uuid=$(uuidgen)

bcachefs format \
--verbose \
--uuid "$uuid" \
--fs_label test-fs \
"$blkdev"

udevadm settle

mount "$blkdev" "$mnt"

bcachefs show-super "$blkdev" | grep -i "external.*$uuid"
bcachefs fs usage "$mnt" | grep "$uuid"
35 changes: 35 additions & 0 deletions checks/subvolume.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/usr/bin/env bash
set -euxo pipefail

blkdev="/dev/vdb"
mnt=$(mktemp -d)
uuid=$(uuidgen)

bcachefs format \
--verbose \
--uuid "$uuid" \
--fs_label test-fs \
"$blkdev"

udevadm settle

mount "$blkdev" "$mnt"

touch "$mnt/file1"

bcachefs subvolume create "$mnt/subvol1"
bcachefs subvolume delete "$mnt/subvol1"

(
cd "$mnt"

bcachefs subvolume create subvol1
bcachefs subvolume create subvol1/subvol1
bcachefs subvolume create subvol1/subvol2
touch subvol1/file1

rm subvol1/file1
bcachefs subvolume delete subvol1/subvol2
bcachefs subvolume delete subvol1/subvol1
bcachefs subvolume delete subvol1
)
Loading
Loading