Compare commits

...

6 Commits

Author SHA1 Message Date
aszlig
1f89aa6c7f nixos/tests: Remove tests.boot.boot* prefixes
As @bobvanderlinden suggests in #13585:

"Looks like that cleans things up quite a bit! Just one aesthetics note,
the boot tests could now be renamed from boot.bootBiosCdrom to
boot.biosCdrom in nixos/tests/boot.nix:L33.

That makes them more consistent with the other tests."

Signed-off-by: aszlig <aszlig@redmoonstudios.org>
2016-03-01 19:02:36 +01:00
aszlig
e45c211b50 nixos/tests/chromium: Split up into subtests
This makes it easier to test just a specific channel rather than to
force testing all builds down the users/testers throat. Especially this
makes it easier to test NixOS channel upgrades only against the Chromium
stable channel instead of just removing the beta/dev channels from the
tests entirely (as done in 69ec09f38a).

Signed-off-by: aszlig <aszlig@redmoonstudios.org>
2016-03-01 01:04:51 +01:00
aszlig
7eea91fbc0 nixos/release: Use callSubTests for subtests
Should clean up a lot of these redundant lines for various sub-tests.

Note that the tests.boot* are now called tests.boot.boot*, but otherwise
all the test attribute names should stay the same.

Signed-off-by: aszlig <aszlig@redmoonstudios.org>
Cc: @edolstra
Cc: @wkennington
Cc: @bobvanderlinden
2016-03-01 01:04:42 +01:00
aszlig
2f2536b935 nixos/tests/networking: Expose subtests via attrs
So far the networking test expression only generated a single test
depending on the passed "test" attribute. This makes it difficult to
autodiscover the subtests with our shiny new callSubTests function.

This change essentially doesn't change the behaviour of the subtests but
rather exposes them as an attribute set instead of relying on a
particular input argument.

The useNetworkd argument still exists however.

Signed-off-by: aszlig <aszlig@redmoonstudios.org>
Cc: @wkennington
2016-03-01 01:04:42 +01:00
aszlig
b3337edd0b nixos/release.nix: Add a callSubTests function
This should de-clutter the various redundant lines of callTest's on
subtests so that every main test file should have only one line with a
callSubTests instead.

Overrides work the same way as callTest, except that if the system
attribute is explicitly specified we do not generate attributes for all
available systems.

Signed-off-by: aszlig <aszlig@redmoonstudios.org>
Cc: @edolstra
2016-03-01 01:04:35 +01:00
aszlig
5bab623fb9 nixos/tests/virtualbox: Split up subtests
Now subtests are separate derivations, because the individual tests do
not depend on state from previous test runs.

This has the advantage that it's easier to run individiual tests and
it's also easier to pinpoint individual tests that randomly fail.

I ran all of these tests locally and they still succeed.

Signed-off-by: aszlig <aszlig@redmoonstudios.org>
2016-02-29 20:15:31 +01:00
6 changed files with 620 additions and 634 deletions

View File

