From 5bab623fb93567e9f3217e90c7e2679388ec86a3 Mon Sep 17 00:00:00 2001 From: aszlig Date: Mon, 29 Feb 2016 19:15:36 +0100 Subject: [PATCH 1/6] 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 --- nixos/release.nix | 7 +- nixos/tests/virtualbox.nix | 248 +++++++++++++++++++------------------ 2 files changed, 132 insertions(+), 123 deletions(-) diff --git a/nixos/release.nix b/nixos/release.nix index cfe152cc163..497056c2274 100644 --- a/nixos/release.nix +++ b/nixos/release.nix @@ -299,7 +299,12 @@ 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 = let + testsOnly = filterAttrs (const (t: t ? test)); + vboxTests = testsOnly (import tests/virtualbox.nix { + system = "x86_64-linux"; + }); + in mapAttrs (const (t: hydraJob t.test)) vboxTests; 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); diff --git a/nixos/tests/virtualbox.nix b/nixos/tests/virtualbox.nix index 01fcd15fd8b..da4c0bddc34 100644 --- a/nixos/tests/virtualbox.nix +++ b/nixos/tests/virtualbox.nix @@ -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 =~ //; - }; - - 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 =~ //; + ''; + + 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; + ''; +} From b3337edd0b77f04d0abe4a29642a5e4fdb4ad692 Mon Sep 17 00:00:00 2001 From: aszlig Date: Mon, 29 Feb 2016 20:02:26 +0100 Subject: [PATCH 2/6] 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 Cc: @edolstra --- nixos/release.nix | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/nixos/release.nix b/nixos/release.nix index 497056c2274..76d0ce90458 100644 --- a/nixos/release.nix +++ b/nixos/release.nix @@ -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"; }; From 2f2536b9354b296dbf12343d232e113d211704df Mon Sep 17 00:00:00 2001 From: aszlig Date: Mon, 29 Feb 2016 20:06:55 +0100 Subject: [PATCH 3/6] 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 Cc: @wkennington --- nixos/tests/networking.nix | 799 +++++++++++++++++++------------------ 1 file changed, 402 insertions(+), 397 deletions(-) diff --git a/nixos/tests/networking.nix b/nixos/tests/networking.nix index 813d7c2bf51..d5a0a9b798f 100644 --- a/nixos/tests/networking.nix +++ b/nixos/tests/networking.nix @@ -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 From 7eea91fbc0efc19f416121369f566c6f5363fbc0 Mon Sep 17 00:00:00 2001 From: aszlig Date: Mon, 29 Feb 2016 20:11:04 +0100 Subject: [PATCH 4/6] 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 Cc: @edolstra Cc: @wkennington Cc: @bobvanderlinden --- nixos/release-combined.nix | 2 +- nixos/release.nix | 45 +++++--------------------------------- 2 files changed, 6 insertions(+), 41 deletions(-) diff --git a/nixos/release-combined.nix b/nixos/release-combined.nix index 06890b458ef..b3bef2deb79 100644 --- a/nixos/release-combined.nix +++ b/nixos/release-combined.nix @@ -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.bootBiosCdrom) (all nixos.tests.ipv6) (all nixos.tests.kde4) #(all nixos.tests.lightdm) diff --git a/nixos/release.nix b/nixos/release.nix index 76d0ce90458..eb614ac1103 100644 --- a/nixos/release.nix +++ b/nixos/release.nix @@ -233,6 +233,7 @@ 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.cjdns = callTest tests/cjdns.nix {}; @@ -250,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 {}; @@ -280,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; }; @@ -317,17 +291,8 @@ in rec { tests.simple = callTest tests/simple.nix {}; tests.tomcat = callTest tests/tomcat.nix {}; tests.udisks2 = callTest tests/udisks2.nix {}; - tests.virtualbox = let - testsOnly = filterAttrs (const (t: t ? test)); - vboxTests = testsOnly (import tests/virtualbox.nix { - system = "x86_64-linux"; - }); - in mapAttrs (const (t: hydraJob t.test)) vboxTests; + 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 From e45c211b50c6f473e3d92d29e1a8426ec4579f05 Mon Sep 17 00:00:00 2001 From: aszlig Date: Tue, 1 Mar 2016 00:20:27 +0100 Subject: [PATCH 5/6] 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 69ec09f38aa1f1d37baec73ebdf9cf5f21050f94). Signed-off-by: aszlig --- nixos/release-combined.nix | 2 +- nixos/release.nix | 2 +- nixos/tests/chromium.nix | 133 +++++++++++++++++-------------------- 3 files changed, 63 insertions(+), 74 deletions(-) diff --git a/nixos/release-combined.nix b/nixos/release-combined.nix index b3bef2deb79..69cc357078d 100644 --- a/nixos/release-combined.nix +++ b/nixos/release-combined.nix @@ -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 diff --git a/nixos/release.nix b/nixos/release.nix index eb614ac1103..18e4e2d6b17 100644 --- a/nixos/release.nix +++ b/nixos/release.nix @@ -235,7 +235,7 @@ in rec { 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"; }); diff --git a/nixos/tests/chromium.nix b/nixos/tests/chromium.nix index 6c61087760d..974af6888b6 100644 --- a/nixos/tests/chromium.nix +++ b/nixos/tests/chromium.nix @@ -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" '' @@ -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; +} From 1f89aa6c7f2f16c8c0834cfa65b8484fecd72af3 Mon Sep 17 00:00:00 2001 From: aszlig Date: Tue, 1 Mar 2016 19:02:36 +0100 Subject: [PATCH 6/6] 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 --- nixos/release-combined.nix | 2 +- nixos/tests/boot.nix | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/nixos/release-combined.nix b/nixos/release-combined.nix index 69cc357078d..958e587444d 100644 --- a/nixos/release-combined.nix +++ b/nixos/release-combined.nix @@ -63,7 +63,7 @@ in rec { (all nixos.tests.installer.btrfsSimple) (all nixos.tests.installer.btrfsSubvols) (all nixos.tests.installer.btrfsSubvolDefault) - (all nixos.tests.boot.bootBiosCdrom) + (all nixos.tests.boot.biosCdrom) (all nixos.tests.ipv6) (all nixos.tests.kde4) #(all nixos.tests.lightdm) diff --git a/nixos/tests/boot.nix b/nixos/tests/boot.nix index 6a1d330155e..905d1645882 100644 --- a/nixos/tests/boot.nix +++ b/nixos/tests/boot.nix @@ -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' '';