nixos/tests/virtualbox: Generalize expression.

We're going to create more than one VirtualBox VM, so let's dynamically
generate subs specific to a particular VirtualBox VM, merging everything
into the testScript and machine expressions.

Signed-off-by: aszlig <aszlig@redmoonstudios.org>
This commit is contained in:
aszlig 2014-12-13 12:13:30 +01:00
parent e07f7cd802
commit 77831e8467
No known key found for this signature in database
GPG Key ID: D0EBD0EC8C2DC961

View File

@ -1,4 +1,4 @@
import ./make-test.nix ({ pkgs, ... }: let
import ./make-test.nix ({ pkgs, ... }: with pkgs.lib; let
testVMConfig = { config, pkgs, ... }: {
boot.kernelParams = [
@ -79,39 +79,17 @@ import ./make-test.nix ({ pkgs, ... }: let
cat > /mnt/grub/grub.cfg <<GRUB
set root=hd0,1
linux /linux ${pkgs.lib.concatStringsSep " " cfg.boot.kernelParams}
linux /linux ${concatStringsSep " " cfg.boot.kernelParams}
initrd /initrd
boot
GRUB
umount /mnt
'');
in {
name = "virtualbox";
createVM = name: let
mkFlags = concatStringsSep " ";
machine = { pkgs, ... }: {
imports = [ ./common/user-account.nix ./common/x11.nix ];
services.virtualboxHost.enable = true;
systemd.sockets.vboxtestlog = {
description = "VirtualBox Test Machine Log Socket";
wantedBy = [ "sockets.target" ];
before = [ "multi-user.target" ];
socketConfig.ListenStream = "/run/virtualbox-log.sock";
socketConfig.Accept = true;
};
systemd.services."vboxtestlog@" = {
description = "VirtualBox Test Machine Log";
serviceConfig.StandardInput = "socket";
serviceConfig.StandardOutput = "syslog";
serviceConfig.SyslogIdentifier = "testvm";
serviceConfig.ExecStart = "${pkgs.coreutils}/bin/cat";
};
};
testScript = let
mkFlags = pkgs.lib.concatStringsSep " ";
sharePath = "/home/alice/vboxshare-${name}";
createFlags = mkFlags [
"--ostype Linux26"
@ -120,7 +98,7 @@ in {
vmFlags = mkFlags [
"--uart1 0x3F8 4"
"--uartmode1 client /run/virtualbox-log.sock"
"--uartmode1 client /run/virtualbox-log-${name}.sock"
];
controllerFlags = mkFlags [
@ -141,91 +119,136 @@ in {
sharedFlags = mkFlags [
"--name vboxshare"
"--hostpath /home/alice/vboxshare"
"--hostpath ${sharePath}"
];
in ''
in {
machine = {
systemd.sockets = listToAttrs (singleton {
name = "vboxtestlog-${name}";
value = {
description = "VirtualBox Test Machine Log Socket";
wantedBy = [ "sockets.target" ];
before = [ "multi-user.target" ];
socketConfig.ListenStream = "/run/virtualbox-log-${name}.sock";
socketConfig.Accept = true;
};
});
systemd.services = listToAttrs (singleton {
name = "vboxtestlog-${name}@";
value = {
description = "VirtualBox Test Machine Log";
serviceConfig.StandardInput = "socket";
serviceConfig.StandardOutput = "syslog";
serviceConfig.SyslogIdentifier = "vbox-${name}";
serviceConfig.ExecStart = "${pkgs.coreutils}/bin/cat";
};
});
};
testSubs = ''
sub createVM_${name} {
vbm("createvm --name ${name} ${createFlags}");
vbm("modifyvm ${name} ${vmFlags}");
vbm("storagectl ${name} ${controllerFlags}");
vbm("storageattach ${name} ${diskFlags}");
vbm("sharedfolder add ${name} ${sharedFlags}");
vbm("showvminfo ${name} >&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 waitForVMBoot {
$machine->execute(ru(
'set -e; i=0; '.
'while ! test -e /home/alice/vboxshare/boot-done; do '.
'sleep 10; i=$(($i + 10)); [ $i -le 3600 ]; '.
'VBoxManage list runningvms | grep -qF test; '.
'done'
));
}
sub vbm {
$machine->succeed(ru("VBoxManage ".$_[0]));
};
sub checkRunning {
my $checkrunning = ru "VBoxManage list runningvms | grep -qF test";
my ($status, $out) = $machine->execute($checkrunning);
return $status == 0;
}
sub waitForStartup {
for (my $i = 0; $i <= 120; $i += 10) {
$machine->sleep(10);
return if checkRunning;
}
die "VirtualBox VM didn't start up within 2 minutes";
}
sub waitForShutdown {
for (my $i = 0; $i <= 120; $i += 10) {
$machine->sleep(10);
return unless checkRunning;
}
die "VirtualBox VM didn't shut down within 2 minutes";
}
sub shutdownVM {
$machine->succeed(ru "touch /home/alice/vboxshare/shutdown");
$machine->waitUntilSucceeds(
"test ! -e /home/alice/vboxshare/shutdown ".
" -a ! -e /home/alice/vboxshare/boot-done"
);
waitForShutdown;
}
sub cleanup {
$machine->execute(ru "VBoxManage controlvm test poweroff")
if checkRunning;
$machine->succeed("rm -rf /home/alice/vboxshare");
$machine->succeed("mkdir -p /home/alice/vboxshare");
$machine->succeed("chown alice.users /home/alice/vboxshare");
}
${concatStrings (mapAttrsToList (_: getAttr "testSubs") vboxVMs)}
$machine->waitForX;
$machine->succeed(ru "VBoxManage createvm --name test ${createFlags}");
$machine->succeed(ru "VBoxManage modifyvm test ${vmFlags}");
createVM_test1;
$machine->fail("test -e '/root/VirtualBox VMs'");
$machine->succeed("test -e '/home/alice/VirtualBox VMs'");
cleanup_test1;
$machine->succeed(ru "VBoxManage storagectl test ${controllerFlags}");
$machine->succeed(ru "VBoxManage storageattach test ${diskFlags}");
$machine->succeed(ru "VBoxManage sharedfolder add test ${sharedFlags}");
$machine->succeed(ru "VBoxManage showvminfo test >&2");
cleanup;
subtest "virtualbox-gui", sub {
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;
waitForStartup_test1;
$machine->screenshot("gui_started");
waitForVMBoot;
waitForVMBoot_test1;
$machine->screenshot("gui_booted");
shutdownVM;
shutdownVM_test1;
$machine->sleep(5);
$machine->screenshot("gui_stopped");
$machine->sendKeys("ctrl-q");
@ -233,17 +256,19 @@ in {
$machine->screenshot("gui_manager_stopped");
};
cleanup;
cleanup_test1;
subtest "virtualbox-cli", sub {
$machine->succeed(ru "VBoxManage startvm test");
waitForStartup;
subtest "simple-cli", sub {
vbm("startvm test1");
waitForStartup_test1;
$machine->screenshot("cli_started");
waitForVMBoot;
waitForVMBoot_test1;
$machine->screenshot("cli_booted");
shutdownVM;
shutdownVM_test1;
};
cleanup_test1;
$machine->fail("test -e '/root/VirtualBox VMs'");
$machine->succeed("test -e '/home/alice/VirtualBox VMs'");
'';