@@ -48,7 +48,7 @@ in rec {
(all nixos.ova)
#(all nixos.tests.containers)
(all nixos.tests.chromium)
(all nixos.tests.chromium.stable)
(all nixos.tests.firefox)
(all nixos.tests.firewall)
nixos.tests.gnome3.x86_64-linux # FIXME: i686-linux
@@ -63,7 +63,7 @@ in rec {
(all nixos.tests.installer.btrfsSimple)
(all nixos.tests.installer.btrfsSubvols)
(all nixos.tests.installer.btrfsSubvolDefault)
(all nixos.tests.bootBiosCdrom)
(all nixos.tests.boot.biosCdrom)
(all nixos.tests.ipv6)
(all nixos.tests.kde4)
#(all nixos.tests.lightdm)

View File

@@ -13,7 +13,25 @@ let
forAllSystems = genAttrs supportedSystems;
callTest = fn: args: forAllSystems (system: hydraJob (import fn ({ inherit system; } // args)));
importTest = fn: args: system: import fn ({
inherit system;
} // args);
callTest = fn: args: forAllSystems (system: hydraJob (importTest fn args system));
callSubTests = fn: args: let
discover = attrs: let
subTests = filterAttrs (const (hasAttr "test")) attrs;
in mapAttrs (const (t: hydraJob t.test)) subTests;
discoverForSystem = system: mapAttrs (_: test: {
${system} = test;
}) (discover (importTest fn args system));
# If the test is only for a particular system, use only the specified
# system instead of generating attributes for all available systems.
in if args ? system then discover (import fn args)
else foldAttrs (a: b: a // b) {} (map discoverForSystem supportedSystems);
pkgs = import nixpkgs { system = "x86_64-linux"; };
@@ -215,8 +233,9 @@ in rec {
tests.avahi = callTest tests/avahi.nix {};
tests.bittorrent = callTest tests/bittorrent.nix {};
tests.blivet = callTest tests/blivet.nix {};
tests.boot = callSubTests tests/boot.nix {};
tests.cadvisor = hydraJob (import tests/cadvisor.nix { system = "x86_64-linux"; });
tests.chromium = callTest tests/chromium.nix {};
tests.chromium = callSubTests tests/chromium.nix {};
tests.cjdns = callTest tests/cjdns.nix {};
tests.containers = callTest tests/containers.nix {};
tests.docker = hydraJob (import tests/docker.nix { system = "x86_64-linux"; });
@@ -232,18 +251,7 @@ in rec {
tests.gnome3-gdm = callTest tests/gnome3-gdm.nix {};
tests.grsecurity = callTest tests/grsecurity.nix {};
tests.i3wm = callTest tests/i3wm.nix {};
tests.installer.grub1 = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).grub1.test);
tests.installer.lvm = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).lvm.test);
tests.installer.luksroot = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).luksroot.test);
tests.installer.separateBoot = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).separateBoot.test);
tests.installer.separateBootFat = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).separateBootFat.test);
tests.installer.simple = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).simple.test);
tests.installer.simpleLabels = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).simpleLabels.test);
tests.installer.simpleProvided = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).simpleProvided.test);
tests.installer.swraid = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).swraid.test);
tests.installer.btrfsSimple = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).btrfsSimple.test);
tests.installer.btrfsSubvols = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).btrfsSubvols.test);
tests.installer.btrfsSubvolDefault = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).btrfsSubvolDefault.test);
tests.installer = callSubTests tests/installer.nix {};
tests.influxdb = callTest tests/influxdb.nix {};
tests.ipv6 = callTest tests/ipv6.nix {};
tests.jenkins = callTest tests/jenkins.nix {};
@@ -262,24 +270,8 @@ in rec {
tests.mysqlReplication = callTest tests/mysql-replication.nix {};
tests.nat.firewall = callTest tests/nat.nix { withFirewall = true; };
tests.nat.standalone = callTest tests/nat.nix { withFirewall = false; };
tests.networking.networkd.loopback = callTest tests/networking.nix { networkd = true; test = "loopback"; };
tests.networking.networkd.static = callTest tests/networking.nix { networkd = true; test = "static"; };
tests.networking.networkd.dhcpSimple = callTest tests/networking.nix { networkd = true; test = "dhcpSimple"; };
tests.networking.networkd.dhcpOneIf = callTest tests/networking.nix { networkd = true; test = "dhcpOneIf"; };
tests.networking.networkd.bond = callTest tests/networking.nix { networkd = true; test = "bond"; };
tests.networking.networkd.bridge = callTest tests/networking.nix { networkd = true; test = "bridge"; };
tests.networking.networkd.macvlan = callTest tests/networking.nix { networkd = true; test = "macvlan"; };
tests.networking.networkd.sit = callTest tests/networking.nix { networkd = true; test = "sit"; };
tests.networking.networkd.vlan = callTest tests/networking.nix { networkd = true; test = "vlan"; };
tests.networking.scripted.loopback = callTest tests/networking.nix { networkd = false; test = "loopback"; };
tests.networking.scripted.static = callTest tests/networking.nix { networkd = false; test = "static"; };
tests.networking.scripted.dhcpSimple = callTest tests/networking.nix { networkd = false; test = "dhcpSimple"; };
tests.networking.scripted.dhcpOneIf = callTest tests/networking.nix { networkd = false; test = "dhcpOneIf"; };
tests.networking.scripted.bond = callTest tests/networking.nix { networkd = false; test = "bond"; };
tests.networking.scripted.bridge = callTest tests/networking.nix { networkd = false; test = "bridge"; };
tests.networking.scripted.macvlan = callTest tests/networking.nix { networkd = false; test = "macvlan"; };
tests.networking.scripted.sit = callTest tests/networking.nix { networkd = false; test = "sit"; };
tests.networking.scripted.vlan = callTest tests/networking.nix { networkd = false; test = "vlan"; };
tests.networking.networkd = callSubTests tests/networking.nix { networkd = true; };
tests.networking.scripted = callSubTests tests/networking.nix { networkd = false; };
# TODO: put in networking.nix after the test becomes more complete
tests.networkingProxy = callTest tests/networking-proxy.nix {};
tests.nfs3 = callTest tests/nfs.nix { version = 3; };
@@ -299,12 +291,8 @@ in rec {
tests.simple = callTest tests/simple.nix {};
tests.tomcat = callTest tests/tomcat.nix {};
tests.udisks2 = callTest tests/udisks2.nix {};
tests.virtualbox = hydraJob (import tests/virtualbox.nix { system = "x86_64-linux"; });
tests.virtualbox = callSubTests tests/virtualbox.nix { system = "x86_64-linux"; };
tests.xfce = callTest tests/xfce.nix {};
tests.bootBiosCdrom = forAllSystems (system: hydraJob (import tests/boot.nix { inherit system; }).bootBiosCdrom);
tests.bootBiosUsb = forAllSystems (system: hydraJob (import tests/boot.nix { inherit system; }).bootBiosUsb);
tests.bootUefiCdrom = forAllSystems (system: hydraJob (import tests/boot.nix { inherit system; }).bootUefiCdrom);
tests.bootUefiUsb = forAllSystems (system: hydraJob (import tests/boot.nix { inherit system; }).bootUefiUsb);
/* Build a bunch of typical closures so that Hydra can keep track of

View File

@@ -30,17 +30,17 @@ let
'';
};
in {
bootBiosCdrom = makeBootTest "bios-cdrom" ''
biosCdrom = makeBootTest "bios-cdrom" ''
cdrom => glob("${iso}/iso/*.iso")
'';
bootBiosUsb = makeBootTest "bios-usb" ''
biosUsb = makeBootTest "bios-usb" ''
usb => glob("${iso}/iso/*.iso")
'';
bootUefiCdrom = makeBootTest "uefi-cdrom" ''
uefiCdrom = makeBootTest "uefi-cdrom" ''
cdrom => glob("${iso}/iso/*.iso"),
bios => '${pkgs.OVMF}/FV/OVMF.fd'
'';
bootUefiUsb = makeBootTest "uefi-usb" ''
uefiUsb = makeBootTest "uefi-usb" ''
usb => glob("${iso}/iso/*.iso"),
bios => '${pkgs.OVMF}/FV/OVMF.fd'
'';

View File

@@ -1,13 +1,10 @@
import ./make-test.nix (
{ pkgs
, channelMap ? {
stable = pkgs.chromium;
#beta = pkgs.chromiumBeta;
#dev = pkgs.chromiumDev;
}
, ...
}: rec {
name = "chromium";
{ system ? builtins.currentSystem }:
with import ../lib/testing.nix { inherit system; };
with pkgs.lib;
mapAttrs (channel: chromiumPkg: makeTest rec {
name = "chromium-${channel}";
meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ aszlig ];
};
@@ -16,6 +13,7 @@ import ./make-test.nix (
machine.imports = [ ./common/x11.nix ];
machine.virtualisation.memorySize = 2047;
machine.environment.systemPackages = [ chromiumPkg ];
startupHTML = pkgs.writeText "chromium-startup.html" ''
<!DOCTYPE html>
@@ -105,74 +103,65 @@ import ./make-test.nix (
closeWin;
}
sub chromiumTest {
my ($channel, $pkg, $code) = @_;
$machine->waitForX;
$machine->waitForX;
my $url = "file://${startupHTML}";
my $args = "--user-data-dir=/tmp/chromium-$channel";
$machine->execute(
"ulimit -c unlimited; ".
"$pkg/bin/chromium $args \"$url\" & disown"
);
$machine->waitForText(qr/Type to search or enter a URL to navigate/);
$machine->waitUntilSucceeds("${xdo "check-startup" ''
search --sync --onlyvisible --name "startup done"
# close first start help popup
key -delay 1000 Escape
my $url = "file://${startupHTML}";
my $args = "--user-data-dir=/tmp/chromium-${channel}";
$machine->execute(
"ulimit -c unlimited; ".
"chromium $args \"$url\" & disown"
);
$machine->waitForText(qr/Type to search or enter a URL to navigate/);
$machine->waitUntilSucceeds("${xdo "check-startup" ''
search --sync --onlyvisible --name "startup done"
# close first start help popup
key -delay 1000 Escape
windowfocus --sync
windowactivate --sync
''}");
createAndWaitForNewWin;
$machine->screenshot("empty_windows");
closeWin;
$machine->screenshot("startup_done");
testNewWin "check sandbox", sub {
$machine->succeed("${xdo "type-url" ''
search --sync --onlyvisible --name "new tab"
windowfocus --sync
windowactivate --sync
type --delay 1000 "chrome://sandbox"
''}");
createAndWaitForNewWin;
$machine->screenshot($channel."_emptywin");
closeWin;
$machine->succeed("${xdo "submit-url" ''
search --sync --onlyvisible --name "new tab"
windowfocus --sync
key --delay 1000 Return
''}");
$machine->screenshot($channel."_startup_done");
$machine->screenshot("sandbox_info");
subtest("Chromium $channel", $code);
$machine->succeed("${xdo "submit-url" ''
search --sync --onlyvisible --name "sandbox status"
windowfocus --sync
''}");
$machine->succeed("${xdo "submit-url" ''
key --delay 1000 Ctrl+a Ctrl+c
''}");
$machine->shutdown;
}
my $clipboard = $machine->succeed("${pkgs.xclip}/bin/xclip -o");
die "sandbox not working properly: $clipboard"
unless $clipboard =~ /namespace sandbox.*yes/mi
&& $clipboard =~ /pid namespaces.*yes/mi
&& $clipboard =~ /network namespaces.*yes/mi
&& $clipboard =~ /seccomp.*sandbox.*yes/mi
&& $clipboard =~ /you are adequately sandboxed/mi;
};
for (${let
mkArray = name: pkg: "[\"${name}\", \"${pkg}\"]";
chanArrays = pkgs.lib.mapAttrsToList mkArray channelMap;
in pkgs.lib.concatStringsSep ", " chanArrays}) {
my ($channel, $pkg) = @$_;
chromiumTest $channel, $pkg, sub {
testNewWin "check sandbox", sub {
$machine->succeed("${xdo "type-url" ''
search --sync --onlyvisible --name "new tab"
windowfocus --sync
type --delay 1000 "chrome://sandbox"
''}");
$machine->succeed("${xdo "submit-url" ''
search --sync --onlyvisible --name "new tab"
windowfocus --sync
key --delay 1000 Return
''}");
$machine->screenshot($channel."_sandbox");
$machine->succeed("${xdo "submit-url" ''
search --sync --onlyvisible --name "sandbox status"
windowfocus --sync
''}");
$machine->succeed("${xdo "submit-url" ''
key --delay 1000 Ctrl+a Ctrl+c
''}");
my $clipboard = $machine->succeed("${pkgs.xclip}/bin/xclip -o");
die "sandbox not working properly: $clipboard"
unless $clipboard =~ /namespace sandbox.*yes/mi
&& $clipboard =~ /pid namespaces.*yes/mi
&& $clipboard =~ /network namespaces.*yes/mi
&& $clipboard =~ /seccomp.*sandbox.*yes/mi
&& $clipboard =~ /you are adequately sandboxed/mi;
};
};
}
$machine->shutdown;
'';
})
}) {
stable = pkgs.chromium;
beta = pkgs.chromiumBeta;
dev = pkgs.chromiumDev;
}

View File

@@ -1,406 +1,411 @@
import ./make-test.nix ({ pkgs, networkd, test, ... }:
let
router = { config, pkgs, ... }:
with pkgs.lib;
let
vlanIfs = range 1 (length config.virtualisation.vlans);
in {
virtualisation.vlans = [ 1 2 3 ];
{ system ? builtins.currentSystem, networkd }:
with import ../lib/testing.nix { inherit system; };
with pkgs.lib;
let
router = { config, pkgs, ... }:
with pkgs.lib;
let
vlanIfs = range 1 (length config.virtualisation.vlans);
in {
virtualisation.vlans = [ 1 2 3 ];
networking = {
useDHCP = false;
useNetworkd = networkd;
firewall.allowPing = true;
interfaces = mkOverride 0 (listToAttrs (flip map vlanIfs (n:
nameValuePair "eth${toString n}" {
ipAddress = "192.168.${toString n}.1";
prefixLength = 24;
})));
};
services.dhcpd = {
enable = true;
interfaces = map (n: "eth${toString n}") vlanIfs;
extraConfig = ''
option subnet-mask 255.255.255.0;
'' + flip concatMapStrings vlanIfs (n: ''
subnet 192.168.${toString n}.0 netmask 255.255.255.0 {
option broadcast-address 192.168.${toString n}.255;
option routers 192.168.${toString n}.1;
range 192.168.${toString n}.2 192.168.${toString n}.254;
}
'');
};
};
testCases = {
loopback = {
name = "Loopback";
machine.networking.useNetworkd = networkd;
testScript = ''
startAll;
$machine->waitForUnit("network-interfaces.target");
$machine->waitForUnit("network.target");
$machine->succeed("ip addr show lo | grep -q 'inet 127.0.0.1/8 '");
$machine->succeed("ip addr show lo | grep -q 'inet6 ::1/128 '");
'';
};
static = {
name = "Static";
nodes.router = router;
nodes.client = { config, pkgs, ... }: with pkgs.lib; {
virtualisation.vlans = [ 1 2 ];
networking = {
useDHCP = false;
useNetworkd = networkd;
firewall.allowPing = true;
interfaces = mkOverride 0 (listToAttrs (flip map vlanIfs (n:
nameValuePair "eth${toString n}" {
ipAddress = "192.168.${toString n}.1";
prefixLength = 24;
})));
};
services.dhcpd = {
enable = true;
interfaces = map (n: "eth${toString n}") vlanIfs;
extraConfig = ''
option subnet-mask 255.255.255.0;
'' + flip concatMapStrings vlanIfs (n: ''
subnet 192.168.${toString n}.0 netmask 255.255.255.0 {
option broadcast-address 192.168.${toString n}.255;
option routers 192.168.${toString n}.1;
range 192.168.${toString n}.2 192.168.${toString n}.254;
}
'');
useDHCP = false;
defaultGateway = "192.168.1.1";
interfaces.eth1.ip4 = mkOverride 0 [
{ address = "192.168.1.2"; prefixLength = 24; }
{ address = "192.168.1.3"; prefixLength = 32; }
{ address = "192.168.1.10"; prefixLength = 32; }
];
interfaces.eth2.ip4 = mkOverride 0 [
{ address = "192.168.2.2"; prefixLength = 24; }
];
};
};
testCases = {
loopback = {
name = "Loopback";
machine.networking.useNetworkd = networkd;
testScript = ''
testScript = { nodes, ... }:
''
startAll;
$machine->waitForUnit("network-interfaces.target");
$machine->waitForUnit("network.target");
$machine->succeed("ip addr show lo | grep -q 'inet 127.0.0.1/8 '");
$machine->succeed("ip addr show lo | grep -q 'inet6 ::1/128 '");
$client->waitForUnit("network-interfaces.target");
$client->waitForUnit("network.target");
$router->waitForUnit("network-interfaces.target");
$router->waitForUnit("network.target");
# Make sure dhcpcd is not started
$client->fail("systemctl status dhcpcd.service");
# Test vlan 1
$client->waitUntilSucceeds("ping -c 1 192.168.1.1");
$client->waitUntilSucceeds("ping -c 1 192.168.1.2");
$client->waitUntilSucceeds("ping -c 1 192.168.1.3");
$client->waitUntilSucceeds("ping -c 1 192.168.1.10");
$router->waitUntilSucceeds("ping -c 1 192.168.1.1");
$router->waitUntilSucceeds("ping -c 1 192.168.1.2");
$router->waitUntilSucceeds("ping -c 1 192.168.1.3");
$router->waitUntilSucceeds("ping -c 1 192.168.1.10");
# Test vlan 2
$client->waitUntilSucceeds("ping -c 1 192.168.2.1");
$client->waitUntilSucceeds("ping -c 1 192.168.2.2");
$router->waitUntilSucceeds("ping -c 1 192.168.2.1");
$router->waitUntilSucceeds("ping -c 1 192.168.2.2");
# Test default gateway
$router->waitUntilSucceeds("ping -c 1 192.168.3.1");
$client->waitUntilSucceeds("ping -c 1 192.168.3.1");
'';
};
static = {
name = "Static";
nodes.router = router;
nodes.client = { config, pkgs, ... }: with pkgs.lib; {
virtualisation.vlans = [ 1 2 ];
networking = {
useNetworkd = networkd;
firewall.allowPing = true;
useDHCP = false;
defaultGateway = "192.168.1.1";
interfaces.eth1.ip4 = mkOverride 0 [
{ address = "192.168.1.2"; prefixLength = 24; }
{ address = "192.168.1.3"; prefixLength = 32; }
{ address = "192.168.1.10"; prefixLength = 32; }
];
interfaces.eth2.ip4 = mkOverride 0 [
{ address = "192.168.2.2"; prefixLength = 24; }
];
};
};
testScript = { nodes, ... }:
''
startAll;
$client->waitForUnit("network-interfaces.target");
$client->waitForUnit("network.target");
$router->waitForUnit("network-interfaces.target");
$router->waitForUnit("network.target");
# Make sure dhcpcd is not started
$client->fail("systemctl status dhcpcd.service");
# Test vlan 1
$client->waitUntilSucceeds("ping -c 1 192.168.1.1");
$client->waitUntilSucceeds("ping -c 1 192.168.1.2");
$client->waitUntilSucceeds("ping -c 1 192.168.1.3");
$client->waitUntilSucceeds("ping -c 1 192.168.1.10");
$router->waitUntilSucceeds("ping -c 1 192.168.1.1");
$router->waitUntilSucceeds("ping -c 1 192.168.1.2");
$router->waitUntilSucceeds("ping -c 1 192.168.1.3");
$router->waitUntilSucceeds("ping -c 1 192.168.1.10");
# Test vlan 2
$client->waitUntilSucceeds("ping -c 1 192.168.2.1");
$client->waitUntilSucceeds("ping -c 1 192.168.2.2");
$router->waitUntilSucceeds("ping -c 1 192.168.2.1");
$router->waitUntilSucceeds("ping -c 1 192.168.2.2");
# Test default gateway
$router->waitUntilSucceeds("ping -c 1 192.168.3.1");
$client->waitUntilSucceeds("ping -c 1 192.168.3.1");
'';
};
dhcpSimple = {
name = "SimpleDHCP";
nodes.router = router;
nodes.client = { config, pkgs, ... }: with pkgs.lib; {
virtualisation.vlans = [ 1 2 ];
networking = {
useNetworkd = networkd;
firewall.allowPing = true;
useDHCP = true;
interfaces.eth1.ip4 = mkOverride 0 [ ];
interfaces.eth2.ip4 = mkOverride 0 [ ];
};
};
testScript = { nodes, ... }:
''
startAll;
$client->waitForUnit("network-interfaces.target");
$client->waitForUnit("network.target");
$router->waitForUnit("network-interfaces.target");
$router->waitForUnit("network.target");
# Wait until we have an ip address on each interface
$client->waitUntilSucceeds("ip addr show dev eth1 | grep -q '192.168.1'");
$client->waitUntilSucceeds("ip addr show dev eth2 | grep -q '192.168.2'");
# Test vlan 1
$client->waitUntilSucceeds("ping -c 1 192.168.1.1");
$client->waitUntilSucceeds("ping -c 1 192.168.1.2");
$router->waitUntilSucceeds("ping -c 1 192.168.1.1");
$router->waitUntilSucceeds("ping -c 1 192.168.1.2");
# Test vlan 2
$client->waitUntilSucceeds("ping -c 1 192.168.2.1");
$client->waitUntilSucceeds("ping -c 1 192.168.2.2");
$router->waitUntilSucceeds("ping -c 1 192.168.2.1");
$router->waitUntilSucceeds("ping -c 1 192.168.2.2");
'';
};
dhcpOneIf = {
name = "OneInterfaceDHCP";
nodes.router = router;
nodes.client = { config, pkgs, ... }: with pkgs.lib; {
virtualisation.vlans = [ 1 2 ];
networking = {
useNetworkd = networkd;
firewall.allowPing = true;
useDHCP = false;
interfaces.eth1 = {
ip4 = mkOverride 0 [ ];
useDHCP = true;
};
interfaces.eth2.ip4 = mkOverride 0 [ ];
};
};
testScript = { nodes, ... }:
''
startAll;
# Wait for networking to come up
$client->waitForUnit("network-interfaces.target");
$client->waitForUnit("network.target");
$router->waitForUnit("network-interfaces.target");
$router->waitForUnit("network.target");
# Wait until we have an ip address on each interface
$client->waitUntilSucceeds("ip addr show dev eth1 | grep -q '192.168.1'");
# Test vlan 1
$client->waitUntilSucceeds("ping -c 1 192.168.1.1");
$client->waitUntilSucceeds("ping -c 1 192.168.1.2");
$router->waitUntilSucceeds("ping -c 1 192.168.1.1");
$router->waitUntilSucceeds("ping -c 1 192.168.1.2");
# Test vlan 2
$client->waitUntilSucceeds("ping -c 1 192.168.2.1");
$client->fail("ping -c 1 192.168.2.2");
$router->waitUntilSucceeds("ping -c 1 192.168.2.1");
$router->fail("ping -c 1 192.168.2.2");
'';
};
bond = let
node = address: { config, pkgs, ... }: with pkgs.lib; {
virtualisation.vlans = [ 1 2 ];
networking = {
useNetworkd = networkd;
firewall.allowPing = true;
useDHCP = false;
bonds.bond = {
mode = "balance-rr";
interfaces = [ "eth1" "eth2" ];
};
interfaces.eth1.ip4 = mkOverride 0 [ ];
interfaces.eth2.ip4 = mkOverride 0 [ ];
interfaces.bond.ip4 = mkOverride 0
[ { inherit address; prefixLength = 30; } ];
};
};
in {
name = "Bond";
nodes.client1 = node "192.168.1.1";
nodes.client2 = node "192.168.1.2";
testScript = { nodes, ... }:
''
startAll;
# Wait for networking to come up
$client1->waitForUnit("network-interfaces.target");
$client1->waitForUnit("network.target");
$client2->waitForUnit("network-interfaces.target");
$client2->waitForUnit("network.target");
# Test bonding
$client1->waitUntilSucceeds("ping -c 2 192.168.1.1");
$client1->waitUntilSucceeds("ping -c 2 192.168.1.2");
$client2->waitUntilSucceeds("ping -c 2 192.168.1.1");
$client2->waitUntilSucceeds("ping -c 2 192.168.1.2");
'';
};
bridge = let
node = { address, vlan }: { config, pkgs, ... }: with pkgs.lib; {
virtualisation.vlans = [ vlan ];
networking = {
useNetworkd = networkd;
firewall.allowPing = true;
useDHCP = false;
interfaces.eth1.ip4 = mkOverride 0
[ { inherit address; prefixLength = 24; } ];
};
};
in {
name = "Bridge";
nodes.client1 = node { address = "192.168.1.2"; vlan = 1; };
nodes.client2 = node { address = "192.168.1.3"; vlan = 2; };
nodes.router = { config, pkgs, ... }: with pkgs.lib; {
virtualisation.vlans = [ 1 2 ];
networking = {
useNetworkd = networkd;
firewall.allowPing = true;
useDHCP = false;
bridges.bridge.interfaces = [ "eth1" "eth2" ];
interfaces.eth1.ip4 = mkOverride 0 [ ];
interfaces.eth2.ip4 = mkOverride 0 [ ];
interfaces.bridge.ip4 = mkOverride 0
[ { address = "192.168.1.1"; prefixLength = 24; } ];
};
};
testScript = { nodes, ... }:
''
startAll;
# Wait for networking to come up
$client1->waitForUnit("network-interfaces.target");
$client1->waitForUnit("network.target");
$client2->waitForUnit("network-interfaces.target");
$client2->waitForUnit("network.target");
$router->waitForUnit("network-interfaces.target");
$router->waitForUnit("network.target");
# Test bridging
$client1->waitUntilSucceeds("ping -c 1 192.168.1.1");
$client1->waitUntilSucceeds("ping -c 1 192.168.1.2");
$client1->waitUntilSucceeds("ping -c 1 192.168.1.3");
$client2->waitUntilSucceeds("ping -c 1 192.168.1.1");
$client2->waitUntilSucceeds("ping -c 1 192.168.1.2");
$client2->waitUntilSucceeds("ping -c 1 192.168.1.3");
$router->waitUntilSucceeds("ping -c 1 192.168.1.1");
$router->waitUntilSucceeds("ping -c 1 192.168.1.2");
$router->waitUntilSucceeds("ping -c 1 192.168.1.3");
'';
};
macvlan = {
name = "MACVLAN";
nodes.router = router;
nodes.client = { config, pkgs, ... }: with pkgs.lib; {
virtualisation.vlans = [ 1 ];
networking = {
useNetworkd = networkd;
firewall.allowPing = true;
useDHCP = true;
macvlans.macvlan.interface = "eth1";
interfaces.eth1.ip4 = mkOverride 0 [ ];
};
};
testScript = { nodes, ... }:
''
startAll;
# Wait for networking to come up
$client->waitForUnit("network-interfaces.target");
$client->waitForUnit("network.target");
$router->waitForUnit("network-interfaces.target");
$router->waitForUnit("network.target");
# Wait until we have an ip address on each interface
$client->waitUntilSucceeds("ip addr show dev eth1 | grep -q '192.168.1'");
$client->waitUntilSucceeds("ip addr show dev macvlan | grep -q '192.168.1'");
# Print diagnosting information
$router->succeed("ip addr >&2");
$client->succeed("ip addr >&2");
# Test macvlan creates routable ips
$client->waitUntilSucceeds("ping -c 1 192.168.1.1");
$client->waitUntilSucceeds("ping -c 1 192.168.1.2");
$client->waitUntilSucceeds("ping -c 1 192.168.1.3");
$router->waitUntilSucceeds("ping -c 1 192.168.1.1");
$router->waitUntilSucceeds("ping -c 1 192.168.1.2");
$router->waitUntilSucceeds("ping -c 1 192.168.1.3");
'';
};
sit = let
node = { address4, remote, address6 }: { config, pkgs, ... }: with pkgs.lib; {
virtualisation.vlans = [ 1 ];
networking = {
useNetworkd = networkd;
firewall.enable = false;
useDHCP = false;
sits.sit = {
inherit remote;
local = address4;
dev = "eth1";
};
interfaces.eth1.ip4 = mkOverride 0
[ { address = address4; prefixLength = 24; } ];
interfaces.sit.ip6 = mkOverride 0
[ { address = address6; prefixLength = 64; } ];
};
};
in {
name = "Sit";
nodes.client1 = node { address4 = "192.168.1.1"; remote = "192.168.1.2"; address6 = "fc00::1"; };
nodes.client2 = node { address4 = "192.168.1.2"; remote = "192.168.1.1"; address6 = "fc00::2"; };
testScript = { nodes, ... }:
''
startAll;
# Wait for networking to be configured
$client1->waitForUnit("network-interfaces.target");
$client1->waitForUnit("network.target");
$client2->waitForUnit("network-interfaces.target");
$client2->waitForUnit("network.target");
# Print diagnostic information
$client1->succeed("ip addr >&2");
$client2->succeed("ip addr >&2");
# Test ipv6
$client1->waitUntilSucceeds("ping6 -c 1 fc00::1");
$client1->waitUntilSucceeds("ping6 -c 1 fc00::2");
$client2->waitUntilSucceeds("ping6 -c 1 fc00::1");
$client2->waitUntilSucceeds("ping6 -c 1 fc00::2");
'';
};
vlan = let
node = address: { config, pkgs, ... }: with pkgs.lib; {
#virtualisation.vlans = [ 1 ];
networking = {
useNetworkd = networkd;
firewall.allowPing = true;
useDHCP = false;
vlans.vlan = {
id = 1;
interface = "eth0";
};
interfaces.eth0.ip4 = mkOverride 0 [ ];
interfaces.eth1.ip4 = mkOverride 0 [ ];
interfaces.vlan.ip4 = mkOverride 0
[ { inherit address; prefixLength = 24; } ];
};
};
in {
name = "vlan";
nodes.client1 = node "192.168.1.1";
nodes.client2 = node "192.168.1.2";
testScript = { nodes, ... }:
''
startAll;
# Wait for networking to be configured
$client1->waitForUnit("network-interfaces.target");
$client1->waitForUnit("network.target");
$client2->waitForUnit("network-interfaces.target");
$client2->waitForUnit("network.target");
# Test vlan is setup
$client1->succeed("ip addr show dev vlan >&2");
$client2->succeed("ip addr show dev vlan >&2");
'';
};
};
case = testCases.${test};
in case // {
name = "${case.name}-Networking-${if networkd then "Networkd" else "Scripted"}";
meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ wkennington ];
dhcpSimple = {
name = "SimpleDHCP";
nodes.router = router;
nodes.client = { config, pkgs, ... }: with pkgs.lib; {
virtualisation.vlans = [ 1 2 ];
networking = {
useNetworkd = networkd;
firewall.allowPing = true;
useDHCP = true;
interfaces.eth1.ip4 = mkOverride 0 [ ];
interfaces.eth2.ip4 = mkOverride 0 [ ];
};
};
testScript = { nodes, ... }:
''
startAll;
$client->waitForUnit("network-interfaces.target");
$client->waitForUnit("network.target");
$router->waitForUnit("network-interfaces.target");
$router->waitForUnit("network.target");
# Wait until we have an ip address on each interface
$client->waitUntilSucceeds("ip addr show dev eth1 | grep -q '192.168.1'");
$client->waitUntilSucceeds("ip addr show dev eth2 | grep -q '192.168.2'");
# Test vlan 1
$client->waitUntilSucceeds("ping -c 1 192.168.1.1");
$client->waitUntilSucceeds("ping -c 1 192.168.1.2");
$router->waitUntilSucceeds("ping -c 1 192.168.1.1");
$router->waitUntilSucceeds("ping -c 1 192.168.1.2");
# Test vlan 2
$client->waitUntilSucceeds("ping -c 1 192.168.2.1");
$client->waitUntilSucceeds("ping -c 1 192.168.2.2");
$router->waitUntilSucceeds("ping -c 1 192.168.2.1");
$router->waitUntilSucceeds("ping -c 1 192.168.2.2");
'';
};
})
dhcpOneIf = {
name = "OneInterfaceDHCP";
nodes.router = router;
nodes.client = { config, pkgs, ... }: with pkgs.lib; {
virtualisation.vlans = [ 1 2 ];
networking = {
useNetworkd = networkd;
firewall.allowPing = true;
useDHCP = false;
interfaces.eth1 = {
ip4 = mkOverride 0 [ ];
useDHCP = true;
};
interfaces.eth2.ip4 = mkOverride 0 [ ];
};
};
testScript = { nodes, ... }:
''
startAll;
# Wait for networking to come up
$client->waitForUnit("network-interfaces.target");
$client->waitForUnit("network.target");
$router->waitForUnit("network-interfaces.target");
$router->waitForUnit("network.target");
# Wait until we have an ip address on each interface
$client->waitUntilSucceeds("ip addr show dev eth1 | grep -q '192.168.1'");
# Test vlan 1
$client->waitUntilSucceeds("ping -c 1 192.168.1.1");
$client->waitUntilSucceeds("ping -c 1 192.168.1.2");
$router->waitUntilSucceeds("ping -c 1 192.168.1.1");
$router->waitUntilSucceeds("ping -c 1 192.168.1.2");
# Test vlan 2
$client->waitUntilSucceeds("ping -c 1 192.168.2.1");
$client->fail("ping -c 1 192.168.2.2");
$router->waitUntilSucceeds("ping -c 1 192.168.2.1");
$router->fail("ping -c 1 192.168.2.2");
'';
};
bond = let
node = address: { config, pkgs, ... }: with pkgs.lib; {
virtualisation.vlans = [ 1 2 ];
networking = {
useNetworkd = networkd;
firewall.allowPing = true;
useDHCP = false;
bonds.bond = {
mode = "balance-rr";
interfaces = [ "eth1" "eth2" ];
};
interfaces.eth1.ip4 = mkOverride 0 [ ];
interfaces.eth2.ip4 = mkOverride 0 [ ];
interfaces.bond.ip4 = mkOverride 0
[ { inherit address; prefixLength = 30; } ];
};
};
in {
name = "Bond";
nodes.client1 = node "192.168.1.1";
nodes.client2 = node "192.168.1.2";
testScript = { nodes, ... }:
''
startAll;
# Wait for networking to come up
$client1->waitForUnit("network-interfaces.target");
$client1->waitForUnit("network.target");
$client2->waitForUnit("network-interfaces.target");
$client2->waitForUnit("network.target");
# Test bonding
$client1->waitUntilSucceeds("ping -c 2 192.168.1.1");
$client1->waitUntilSucceeds("ping -c 2 192.168.1.2");
$client2->waitUntilSucceeds("ping -c 2 192.168.1.1");
$client2->waitUntilSucceeds("ping -c 2 192.168.1.2");
'';
};
bridge = let
node = { address, vlan }: { config, pkgs, ... }: with pkgs.lib; {
virtualisation.vlans = [ vlan ];
networking = {
useNetworkd = networkd;
firewall.allowPing = true;
useDHCP = false;
interfaces.eth1.ip4 = mkOverride 0
[ { inherit address; prefixLength = 24; } ];
};
};
in {
name = "Bridge";
nodes.client1 = node { address = "192.168.1.2"; vlan = 1; };
nodes.client2 = node { address = "192.168.1.3"; vlan = 2; };
nodes.router = { config, pkgs, ... }: with pkgs.lib; {
virtualisation.vlans = [ 1 2 ];
networking = {
useNetworkd = networkd;
firewall.allowPing = true;
useDHCP = false;
bridges.bridge.interfaces = [ "eth1" "eth2" ];
interfaces.eth1.ip4 = mkOverride 0 [ ];
interfaces.eth2.ip4 = mkOverride 0 [ ];
interfaces.bridge.ip4 = mkOverride 0
[ { address = "192.168.1.1"; prefixLength = 24; } ];
};
};
testScript = { nodes, ... }:
''
startAll;
# Wait for networking to come up
$client1->waitForUnit("network-interfaces.target");
$client1->waitForUnit("network.target");
$client2->waitForUnit("network-interfaces.target");
$client2->waitForUnit("network.target");
$router->waitForUnit("network-interfaces.target");
$router->waitForUnit("network.target");
# Test bridging
$client1->waitUntilSucceeds("ping -c 1 192.168.1.1");
$client1->waitUntilSucceeds("ping -c 1 192.168.1.2");
$client1->waitUntilSucceeds("ping -c 1 192.168.1.3");
$client2->waitUntilSucceeds("ping -c 1 192.168.1.1");
$client2->waitUntilSucceeds("ping -c 1 192.168.1.2");
$client2->waitUntilSucceeds("ping -c 1 192.168.1.3");
$router->waitUntilSucceeds("ping -c 1 192.168.1.1");
$router->waitUntilSucceeds("ping -c 1 192.168.1.2");
$router->waitUntilSucceeds("ping -c 1 192.168.1.3");
'';
};
macvlan = {
name = "MACVLAN";
nodes.router = router;
nodes.client = { config, pkgs, ... }: with pkgs.lib; {
virtualisation.vlans = [ 1 ];
networking = {
useNetworkd = networkd;
firewall.allowPing = true;
useDHCP = true;
macvlans.macvlan.interface = "eth1";
interfaces.eth1.ip4 = mkOverride 0 [ ];
};
};
testScript = { nodes, ... }:
''
startAll;
# Wait for networking to come up
$client->waitForUnit("network-interfaces.target");
$client->waitForUnit("network.target");
$router->waitForUnit("network-interfaces.target");
$router->waitForUnit("network.target");
# Wait until we have an ip address on each interface
$client->waitUntilSucceeds("ip addr show dev eth1 | grep -q '192.168.1'");
$client->waitUntilSucceeds("ip addr show dev macvlan | grep -q '192.168.1'");
# Print diagnosting information
$router->succeed("ip addr >&2");
$client->succeed("ip addr >&2");
# Test macvlan creates routable ips
$client->waitUntilSucceeds("ping -c 1 192.168.1.1");
$client->waitUntilSucceeds("ping -c 1 192.168.1.2");
$client->waitUntilSucceeds("ping -c 1 192.168.1.3");
$router->waitUntilSucceeds("ping -c 1 192.168.1.1");
$router->waitUntilSucceeds("ping -c 1 192.168.1.2");
$router->waitUntilSucceeds("ping -c 1 192.168.1.3");
'';
};
sit = let
node = { address4, remote, address6 }: { config, pkgs, ... }: with pkgs.lib; {
virtualisation.vlans = [ 1 ];
networking = {
useNetworkd = networkd;
firewall.enable = false;
useDHCP = false;
sits.sit = {
inherit remote;
local = address4;
dev = "eth1";
};
interfaces.eth1.ip4 = mkOverride 0
[ { address = address4; prefixLength = 24; } ];
interfaces.sit.ip6 = mkOverride 0
[ { address = address6; prefixLength = 64; } ];
};
};
in {
name = "Sit";
nodes.client1 = node { address4 = "192.168.1.1"; remote = "192.168.1.2"; address6 = "fc00::1"; };
nodes.client2 = node { address4 = "192.168.1.2"; remote = "192.168.1.1"; address6 = "fc00::2"; };
testScript = { nodes, ... }:
''
startAll;
# Wait for networking to be configured
$client1->waitForUnit("network-interfaces.target");
$client1->waitForUnit("network.target");
$client2->waitForUnit("network-interfaces.target");
$client2->waitForUnit("network.target");
# Print diagnostic information
$client1->succeed("ip addr >&2");
$client2->succeed("ip addr >&2");
# Test ipv6
$client1->waitUntilSucceeds("ping6 -c 1 fc00::1");
$client1->waitUntilSucceeds("ping6 -c 1 fc00::2");
$client2->waitUntilSucceeds("ping6 -c 1 fc00::1");
$client2->waitUntilSucceeds("ping6 -c 1 fc00::2");
'';
};
vlan = let
node = address: { config, pkgs, ... }: with pkgs.lib; {
#virtualisation.vlans = [ 1 ];
networking = {
useNetworkd = networkd;
firewall.allowPing = true;
useDHCP = false;
vlans.vlan = {
id = 1;
interface = "eth0";
};
interfaces.eth0.ip4 = mkOverride 0 [ ];
interfaces.eth1.ip4 = mkOverride 0 [ ];
interfaces.vlan.ip4 = mkOverride 0
[ { inherit address; prefixLength = 24; } ];
};
};
in {
name = "vlan";
nodes.client1 = node "192.168.1.1";
nodes.client2 = node "192.168.1.2";
testScript = { nodes, ... }:
''
startAll;
# Wait for networking to be configured
$client1->waitForUnit("network-interfaces.target");
$client1->waitForUnit("network.target");
$client2->waitForUnit("network-interfaces.target");
$client2->waitForUnit("network.target");
# Test vlan is setup
$client1->succeed("ip addr show dev vlan >&2");
$client2->succeed("ip addr show dev vlan >&2");
'';
};
};
in mapAttrs (const (attrs: makeTest (attrs // {
name = "${attrs.name}-Networking-${if networkd then "Networkd" else "Scripted"}";
meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ wkennington ];
};
}))) testCases

View File

@@ -1,7 +1,9 @@
{ debug ? false, ... } @ args:
{ system ? builtins.currentSystem, debug ? false }:
import ./make-test.nix ({ pkgs, ... }: with pkgs.lib; let
with import ../lib/testing.nix { inherit system; };
with pkgs.lib;
let
testVMConfig = vmName: attrs: { config, pkgs, ... }: let
guestAdditions = pkgs.linuxPackages.virtualboxGuestAdditions;
@@ -314,138 +316,140 @@ import ./make-test.nix ({ pkgs, ... }: with pkgs.lib; let
test2.vmScript = dhcpScript;
};
in {
name = "virtualbox";
meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ aszlig wkennington ];
};
mkVBoxTest = name: testScript: makeTest {
name = "virtualbox-${name}";
machine = { pkgs, lib, config, ... }: {
imports = let
mkVMConf = name: val: val.machine // { key = "${name}-config"; };
vmConfigs = mapAttrsToList mkVMConf vboxVMs;
in [ ./common/user-account.nix ./common/x11.nix ] ++ vmConfigs;
virtualisation.memorySize = 2048;
virtualisation.virtualbox.host.enable = true;
users.extraUsers.alice.extraGroups = let
inherit (config.virtualisation.virtualbox.host) enableHardening;
in lib.mkIf enableHardening (lib.singleton "vboxusers");
};
testScript = ''
sub ru ($) {
my $esc = $_[0] =~ s/'/'\\${"'"}'/gr;
return "su - alice -c '$esc'";
}
sub vbm {
$machine->succeed(ru("VBoxManage ".$_[0]));
machine = { lib, config, ... }: {
imports = let
mkVMConf = name: val: val.machine // { key = "${name}-config"; };
vmConfigs = mapAttrsToList mkVMConf vboxVMs;
in [ ./common/user-account.nix ./common/x11.nix ] ++ vmConfigs;
virtualisation.memorySize = 2048;
virtualisation.virtualbox.host.enable = true;
users.extraUsers.alice.extraGroups = let
inherit (config.virtualisation.virtualbox.host) enableHardening;
in lib.mkIf enableHardening (lib.singleton "vboxusers");
};
${concatStrings (mapAttrsToList (_: getAttr "testSubs") vboxVMs)}
testScript = ''
sub ru ($) {
my $esc = $_[0] =~ s/'/'\\${"'"}'/gr;
return "su - alice -c '$esc'";
}
$machine->waitForX;
sub vbm {
$machine->succeed(ru("VBoxManage ".$_[0]));
};
${mkLog "$HOME/.config/VirtualBox/VBoxSVC.log" "HOST-SVC"}
sub removeUUIDs {
return join("\n", grep { $_ !~ /^UUID:/ } split(/\n/, $_[0]))."\n";
}
${concatStrings (mapAttrsToList (_: getAttr "testSubs") vboxVMs)}
$machine->waitForX;
${mkLog "$HOME/.config/VirtualBox/VBoxSVC.log" "HOST-SVC"}
${testScript}
'';
meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ aszlig wkennington ];
};
};
in mapAttrs mkVBoxTest {
simple-gui = ''
createVM_simple;
subtest "simple-gui", sub {
$machine->succeed(ru "VirtualBox &");
$machine->waitForWindow(qr/Oracle VM VirtualBox Manager/);
$machine->sleep(5);
$machine->screenshot("gui_manager_started");
$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_simple (sub {
$machine->sendKeys("ret");
$machine->screenshot("gui_manager_sent_startup");
waitForStartup_simple (sub {
$machine->sendKeys("ret");
});
$machine->screenshot("gui_started");
waitForVMBoot_simple;
$machine->screenshot("gui_booted");
shutdownVM_simple;
$machine->sleep(5);
$machine->screenshot("gui_stopped");
$machine->sendKeys("ctrl-q");
$machine->sleep(5);
$machine->screenshot("gui_manager_stopped");
};
});
$machine->screenshot("gui_started");
waitForVMBoot_simple;
$machine->screenshot("gui_booted");
shutdownVM_simple;
$machine->sleep(5);
$machine->screenshot("gui_stopped");
$machine->sendKeys("ctrl-q");
$machine->sleep(5);
$machine->screenshot("gui_manager_stopped");
'';
cleanup_simple;
simple-cli = ''
createVM_simple;
vbm("startvm simple");
waitForStartup_simple;
$machine->screenshot("cli_started");
waitForVMBoot_simple;
$machine->screenshot("cli_booted");
subtest "simple-cli", sub {
vbm("startvm simple");
waitForStartup_simple;
$machine->screenshot("cli_started");
waitForVMBoot_simple;
$machine->screenshot("cli_booted");
shutdownVM_simple;
};
subtest "privilege-escalation", sub {
$machine->nest("Checking for privilege escalation", sub {
$machine->fail("test -e '/root/VirtualBox VMs'");
$machine->fail("test -e '/root/.config/VirtualBox'");
$machine->succeed("test -e '/home/alice/VirtualBox VMs'");
};
});
destroyVM_simple;
sub removeUUIDs {
return join("\n", grep { $_ !~ /^UUID:/ } split(/\n/, $_[0]))."\n";
}
subtest "host-usb-permissions", sub {
my $userUSB = removeUUIDs vbm("list usbhost");
print STDERR $userUSB;
my $rootUSB = removeUUIDs $machine->succeed("VBoxManage list usbhost");
print STDERR $rootUSB;
die "USB host devices differ for root and normal user"
if $userUSB ne $rootUSB;
die "No USB host devices found" if $userUSB =~ /<none>/;
};
subtest "systemd-detect-virt", sub {
createVM_detectvirt;
vbm("startvm detectvirt");
waitForStartup_detectvirt;
waitForVMBoot_detectvirt;
shutdownVM_detectvirt;
my $result = $machine->succeed("cat '$detectvirt_sharepath/result'");
chomp $result;
destroyVM_detectvirt;
die "systemd-detect-virt returned \"$result\" instead of \"oracle\""
if $result ne "oracle";
};
subtest "net-hostonlyif", sub {
createVM_test1;
createVM_test2;
vbm("startvm test1");
waitForStartup_test1;
waitForVMBoot_test1;
vbm("startvm test2");
waitForStartup_test2;
waitForVMBoot_test2;
$machine->screenshot("net_booted");
my $test1IP = waitForIP_test1 1;
my $test2IP = waitForIP_test2 1;
$machine->succeed("echo '$test2IP' | netcat -c '$test1IP' 1234");
$machine->succeed("echo '$test1IP' | netcat -c '$test2IP' 1234");
$machine->waitUntilSucceeds("netcat -c '$test1IP' 5678 >&2");
$machine->waitUntilSucceeds("netcat -c '$test2IP' 5678 >&2");
shutdownVM_test1;
shutdownVM_test2;
destroyVM_test1;
destroyVM_test2;
};
shutdownVM_simple;
'';
}) args
host-usb-permissions = ''
my $userUSB = removeUUIDs vbm("list usbhost");
print STDERR $userUSB;
my $rootUSB = removeUUIDs $machine->succeed("VBoxManage list usbhost");
print STDERR $rootUSB;
die "USB host devices differ for root and normal user"
if $userUSB ne $rootUSB;
die "No USB host devices found" if $userUSB =~ /<none>/;
'';
systemd-detect-virt = ''
createVM_detectvirt;
vbm("startvm detectvirt");
waitForStartup_detectvirt;
waitForVMBoot_detectvirt;
shutdownVM_detectvirt;
my $result = $machine->succeed("cat '$detectvirt_sharepath/result'");
chomp $result;
destroyVM_detectvirt;
die "systemd-detect-virt returned \"$result\" instead of \"oracle\""
if $result ne "oracle";
'';
net-hostonlyif = ''
createVM_test1;
createVM_test2;
vbm("startvm test1");
waitForStartup_test1;
waitForVMBoot_test1;
vbm("startvm test2");
waitForStartup_test2;
waitForVMBoot_test2;
$machine->screenshot("net_booted");
my $test1IP = waitForIP_test1 1;
my $test2IP = waitForIP_test2 1;
$machine->succeed("echo '$test2IP' | netcat -c '$test1IP' 1234");
$machine->succeed("echo '$test1IP' | netcat -c '$test2IP' 1234");
$machine->waitUntilSucceeds("netcat -c '$test1IP' 5678 >&2");
$machine->waitUntilSucceeds("netcat -c '$test2IP' 5678 >&2");
shutdownVM_test1;
shutdownVM_test2;
destroyVM_test1;
destroyVM_test2;
'';
}