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.

aszlig f70ec0de afa7d845

+558 -572
+2 -2
nixos/release-combined.nix
··· 48 48 (all nixos.ova) 49 49 50 50 #(all nixos.tests.containers) 51 - (all nixos.tests.chromium) 51 + (all nixos.tests.chromium.stable) 52 52 (all nixos.tests.firefox) 53 53 (all nixos.tests.firewall) 54 54 nixos.tests.gnome3.x86_64-linux # FIXME: i686-linux ··· 63 63 (all nixos.tests.installer.btrfsSimple) 64 64 (all nixos.tests.installer.btrfsSubvols) 65 65 (all nixos.tests.installer.btrfsSubvolDefault) 66 - (all nixos.tests.bootBiosCdrom) 66 + (all nixos.tests.boot.biosCdrom) 67 67 (all nixos.tests.ipv6) 68 68 (all nixos.tests.kde4) 69 69 #(all nixos.tests.lightdm)
+25 -37
nixos/release.nix
··· 13 13 14 14 forAllSystems = genAttrs supportedSystems; 15 15 16 - callTest = fn: args: forAllSystems (system: hydraJob (import fn ({ inherit system; } // args))); 16 + importTest = fn: args: system: import fn ({ 17 + inherit system; 18 + } // args); 19 + 20 + callTest = fn: args: forAllSystems (system: hydraJob (importTest fn args system)); 21 + 22 + callSubTests = fn: args: let 23 + discover = attrs: let 24 + subTests = filterAttrs (const (hasAttr "test")) attrs; 25 + in mapAttrs (const (t: hydraJob t.test)) subTests; 26 + 27 + discoverForSystem = system: mapAttrs (_: test: { 28 + ${system} = test; 29 + }) (discover (importTest fn args system)); 30 + 31 + # If the test is only for a particular system, use only the specified 32 + # system instead of generating attributes for all available systems. 33 + in if args ? system then discover (import fn args) 34 + else foldAttrs (a: b: a // b) {} (map discoverForSystem supportedSystems); 17 35 18 36 pkgs = import nixpkgs { system = "x86_64-linux"; }; 19 37 ··· 215 233 tests.avahi = callTest tests/avahi.nix {}; 216 234 tests.bittorrent = callTest tests/bittorrent.nix {}; 217 235 tests.blivet = callTest tests/blivet.nix {}; 236 + tests.boot = callSubTests tests/boot.nix {}; 218 237 tests.cadvisor = hydraJob (import tests/cadvisor.nix { system = "x86_64-linux"; }); 219 - tests.chromium = callTest tests/chromium.nix {}; 238 + tests.chromium = callSubTests tests/chromium.nix {}; 220 239 tests.cjdns = callTest tests/cjdns.nix {}; 221 240 tests.containers = callTest tests/containers.nix {}; 222 241 tests.docker = hydraJob (import tests/docker.nix { system = "x86_64-linux"; }); ··· 232 251 tests.gnome3-gdm = callTest tests/gnome3-gdm.nix {}; 233 252 tests.grsecurity = callTest tests/grsecurity.nix {}; 234 253 tests.i3wm = callTest tests/i3wm.nix {}; 235 - tests.installer.grub1 = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).grub1.test); 236 - tests.installer.lvm = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).lvm.test); 237 - tests.installer.luksroot = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).luksroot.test); 238 - tests.installer.separateBoot = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).separateBoot.test); 239 - tests.installer.separateBootFat = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).separateBootFat.test); 240 - tests.installer.simple = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).simple.test); 241 - tests.installer.simpleLabels = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).simpleLabels.test); 242 - tests.installer.simpleProvided = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).simpleProvided.test); 243 - tests.installer.swraid = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).swraid.test); 244 - tests.installer.btrfsSimple = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).btrfsSimple.test); 245 - tests.installer.btrfsSubvols = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).btrfsSubvols.test); 246 - tests.installer.btrfsSubvolDefault = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).btrfsSubvolDefault.test); 254 + tests.installer = callSubTests tests/installer.nix {}; 247 255 tests.influxdb = callTest tests/influxdb.nix {}; 248 256 tests.ipv6 = callTest tests/ipv6.nix {}; 249 257 tests.jenkins = callTest tests/jenkins.nix {}; ··· 262 270 tests.mysqlReplication = callTest tests/mysql-replication.nix {}; 263 271 tests.nat.firewall = callTest tests/nat.nix { withFirewall = true; }; 264 272 tests.nat.standalone = callTest tests/nat.nix { withFirewall = false; }; 265 - tests.networking.networkd.loopback = callTest tests/networking.nix { networkd = true; test = "loopback"; }; 266 - tests.networking.networkd.static = callTest tests/networking.nix { networkd = true; test = "static"; }; 267 - tests.networking.networkd.dhcpSimple = callTest tests/networking.nix { networkd = true; test = "dhcpSimple"; }; 268 - tests.networking.networkd.dhcpOneIf = callTest tests/networking.nix { networkd = true; test = "dhcpOneIf"; }; 269 - tests.networking.networkd.bond = callTest tests/networking.nix { networkd = true; test = "bond"; }; 270 - tests.networking.networkd.bridge = callTest tests/networking.nix { networkd = true; test = "bridge"; }; 271 - tests.networking.networkd.macvlan = callTest tests/networking.nix { networkd = true; test = "macvlan"; }; 272 - tests.networking.networkd.sit = callTest tests/networking.nix { networkd = true; test = "sit"; }; 273 - tests.networking.networkd.vlan = callTest tests/networking.nix { networkd = true; test = "vlan"; }; 274 - tests.networking.scripted.loopback = callTest tests/networking.nix { networkd = false; test = "loopback"; }; 275 - tests.networking.scripted.static = callTest tests/networking.nix { networkd = false; test = "static"; }; 276 - tests.networking.scripted.dhcpSimple = callTest tests/networking.nix { networkd = false; test = "dhcpSimple"; }; 277 - tests.networking.scripted.dhcpOneIf = callTest tests/networking.nix { networkd = false; test = "dhcpOneIf"; }; 278 - tests.networking.scripted.bond = callTest tests/networking.nix { networkd = false; test = "bond"; }; 279 - tests.networking.scripted.bridge = callTest tests/networking.nix { networkd = false; test = "bridge"; }; 280 - tests.networking.scripted.macvlan = callTest tests/networking.nix { networkd = false; test = "macvlan"; }; 281 - tests.networking.scripted.sit = callTest tests/networking.nix { networkd = false; test = "sit"; }; 282 - tests.networking.scripted.vlan = callTest tests/networking.nix { networkd = false; test = "vlan"; }; 273 + tests.networking.networkd = callSubTests tests/networking.nix { networkd = true; }; 274 + tests.networking.scripted = callSubTests tests/networking.nix { networkd = false; }; 283 275 # TODO: put in networking.nix after the test becomes more complete 284 276 tests.networkingProxy = callTest tests/networking-proxy.nix {}; 285 277 tests.nfs3 = callTest tests/nfs.nix { version = 3; }; ··· 299 291 tests.simple = callTest tests/simple.nix {}; 300 292 tests.tomcat = callTest tests/tomcat.nix {}; 301 293 tests.udisks2 = callTest tests/udisks2.nix {}; 302 - tests.virtualbox = hydraJob (import tests/virtualbox.nix { system = "x86_64-linux"; }); 294 + tests.virtualbox = callSubTests tests/virtualbox.nix { system = "x86_64-linux"; }; 303 295 tests.xfce = callTest tests/xfce.nix {}; 304 - tests.bootBiosCdrom = forAllSystems (system: hydraJob (import tests/boot.nix { inherit system; }).bootBiosCdrom); 305 - tests.bootBiosUsb = forAllSystems (system: hydraJob (import tests/boot.nix { inherit system; }).bootBiosUsb); 306 - tests.bootUefiCdrom = forAllSystems (system: hydraJob (import tests/boot.nix { inherit system; }).bootUefiCdrom); 307 - tests.bootUefiUsb = forAllSystems (system: hydraJob (import tests/boot.nix { inherit system; }).bootUefiUsb); 308 296 309 297 310 298 /* Build a bunch of typical closures so that Hydra can keep track of
+4 -4
nixos/tests/boot.nix
··· 30 30 ''; 31 31 }; 32 32 in { 33 - bootBiosCdrom = makeBootTest "bios-cdrom" '' 33 + biosCdrom = makeBootTest "bios-cdrom" '' 34 34 cdrom => glob("${iso}/iso/*.iso") 35 35 ''; 36 - bootBiosUsb = makeBootTest "bios-usb" '' 36 + biosUsb = makeBootTest "bios-usb" '' 37 37 usb => glob("${iso}/iso/*.iso") 38 38 ''; 39 - bootUefiCdrom = makeBootTest "uefi-cdrom" '' 39 + uefiCdrom = makeBootTest "uefi-cdrom" '' 40 40 cdrom => glob("${iso}/iso/*.iso"), 41 41 bios => '${pkgs.OVMF}/FV/OVMF.fd' 42 42 ''; 43 - bootUefiUsb = makeBootTest "uefi-usb" '' 43 + uefiUsb = makeBootTest "uefi-usb" '' 44 44 usb => glob("${iso}/iso/*.iso"), 45 45 bios => '${pkgs.OVMF}/FV/OVMF.fd' 46 46 '';
+60 -71
nixos/tests/chromium.nix
··· 1 - import ./make-test.nix ( 2 - { pkgs 3 - , channelMap ? { 4 - stable = pkgs.chromium; 5 - #beta = pkgs.chromiumBeta; 6 - #dev = pkgs.chromiumDev; 7 - } 8 - , ... 9 - }: rec { 10 - name = "chromium"; 1 + { system ? builtins.currentSystem }: 2 + 3 + with import ../lib/testing.nix { inherit system; }; 4 + with pkgs.lib; 5 + 6 + mapAttrs (channel: chromiumPkg: makeTest rec { 7 + name = "chromium-${channel}"; 11 8 meta = with pkgs.stdenv.lib.maintainers; { 12 9 maintainers = [ aszlig ]; 13 10 }; ··· 16 13 17 14 machine.imports = [ ./common/x11.nix ]; 18 15 machine.virtualisation.memorySize = 2047; 16 + machine.environment.systemPackages = [ chromiumPkg ]; 19 17 20 18 startupHTML = pkgs.writeText "chromium-startup.html" '' 21 19 <!DOCTYPE html> ··· 105 103 closeWin; 106 104 } 107 105 108 - sub chromiumTest { 109 - my ($channel, $pkg, $code) = @_; 110 - $machine->waitForX; 106 + $machine->waitForX; 111 107 112 - my $url = "file://${startupHTML}"; 113 - my $args = "--user-data-dir=/tmp/chromium-$channel"; 114 - $machine->execute( 115 - "ulimit -c unlimited; ". 116 - "$pkg/bin/chromium $args \"$url\" & disown" 117 - ); 118 - $machine->waitForText(qr/Type to search or enter a URL to navigate/); 119 - $machine->waitUntilSucceeds("${xdo "check-startup" '' 120 - search --sync --onlyvisible --name "startup done" 121 - # close first start help popup 122 - key -delay 1000 Escape 123 - windowfocus --sync 124 - windowactivate --sync 125 - ''}"); 108 + my $url = "file://${startupHTML}"; 109 + my $args = "--user-data-dir=/tmp/chromium-${channel}"; 110 + $machine->execute( 111 + "ulimit -c unlimited; ". 112 + "chromium $args \"$url\" & disown" 113 + ); 114 + $machine->waitForText(qr/Type to search or enter a URL to navigate/); 115 + $machine->waitUntilSucceeds("${xdo "check-startup" '' 116 + search --sync --onlyvisible --name "startup done" 117 + # close first start help popup 118 + key -delay 1000 Escape 119 + windowfocus --sync 120 + windowactivate --sync 121 + ''}"); 126 122 127 - createAndWaitForNewWin; 128 - $machine->screenshot($channel."_emptywin"); 129 - closeWin; 123 + createAndWaitForNewWin; 124 + $machine->screenshot("empty_windows"); 125 + closeWin; 130 126 131 - $machine->screenshot($channel."_startup_done"); 127 + $machine->screenshot("startup_done"); 132 128 133 - subtest("Chromium $channel", $code); 129 + testNewWin "check sandbox", sub { 130 + $machine->succeed("${xdo "type-url" '' 131 + search --sync --onlyvisible --name "new tab" 132 + windowfocus --sync 133 + type --delay 1000 "chrome://sandbox" 134 + ''}"); 134 135 135 - $machine->shutdown; 136 - } 136 + $machine->succeed("${xdo "submit-url" '' 137 + search --sync --onlyvisible --name "new tab" 138 + windowfocus --sync 139 + key --delay 1000 Return 140 + ''}"); 137 141 138 - for (${let 139 - mkArray = name: pkg: "[\"${name}\", \"${pkg}\"]"; 140 - chanArrays = pkgs.lib.mapAttrsToList mkArray channelMap; 141 - in pkgs.lib.concatStringsSep ", " chanArrays}) { 142 - my ($channel, $pkg) = @$_; 143 - chromiumTest $channel, $pkg, sub { 144 - testNewWin "check sandbox", sub { 145 - $machine->succeed("${xdo "type-url" '' 146 - search --sync --onlyvisible --name "new tab" 147 - windowfocus --sync 148 - type --delay 1000 "chrome://sandbox" 149 - ''}"); 142 + $machine->screenshot("sandbox_info"); 150 143 151 - $machine->succeed("${xdo "submit-url" '' 152 - search --sync --onlyvisible --name "new tab" 153 - windowfocus --sync 154 - key --delay 1000 Return 155 - ''}"); 156 - 157 - $machine->screenshot($channel."_sandbox"); 144 + $machine->succeed("${xdo "submit-url" '' 145 + search --sync --onlyvisible --name "sandbox status" 146 + windowfocus --sync 147 + ''}"); 148 + $machine->succeed("${xdo "submit-url" '' 149 + key --delay 1000 Ctrl+a Ctrl+c 150 + ''}"); 158 151 159 - $machine->succeed("${xdo "submit-url" '' 160 - search --sync --onlyvisible --name "sandbox status" 161 - windowfocus --sync 162 - ''}"); 163 - $machine->succeed("${xdo "submit-url" '' 164 - key --delay 1000 Ctrl+a Ctrl+c 165 - ''}"); 152 + my $clipboard = $machine->succeed("${pkgs.xclip}/bin/xclip -o"); 153 + die "sandbox not working properly: $clipboard" 154 + unless $clipboard =~ /namespace sandbox.*yes/mi 155 + && $clipboard =~ /pid namespaces.*yes/mi 156 + && $clipboard =~ /network namespaces.*yes/mi 157 + && $clipboard =~ /seccomp.*sandbox.*yes/mi 158 + && $clipboard =~ /you are adequately sandboxed/mi; 159 + }; 166 160 167 - my $clipboard = $machine->succeed("${pkgs.xclip}/bin/xclip -o"); 168 - die "sandbox not working properly: $clipboard" 169 - unless $clipboard =~ /namespace sandbox.*yes/mi 170 - && $clipboard =~ /pid namespaces.*yes/mi 171 - && $clipboard =~ /network namespaces.*yes/mi 172 - && $clipboard =~ /seccomp.*sandbox.*yes/mi 173 - && $clipboard =~ /you are adequately sandboxed/mi; 174 - }; 175 - }; 176 - } 161 + $machine->shutdown; 177 162 ''; 178 - }) 163 + }) { 164 + stable = pkgs.chromium; 165 + beta = pkgs.chromiumBeta; 166 + dev = pkgs.chromiumDev; 167 + }
+355 -350
nixos/tests/networking.nix
··· 1 - import ./make-test.nix ({ pkgs, networkd, test, ... }: 2 - let 3 - router = { config, pkgs, ... }: 4 - with pkgs.lib; 5 - let 6 - vlanIfs = range 1 (length config.virtualisation.vlans); 7 - in { 8 - virtualisation.vlans = [ 1 2 3 ]; 1 + { system ? builtins.currentSystem, networkd }: 2 + 3 + with import ../lib/testing.nix { inherit system; }; 4 + with pkgs.lib; 5 + 6 + let 7 + router = { config, pkgs, ... }: 8 + with pkgs.lib; 9 + let 10 + vlanIfs = range 1 (length config.virtualisation.vlans); 11 + in { 12 + virtualisation.vlans = [ 1 2 3 ]; 13 + networking = { 14 + useDHCP = false; 15 + useNetworkd = networkd; 16 + firewall.allowPing = true; 17 + interfaces = mkOverride 0 (listToAttrs (flip map vlanIfs (n: 18 + nameValuePair "eth${toString n}" { 19 + ipAddress = "192.168.${toString n}.1"; 20 + prefixLength = 24; 21 + }))); 22 + }; 23 + services.dhcpd = { 24 + enable = true; 25 + interfaces = map (n: "eth${toString n}") vlanIfs; 26 + extraConfig = '' 27 + option subnet-mask 255.255.255.0; 28 + '' + flip concatMapStrings vlanIfs (n: '' 29 + subnet 192.168.${toString n}.0 netmask 255.255.255.0 { 30 + option broadcast-address 192.168.${toString n}.255; 31 + option routers 192.168.${toString n}.1; 32 + range 192.168.${toString n}.2 192.168.${toString n}.254; 33 + } 34 + ''); 35 + }; 36 + }; 37 + 38 + testCases = { 39 + loopback = { 40 + name = "Loopback"; 41 + machine.networking.useNetworkd = networkd; 42 + testScript = '' 43 + startAll; 44 + $machine->waitForUnit("network-interfaces.target"); 45 + $machine->waitForUnit("network.target"); 46 + $machine->succeed("ip addr show lo | grep -q 'inet 127.0.0.1/8 '"); 47 + $machine->succeed("ip addr show lo | grep -q 'inet6 ::1/128 '"); 48 + ''; 49 + }; 50 + static = { 51 + name = "Static"; 52 + nodes.router = router; 53 + nodes.client = { config, pkgs, ... }: with pkgs.lib; { 54 + virtualisation.vlans = [ 1 2 ]; 9 55 networking = { 10 - useDHCP = false; 11 56 useNetworkd = networkd; 12 57 firewall.allowPing = true; 13 - interfaces = mkOverride 0 (listToAttrs (flip map vlanIfs (n: 14 - nameValuePair "eth${toString n}" { 15 - ipAddress = "192.168.${toString n}.1"; 16 - prefixLength = 24; 17 - }))); 18 - }; 19 - services.dhcpd = { 20 - enable = true; 21 - interfaces = map (n: "eth${toString n}") vlanIfs; 22 - extraConfig = '' 23 - option subnet-mask 255.255.255.0; 24 - '' + flip concatMapStrings vlanIfs (n: '' 25 - subnet 192.168.${toString n}.0 netmask 255.255.255.0 { 26 - option broadcast-address 192.168.${toString n}.255; 27 - option routers 192.168.${toString n}.1; 28 - range 192.168.${toString n}.2 192.168.${toString n}.254; 29 - } 30 - ''); 58 + useDHCP = false; 59 + defaultGateway = "192.168.1.1"; 60 + interfaces.eth1.ip4 = mkOverride 0 [ 61 + { address = "192.168.1.2"; prefixLength = 24; } 62 + { address = "192.168.1.3"; prefixLength = 32; } 63 + { address = "192.168.1.10"; prefixLength = 32; } 64 + ]; 65 + interfaces.eth2.ip4 = mkOverride 0 [ 66 + { address = "192.168.2.2"; prefixLength = 24; } 67 + ]; 31 68 }; 32 69 }; 33 - testCases = { 34 - loopback = { 35 - name = "Loopback"; 36 - machine.networking.useNetworkd = networkd; 37 - testScript = '' 70 + testScript = { nodes, ... }: 71 + '' 38 72 startAll; 39 - $machine->waitForUnit("network-interfaces.target"); 40 - $machine->waitForUnit("network.target"); 41 - $machine->succeed("ip addr show lo | grep -q 'inet 127.0.0.1/8 '"); 42 - $machine->succeed("ip addr show lo | grep -q 'inet6 ::1/128 '"); 43 - ''; 44 - }; 45 - static = { 46 - name = "Static"; 47 - nodes.router = router; 48 - nodes.client = { config, pkgs, ... }: with pkgs.lib; { 49 - virtualisation.vlans = [ 1 2 ]; 50 - networking = { 51 - useNetworkd = networkd; 52 - firewall.allowPing = true; 53 - useDHCP = false; 54 - defaultGateway = "192.168.1.1"; 55 - interfaces.eth1.ip4 = mkOverride 0 [ 56 - { address = "192.168.1.2"; prefixLength = 24; } 57 - { address = "192.168.1.3"; prefixLength = 32; } 58 - { address = "192.168.1.10"; prefixLength = 32; } 59 - ]; 60 - interfaces.eth2.ip4 = mkOverride 0 [ 61 - { address = "192.168.2.2"; prefixLength = 24; } 62 - ]; 63 - }; 64 - }; 65 - testScript = { nodes, ... }: 66 - '' 67 - startAll; 68 73 69 - $client->waitForUnit("network-interfaces.target"); 70 - $client->waitForUnit("network.target"); 71 - $router->waitForUnit("network-interfaces.target"); 72 - $router->waitForUnit("network.target"); 74 + $client->waitForUnit("network-interfaces.target"); 75 + $client->waitForUnit("network.target"); 76 + $router->waitForUnit("network-interfaces.target"); 77 + $router->waitForUnit("network.target"); 73 78 74 - # Make sure dhcpcd is not started 75 - $client->fail("systemctl status dhcpcd.service"); 79 + # Make sure dhcpcd is not started 80 + $client->fail("systemctl status dhcpcd.service"); 76 81 77 - # Test vlan 1 78 - $client->waitUntilSucceeds("ping -c 1 192.168.1.1"); 79 - $client->waitUntilSucceeds("ping -c 1 192.168.1.2"); 80 - $client->waitUntilSucceeds("ping -c 1 192.168.1.3"); 81 - $client->waitUntilSucceeds("ping -c 1 192.168.1.10"); 82 + # Test vlan 1 83 + $client->waitUntilSucceeds("ping -c 1 192.168.1.1"); 84 + $client->waitUntilSucceeds("ping -c 1 192.168.1.2"); 85 + $client->waitUntilSucceeds("ping -c 1 192.168.1.3"); 86 + $client->waitUntilSucceeds("ping -c 1 192.168.1.10"); 82 87 83 - $router->waitUntilSucceeds("ping -c 1 192.168.1.1"); 84 - $router->waitUntilSucceeds("ping -c 1 192.168.1.2"); 85 - $router->waitUntilSucceeds("ping -c 1 192.168.1.3"); 86 - $router->waitUntilSucceeds("ping -c 1 192.168.1.10"); 88 + $router->waitUntilSucceeds("ping -c 1 192.168.1.1"); 89 + $router->waitUntilSucceeds("ping -c 1 192.168.1.2"); 90 + $router->waitUntilSucceeds("ping -c 1 192.168.1.3"); 91 + $router->waitUntilSucceeds("ping -c 1 192.168.1.10"); 87 92 88 - # Test vlan 2 89 - $client->waitUntilSucceeds("ping -c 1 192.168.2.1"); 90 - $client->waitUntilSucceeds("ping -c 1 192.168.2.2"); 93 + # Test vlan 2 94 + $client->waitUntilSucceeds("ping -c 1 192.168.2.1"); 95 + $client->waitUntilSucceeds("ping -c 1 192.168.2.2"); 91 96 92 - $router->waitUntilSucceeds("ping -c 1 192.168.2.1"); 93 - $router->waitUntilSucceeds("ping -c 1 192.168.2.2"); 97 + $router->waitUntilSucceeds("ping -c 1 192.168.2.1"); 98 + $router->waitUntilSucceeds("ping -c 1 192.168.2.2"); 94 99 95 - # Test default gateway 96 - $router->waitUntilSucceeds("ping -c 1 192.168.3.1"); 97 - $client->waitUntilSucceeds("ping -c 1 192.168.3.1"); 98 - ''; 99 - }; 100 - dhcpSimple = { 101 - name = "SimpleDHCP"; 102 - nodes.router = router; 103 - nodes.client = { config, pkgs, ... }: with pkgs.lib; { 104 - virtualisation.vlans = [ 1 2 ]; 105 - networking = { 106 - useNetworkd = networkd; 107 - firewall.allowPing = true; 108 - useDHCP = true; 109 - interfaces.eth1.ip4 = mkOverride 0 [ ]; 110 - interfaces.eth2.ip4 = mkOverride 0 [ ]; 111 - }; 100 + # Test default gateway 101 + $router->waitUntilSucceeds("ping -c 1 192.168.3.1"); 102 + $client->waitUntilSucceeds("ping -c 1 192.168.3.1"); 103 + ''; 104 + }; 105 + dhcpSimple = { 106 + name = "SimpleDHCP"; 107 + nodes.router = router; 108 + nodes.client = { config, pkgs, ... }: with pkgs.lib; { 109 + virtualisation.vlans = [ 1 2 ]; 110 + networking = { 111 + useNetworkd = networkd; 112 + firewall.allowPing = true; 113 + useDHCP = true; 114 + interfaces.eth1.ip4 = mkOverride 0 [ ]; 115 + interfaces.eth2.ip4 = mkOverride 0 [ ]; 112 116 }; 113 - testScript = { nodes, ... }: 114 - '' 115 - startAll; 117 + }; 118 + testScript = { nodes, ... }: 119 + '' 120 + startAll; 116 121 117 - $client->waitForUnit("network-interfaces.target"); 118 - $client->waitForUnit("network.target"); 119 - $router->waitForUnit("network-interfaces.target"); 120 - $router->waitForUnit("network.target"); 122 + $client->waitForUnit("network-interfaces.target"); 123 + $client->waitForUnit("network.target"); 124 + $router->waitForUnit("network-interfaces.target"); 125 + $router->waitForUnit("network.target"); 121 126 122 - # Wait until we have an ip address on each interface 123 - $client->waitUntilSucceeds("ip addr show dev eth1 | grep -q '192.168.1'"); 124 - $client->waitUntilSucceeds("ip addr show dev eth2 | grep -q '192.168.2'"); 127 + # Wait until we have an ip address on each interface 128 + $client->waitUntilSucceeds("ip addr show dev eth1 | grep -q '192.168.1'"); 129 + $client->waitUntilSucceeds("ip addr show dev eth2 | grep -q '192.168.2'"); 125 130 126 - # Test vlan 1 127 - $client->waitUntilSucceeds("ping -c 1 192.168.1.1"); 128 - $client->waitUntilSucceeds("ping -c 1 192.168.1.2"); 131 + # Test vlan 1 132 + $client->waitUntilSucceeds("ping -c 1 192.168.1.1"); 133 + $client->waitUntilSucceeds("ping -c 1 192.168.1.2"); 129 134 130 - $router->waitUntilSucceeds("ping -c 1 192.168.1.1"); 131 - $router->waitUntilSucceeds("ping -c 1 192.168.1.2"); 135 + $router->waitUntilSucceeds("ping -c 1 192.168.1.1"); 136 + $router->waitUntilSucceeds("ping -c 1 192.168.1.2"); 132 137 133 - # Test vlan 2 134 - $client->waitUntilSucceeds("ping -c 1 192.168.2.1"); 135 - $client->waitUntilSucceeds("ping -c 1 192.168.2.2"); 138 + # Test vlan 2 139 + $client->waitUntilSucceeds("ping -c 1 192.168.2.1"); 140 + $client->waitUntilSucceeds("ping -c 1 192.168.2.2"); 136 141 137 - $router->waitUntilSucceeds("ping -c 1 192.168.2.1"); 138 - $router->waitUntilSucceeds("ping -c 1 192.168.2.2"); 139 - ''; 140 - }; 141 - dhcpOneIf = { 142 - name = "OneInterfaceDHCP"; 143 - nodes.router = router; 144 - nodes.client = { config, pkgs, ... }: with pkgs.lib; { 145 - virtualisation.vlans = [ 1 2 ]; 146 - networking = { 147 - useNetworkd = networkd; 148 - firewall.allowPing = true; 149 - useDHCP = false; 150 - interfaces.eth1 = { 151 - ip4 = mkOverride 0 [ ]; 152 - useDHCP = true; 153 - }; 154 - interfaces.eth2.ip4 = mkOverride 0 [ ]; 142 + $router->waitUntilSucceeds("ping -c 1 192.168.2.1"); 143 + $router->waitUntilSucceeds("ping -c 1 192.168.2.2"); 144 + ''; 145 + }; 146 + dhcpOneIf = { 147 + name = "OneInterfaceDHCP"; 148 + nodes.router = router; 149 + nodes.client = { config, pkgs, ... }: with pkgs.lib; { 150 + virtualisation.vlans = [ 1 2 ]; 151 + networking = { 152 + useNetworkd = networkd; 153 + firewall.allowPing = true; 154 + useDHCP = false; 155 + interfaces.eth1 = { 156 + ip4 = mkOverride 0 [ ]; 157 + useDHCP = true; 155 158 }; 159 + interfaces.eth2.ip4 = mkOverride 0 [ ]; 156 160 }; 157 - testScript = { nodes, ... }: 158 - '' 159 - startAll; 161 + }; 162 + testScript = { nodes, ... }: 163 + '' 164 + startAll; 160 165 161 - # Wait for networking to come up 162 - $client->waitForUnit("network-interfaces.target"); 163 - $client->waitForUnit("network.target"); 164 - $router->waitForUnit("network-interfaces.target"); 165 - $router->waitForUnit("network.target"); 166 + # Wait for networking to come up 167 + $client->waitForUnit("network-interfaces.target"); 168 + $client->waitForUnit("network.target"); 169 + $router->waitForUnit("network-interfaces.target"); 170 + $router->waitForUnit("network.target"); 166 171 167 - # Wait until we have an ip address on each interface 168 - $client->waitUntilSucceeds("ip addr show dev eth1 | grep -q '192.168.1'"); 172 + # Wait until we have an ip address on each interface 173 + $client->waitUntilSucceeds("ip addr show dev eth1 | grep -q '192.168.1'"); 169 174 170 - # Test vlan 1 171 - $client->waitUntilSucceeds("ping -c 1 192.168.1.1"); 172 - $client->waitUntilSucceeds("ping -c 1 192.168.1.2"); 175 + # Test vlan 1 176 + $client->waitUntilSucceeds("ping -c 1 192.168.1.1"); 177 + $client->waitUntilSucceeds("ping -c 1 192.168.1.2"); 173 178 174 - $router->waitUntilSucceeds("ping -c 1 192.168.1.1"); 175 - $router->waitUntilSucceeds("ping -c 1 192.168.1.2"); 179 + $router->waitUntilSucceeds("ping -c 1 192.168.1.1"); 180 + $router->waitUntilSucceeds("ping -c 1 192.168.1.2"); 176 181 177 - # Test vlan 2 178 - $client->waitUntilSucceeds("ping -c 1 192.168.2.1"); 179 - $client->fail("ping -c 1 192.168.2.2"); 182 + # Test vlan 2 183 + $client->waitUntilSucceeds("ping -c 1 192.168.2.1"); 184 + $client->fail("ping -c 1 192.168.2.2"); 180 185 181 - $router->waitUntilSucceeds("ping -c 1 192.168.2.1"); 182 - $router->fail("ping -c 1 192.168.2.2"); 183 - ''; 184 - }; 185 - bond = let 186 - node = address: { config, pkgs, ... }: with pkgs.lib; { 187 - virtualisation.vlans = [ 1 2 ]; 188 - networking = { 189 - useNetworkd = networkd; 190 - firewall.allowPing = true; 191 - useDHCP = false; 192 - bonds.bond = { 193 - mode = "balance-rr"; 194 - interfaces = [ "eth1" "eth2" ]; 195 - }; 196 - interfaces.eth1.ip4 = mkOverride 0 [ ]; 197 - interfaces.eth2.ip4 = mkOverride 0 [ ]; 198 - interfaces.bond.ip4 = mkOverride 0 199 - [ { inherit address; prefixLength = 30; } ]; 186 + $router->waitUntilSucceeds("ping -c 1 192.168.2.1"); 187 + $router->fail("ping -c 1 192.168.2.2"); 188 + ''; 189 + }; 190 + bond = let 191 + node = address: { config, pkgs, ... }: with pkgs.lib; { 192 + virtualisation.vlans = [ 1 2 ]; 193 + networking = { 194 + useNetworkd = networkd; 195 + firewall.allowPing = true; 196 + useDHCP = false; 197 + bonds.bond = { 198 + mode = "balance-rr"; 199 + interfaces = [ "eth1" "eth2" ]; 200 200 }; 201 + interfaces.eth1.ip4 = mkOverride 0 [ ]; 202 + interfaces.eth2.ip4 = mkOverride 0 [ ]; 203 + interfaces.bond.ip4 = mkOverride 0 204 + [ { inherit address; prefixLength = 30; } ]; 201 205 }; 202 - in { 203 - name = "Bond"; 204 - nodes.client1 = node "192.168.1.1"; 205 - nodes.client2 = node "192.168.1.2"; 206 - testScript = { nodes, ... }: 207 - '' 208 - startAll; 206 + }; 207 + in { 208 + name = "Bond"; 209 + nodes.client1 = node "192.168.1.1"; 210 + nodes.client2 = node "192.168.1.2"; 211 + testScript = { nodes, ... }: 212 + '' 213 + startAll; 209 214 210 - # Wait for networking to come up 211 - $client1->waitForUnit("network-interfaces.target"); 212 - $client1->waitForUnit("network.target"); 213 - $client2->waitForUnit("network-interfaces.target"); 214 - $client2->waitForUnit("network.target"); 215 + # Wait for networking to come up 216 + $client1->waitForUnit("network-interfaces.target"); 217 + $client1->waitForUnit("network.target"); 218 + $client2->waitForUnit("network-interfaces.target"); 219 + $client2->waitForUnit("network.target"); 215 220 216 - # Test bonding 217 - $client1->waitUntilSucceeds("ping -c 2 192.168.1.1"); 218 - $client1->waitUntilSucceeds("ping -c 2 192.168.1.2"); 221 + # Test bonding 222 + $client1->waitUntilSucceeds("ping -c 2 192.168.1.1"); 223 + $client1->waitUntilSucceeds("ping -c 2 192.168.1.2"); 219 224 220 - $client2->waitUntilSucceeds("ping -c 2 192.168.1.1"); 221 - $client2->waitUntilSucceeds("ping -c 2 192.168.1.2"); 222 - ''; 223 - }; 224 - bridge = let 225 - node = { address, vlan }: { config, pkgs, ... }: with pkgs.lib; { 226 - virtualisation.vlans = [ vlan ]; 227 - networking = { 228 - useNetworkd = networkd; 229 - firewall.allowPing = true; 230 - useDHCP = false; 231 - interfaces.eth1.ip4 = mkOverride 0 232 - [ { inherit address; prefixLength = 24; } ]; 233 - }; 225 + $client2->waitUntilSucceeds("ping -c 2 192.168.1.1"); 226 + $client2->waitUntilSucceeds("ping -c 2 192.168.1.2"); 227 + ''; 228 + }; 229 + bridge = let 230 + node = { address, vlan }: { config, pkgs, ... }: with pkgs.lib; { 231 + virtualisation.vlans = [ vlan ]; 232 + networking = { 233 + useNetworkd = networkd; 234 + firewall.allowPing = true; 235 + useDHCP = false; 236 + interfaces.eth1.ip4 = mkOverride 0 237 + [ { inherit address; prefixLength = 24; } ]; 234 238 }; 235 - in { 236 - name = "Bridge"; 237 - nodes.client1 = node { address = "192.168.1.2"; vlan = 1; }; 238 - nodes.client2 = node { address = "192.168.1.3"; vlan = 2; }; 239 - nodes.router = { config, pkgs, ... }: with pkgs.lib; { 240 - virtualisation.vlans = [ 1 2 ]; 241 - networking = { 242 - useNetworkd = networkd; 243 - firewall.allowPing = true; 244 - useDHCP = false; 245 - bridges.bridge.interfaces = [ "eth1" "eth2" ]; 246 - interfaces.eth1.ip4 = mkOverride 0 [ ]; 247 - interfaces.eth2.ip4 = mkOverride 0 [ ]; 248 - interfaces.bridge.ip4 = mkOverride 0 249 - [ { address = "192.168.1.1"; prefixLength = 24; } ]; 250 - }; 239 + }; 240 + in { 241 + name = "Bridge"; 242 + nodes.client1 = node { address = "192.168.1.2"; vlan = 1; }; 243 + nodes.client2 = node { address = "192.168.1.3"; vlan = 2; }; 244 + nodes.router = { config, pkgs, ... }: with pkgs.lib; { 245 + virtualisation.vlans = [ 1 2 ]; 246 + networking = { 247 + useNetworkd = networkd; 248 + firewall.allowPing = true; 249 + useDHCP = false; 250 + bridges.bridge.interfaces = [ "eth1" "eth2" ]; 251 + interfaces.eth1.ip4 = mkOverride 0 [ ]; 252 + interfaces.eth2.ip4 = mkOverride 0 [ ]; 253 + interfaces.bridge.ip4 = mkOverride 0 254 + [ { address = "192.168.1.1"; prefixLength = 24; } ]; 251 255 }; 252 - testScript = { nodes, ... }: 253 - '' 254 - startAll; 256 + }; 257 + testScript = { nodes, ... }: 258 + '' 259 + startAll; 255 260 256 - # Wait for networking to come up 257 - $client1->waitForUnit("network-interfaces.target"); 258 - $client1->waitForUnit("network.target"); 259 - $client2->waitForUnit("network-interfaces.target"); 260 - $client2->waitForUnit("network.target"); 261 - $router->waitForUnit("network-interfaces.target"); 262 - $router->waitForUnit("network.target"); 261 + # Wait for networking to come up 262 + $client1->waitForUnit("network-interfaces.target"); 263 + $client1->waitForUnit("network.target"); 264 + $client2->waitForUnit("network-interfaces.target"); 265 + $client2->waitForUnit("network.target"); 266 + $router->waitForUnit("network-interfaces.target"); 267 + $router->waitForUnit("network.target"); 263 268 264 - # Test bridging 265 - $client1->waitUntilSucceeds("ping -c 1 192.168.1.1"); 266 - $client1->waitUntilSucceeds("ping -c 1 192.168.1.2"); 267 - $client1->waitUntilSucceeds("ping -c 1 192.168.1.3"); 269 + # Test bridging 270 + $client1->waitUntilSucceeds("ping -c 1 192.168.1.1"); 271 + $client1->waitUntilSucceeds("ping -c 1 192.168.1.2"); 272 + $client1->waitUntilSucceeds("ping -c 1 192.168.1.3"); 268 273 269 - $client2->waitUntilSucceeds("ping -c 1 192.168.1.1"); 270 - $client2->waitUntilSucceeds("ping -c 1 192.168.1.2"); 271 - $client2->waitUntilSucceeds("ping -c 1 192.168.1.3"); 274 + $client2->waitUntilSucceeds("ping -c 1 192.168.1.1"); 275 + $client2->waitUntilSucceeds("ping -c 1 192.168.1.2"); 276 + $client2->waitUntilSucceeds("ping -c 1 192.168.1.3"); 272 277 273 - $router->waitUntilSucceeds("ping -c 1 192.168.1.1"); 274 - $router->waitUntilSucceeds("ping -c 1 192.168.1.2"); 275 - $router->waitUntilSucceeds("ping -c 1 192.168.1.3"); 276 - ''; 277 - }; 278 - macvlan = { 279 - name = "MACVLAN"; 280 - nodes.router = router; 281 - nodes.client = { config, pkgs, ... }: with pkgs.lib; { 282 - virtualisation.vlans = [ 1 ]; 283 - networking = { 284 - useNetworkd = networkd; 285 - firewall.allowPing = true; 286 - useDHCP = true; 287 - macvlans.macvlan.interface = "eth1"; 288 - interfaces.eth1.ip4 = mkOverride 0 [ ]; 289 - }; 278 + $router->waitUntilSucceeds("ping -c 1 192.168.1.1"); 279 + $router->waitUntilSucceeds("ping -c 1 192.168.1.2"); 280 + $router->waitUntilSucceeds("ping -c 1 192.168.1.3"); 281 + ''; 282 + }; 283 + macvlan = { 284 + name = "MACVLAN"; 285 + nodes.router = router; 286 + nodes.client = { config, pkgs, ... }: with pkgs.lib; { 287 + virtualisation.vlans = [ 1 ]; 288 + networking = { 289 + useNetworkd = networkd; 290 + firewall.allowPing = true; 291 + useDHCP = true; 292 + macvlans.macvlan.interface = "eth1"; 293 + interfaces.eth1.ip4 = mkOverride 0 [ ]; 290 294 }; 291 - testScript = { nodes, ... }: 292 - '' 293 - startAll; 295 + }; 296 + testScript = { nodes, ... }: 297 + '' 298 + startAll; 294 299 295 - # Wait for networking to come up 296 - $client->waitForUnit("network-interfaces.target"); 297 - $client->waitForUnit("network.target"); 298 - $router->waitForUnit("network-interfaces.target"); 299 - $router->waitForUnit("network.target"); 300 + # Wait for networking to come up 301 + $client->waitForUnit("network-interfaces.target"); 302 + $client->waitForUnit("network.target"); 303 + $router->waitForUnit("network-interfaces.target"); 304 + $router->waitForUnit("network.target"); 300 305 301 - # Wait until we have an ip address on each interface 302 - $client->waitUntilSucceeds("ip addr show dev eth1 | grep -q '192.168.1'"); 303 - $client->waitUntilSucceeds("ip addr show dev macvlan | grep -q '192.168.1'"); 306 + # Wait until we have an ip address on each interface 307 + $client->waitUntilSucceeds("ip addr show dev eth1 | grep -q '192.168.1'"); 308 + $client->waitUntilSucceeds("ip addr show dev macvlan | grep -q '192.168.1'"); 304 309 305 - # Print diagnosting information 306 - $router->succeed("ip addr >&2"); 307 - $client->succeed("ip addr >&2"); 310 + # Print diagnosting information 311 + $router->succeed("ip addr >&2"); 312 + $client->succeed("ip addr >&2"); 308 313 309 - # Test macvlan creates routable ips 310 - $client->waitUntilSucceeds("ping -c 1 192.168.1.1"); 311 - $client->waitUntilSucceeds("ping -c 1 192.168.1.2"); 312 - $client->waitUntilSucceeds("ping -c 1 192.168.1.3"); 314 + # Test macvlan creates routable ips 315 + $client->waitUntilSucceeds("ping -c 1 192.168.1.1"); 316 + $client->waitUntilSucceeds("ping -c 1 192.168.1.2"); 317 + $client->waitUntilSucceeds("ping -c 1 192.168.1.3"); 313 318 314 - $router->waitUntilSucceeds("ping -c 1 192.168.1.1"); 315 - $router->waitUntilSucceeds("ping -c 1 192.168.1.2"); 316 - $router->waitUntilSucceeds("ping -c 1 192.168.1.3"); 317 - ''; 318 - }; 319 - sit = let 320 - node = { address4, remote, address6 }: { config, pkgs, ... }: with pkgs.lib; { 321 - virtualisation.vlans = [ 1 ]; 322 - networking = { 323 - useNetworkd = networkd; 324 - firewall.enable = false; 325 - useDHCP = false; 326 - sits.sit = { 327 - inherit remote; 328 - local = address4; 329 - dev = "eth1"; 330 - }; 331 - interfaces.eth1.ip4 = mkOverride 0 332 - [ { address = address4; prefixLength = 24; } ]; 333 - interfaces.sit.ip6 = mkOverride 0 334 - [ { address = address6; prefixLength = 64; } ]; 319 + $router->waitUntilSucceeds("ping -c 1 192.168.1.1"); 320 + $router->waitUntilSucceeds("ping -c 1 192.168.1.2"); 321 + $router->waitUntilSucceeds("ping -c 1 192.168.1.3"); 322 + ''; 323 + }; 324 + sit = let 325 + node = { address4, remote, address6 }: { config, pkgs, ... }: with pkgs.lib; { 326 + virtualisation.vlans = [ 1 ]; 327 + networking = { 328 + useNetworkd = networkd; 329 + firewall.enable = false; 330 + useDHCP = false; 331 + sits.sit = { 332 + inherit remote; 333 + local = address4; 334 + dev = "eth1"; 335 335 }; 336 + interfaces.eth1.ip4 = mkOverride 0 337 + [ { address = address4; prefixLength = 24; } ]; 338 + interfaces.sit.ip6 = mkOverride 0 339 + [ { address = address6; prefixLength = 64; } ]; 336 340 }; 337 - in { 338 - name = "Sit"; 339 - nodes.client1 = node { address4 = "192.168.1.1"; remote = "192.168.1.2"; address6 = "fc00::1"; }; 340 - nodes.client2 = node { address4 = "192.168.1.2"; remote = "192.168.1.1"; address6 = "fc00::2"; }; 341 - testScript = { nodes, ... }: 342 - '' 343 - startAll; 341 + }; 342 + in { 343 + name = "Sit"; 344 + nodes.client1 = node { address4 = "192.168.1.1"; remote = "192.168.1.2"; address6 = "fc00::1"; }; 345 + nodes.client2 = node { address4 = "192.168.1.2"; remote = "192.168.1.1"; address6 = "fc00::2"; }; 346 + testScript = { nodes, ... }: 347 + '' 348 + startAll; 344 349 345 - # Wait for networking to be configured 346 - $client1->waitForUnit("network-interfaces.target"); 347 - $client1->waitForUnit("network.target"); 348 - $client2->waitForUnit("network-interfaces.target"); 349 - $client2->waitForUnit("network.target"); 350 + # Wait for networking to be configured 351 + $client1->waitForUnit("network-interfaces.target"); 352 + $client1->waitForUnit("network.target"); 353 + $client2->waitForUnit("network-interfaces.target"); 354 + $client2->waitForUnit("network.target"); 350 355 351 - # Print diagnostic information 352 - $client1->succeed("ip addr >&2"); 353 - $client2->succeed("ip addr >&2"); 356 + # Print diagnostic information 357 + $client1->succeed("ip addr >&2"); 358 + $client2->succeed("ip addr >&2"); 354 359 355 - # Test ipv6 356 - $client1->waitUntilSucceeds("ping6 -c 1 fc00::1"); 357 - $client1->waitUntilSucceeds("ping6 -c 1 fc00::2"); 360 + # Test ipv6 361 + $client1->waitUntilSucceeds("ping6 -c 1 fc00::1"); 362 + $client1->waitUntilSucceeds("ping6 -c 1 fc00::2"); 358 363 359 - $client2->waitUntilSucceeds("ping6 -c 1 fc00::1"); 360 - $client2->waitUntilSucceeds("ping6 -c 1 fc00::2"); 361 - ''; 362 - }; 363 - vlan = let 364 - node = address: { config, pkgs, ... }: with pkgs.lib; { 365 - #virtualisation.vlans = [ 1 ]; 366 - networking = { 367 - useNetworkd = networkd; 368 - firewall.allowPing = true; 369 - useDHCP = false; 370 - vlans.vlan = { 371 - id = 1; 372 - interface = "eth0"; 373 - }; 374 - interfaces.eth0.ip4 = mkOverride 0 [ ]; 375 - interfaces.eth1.ip4 = mkOverride 0 [ ]; 376 - interfaces.vlan.ip4 = mkOverride 0 377 - [ { inherit address; prefixLength = 24; } ]; 364 + $client2->waitUntilSucceeds("ping6 -c 1 fc00::1"); 365 + $client2->waitUntilSucceeds("ping6 -c 1 fc00::2"); 366 + ''; 367 + }; 368 + vlan = let 369 + node = address: { config, pkgs, ... }: with pkgs.lib; { 370 + #virtualisation.vlans = [ 1 ]; 371 + networking = { 372 + useNetworkd = networkd; 373 + firewall.allowPing = true; 374 + useDHCP = false; 375 + vlans.vlan = { 376 + id = 1; 377 + interface = "eth0"; 378 378 }; 379 + interfaces.eth0.ip4 = mkOverride 0 [ ]; 380 + interfaces.eth1.ip4 = mkOverride 0 [ ]; 381 + interfaces.vlan.ip4 = mkOverride 0 382 + [ { inherit address; prefixLength = 24; } ]; 379 383 }; 380 - in { 381 - name = "vlan"; 382 - nodes.client1 = node "192.168.1.1"; 383 - nodes.client2 = node "192.168.1.2"; 384 - testScript = { nodes, ... }: 385 - '' 386 - startAll; 384 + }; 385 + in { 386 + name = "vlan"; 387 + nodes.client1 = node "192.168.1.1"; 388 + nodes.client2 = node "192.168.1.2"; 389 + testScript = { nodes, ... }: 390 + '' 391 + startAll; 387 392 388 - # Wait for networking to be configured 389 - $client1->waitForUnit("network-interfaces.target"); 390 - $client1->waitForUnit("network.target"); 391 - $client2->waitForUnit("network-interfaces.target"); 392 - $client2->waitForUnit("network.target"); 393 + # Wait for networking to be configured 394 + $client1->waitForUnit("network-interfaces.target"); 395 + $client1->waitForUnit("network.target"); 396 + $client2->waitForUnit("network-interfaces.target"); 397 + $client2->waitForUnit("network.target"); 393 398 394 - # Test vlan is setup 395 - $client1->succeed("ip addr show dev vlan >&2"); 396 - $client2->succeed("ip addr show dev vlan >&2"); 397 - ''; 398 - }; 399 - }; 400 - case = testCases.${test}; 401 - in case // { 402 - name = "${case.name}-Networking-${if networkd then "Networkd" else "Scripted"}"; 403 - meta = with pkgs.stdenv.lib.maintainers; { 404 - maintainers = [ wkennington ]; 399 + # Test vlan is setup 400 + $client1->succeed("ip addr show dev vlan >&2"); 401 + $client2->succeed("ip addr show dev vlan >&2"); 402 + ''; 405 403 }; 406 - }) 404 + }; 405 + 406 + in mapAttrs (const (attrs: makeTest (attrs // { 407 + name = "${attrs.name}-Networking-${if networkd then "Networkd" else "Scripted"}"; 408 + meta = with pkgs.stdenv.lib.maintainers; { 409 + maintainers = [ wkennington ]; 410 + }; 411 + }))) testCases
+112 -108
nixos/tests/virtualbox.nix
··· 1 - { debug ? false, ... } @ args: 1 + { system ? builtins.currentSystem, debug ? false }: 2 2 3 - import ./make-test.nix ({ pkgs, ... }: with pkgs.lib; let 3 + with import ../lib/testing.nix { inherit system; }; 4 + with pkgs.lib; 4 5 6 + let 5 7 testVMConfig = vmName: attrs: { config, pkgs, ... }: let 6 8 guestAdditions = pkgs.linuxPackages.virtualboxGuestAdditions; 7 9 ··· 314 316 test2.vmScript = dhcpScript; 315 317 }; 316 318 317 - in { 318 - name = "virtualbox"; 319 - meta = with pkgs.stdenv.lib.maintainers; { 320 - maintainers = [ aszlig wkennington ]; 321 - }; 319 + mkVBoxTest = name: testScript: makeTest { 320 + name = "virtualbox-${name}"; 322 321 323 - machine = { pkgs, lib, config, ... }: { 324 - imports = let 325 - mkVMConf = name: val: val.machine // { key = "${name}-config"; }; 326 - vmConfigs = mapAttrsToList mkVMConf vboxVMs; 327 - in [ ./common/user-account.nix ./common/x11.nix ] ++ vmConfigs; 328 - virtualisation.memorySize = 2048; 329 - virtualisation.virtualbox.host.enable = true; 330 - users.extraUsers.alice.extraGroups = let 331 - inherit (config.virtualisation.virtualbox.host) enableHardening; 332 - in lib.mkIf enableHardening (lib.singleton "vboxusers"); 333 - }; 322 + machine = { lib, config, ... }: { 323 + imports = let 324 + mkVMConf = name: val: val.machine // { key = "${name}-config"; }; 325 + vmConfigs = mapAttrsToList mkVMConf vboxVMs; 326 + in [ ./common/user-account.nix ./common/x11.nix ] ++ vmConfigs; 327 + virtualisation.memorySize = 2048; 328 + virtualisation.virtualbox.host.enable = true; 329 + users.extraUsers.alice.extraGroups = let 330 + inherit (config.virtualisation.virtualbox.host) enableHardening; 331 + in lib.mkIf enableHardening (lib.singleton "vboxusers"); 332 + }; 334 333 335 - testScript = '' 336 - sub ru ($) { 337 - my $esc = $_[0] =~ s/'/'\\${"'"}'/gr; 338 - return "su - alice -c '$esc'"; 339 - } 334 + testScript = '' 335 + sub ru ($) { 336 + my $esc = $_[0] =~ s/'/'\\${"'"}'/gr; 337 + return "su - alice -c '$esc'"; 338 + } 339 + 340 + sub vbm { 341 + $machine->succeed(ru("VBoxManage ".$_[0])); 342 + }; 340 343 341 - sub vbm { 342 - $machine->succeed(ru("VBoxManage ".$_[0])); 343 - }; 344 + sub removeUUIDs { 345 + return join("\n", grep { $_ !~ /^UUID:/ } split(/\n/, $_[0]))."\n"; 346 + } 344 347 345 - ${concatStrings (mapAttrsToList (_: getAttr "testSubs") vboxVMs)} 348 + ${concatStrings (mapAttrsToList (_: getAttr "testSubs") vboxVMs)} 346 349 347 - $machine->waitForX; 350 + $machine->waitForX; 348 351 349 - ${mkLog "$HOME/.config/VirtualBox/VBoxSVC.log" "HOST-SVC"} 352 + ${mkLog "$HOME/.config/VirtualBox/VBoxSVC.log" "HOST-SVC"} 350 353 351 - createVM_simple; 354 + ${testScript} 355 + ''; 352 356 353 - subtest "simple-gui", sub { 354 - $machine->succeed(ru "VirtualBox &"); 355 - $machine->waitForWindow(qr/Oracle VM VirtualBox Manager/); 356 - $machine->sleep(5); 357 - $machine->screenshot("gui_manager_started"); 358 - $machine->sendKeys("ret"); 359 - $machine->screenshot("gui_manager_sent_startup"); 360 - waitForStartup_simple (sub { 361 - $machine->sendKeys("ret"); 362 - }); 363 - $machine->screenshot("gui_started"); 364 - waitForVMBoot_simple; 365 - $machine->screenshot("gui_booted"); 366 - shutdownVM_simple; 367 - $machine->sleep(5); 368 - $machine->screenshot("gui_stopped"); 369 - $machine->sendKeys("ctrl-q"); 370 - $machine->sleep(5); 371 - $machine->screenshot("gui_manager_stopped"); 357 + meta = with pkgs.stdenv.lib.maintainers; { 358 + maintainers = [ aszlig wkennington ]; 372 359 }; 360 + }; 373 361 374 - cleanup_simple; 362 + in mapAttrs mkVBoxTest { 363 + simple-gui = '' 364 + createVM_simple; 365 + $machine->succeed(ru "VirtualBox &"); 366 + $machine->waitForWindow(qr/Oracle VM VirtualBox Manager/); 367 + $machine->sleep(5); 368 + $machine->screenshot("gui_manager_started"); 369 + $machine->sendKeys("ret"); 370 + $machine->screenshot("gui_manager_sent_startup"); 371 + waitForStartup_simple (sub { 372 + $machine->sendKeys("ret"); 373 + }); 374 + $machine->screenshot("gui_started"); 375 + waitForVMBoot_simple; 376 + $machine->screenshot("gui_booted"); 377 + shutdownVM_simple; 378 + $machine->sleep(5); 379 + $machine->screenshot("gui_stopped"); 380 + $machine->sendKeys("ctrl-q"); 381 + $machine->sleep(5); 382 + $machine->screenshot("gui_manager_stopped"); 383 + ''; 375 384 376 - subtest "simple-cli", sub { 377 - vbm("startvm simple"); 378 - waitForStartup_simple; 379 - $machine->screenshot("cli_started"); 380 - waitForVMBoot_simple; 381 - $machine->screenshot("cli_booted"); 382 - shutdownVM_simple; 383 - }; 385 + simple-cli = '' 386 + createVM_simple; 387 + vbm("startvm simple"); 388 + waitForStartup_simple; 389 + $machine->screenshot("cli_started"); 390 + waitForVMBoot_simple; 391 + $machine->screenshot("cli_booted"); 384 392 385 - subtest "privilege-escalation", sub { 393 + $machine->nest("Checking for privilege escalation", sub { 386 394 $machine->fail("test -e '/root/VirtualBox VMs'"); 387 395 $machine->fail("test -e '/root/.config/VirtualBox'"); 388 396 $machine->succeed("test -e '/home/alice/VirtualBox VMs'"); 389 - }; 397 + }); 390 398 391 - destroyVM_simple; 399 + shutdownVM_simple; 400 + ''; 392 401 393 - sub removeUUIDs { 394 - return join("\n", grep { $_ !~ /^UUID:/ } split(/\n/, $_[0]))."\n"; 395 - } 402 + host-usb-permissions = '' 403 + my $userUSB = removeUUIDs vbm("list usbhost"); 404 + print STDERR $userUSB; 405 + my $rootUSB = removeUUIDs $machine->succeed("VBoxManage list usbhost"); 406 + print STDERR $rootUSB; 396 407 397 - subtest "host-usb-permissions", sub { 398 - my $userUSB = removeUUIDs vbm("list usbhost"); 399 - print STDERR $userUSB; 400 - my $rootUSB = removeUUIDs $machine->succeed("VBoxManage list usbhost"); 401 - print STDERR $rootUSB; 408 + die "USB host devices differ for root and normal user" 409 + if $userUSB ne $rootUSB; 410 + die "No USB host devices found" if $userUSB =~ /<none>/; 411 + ''; 402 412 403 - die "USB host devices differ for root and normal user" 404 - if $userUSB ne $rootUSB; 405 - die "No USB host devices found" if $userUSB =~ /<none>/; 406 - }; 413 + systemd-detect-virt = '' 414 + createVM_detectvirt; 415 + vbm("startvm detectvirt"); 416 + waitForStartup_detectvirt; 417 + waitForVMBoot_detectvirt; 418 + shutdownVM_detectvirt; 419 + my $result = $machine->succeed("cat '$detectvirt_sharepath/result'"); 420 + chomp $result; 421 + destroyVM_detectvirt; 422 + die "systemd-detect-virt returned \"$result\" instead of \"oracle\"" 423 + if $result ne "oracle"; 424 + ''; 407 425 408 - subtest "systemd-detect-virt", sub { 409 - createVM_detectvirt; 410 - vbm("startvm detectvirt"); 411 - waitForStartup_detectvirt; 412 - waitForVMBoot_detectvirt; 413 - shutdownVM_detectvirt; 414 - my $result = $machine->succeed("cat '$detectvirt_sharepath/result'"); 415 - chomp $result; 416 - destroyVM_detectvirt; 417 - die "systemd-detect-virt returned \"$result\" instead of \"oracle\"" 418 - if $result ne "oracle"; 419 - }; 426 + net-hostonlyif = '' 427 + createVM_test1; 428 + createVM_test2; 420 429 421 - subtest "net-hostonlyif", sub { 422 - createVM_test1; 423 - createVM_test2; 430 + vbm("startvm test1"); 431 + waitForStartup_test1; 432 + waitForVMBoot_test1; 424 433 425 - vbm("startvm test1"); 426 - waitForStartup_test1; 427 - waitForVMBoot_test1; 434 + vbm("startvm test2"); 435 + waitForStartup_test2; 436 + waitForVMBoot_test2; 428 437 429 - vbm("startvm test2"); 430 - waitForStartup_test2; 431 - waitForVMBoot_test2; 438 + $machine->screenshot("net_booted"); 432 439 433 - $machine->screenshot("net_booted"); 440 + my $test1IP = waitForIP_test1 1; 441 + my $test2IP = waitForIP_test2 1; 434 442 435 - my $test1IP = waitForIP_test1 1; 436 - my $test2IP = waitForIP_test2 1; 443 + $machine->succeed("echo '$test2IP' | netcat -c '$test1IP' 1234"); 444 + $machine->succeed("echo '$test1IP' | netcat -c '$test2IP' 1234"); 437 445 438 - $machine->succeed("echo '$test2IP' | netcat -c '$test1IP' 1234"); 439 - $machine->succeed("echo '$test1IP' | netcat -c '$test2IP' 1234"); 440 - 441 - $machine->waitUntilSucceeds("netcat -c '$test1IP' 5678 >&2"); 442 - $machine->waitUntilSucceeds("netcat -c '$test2IP' 5678 >&2"); 446 + $machine->waitUntilSucceeds("netcat -c '$test1IP' 5678 >&2"); 447 + $machine->waitUntilSucceeds("netcat -c '$test2IP' 5678 >&2"); 443 448 444 - shutdownVM_test1; 445 - shutdownVM_test2; 449 + shutdownVM_test1; 450 + shutdownVM_test2; 446 451 447 - destroyVM_test1; 448 - destroyVM_test2; 449 - }; 452 + destroyVM_test1; 453 + destroyVM_test2; 450 454 ''; 451 - }) args 455 + }