import ./make-test.nix ({ pkgs, ... }: with pkgs.lib; let testVMConfig = { config, pkgs, ... }: { boot.kernelParams = [ "console=tty0" "console=ttyS0" "ignore_loglevel" "boot.trace" "panic=1" "boot.panic_on_fail" ]; fileSystems."/" = { device = "vboxshare"; fsType = "vboxsf"; }; services.virtualboxGuest.enable = true; boot.initrd.kernelModules = [ "vboxsf" ]; boot.initrd.extraUtilsCommands = '' cp -av -t "$out/bin/" \ "${pkgs.linuxPackages.virtualboxGuestAdditions}/sbin/mount.vboxsf" ''; boot.initrd.postMountCommands = '' touch /mnt-root/boot-done i=0 while [ ! -e /mnt-root/shutdown ]; do sleep 10 i=$(($i + 10)) [ $i -le 120 ] || fail done rm -f /mnt-root/boot-done /mnt-root/shutdown poweroff -f ''; system.requiredKernelConfig = with config.lib.kernelConfig; [ (isYes "SERIAL_8250_CONSOLE") (isYes "SERIAL_8250") ]; }; testVM = let cfg = (import ../lib/eval-config.nix { system = "i686-linux"; modules = [ ../modules/profiles/minimal.nix testVMConfig ]; }).config; in pkgs.vmTools.runInLinuxVM (pkgs.runCommand "virtualbox-image" { preVM = '' mkdir -p "$out" diskImage="$(pwd)/qimage" ${pkgs.vmTools.qemu}/bin/qemu-img create -f raw "$diskImage" 100M ''; postVM = '' echo "creating VirtualBox disk image..." ${pkgs.vmTools.qemu}/bin/qemu-img convert -f raw -O vdi \ "$diskImage" "$out/disk.vdi" ''; buildInputs = [ pkgs.utillinux pkgs.perl ]; } '' ${pkgs.parted}/sbin/parted /dev/vda mklabel msdos ${pkgs.parted}/sbin/parted /dev/vda -- mkpart primary ext2 1M -1s . /sys/class/block/vda1/uevent mknod /dev/vda1 b $MAJOR $MINOR ${pkgs.e2fsprogs}/sbin/mkfs.ext4 /dev/vda1 ${pkgs.e2fsprogs}/sbin/tune2fs -c 0 -i 0 /dev/vda1 mkdir /mnt mount /dev/vda1 /mnt cp "${cfg.system.build.kernel}/bzImage" /mnt/linux cp "${cfg.system.build.initialRamdisk}/initrd" /mnt/initrd ${pkgs.grub2}/bin/grub-install --boot-directory=/mnt /dev/vda cat > /mnt/grub/grub.cfg <&2"); } sub waitForVMBoot_${name} { $machine->execute(ru( 'set -e; i=0; '. 'while ! test -e ${sharePath}/boot-done; do '. 'sleep 10; i=$(($i + 10)); [ $i -le 3600 ]; '. 'VBoxManage list runningvms | grep -q "^\"${name}\""; '. 'done' )); } sub checkRunning_${name} { my $cmd = 'VBoxManage list runningvms | grep -q "^\"${name}\""'; my ($status, $out) = $machine->execute(ru $cmd); return $status == 0; } sub waitForStartup_${name} { for (my $i = 0; $i <= 120; $i += 10) { $machine->sleep(10); return if checkRunning_${name}; } die "VirtualBox VM didn't start up within 2 minutes"; } sub waitForShutdown_${name} { for (my $i = 0; $i <= 120; $i += 10) { $machine->sleep(10); return unless checkRunning_${name}; } die "VirtualBox VM didn't shut down within 2 minutes"; } sub shutdownVM_${name} { $machine->succeed(ru "touch ${sharePath}/shutdown"); $machine->waitUntilSucceeds( "test ! -e ${sharePath}/shutdown ". " -a ! -e ${sharePath}/boot-done" ); waitForShutdown_${name}; } sub cleanup_${name} { $machine->execute(ru "VBoxManage controlvm ${name} poweroff") if checkRunning_${name}; $machine->succeed("rm -rf ${sharePath}"); $machine->succeed("mkdir -p ${sharePath}"); $machine->succeed("chown alice.users ${sharePath}"); } ''; }; vboxVMs.test1 = createVM "test1"; in { name = "virtualbox"; machine = { pkgs, ... }: { imports = let mkVMConf = name: val: val.machine // { key = "${name}-config"; }; vmConfigs = mapAttrsToList mkVMConf vboxVMs; in [ ./common/user-account.nix ./common/x11.nix ] ++ vmConfigs; services.virtualboxHost.enable = true; }; testScript = '' sub ru { return "su - alice -c '$_[0]'"; } sub vbm { $machine->succeed(ru("VBoxManage ".$_[0])); }; ${concatStrings (mapAttrsToList (_: getAttr "testSubs") vboxVMs)} $machine->waitForX; createVM_test1; cleanup_test1; subtest "simple-gui", sub { $machine->succeed(ru "VirtualBox &"); $machine->waitForWindow(qr/Oracle VM VirtualBox Manager/); $machine->sleep(5); $machine->screenshot("gui_manager_started"); $machine->sendKeys("ret"); $machine->screenshot("gui_manager_sent_startup"); waitForStartup_test1; $machine->screenshot("gui_started"); waitForVMBoot_test1; $machine->screenshot("gui_booted"); shutdownVM_test1; $machine->sleep(5); $machine->screenshot("gui_stopped"); $machine->sendKeys("ctrl-q"); $machine->sleep(5); $machine->screenshot("gui_manager_stopped"); }; cleanup_test1; subtest "simple-cli", sub { vbm("startvm test1"); waitForStartup_test1; $machine->screenshot("cli_started"); waitForVMBoot_test1; $machine->screenshot("cli_booted"); shutdownVM_test1; }; cleanup_test1; $machine->fail("test -e '/root/VirtualBox VMs'"); $machine->succeed("test -e '/home/alice/VirtualBox VMs'"); ''; })