diff --git a/checks/autoescalate/default.nix b/checks/autoescalate/default.nix index da90eda..65cc372 100644 --- a/checks/autoescalate/default.nix +++ b/checks/autoescalate/default.nix @@ -35,12 +35,20 @@ nixosTest { }; testScript = '' - # Set up loop devices - machine.succeed('dd if=/dev/zero of=/tmp/blockfile bs=1M count=1') - machine.succeed('dd if=/dev/urandom of=/tmp/input.iso bs=100K count=1') - machine.succeed('losetup /dev/loop0 /tmp/blockfile') + ${builtins.readFile ../common.py} - with subtest("should succeed when run as non-root wheel user"): - machine.succeed('timeout 10 su admin -c "caligula burn /tmp/input.iso --force -o /dev/loop0 --hash skip --compression auto --root always --interactive never"') + try: + # Set up loop devices + machine.succeed('dd if=/dev/zero of=/tmp/blockfile bs=1M count=1') + machine.succeed('dd if=/dev/urandom of=/tmp/input.iso bs=100K count=1') + machine.succeed('losetup /dev/loop0 /tmp/blockfile') + + # Sanity check: can we run something without asking for a password? + machine.succeed('timeout 10 su admin -c "${escalationTool} -- echo We are able to escalate without asking for a password"') + + with subtest("should succeed when run as non-root wheel user"): + machine.succeed('timeout 10 su admin -c "caligula burn /tmp/input.iso --force -o /dev/loop0 --hash skip --compression auto --root always --interactive never"') + finally: + print_logs(machine) ''; } diff --git a/checks/blocksize.nix b/checks/blocksize.nix new file mode 100644 index 0000000..80c9aa2 --- /dev/null +++ b/checks/blocksize.nix @@ -0,0 +1,62 @@ +{ lib, nixosTest, imageSize, blockSize, diskSizeMiB }: +let + serial = "awawawawawa"; + diskFile = "/tmp/block-file.img"; + byDiskPath = "/dev/disk/by-id/usb-QEMU_QEMU_HARDDISK_${serial}-0:0"; +in nixosTest { + name = "blocksize-bs${toString blockSize}-image${toString imageSize}-diskMiB${ + toString diskSizeMiB + }"; + + nodes.machine = { pkgs, lib, ... }: + with lib; { + imports = [ ]; + + users.users = { + admin = { + isNormalUser = true; + extraGroups = [ "wheel" ]; + }; + }; + + environment.systemPackages = with pkgs; [ caligula ]; + virtualisation.qemu.options = + [ "-drive" "if=none,id=usbstick,format=raw,file=${diskFile}" ] + ++ [ "-usb" ] ++ [ "-device" "usb-ehci,id=ehci" ] ++ [ + "-device" + "usb-storage,bus=ehci.0,drive=usbstick,serial=${serial},physical_block_size=${ + toString blockSize + }" + ]; + }; + + testScript = with lib; '' + import os + + print("Creating file image at ${diskFile}") + os.system("dd bs=1M count=${ + toString diskSizeMiB + } if=/dev/urandom of=${diskFile}") + + ${readFile ./common.py} + + machine.start() + machine.wait_for_unit('default.target') + print(machine.execute('stat $(readlink -f ${byDiskPath})', check_output=True)[1]) + try: + machine.succeed('dd if=/dev/urandom of=/tmp/input.iso bs=1 count=${ + toString imageSize + }') + with subtest("executes successfully"): + machine.succeed('caligula burn /tmp/input.iso --force -o $(readlink -f ${byDiskPath}) --hash skip --compression auto --interactive never') + + with subtest("burns correctly"): + machine.succeed('dd if=${byDiskPath} of=/tmp/written.iso bs=1 count=${ + toString imageSize + }') + machine.succeed('diff -s /tmp/input.iso /tmp/written.iso') + + finally: + print_logs(machine) + ''; +} diff --git a/checks/common.py b/checks/common.py new file mode 100644 index 0000000..84b0309 --- /dev/null +++ b/checks/common.py @@ -0,0 +1,6 @@ +def print_logs(machine): + _, output = machine.execute( + 'for x in $(find /tmp/caligula-* -type f); do echo "$x"; cat "$x"; echo; done', + check_output=True, + ) + print(output) diff --git a/checks/default.nix b/checks/default.nix index 51e76d4..07b1654 100644 --- a/checks/default.nix +++ b/checks/default.nix @@ -5,15 +5,34 @@ let inherit system; overlays = [ self.overlays.default ]; }; -in { + lib = pkgs.lib; +in with lib; +{ headless = pkgs.callPackage ./headless { }; smoke-test-simple = pkgs.callPackage ./smoke-test-simple { }; } // -(if system == "x86_64-linux" then { - autoescalate-doas = - pkgs.callPackage ./autoescalate { escalationTool = "doas"; }; - autoescalate-sudo = - pkgs.callPackage ./autoescalate { escalationTool = "sudo"; }; -} else +(if system == "x86_64-linux" then + { + autoescalate-doas = + pkgs.callPackage ./autoescalate { escalationTool = "doas"; }; + autoescalate-sudo = + pkgs.callPackage ./autoescalate { escalationTool = "sudo"; }; + } // + + # blocksize alignment tests + (let + MiB = 1048576; + parameters = cartesianProduct { + blockSize = [ 512 1024 2048 4096 8192 ]; + imageSize = [ (10 * MiB) (10 * MiB + 51) ]; + }; + in listToAttrs (map ({ imageSize, blockSize }: rec { + name = value.name; + value = pkgs.callPackage ./blocksize.nix { + inherit lib blockSize imageSize; + diskSizeMiB = 64; + }; + }) parameters)) +else { }) diff --git a/checks/headless/default.nix b/checks/headless/default.nix index 674b64c..3f358d4 100644 --- a/checks/headless/default.nix +++ b/checks/headless/default.nix @@ -1,7 +1,8 @@ { lib, caligula, runCommand }: runCommand "caligula-headless-test" { buildInputs = [ caligula ]; - isoInnerHash = "3972dc9744f6499f0f9b2dbf76696f2ae7ad8af9b23dde66d6af86c9dfb36986"; + isoInnerHash = + "3972dc9744f6499f0f9b2dbf76696f2ae7ad8af9b23dde66d6af86c9dfb36986"; meta.timeout = 10; } '' caligula burn ${./input.iso.gz} \ @@ -11,11 +12,7 @@ runCommand "caligula-headless-test" { --hash-of raw \ --compression auto - for x in $(find /tmp/caligula-* -type f); do - echo "$x" - cat "$x" - echo - done + diff ${./expected.iso} ./out.iso - diff ${./expected.iso} ./out.iso && (echo 1 > $out) + echo 1 > $out ''