Merge pull request #13585 (nixos-tests-splitup)
This splits a few NixOS tests (namely Chromium, VirtualBox and the networking tests) into several subtests that are exposed via attributes. The networking tests were already split up but they didn't expose an attribute set of available tests but used a function attribute to specify the resulting test instead. A new function callSubTests in nixos/release.nix is now responsible for gathering subtests, which is also used for the installer and boot tests. The latter is now placed in a tests.boot.* namespace rather than "polluting" the tests attribute set with its subtest.
This commit is contained in:
commit
f70ec0de69
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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'
|
||||
'';
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
'';
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue