diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index f129a36e139e..6bca5f110fd2 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -1086,7 +1086,7 @@ in { without-nix = handleTest ./without-nix.nix {}; wmderland = handleTest ./wmderland.nix {}; workout-tracker = handleTest ./workout-tracker.nix {}; - wpa_supplicant = handleTest ./wpa_supplicant.nix {}; + wpa_supplicant = import ./wpa_supplicant.nix { inherit pkgs runTest; }; wordpress = handleTest ./wordpress.nix {}; wrappers = handleTest ./wrappers.nix {}; writefreely = handleTest ./web-apps/writefreely.nix {}; diff --git a/nixos/tests/wpa_supplicant.nix b/nixos/tests/wpa_supplicant.nix index 51b3396329fc..808e39b03644 100644 --- a/nixos/tests/wpa_supplicant.nix +++ b/nixos/tests/wpa_supplicant.nix @@ -1,17 +1,18 @@ -import ./make-test-python.nix ({ pkgs, lib, ...}: -{ - name = "wpa_supplicant"; +{ pkgs, runTest }: + +let + + inherit (pkgs) lib; + meta = with lib.maintainers; { maintainers = [ oddlama rnhmjoj ]; }; - nodes = let - machineWithHostapd = extraConfigModule: { ... }: { - imports = [ - ../modules/profiles/minimal.nix - extraConfigModule - ]; + runConnectionTest = name: extraConfig: runTest { + name = "wpa_supplicant-${name}"; + inherit meta; + nodes.machine = { # add a virtual wlan interface boot.kernelModules = [ "mac80211_hwsim" ]; @@ -53,27 +54,49 @@ import ./make-test-python.nix ({ pkgs, lib, ...}: }; # wireless client - networking.wireless = { - # the override is needed because the wifi is - # disabled with mkVMOverride in qemu-vm.nix. - enable = lib.mkOverride 0 true; - userControlled.enable = true; - interfaces = [ "wlan1" ]; - fallbackToWPA2 = lib.mkDefault true; + networking.wireless = lib.mkMerge [ + { + # the override is needed because the wifi is + # disabled with mkVMOverride in qemu-vm.nix. + enable = lib.mkOverride 0 true; + userControlled.enable = true; + interfaces = [ "wlan1" ]; + fallbackToWPA2 = lib.mkDefault true; - # networks will be added on-demand below for the specific - # network that should be tested - - # secrets - secretsFile = pkgs.writeText "wpa-secrets" '' - psk_nixos_test="reproducibility" - ''; - }; + # secrets + secretsFile = pkgs.writeText "wpa-secrets" '' + psk_nixos_test=reproducibility + ''; + } + extraConfig + ]; }; - in { - basic = { ... }: { - imports = [ ../modules/profiles/minimal.nix ]; + testScript = '' + # save hostapd config file for manual inspection + machine.wait_for_unit("hostapd.service") + machine.copy_from_vm("/run/hostapd/wlan0.hostapd.conf") + + with subtest("Daemon can connect to the access point"): + machine.wait_for_unit("wpa_supplicant-wlan1.service") + machine.wait_until_succeeds( + "wpa_cli -i wlan1 status | grep -q wpa_state=COMPLETED" + ) + ''; + }; + +in + +{ + # Test the basic setup: + # - automatic interface discovery + # - WPA2 fallbacks + # - connecting to the daemon + basic = runTest { + name = "wpa_supplicant-basic"; + inherit meta; + + nodes.machine = { # add a virtual wlan interface boot.kernelModules = [ "mac80211_hwsim" ]; @@ -83,7 +106,6 @@ import ./make-test-python.nix ({ pkgs, lib, ...}: # disabled with mkVMOverride in qemu-vm.nix. enable = lib.mkOverride 0 true; userControlled.enable = true; - interfaces = [ "wlan1" ]; fallbackToWPA2 = true; networks = { @@ -100,9 +122,32 @@ import ./make-test-python.nix ({ pkgs, lib, ...}: }; }; - imperative = { ... }: { - imports = [ ../modules/profiles/minimal.nix ]; + testScript = '' + with subtest("Daemon is running and accepting connections"): + machine.wait_for_unit("wpa_supplicant.service") + status = machine.wait_until_succeeds("wpa_cli status") + assert "Failed to connect" not in status, \ + "Failed to connect to the daemon" + # get the configuration file + cmdline = machine.succeed("cat /proc/$(pgrep wpa)/cmdline").split('\x00') + config_file = cmdline[cmdline.index("-c") + 1] + + with subtest("WPA2 fallbacks have been generated"): + assert int(machine.succeed(f"grep -c sae-only {config_file}")) == 1 + assert int(machine.succeed(f"grep -c mixed-wpa {config_file}")) == 2 + + # save file for manual inspection + machine.copy_from_vm(config_file) + ''; + }; + + # Test configuring the daemon imperatively + imperative = runTest { + name = "wpa_supplicant-imperative"; + inherit meta; + + nodes.machine = { # add a virtual wlan interface boot.kernelModules = [ "mac80211_hwsim" ]; @@ -115,99 +160,55 @@ import ./make-test-python.nix ({ pkgs, lib, ...}: }; }; - # Test connecting to the SAE-only hotspot using SAE - machineSae = machineWithHostapd { - networking.wireless = { - fallbackToWPA2 = false; - networks.nixos-test-sae = { - pskRaw = "ext:psk_nixos_test"; - authProtocols = [ "SAE" ]; - }; - }; - }; - - # Test connecting to the SAE and WPA2 mixed hotspot using SAE - machineMixedUsingSae = machineWithHostapd { - networking.wireless = { - fallbackToWPA2 = false; - networks.nixos-test-mixed = { - pskRaw = "ext:psk_nixos_test"; - authProtocols = [ "SAE" ]; - }; - }; - }; - - # Test connecting to the SAE and WPA2 mixed hotspot using WPA2 - machineMixedUsingWpa2 = machineWithHostapd { - networking.wireless = { - fallbackToWPA2 = true; - networks.nixos-test-mixed = { - pskRaw = "ext:psk_nixos_test"; - authProtocols = [ "WPA-PSK-SHA256" ]; - }; - }; - }; - - # Test connecting to the WPA2 legacy hotspot using WPA2 - machineWpa2 = machineWithHostapd { - networking.wireless = { - fallbackToWPA2 = true; - networks.nixos-test-wpa2 = { - pskRaw = "ext:psk_nixos_test"; - authProtocols = [ "WPA-PSK-SHA256" ]; - }; - }; - }; - }; - - testScript = - '' - # get the configuration file - basic.wait_for_unit("wpa_supplicant-wlan1.service") - cmdline = basic.succeed("cat /proc/$(pgrep wpa)/cmdline").split('\x00') - config_file = cmdline[cmdline.index("-c") + 1] - - with subtest("WPA2 fallbacks have been generated"): - assert int(basic.succeed(f"grep -c sae-only {config_file}")) == 1 - assert int(basic.succeed(f"grep -c mixed-wpa {config_file}")) == 2 - - # save file for manual inspection - basic.copy_from_vm(config_file) - + testScript = '' with subtest("Daemon is running and accepting connections"): - basic.wait_for_unit("wpa_supplicant-wlan1.service") - status = basic.succeed("wpa_cli -i wlan1 status") + machine.wait_for_unit("wpa_supplicant-wlan1.service") + status = machine.wait_until_succeeds("wpa_cli -i wlan1 status") assert "Failed to connect" not in status, \ "Failed to connect to the daemon" with subtest("Daemon can be configured imperatively"): - imperative.wait_until_succeeds("wpa_cli -i wlan1 status") - imperative.succeed("wpa_cli -i wlan1 add_network") - imperative.succeed("wpa_cli -i wlan1 set_network 0 ssid '\"nixos-test\"'") - imperative.succeed("wpa_cli -i wlan1 set_network 0 psk '\"reproducibility\"'") - imperative.succeed("wpa_cli -i wlan1 save_config") - imperative.succeed("grep -q nixos-test /etc/wpa_supplicant.conf") - - machineSae.wait_for_unit("hostapd.service") - machineSae.copy_from_vm("/run/hostapd/wlan0.hostapd.conf") - with subtest("Daemon can connect to the SAE access point using SAE"): - machineSae.wait_until_succeeds( - "wpa_cli -i wlan1 status | grep -q wpa_state=COMPLETED" - ) - - with subtest("Daemon can connect to the SAE and WPA2 mixed access point using SAE"): - machineMixedUsingSae.wait_until_succeeds( - "wpa_cli -i wlan1 status | grep -q wpa_state=COMPLETED" - ) - - with subtest("Daemon can connect to the SAE and WPA2 mixed access point using WPA2"): - machineMixedUsingWpa2.wait_until_succeeds( - "wpa_cli -i wlan1 status | grep -q wpa_state=COMPLETED" - ) - - with subtest("Daemon can connect to the WPA2 access point using WPA2"): - machineWpa2.wait_until_succeeds( - "wpa_cli -i wlan1 status | grep -q wpa_state=COMPLETED" - ) + machine.succeed("wpa_cli -i wlan1 add_network") + machine.succeed("wpa_cli -i wlan1 set_network 0 ssid '\"nixos-test\"'") + machine.succeed("wpa_cli -i wlan1 set_network 0 psk '\"reproducibility\"'") + machine.succeed("wpa_cli -i wlan1 save_config") + machine.succeed("grep -q nixos-test /etc/wpa_supplicant.conf") ''; -}) + }; + + # Test connecting to a SAE-only hotspot using SAE + saeOnly = runConnectionTest "sae-only" { + fallbackToWPA2 = false; + networks.nixos-test-sae = { + pskRaw = "ext:psk_nixos_test"; + authProtocols = [ "SAE" ]; + }; + }; + + # Test connecting to a mixed SAE/WPA2 hotspot using SAE + mixedUsingSae = runConnectionTest "mixed-using-sae" { + fallbackToWPA2 = false; + networks.nixos-test-mixed = { + pskRaw = "ext:psk_nixos_test"; + authProtocols = [ "SAE" ]; + }; + }; + + # Test connecting to a mixed SAE/WPA2 hotspot using WPA2 + mixedUsingWpa2 = runConnectionTest "mixed-using-wpa2" { + fallbackToWPA2 = true; + networks.nixos-test-mixed = { + pskRaw = "ext:psk_nixos_test"; + authProtocols = [ "WPA-PSK-SHA256" ]; + }; + }; + + # Test connecting to a legacy WPA2-only hotspot using WPA2 + legacy = runConnectionTest "legacy" { + fallbackToWPA2 = true; + networks.nixos-test-wpa2 = { + pskRaw = "ext:psk_nixos_test"; + authProtocols = [ "WPA-PSK-SHA256" ]; + }; + }; +}