diff options
author | Alyssa Ross <hi@alyssa.is> | 2022-12-06 19:57:55 +0000 |
---|---|---|
committer | Alyssa Ross <hi@alyssa.is> | 2023-02-08 13:48:30 +0000 |
commit | bf3aadfdd39aa197e18bade671fab6726349ffa4 (patch) | |
tree | 698567af766ed441d757b57a7b21e68d4a342a2b /nixpkgs/nixos/tests | |
parent | f4afc5a01d9539ce09e47494e679c51f80723d07 (diff) | |
parent | 99665eb45f58d959d2cb9e49ddb960c79d596f33 (diff) | |
download | nixlib-bf3aadfdd39aa197e18bade671fab6726349ffa4.tar nixlib-bf3aadfdd39aa197e18bade671fab6726349ffa4.tar.gz nixlib-bf3aadfdd39aa197e18bade671fab6726349ffa4.tar.bz2 nixlib-bf3aadfdd39aa197e18bade671fab6726349ffa4.tar.lz nixlib-bf3aadfdd39aa197e18bade671fab6726349ffa4.tar.xz nixlib-bf3aadfdd39aa197e18bade671fab6726349ffa4.tar.zst nixlib-bf3aadfdd39aa197e18bade671fab6726349ffa4.zip |
Merge commit '99665eb45f58d959d2cb9e49ddb960c79d596f33'
Diffstat (limited to 'nixpkgs/nixos/tests')
385 files changed, 5425 insertions, 1480 deletions
diff --git a/nixpkgs/nixos/tests/3proxy.nix b/nixpkgs/nixos/tests/3proxy.nix index dfc4b35a772d..8127438fabd9 100644 --- a/nixpkgs/nixos/tests/3proxy.nix +++ b/nixpkgs/nixos/tests/3proxy.nix @@ -139,7 +139,7 @@ import ./make-test-python.nix ({ pkgs, ...} : { peer0.wait_for_unit("network-online.target") peer1.wait_for_unit("3proxy.service") - peer1.wait_for_open_port("9999") + peer1.wait_for_open_port(9999) # test none auth peer0.succeed( @@ -153,7 +153,7 @@ import ./make-test-python.nix ({ pkgs, ...} : { ) peer2.wait_for_unit("3proxy.service") - peer2.wait_for_open_port("9999") + peer2.wait_for_open_port(9999) # test iponly auth peer0.succeed( @@ -167,7 +167,7 @@ import ./make-test-python.nix ({ pkgs, ...} : { ) peer3.wait_for_unit("3proxy.service") - peer3.wait_for_open_port("9999") + peer3.wait_for_open_port(9999) # test strong auth peer0.succeed( diff --git a/nixpkgs/nixos/tests/acme.nix b/nixpkgs/nixos/tests/acme.nix index 2dd06a50f40b..c07f99c5db3a 100644 --- a/nixpkgs/nixos/tests/acme.nix +++ b/nixpkgs/nixos/tests/acme.nix @@ -578,7 +578,7 @@ in { webserver.wait_for_unit(f"acme-finished-{test_domain}.target") wait_for_server() check_connection(client, test_domain) - rc, _ = client.execute( + rc, _s = client.execute( f"openssl s_client -CAfile /tmp/ca.crt -connect {test_alias}:443" " </dev/null 2>/dev/null | openssl x509 -noout -text" f" | grep DNS: | grep {test_alias}" diff --git a/nixpkgs/nixos/tests/aesmd.nix b/nixpkgs/nixos/tests/aesmd.nix index 59c04fe7e96a..9f07426be8d8 100644 --- a/nixpkgs/nixos/tests/aesmd.nix +++ b/nixpkgs/nixos/tests/aesmd.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { maintainers = with lib.maintainers; [ veehaitch ]; }; - machine = { lib, ... }: { + nodes.machine = { lib, ... }: { services.aesmd = { enable = true; settings = { diff --git a/nixpkgs/nixos/tests/agda.nix b/nixpkgs/nixos/tests/agda.nix index ec61af2afe75..6f51300111ac 100644 --- a/nixpkgs/nixos/tests/agda.nix +++ b/nixpkgs/nixos/tests/agda.nix @@ -15,7 +15,7 @@ in maintainers = [ alexarice turion ]; }; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { environment.systemPackages = [ (pkgs.agda.withPackages { pkgs = p: [ p.standard-library ]; diff --git a/nixpkgs/nixos/tests/airsonic.nix b/nixpkgs/nixos/tests/airsonic.nix index d8df092c2ecf..69f979726bce 100644 --- a/nixpkgs/nixos/tests/airsonic.nix +++ b/nixpkgs/nixos/tests/airsonic.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { maintainers = [ sumnerevans ]; }; - machine = + nodes.machine = { pkgs, ... }: { services.airsonic = { @@ -15,7 +15,8 @@ import ./make-test-python.nix ({ pkgs, ... }: { testScript = '' def airsonic_is_up(_) -> bool: - return machine.succeed("curl --fail http://localhost:4040/login") + status, _ = machine.execute("curl --fail http://localhost:4040/login") + return status == 0 machine.start() diff --git a/nixpkgs/nixos/tests/all-terminfo.nix b/nixpkgs/nixos/tests/all-terminfo.nix new file mode 100644 index 000000000000..dd47c66ee1c1 --- /dev/null +++ b/nixpkgs/nixos/tests/all-terminfo.nix @@ -0,0 +1,31 @@ +import ./make-test-python.nix ({ pkgs, ... }: rec { + name = "all-terminfo"; + meta = with pkgs.lib.maintainers; { + maintainers = [ jkarlson ]; + }; + + nodes.machine = { pkgs, config, lib, ... }: + let + infoFilter = name: drv: + let + o = builtins.tryEval drv; + in + o.success && lib.isDerivation o.value && o.value ? outputs && builtins.elem "terminfo" o.value.outputs; + terminfos = lib.filterAttrs infoFilter pkgs; + excludedTerminfos = lib.filterAttrs (_: drv: !(builtins.elem drv.terminfo config.environment.systemPackages)) terminfos; + includedOuts = lib.filterAttrs (_: drv: builtins.elem drv.out config.environment.systemPackages) terminfos; + in + { + environment = { + enableAllTerminfo = true; + etc."terminfo-missing".text = builtins.concatStringsSep "\n" (builtins.attrNames excludedTerminfos); + etc."terminfo-extra-outs".text = builtins.concatStringsSep "\n" (builtins.attrNames includedOuts); + }; + }; + + testScript = + '' + machine.fail("grep . /etc/terminfo-missing >&2") + machine.fail("grep . /etc/terminfo-extra-outs >&2") + ''; +}) diff --git a/nixpkgs/nixos/tests/all-tests.nix b/nixpkgs/nixos/tests/all-tests.nix index ab6906cd24e2..c718c292b257 100644 --- a/nixpkgs/nixos/tests/all-tests.nix +++ b/nixpkgs/nixos/tests/all-tests.nix @@ -26,8 +26,8 @@ let featureFlags.minimalModules = {}; }; evalMinimalConfig = module: nixosLib.evalModules { modules = [ module ]; }; -in -{ + +in { _3proxy = handleTest ./3proxy.nix {}; acme = handleTest ./acme.nix {}; adguardhome = handleTest ./adguardhome.nix {}; @@ -35,11 +35,13 @@ in agate = handleTest ./web-servers/agate.nix {}; agda = handleTest ./agda.nix {}; airsonic = handleTest ./airsonic.nix {}; + allTerminfo = handleTest ./all-terminfo.nix {}; amazon-init-shell = handleTest ./amazon-init-shell.nix {}; apfs = handleTest ./apfs.nix {}; apparmor = handleTest ./apparmor.nix {}; atd = handleTest ./atd.nix {}; atop = handleTest ./atop.nix {}; + auth-mysql = handleTest ./auth-mysql.nix {}; avahi = handleTest ./avahi.nix {}; avahi-with-resolved = handleTest ./avahi.nix { networkd = true; }; babeld = handleTest ./babeld.nix {}; @@ -61,6 +63,7 @@ in breitbandmessung = handleTest ./breitbandmessung.nix {}; brscan5 = handleTest ./brscan5.nix {}; btrbk = handleTest ./btrbk.nix {}; + btrbk-no-timer = handleTest ./btrbk-no-timer.nix {}; buildbot = handleTest ./buildbot.nix {}; buildkite-agents = handleTest ./buildkite-agents.nix {}; caddy = handleTest ./caddy.nix {}; @@ -108,9 +111,8 @@ in cri-o = handleTestOn ["x86_64-linux"] ./cri-o.nix {}; custom-ca = handleTest ./custom-ca.nix {}; croc = handleTest ./croc.nix {}; - cryptpad = handleTest ./cryptpad.nix {}; deluge = handleTest ./deluge.nix {}; - dendrite = handleTest ./dendrite.nix {}; + dendrite = handleTest ./matrix/dendrite.nix {}; dex-oidc = handleTest ./dex-oidc.nix {}; dhparams = handleTest ./dhparams.nix {}; disable-installer-tools = handleTest ./disable-installer-tools.nix {}; @@ -121,12 +123,12 @@ in doas = handleTest ./doas.nix {}; docker = handleTestOn ["x86_64-linux"] ./docker.nix {}; docker-rootless = handleTestOn ["x86_64-linux"] ./docker-rootless.nix {}; - docker-edge = handleTestOn ["x86_64-linux"] ./docker-edge.nix {}; docker-registry = handleTest ./docker-registry.nix {}; docker-tools = handleTestOn ["x86_64-linux"] ./docker-tools.nix {}; docker-tools-cross = handleTestOn ["x86_64-linux" "aarch64-linux"] ./docker-tools-cross.nix {}; docker-tools-overlay = handleTestOn ["x86_64-linux"] ./docker-tools-overlay.nix {}; documize = handleTest ./documize.nix {}; + documentation = pkgs.callPackage ../modules/misc/documentation/test.nix { inherit nixosLib; }; doh-proxy-rust = handleTest ./doh-proxy-rust.nix {}; dokuwiki = handleTest ./dokuwiki.nix {}; domination = handleTest ./domination.nix {}; @@ -142,6 +144,7 @@ in engelsystem = handleTest ./engelsystem.nix {}; enlightenment = handleTest ./enlightenment.nix {}; env = handleTest ./env.nix {}; + envoy = handleTest ./envoy.nix {}; ergo = handleTest ./ergo.nix {}; ergochat = handleTest ./ergochat.nix {}; etc = pkgs.callPackage ../modules/system/etc/test.nix { inherit evalMinimalConfig; }; @@ -149,6 +152,7 @@ in etcd-cluster = handleTestOn ["x86_64-linux"] ./etcd-cluster.nix {}; etebase-server = handleTest ./etebase-server.nix {}; etesync-dav = handleTest ./etesync-dav.nix {}; + extra-python-packages = handleTest ./extra-python-packages.nix {}; fancontrol = handleTest ./fancontrol.nix {}; fcitx = handleTest ./fcitx {}; fenics = handleTest ./fenics.nix {}; @@ -156,6 +160,7 @@ in firefox = handleTest ./firefox.nix { firefoxPackage = pkgs.firefox; }; firefox-esr = handleTest ./firefox.nix { firefoxPackage = pkgs.firefox-esr; }; # used in `tested` job firefox-esr-91 = handleTest ./firefox.nix { firefoxPackage = pkgs.firefox-esr-91; }; + firefox-esr-102 = handleTest ./firefox.nix { firefoxPackage = pkgs.firefox-esr-102; }; firejail = handleTest ./firejail.nix {}; firewall = handleTest ./firewall.nix {}; fish = handleTest ./fish.nix {}; @@ -167,6 +172,7 @@ in frr = handleTest ./frr.nix {}; fsck = handleTest ./fsck.nix {}; ft2-clone = handleTest ./ft2-clone.nix {}; + mimir = handleTest ./mimir.nix {}; gerrit = handleTest ./gerrit.nix {}; geth = handleTest ./geth.nix {}; ghostunnel = handleTest ./ghostunnel.nix {}; @@ -185,6 +191,7 @@ in google-oslogin = handleTest ./google-oslogin {}; gotify-server = handleTest ./gotify-server.nix {}; grafana = handleTest ./grafana.nix {}; + grafana-agent = handleTest ./grafana-agent.nix {}; graphite = handleTest ./graphite.nix {}; graylog = handleTest ./graylog.nix {}; grocy = handleTest ./grocy.nix {}; @@ -194,8 +201,13 @@ in hadoop_3_2 = import ./hadoop { inherit handleTestOn; package=pkgs.hadoop_3_2; }; hadoop2 = import ./hadoop { inherit handleTestOn; package=pkgs.hadoop2; }; haka = handleTest ./haka.nix {}; + haste-server = handleTest ./haste-server.nix {}; haproxy = handleTest ./haproxy.nix {}; hardened = handleTest ./hardened.nix {}; + healthchecks = handleTest ./web-apps/healthchecks.nix {}; + hbase1 = handleTest ./hbase.nix { package=pkgs.hbase1; }; + hbase2 = handleTest ./hbase.nix { package=pkgs.hbase2; }; + hbase3 = handleTest ./hbase.nix { package=pkgs.hbase3; }; hedgedoc = handleTest ./hedgedoc.nix {}; herbstluftwm = handleTest ./herbstluftwm.nix {}; installed-tests = pkgs.recurseIntoAttrs (handleTest ./installed-tests {}); @@ -206,6 +218,7 @@ in # hibernation. This test happens to work on x86_64-linux but # not on other platforms. hibernate = handleTestOn ["x86_64-linux"] ./hibernate.nix {}; + hibernate-systemd-stage-1 = handleTestOn ["x86_64-linux"] ./hibernate.nix { systemdStage1 = true; }; hitch = handleTest ./hitch {}; hledger-web = handleTest ./hledger-web.nix {}; hocker-fetchdocker = handleTest ./hocker-fetchdocker {}; @@ -228,6 +241,7 @@ in input-remapper = handleTest ./input-remapper.nix {}; inspircd = handleTest ./inspircd.nix {}; installer = handleTest ./installer.nix {}; + installer-systemd-stage-1 = handleTest ./installer-systemd-stage-1.nix {}; invoiceplane = handleTest ./invoiceplane.nix {}; iodine = handleTest ./iodine.nix {}; ipfs = handleTest ./ipfs.nix {}; @@ -242,9 +256,9 @@ in jibri = handleTest ./jibri.nix {}; jirafeau = handleTest ./jirafeau.nix {}; jitsi-meet = handleTest ./jitsi-meet.nix {}; - k3s-single-node = handleTest ./k3s-single-node.nix {}; - k3s-single-node-docker = handleTest ./k3s-single-node-docker.nix {}; + k3s = handleTest ./k3s {}; kafka = handleTest ./kafka.nix {}; + kanidm = handleTest ./kanidm.nix {}; kbd-setfont-decompress = handleTest ./kbd-setfont-decompress.nix {}; kbd-update-search-paths-patch = handleTest ./kbd-update-search-paths-patch.nix {}; kea = handleTest ./kea.nix {}; @@ -253,10 +267,12 @@ in kerberos = handleTest ./kerberos/default.nix {}; kernel-generic = handleTest ./kernel-generic.nix {}; kernel-latest-ath-user-regd = handleTest ./kernel-latest-ath-user-regd.nix {}; + keter = handleTest ./keter.nix {}; kexec = handleTest ./kexec.nix {}; keycloak = discoverTests (import ./keycloak.nix); keymap = handleTest ./keymap.nix {}; knot = handleTest ./knot.nix {}; + komga = handleTest ./komga.nix {}; krb5 = discoverTests (import ./krb5 {}); ksm = handleTest ./ksm.nix {}; kubernetes = handleTestOn ["x86_64-linux"] ./kubernetes {}; @@ -266,21 +282,25 @@ in libreddit = handleTest ./libreddit.nix {}; libresprite = handleTest ./libresprite.nix {}; libreswan = handleTest ./libreswan.nix {}; + librewolf = handleTest ./firefox.nix { firefoxPackage = pkgs.librewolf; }; + libuiohook = handleTest ./libuiohook.nix {}; lidarr = handleTest ./lidarr.nix {}; lightdm = handleTest ./lightdm.nix {}; + lighttpd = handleTest ./lighttpd.nix {}; limesurvey = handleTest ./limesurvey.nix {}; litestream = handleTest ./litestream.nix {}; locate = handleTest ./locate.nix {}; login = handleTest ./login.nix {}; logrotate = handleTest ./logrotate.nix {}; loki = handleTest ./loki.nix {}; + lvm2 = handleTest ./lvm2 {}; lxd = handleTest ./lxd.nix {}; - lxd-image = handleTest ./lxd-image.nix {}; lxd-nftables = handleTest ./lxd-nftables.nix {}; lxd-image-server = handleTest ./lxd-image-server.nix {}; #logstash = handleTest ./logstash.nix {}; lorri = handleTest ./lorri/default.nix {}; maddy = handleTest ./maddy.nix {}; + maestral = handleTest ./maestral.nix {}; magic-wormhole-mailbox-server = handleTest ./magic-wormhole-mailbox-server.nix {}; magnetico = handleTest ./magnetico.nix {}; mailcatcher = handleTest ./mailcatcher.nix {}; @@ -289,9 +309,9 @@ in mariadb-galera = handleTest ./mysql/mariadb-galera.nix {}; mastodon = handleTestOn ["x86_64-linux" "i686-linux" "aarch64-linux"] ./web-apps/mastodon.nix {}; matomo = handleTest ./matomo.nix {}; - matrix-appservice-irc = handleTest ./matrix-appservice-irc.nix {}; - matrix-conduit = handleTest ./matrix-conduit.nix {}; - matrix-synapse = handleTest ./matrix-synapse.nix {}; + matrix-appservice-irc = handleTest ./matrix/appservice-irc.nix {}; + matrix-conduit = handleTest ./matrix/conduit.nix {}; + matrix-synapse = handleTest ./matrix/synapse.nix {}; mattermost = handleTest ./mattermost.nix {}; mediatomb = handleTest ./mediatomb.nix {}; mediawiki = handleTest ./mediawiki.nix {}; @@ -315,6 +335,7 @@ in moosefs = handleTest ./moosefs.nix {}; mpd = handleTest ./mpd.nix {}; mpv = handleTest ./mpv.nix {}; + mtp = handleTest ./mtp.nix {}; mumble = handleTest ./mumble.nix {}; musescore = handleTest ./musescore.nix {}; munin = handleTest ./munin.nix {}; @@ -341,6 +362,7 @@ in networking.networkd = handleTest ./networking.nix { networkd = true; }; networking.scripted = handleTest ./networking.nix { networkd = false; }; specialisation = handleTest ./specialisation.nix {}; + netbox = handleTest ./web-apps/netbox.nix {}; # TODO: put in networking.nix after the test becomes more complete networkingProxy = handleTest ./networking-proxy.nix {}; nextcloud = handleTest ./nextcloud {}; @@ -352,13 +374,15 @@ in nginx = handleTest ./nginx.nix {}; nginx-auth = handleTest ./nginx-auth.nix {}; nginx-etag = handleTest ./nginx-etag.nix {}; + nginx-http3 = handleTest ./nginx-http3.nix {}; nginx-modsecurity = handleTest ./nginx-modsecurity.nix {}; nginx-pubhtml = handleTest ./nginx-pubhtml.nix {}; nginx-sandbox = handleTestOn ["x86_64-linux"] ./nginx-sandbox.nix {}; nginx-sso = handleTest ./nginx-sso.nix {}; nginx-variants = handleTest ./nginx-variants.nix {}; + nifi = handleTestOn ["x86_64-linux"] ./web-apps/nifi.nix {}; nitter = handleTest ./nitter.nix {}; - nix-ld = handleTest ./nix-ld {}; + nix-ld = handleTest ./nix-ld.nix {}; nix-serve = handleTest ./nix-serve.nix {}; nix-serve-ssh = handleTest ./nix-serve-ssh.nix {}; nixops = handleTest ./nixops/default.nix {}; @@ -366,6 +390,7 @@ in nixpkgs = pkgs.callPackage ../modules/misc/nixpkgs/test.nix { inherit evalMinimalConfig; }; node-red = handleTest ./node-red.nix {}; nomad = handleTest ./nomad.nix {}; + non-default-filesystems = handleTest ./non-default-filesystems.nix {}; noto-fonts = handleTest ./noto-fonts.nix {}; novacomd = handleTestOn ["x86_64-linux"] ./novacomd.nix {}; nsd = handleTest ./nsd.nix {}; @@ -393,9 +418,12 @@ in pam-file-contents = handleTest ./pam/pam-file-contents.nix {}; pam-oath-login = handleTest ./pam/pam-oath-login.nix {}; pam-u2f = handleTest ./pam/pam-u2f.nix {}; + pam-ussh = handleTest ./pam/pam-ussh.nix {}; + pass-secret-service = handleTest ./pass-secret-service.nix {}; + patroni = handleTest ./patroni.nix {}; pantalaimon = handleTest ./matrix/pantalaimon.nix {}; pantheon = handleTest ./pantheon.nix {}; - paperless-ng = handleTest ./paperless-ng.nix {}; + paperless = handleTest ./paperless.nix {}; parsedmarc = handleTest ./parsedmarc {}; pdns-recursor = handleTest ./pdns-recursor.nix {}; peerflix = handleTest ./peerflix.nix {}; @@ -405,9 +433,9 @@ in pgjwt = handleTest ./pgjwt.nix {}; pgmanage = handleTest ./pgmanage.nix {}; php = handleTest ./php {}; - php74 = handleTest ./php { php = pkgs.php74; }; php80 = handleTest ./php { php = pkgs.php80; }; php81 = handleTest ./php { php = pkgs.php81; }; + phylactery = handleTest ./web-apps/phylactery.nix {}; pict-rs = handleTest ./pict-rs.nix {}; pinnwand = handleTest ./pinnwand.nix {}; plasma5 = handleTest ./plasma5.nix {}; @@ -420,6 +448,7 @@ in podman = handleTestOn ["x86_64-linux"] ./podman/default.nix {}; podman-dnsname = handleTestOn ["x86_64-linux"] ./podman/dnsname.nix {}; podman-tls-ghostunnel = handleTestOn ["x86_64-linux"] ./podman/tls-ghostunnel.nix {}; + polaris = handleTest ./polaris.nix {}; pomerium = handleTestOn ["x86_64-linux"] ./pomerium.nix {}; postfix = handleTest ./postfix.nix {}; postfix-raise-smtpd-tls-security-level = handleTest ./postfix-raise-smtpd-tls-security-level.nix {}; @@ -442,6 +471,8 @@ in proxy = handleTest ./proxy.nix {}; prowlarr = handleTest ./prowlarr.nix {}; pt2-clone = handleTest ./pt2-clone.nix {}; + pykms = handleTest ./pykms.nix {}; + public-inbox = handleTest ./public-inbox.nix {}; pulseaudio = discoverTests (import ./pulseaudio.nix); qboot = handleTestOn ["x86_64-linux" "i686-linux"] ./qboot.nix {}; quorum = handleTest ./quorum.nix {}; @@ -455,7 +486,6 @@ in restartByActivationScript = handleTest ./restart-by-activation-script.nix {}; restic = handleTest ./restic.nix {}; retroarch = handleTest ./retroarch.nix {}; - riak = handleTest ./riak.nix {}; robustirc-bridge = handleTest ./robustirc-bridge.nix {}; roundcube = handleTest ./roundcube.nix {}; rspamd = handleTest ./rspamd.nix {}; @@ -468,6 +498,7 @@ in samba = handleTest ./samba.nix {}; samba-wsdd = handleTest ./samba-wsdd.nix {}; sanoid = handleTest ./sanoid.nix {}; + schleuder = handleTest ./schleuder.nix {}; sddm = handleTest ./sddm.nix {}; seafile = handleTest ./seafile.nix {}; searx = handleTest ./searx.nix {}; @@ -497,7 +528,9 @@ in starship = handleTest ./starship.nix {}; step-ca = handleTestOn ["x86_64-linux"] ./step-ca.nix {}; strongswan-swanctl = handleTest ./strongswan-swanctl.nix {}; + stunnel = handleTest ./stunnel.nix {}; sudo = handleTest ./sudo.nix {}; + swap-partition = handleTest ./swap-partition.nix {}; sway = handleTest ./sway.nix {}; switchTest = handleTest ./switch-test.nix {}; sympa = handleTest ./sympa.nix {}; @@ -509,8 +542,15 @@ in systemd-binfmt = handleTestOn ["x86_64-linux"] ./systemd-binfmt.nix {}; systemd-boot = handleTest ./systemd-boot.nix {}; systemd-confinement = handleTest ./systemd-confinement.nix {}; + systemd-coredump = handleTest ./systemd-coredump.nix {}; systemd-cryptenroll = handleTest ./systemd-cryptenroll.nix {}; systemd-escaping = handleTest ./systemd-escaping.nix {}; + systemd-initrd-btrfs-raid = handleTest ./systemd-initrd-btrfs-raid.nix {}; + systemd-initrd-luks-keyfile = handleTest ./systemd-initrd-luks-keyfile.nix {}; + systemd-initrd-luks-password = handleTest ./systemd-initrd-luks-password.nix {}; + systemd-initrd-shutdown = handleTest ./systemd-shutdown.nix { systemdStage1 = true; }; + systemd-initrd-simple = handleTest ./systemd-initrd-simple.nix {}; + systemd-initrd-swraid = handleTest ./systemd-initrd-swraid.nix {}; systemd-journal = handleTest ./systemd-journal.nix {}; systemd-machinectl = handleTest ./systemd-machinectl.nix {}; systemd-networkd = handleTest ./systemd-networkd.nix {}; @@ -519,6 +559,7 @@ in systemd-networkd-ipv6-prefix-delegation = handleTest ./systemd-networkd-ipv6-prefix-delegation.nix {}; systemd-networkd-vrf = handleTest ./systemd-networkd-vrf.nix {}; systemd-nspawn = handleTest ./systemd-nspawn.nix {}; + systemd-shutdown = handleTest ./systemd-shutdown.nix {}; systemd-timesyncd = handleTest ./systemd-timesyncd.nix {}; systemd-misc = handleTest ./systemd-misc.nix {}; taskserver = handleTest ./taskserver.nix {}; @@ -553,11 +594,14 @@ in unifi = handleTest ./unifi.nix {}; unit-php = handleTest ./web-servers/unit-php.nix {}; upnp = handleTest ./upnp.nix {}; + uptermd = handleTest ./uptermd.nix {}; usbguard = handleTest ./usbguard.nix {}; user-activation-scripts = handleTest ./user-activation-scripts.nix {}; + user-home-mode = handleTest ./user-home-mode.nix {}; uwsgi = handleTest ./uwsgi.nix {}; v2ray = handleTest ./v2ray.nix {}; vault = handleTest ./vault.nix {}; + vault-dev = handleTest ./vault-dev.nix {}; vault-postgresql = handleTest ./vault-postgresql.nix {}; vaultwarden = handleTest ./vaultwarden.nix {}; vector = handleTest ./vector.nix {}; @@ -579,6 +623,7 @@ in xautolock = handleTest ./xautolock.nix {}; xfce = handleTest ./xfce.nix {}; xmonad = handleTest ./xmonad.nix {}; + xmonad-xdg-autostart = handleTest ./xmonad-xdg-autostart.nix {}; xrdp = handleTest ./xrdp.nix {}; xss-lock = handleTest ./xss-lock.nix {}; xterm = handleTest ./xterm.nix {}; @@ -586,9 +631,11 @@ in yabar = handleTest ./yabar.nix {}; yggdrasil = handleTest ./yggdrasil.nix {}; zammad = handleTest ./zammad.nix {}; + zeronet-conservancy = handleTest ./zeronet-conservancy.nix {}; zfs = handleTest ./zfs.nix {}; zigbee2mqtt = handleTest ./zigbee2mqtt.nix {}; zoneminder = handleTest ./zoneminder.nix {}; zookeeper = handleTest ./zookeeper.nix {}; + zrepl = handleTest ./zrepl.nix {}; zsh-history = handleTest ./zsh-history.nix {}; } diff --git a/nixpkgs/nixos/tests/amazon-init-shell.nix b/nixpkgs/nixos/tests/amazon-init-shell.nix index f9268b2f3a00..3c040841b6d2 100644 --- a/nixpkgs/nixos/tests/amazon-init-shell.nix +++ b/nixpkgs/nixos/tests/amazon-init-shell.nix @@ -18,7 +18,7 @@ makeTest { meta = with maintainers; { maintainers = [ urbas ]; }; - machine = { ... }: + nodes.machine = { ... }: { imports = [ ../modules/profiles/headless.nix ../modules/virtualisation/amazon-init.nix ]; services.openssh.enable = true; diff --git a/nixpkgs/nixos/tests/apfs.nix b/nixpkgs/nixos/tests/apfs.nix index a82886cbe731..a8841fe93046 100644 --- a/nixpkgs/nixos/tests/apfs.nix +++ b/nixpkgs/nixos/tests/apfs.nix @@ -2,7 +2,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { name = "apfs"; meta.maintainers = with pkgs.lib.maintainers; [ Luflosi ]; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { virtualisation.emptyDiskImages = [ 1024 ]; boot.supportedFilesystems = [ "apfs" ]; diff --git a/nixpkgs/nixos/tests/apparmor.nix b/nixpkgs/nixos/tests/apparmor.nix index c6daa8e67de3..f85bff0295e7 100644 --- a/nixpkgs/nixos/tests/apparmor.nix +++ b/nixpkgs/nixos/tests/apparmor.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, ... } : { maintainers = [ julm ]; }; - machine = + nodes.machine = { lib, pkgs, config, ... }: with lib; { diff --git a/nixpkgs/nixos/tests/atd.nix b/nixpkgs/nixos/tests/atd.nix index ad4d60067cf1..4342e9d7dc18 100644 --- a/nixpkgs/nixos/tests/atd.nix +++ b/nixpkgs/nixos/tests/atd.nix @@ -6,7 +6,7 @@ import ./make-test-python.nix ({ pkgs, ... }: maintainers = [ bjornfor ]; }; - machine = + nodes.machine = { ... }: { services.atd.enable = true; users.users.alice = { isNormalUser = true; }; diff --git a/nixpkgs/nixos/tests/atop.nix b/nixpkgs/nixos/tests/atop.nix index f7a90346f3d7..ec10369a24fd 100644 --- a/nixpkgs/nixos/tests/atop.nix +++ b/nixpkgs/nixos/tests/atop.nix @@ -107,7 +107,7 @@ in { justThePackage = makeTest { name = "atop-justThePackage"; - machine = { + nodes.machine = { environment.systemPackages = [ pkgs.atop ]; }; testScript = with assertions; builtins.concatStringsSep "\n" [ @@ -123,7 +123,7 @@ in }; defaults = makeTest { name = "atop-defaults"; - machine = { + nodes.machine = { programs.atop = { enable = true; }; @@ -141,7 +141,7 @@ in }; minimal = makeTest { name = "atop-minimal"; - machine = { + nodes.machine = { programs.atop = { enable = true; atopService.enable = false; @@ -162,7 +162,7 @@ in }; netatop = makeTest { name = "atop-netatop"; - machine = { + nodes.machine = { programs.atop = { enable = true; netatop.enable = true; @@ -181,11 +181,7 @@ in }; atopgpu = makeTest { name = "atop-atopgpu"; - machine = { - nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (getName pkg) [ - "cudatoolkit" - ]; - + nodes.machine = { programs.atop = { enable = true; atopgpu.enable = true; @@ -204,11 +200,7 @@ in }; everything = makeTest { name = "atop-everthing"; - machine = { - nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (getName pkg) [ - "cudatoolkit" - ]; - + nodes.machine = { programs.atop = { enable = true; settings = { diff --git a/nixpkgs/nixos/tests/auth-mysql.nix b/nixpkgs/nixos/tests/auth-mysql.nix new file mode 100644 index 000000000000..0ed4b050a69a --- /dev/null +++ b/nixpkgs/nixos/tests/auth-mysql.nix @@ -0,0 +1,177 @@ +import ./make-test-python.nix ({ pkgs, lib, ... }: + +let + dbUser = "nixos_auth"; + dbPassword = "topsecret123"; + dbName = "auth"; + + mysqlUsername = "mysqltest"; + mysqlPassword = "topsecretmysqluserpassword123"; + mysqlGroup = "mysqlusers"; + + localUsername = "localtest"; + localPassword = "topsecretlocaluserpassword123"; + + mysqlInit = pkgs.writeText "mysqlInit" '' + CREATE USER '${dbUser}'@'localhost' IDENTIFIED BY '${dbPassword}'; + CREATE DATABASE ${dbName}; + GRANT ALL PRIVILEGES ON ${dbName}.* TO '${dbUser}'@'localhost'; + FLUSH PRIVILEGES; + + USE ${dbName}; + CREATE TABLE `groups` ( + rowid int(11) NOT NULL auto_increment, + gid int(11) NOT NULL, + name char(255) NOT NULL, + PRIMARY KEY (rowid) + ); + + CREATE TABLE `users` ( + name varchar(255) NOT NULL, + uid int(11) NOT NULL auto_increment, + gid int(11) NOT NULL, + password varchar(255) NOT NULL, + PRIMARY KEY (uid), + UNIQUE (name) + ) AUTO_INCREMENT=5000; + + INSERT INTO `users` (name, uid, gid, password) VALUES + ('${mysqlUsername}', 5000, 5000, SHA2('${mysqlPassword}', 256)); + INSERT INTO `groups` (name, gid) VALUES ('${mysqlGroup}', 5000); + ''; +in +{ + name = "auth-mysql"; + meta.maintainers = with lib.maintainers; [ netali ]; + + nodes.machine = + { ... }: + { + services.mysql = { + enable = true; + package = pkgs.mariadb; + settings.mysqld.bind-address = "127.0.0.1"; + initialScript = mysqlInit; + }; + + users.users.${localUsername} = { + isNormalUser = true; + password = localPassword; + }; + + security.pam.services.login.makeHomeDir = true; + + users.mysql = { + enable = true; + host = "127.0.0.1"; + user = dbUser; + database = dbName; + passwordFile = "${builtins.toFile "dbPassword" dbPassword}"; + pam = { + table = "users"; + userColumn = "name"; + passwordColumn = "password"; + passwordCrypt = "sha256"; + disconnectEveryOperation = true; + }; + nss = { + getpwnam = '' + SELECT name, 'x', uid, gid, name, CONCAT('/home/', name), "/run/current-system/sw/bin/bash" \ + FROM users \ + WHERE name='%1$s' \ + LIMIT 1 + ''; + getpwuid = '' + SELECT name, 'x', uid, gid, name, CONCAT('/home/', name), "/run/current-system/sw/bin/bash" \ + FROM users \ + WHERE id=%1$u \ + LIMIT 1 + ''; + getspnam = '' + SELECT name, password, 1, 0, 99999, 7, 0, -1, 0 \ + FROM users \ + WHERE name='%1$s' \ + LIMIT 1 + ''; + getpwent = '' + SELECT name, 'x', uid, gid, name, CONCAT('/home/', name), "/run/current-system/sw/bin/bash" \ + FROM users + ''; + getspent = '' + SELECT name, password, 1, 0, 99999, 7, 0, -1, 0 \ + FROM users + ''; + getgrnam = '' + SELECT name, 'x', gid FROM groups WHERE name='%1$s' LIMIT 1 + ''; + getgrgid = '' + SELECT name, 'x', gid FROM groups WHERE gid='%1$u' LIMIT 1 + ''; + getgrent = '' + SELECT name, 'x', gid FROM groups + ''; + memsbygid = '' + SELECT name FROM users WHERE gid=%1$u + ''; + gidsbymem = '' + SELECT gid FROM users WHERE name='%1$s' + ''; + }; + }; + }; + + testScript = '' + def switch_to_tty(tty_number): + machine.fail(f"pgrep -f 'agetty.*tty{tty_number}'") + machine.send_key(f"alt-f{tty_number}") + machine.wait_until_succeeds(f"[ $(fgconsole) = {tty_number} ]") + machine.wait_for_unit(f"getty@tty{tty_number}.service") + machine.wait_until_succeeds(f"pgrep -f 'agetty.*tty{tty_number}'") + + + def try_login(tty_number, username, password): + machine.wait_until_tty_matches(tty_number, "login: ") + machine.send_chars(f"{username}\n") + machine.wait_until_tty_matches(tty_number, f"login: {username}") + machine.wait_until_succeeds("pgrep login") + machine.wait_until_tty_matches(tty_number, "Password: ") + machine.send_chars(f"{password}\n") + + + machine.wait_for_unit("multi-user.target") + machine.wait_for_unit("mysql.service") + machine.wait_until_succeeds("pgrep -f 'agetty.*tty1'") + + with subtest("Local login"): + switch_to_tty("2") + try_login("2", "${localUsername}", "${localPassword}") + + machine.wait_until_succeeds("pgrep -u ${localUsername} bash") + machine.send_chars("id > local_id.txt\n") + machine.wait_for_file("/home/${localUsername}/local_id.txt") + machine.succeed("cat /home/${localUsername}/local_id.txt | grep 'uid=1000(${localUsername}) gid=100(users) groups=100(users)'") + + with subtest("Local incorrect login"): + switch_to_tty("3") + try_login("3", "${localUsername}", "wrongpassword") + + machine.wait_until_tty_matches("3", "Login incorrect") + machine.wait_until_tty_matches("3", "login:") + + with subtest("MySQL login"): + switch_to_tty("4") + try_login("4", "${mysqlUsername}", "${mysqlPassword}") + + machine.wait_until_succeeds("pgrep -u ${mysqlUsername} bash") + machine.send_chars("id > mysql_id.txt\n") + machine.wait_for_file("/home/${mysqlUsername}/mysql_id.txt") + machine.succeed("cat /home/${mysqlUsername}/mysql_id.txt | grep 'uid=5000(${mysqlUsername}) gid=5000(${mysqlGroup}) groups=5000(${mysqlGroup})'") + + with subtest("MySQL incorrect login"): + switch_to_tty("5") + try_login("5", "${mysqlUsername}", "wrongpassword") + + machine.wait_until_tty_matches("5", "Login incorrect") + machine.wait_until_tty_matches("5", "login:") + ''; +}) diff --git a/nixpkgs/nixos/tests/bazarr.nix b/nixpkgs/nixos/tests/bazarr.nix index c3337611aa29..efcd9de01080 100644 --- a/nixpkgs/nixos/tests/bazarr.nix +++ b/nixpkgs/nixos/tests/bazarr.nix @@ -20,7 +20,7 @@ in testScript = '' machine.wait_for_unit("bazarr.service") - machine.wait_for_open_port("${toString port}") + machine.wait_for_open_port(port) machine.succeed("curl --fail http://localhost:${toString port}/") ''; }) diff --git a/nixpkgs/nixos/tests/bcachefs.nix b/nixpkgs/nixos/tests/bcachefs.nix index 44997a746879..68ac49d0a6a6 100644 --- a/nixpkgs/nixos/tests/bcachefs.nix +++ b/nixpkgs/nixos/tests/bcachefs.nix @@ -1,8 +1,8 @@ import ./make-test-python.nix ({ pkgs, ... }: { name = "bcachefs"; - meta.maintainers = with pkgs.lib.maintainers; [ chiiruno ]; + meta.maintainers = with pkgs.lib.maintainers; [ Madouura ]; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { virtualisation.emptyDiskImages = [ 4096 ]; networking.hostId = "deadbeef"; boot.supportedFilesystems = [ "bcachefs" ]; diff --git a/nixpkgs/nixos/tests/beanstalkd.nix b/nixpkgs/nixos/tests/beanstalkd.nix index 4f4a454fb47f..518f018408ad 100644 --- a/nixpkgs/nixos/tests/beanstalkd.nix +++ b/nixpkgs/nixos/tests/beanstalkd.nix @@ -28,7 +28,7 @@ in name = "beanstalkd"; meta.maintainers = [ lib.maintainers.aanderse ]; - machine = + nodes.machine = { ... }: { services.beanstalkd.enable = true; }; diff --git a/nixpkgs/nixos/tests/bees.nix b/nixpkgs/nixos/tests/bees.nix index 58a9c2951356..3ab9f38ada8f 100644 --- a/nixpkgs/nixos/tests/bees.nix +++ b/nixpkgs/nixos/tests/bees.nix @@ -2,7 +2,7 @@ import ./make-test-python.nix ({ lib, pkgs, ... }: { name = "bees"; - machine = { config, pkgs, ... }: { + nodes.machine = { config, pkgs, ... }: { boot.initrd.postDeviceCommands = '' ${pkgs.btrfs-progs}/bin/mkfs.btrfs -f -L aux1 /dev/vdb ${pkgs.btrfs-progs}/bin/mkfs.btrfs -f -L aux2 /dev/vdc diff --git a/nixpkgs/nixos/tests/bind.nix b/nixpkgs/nixos/tests/bind.nix index 7234f56a1c3a..15accbd49db4 100644 --- a/nixpkgs/nixos/tests/bind.nix +++ b/nixpkgs/nixos/tests/bind.nix @@ -1,7 +1,7 @@ import ./make-test-python.nix { name = "bind"; - machine = { pkgs, lib, ... }: { + nodes.machine = { pkgs, lib, ... }: { services.bind.enable = true; services.bind.extraOptions = "empty-zones-enable no;"; services.bind.zones = lib.singleton { diff --git a/nixpkgs/nixos/tests/bitcoind.nix b/nixpkgs/nixos/tests/bitcoind.nix index 3e9e085287ac..7726a23d853e 100644 --- a/nixpkgs/nixos/tests/bitcoind.nix +++ b/nixpkgs/nixos/tests/bitcoind.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { maintainers = with maintainers; [ _1000101 ]; }; - machine = { ... }: { + nodes.machine = { ... }: { services.bitcoind."mainnet" = { enable = true; rpc = { @@ -13,9 +13,11 @@ import ./make-test-python.nix ({ pkgs, ... }: { users.rpc2.passwordHMAC = "1495e4a3ad108187576c68f7f9b5ddc5$accce0881c74aa01bb8960ff3bdbd39f607fd33178147679e055a4ac35f53225"; }; }; + + environment.etc."test.blank".text = ""; services.bitcoind."testnet" = { enable = true; - configFile = "/test.blank"; + configFile = "/etc/test.blank"; testnet = true; rpc = { port = 18332; diff --git a/nixpkgs/nixos/tests/blockbook-frontend.nix b/nixpkgs/nixos/tests/blockbook-frontend.nix index e17a2d057797..dca4f2f53cc1 100644 --- a/nixpkgs/nixos/tests/blockbook-frontend.nix +++ b/nixpkgs/nixos/tests/blockbook-frontend.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { maintainers = with maintainers; [ _1000101 ]; }; - machine = { ... }: { + nodes.machine = { ... }: { services.blockbook-frontend."test" = { enable = true; }; diff --git a/nixpkgs/nixos/tests/boot-stage1.nix b/nixpkgs/nixos/tests/boot-stage1.nix index 756decd2039d..fbe82d61afae 100644 --- a/nixpkgs/nixos/tests/boot-stage1.nix +++ b/nixpkgs/nixos/tests/boot-stage1.nix @@ -1,7 +1,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { name = "boot-stage1"; - machine = { config, pkgs, lib, ... }: { + nodes.machine = { config, pkgs, lib, ... }: { boot.extraModulePackages = let compileKernelModule = name: source: pkgs.runCommandCC name rec { inherit source; diff --git a/nixpkgs/nixos/tests/botamusique.nix b/nixpkgs/nixos/tests/botamusique.nix index ccb105dc142f..ecb79cb69867 100644 --- a/nixpkgs/nixos/tests/botamusique.nix +++ b/nixpkgs/nixos/tests/botamusique.nix @@ -6,6 +6,10 @@ import ./make-test-python.nix ({ pkgs, lib, ...} : nodes = { machine = { config, ... }: { + networking.extraHosts = '' + 127.0.0.1 all.api.radio-browser.info + ''; + services.murmur = { enable = true; registerName = "NixOS tests"; diff --git a/nixpkgs/nixos/tests/bpf.nix b/nixpkgs/nixos/tests/bpf.nix index e479cd057921..5868e3bfcb4c 100644 --- a/nixpkgs/nixos/tests/bpf.nix +++ b/nixpkgs/nixos/tests/bpf.nix @@ -2,7 +2,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { name = "bpf"; meta.maintainers = with pkgs.lib.maintainers; [ martinetd ]; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { programs.bcc.enable = true; environment.systemPackages = with pkgs; [ bpftrace ]; }; diff --git a/nixpkgs/nixos/tests/breitbandmessung.nix b/nixpkgs/nixos/tests/breitbandmessung.nix index 12b1a094839b..78df0d5017eb 100644 --- a/nixpkgs/nixos/tests/breitbandmessung.nix +++ b/nixpkgs/nixos/tests/breitbandmessung.nix @@ -2,7 +2,7 @@ import ./make-test-python.nix ({ lib, ... }: { name = "breitbandmessung"; meta.maintainers = with lib.maintainers; [ b4dm4n ]; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { imports = [ ./common/user-account.nix ./common/x11.nix diff --git a/nixpkgs/nixos/tests/brscan5.nix b/nixpkgs/nixos/tests/brscan5.nix index 9aed742f6de7..9156a4cccfcf 100644 --- a/nixpkgs/nixos/tests/brscan5.nix +++ b/nixpkgs/nixos/tests/brscan5.nix @@ -7,7 +7,7 @@ import ./make-test-python.nix ({ pkgs, ...} : { maintainers = [ mattchrist ]; }; - machine = { pkgs, ... }: + nodes.machine = { pkgs, ... }: { nixpkgs.config.allowUnfree = true; hardware.sane = { diff --git a/nixpkgs/nixos/tests/btrbk-no-timer.nix b/nixpkgs/nixos/tests/btrbk-no-timer.nix new file mode 100644 index 000000000000..4fcab8839c89 --- /dev/null +++ b/nixpkgs/nixos/tests/btrbk-no-timer.nix @@ -0,0 +1,37 @@ +import ./make-test-python.nix ({ lib, pkgs, ... }: + { + name = "btrbk-no-timer"; + meta.maintainers = with lib.maintainers; [ oxalica ]; + + nodes.machine = { ... }: { + environment.systemPackages = with pkgs; [ btrfs-progs ]; + services.btrbk.instances.local = { + onCalendar = null; + settings.volume."/mnt" = { + snapshot_dir = "btrbk/local"; + subvolume = "to_backup"; + }; + }; + }; + + testScript = '' + start_all() + + # Create btrfs partition at /mnt + machine.succeed("truncate --size=128M /data_fs") + machine.succeed("mkfs.btrfs /data_fs") + machine.succeed("mkdir /mnt") + machine.succeed("mount /data_fs /mnt") + machine.succeed("btrfs subvolume create /mnt/to_backup") + machine.succeed("mkdir -p /mnt/btrbk/local") + + # The service should not have any triggering timer. + unit = machine.get_unit_info('btrbk-local.service') + assert "TriggeredBy" not in unit + + # Manually starting the service should still work. + machine.succeed("echo foo > /mnt/to_backup/bar") + machine.start_job("btrbk-local.service") + machine.wait_until_succeeds("cat /mnt/btrbk/local/*/bar | grep foo") + ''; + }) diff --git a/nixpkgs/nixos/tests/buildkite-agents.nix b/nixpkgs/nixos/tests/buildkite-agents.nix index 6674a0e884ed..2c5593323e87 100644 --- a/nixpkgs/nixos/tests/buildkite-agents.nix +++ b/nixpkgs/nixos/tests/buildkite-agents.nix @@ -6,7 +6,7 @@ import ./make-test-python.nix ({ pkgs, ... }: maintainers = [ flokli ]; }; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { services.buildkite-agents = { one = { privateSshKeyPath = (import ./ssh-keys.nix pkgs).snakeOilPrivateKey; diff --git a/nixpkgs/nixos/tests/caddy.nix b/nixpkgs/nixos/tests/caddy.nix index 16436ab52800..c4abd33d0395 100644 --- a/nixpkgs/nixos/tests/caddy.nix +++ b/nixpkgs/nixos/tests/caddy.nix @@ -61,7 +61,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { '' url = "http://localhost/example.html" webserver.wait_for_unit("caddy") - webserver.wait_for_open_port("80") + webserver.wait_for_open_port(80) def check_etag(url): @@ -95,13 +95,13 @@ import ./make-test-python.nix ({ pkgs, ... }: { webserver.succeed( "${justReloadSystem}/bin/switch-to-configuration test >&2" ) - webserver.wait_for_open_port("8080") + webserver.wait_for_open_port(8080) with subtest("multiple configs are correctly merged"): webserver.succeed( "${multipleConfigs}/bin/switch-to-configuration test >&2" ) - webserver.wait_for_open_port("8080") - webserver.wait_for_open_port("8081") + webserver.wait_for_open_port(8080) + webserver.wait_for_open_port(8081) ''; }) diff --git a/nixpkgs/nixos/tests/cage.nix b/nixpkgs/nixos/tests/cage.nix index 83bae3deeeab..39c8d0441b6d 100644 --- a/nixpkgs/nixos/tests/cage.nix +++ b/nixpkgs/nixos/tests/cage.nix @@ -6,7 +6,7 @@ import ./make-test-python.nix ({ pkgs, ...} : maintainers = [ matthewbauer ]; }; - machine = { ... }: + nodes.machine = { ... }: { imports = [ ./common/user-account.nix ]; diff --git a/nixpkgs/nixos/tests/cagebreak.nix b/nixpkgs/nixos/tests/cagebreak.nix index c6c2c632b61a..1dcc910f9744 100644 --- a/nixpkgs/nixos/tests/cagebreak.nix +++ b/nixpkgs/nixos/tests/cagebreak.nix @@ -13,7 +13,7 @@ in maintainers = [ berbiche ]; }; - machine = { config, ... }: + nodes.machine = { config, ... }: let alice = config.users.users.alice; in { diff --git a/nixpkgs/nixos/tests/cfssl.nix b/nixpkgs/nixos/tests/cfssl.nix index 170f09d9b76c..e673df3131f8 100644 --- a/nixpkgs/nixos/tests/cfssl.nix +++ b/nixpkgs/nixos/tests/cfssl.nix @@ -1,7 +1,7 @@ import ./make-test-python.nix ({ pkgs, ...} : { name = "cfssl"; - machine = { config, lib, pkgs, ... }: + nodes.machine = { config, lib, pkgs, ... }: { networking.firewall.allowedTCPPorts = [ config.services.cfssl.port ]; diff --git a/nixpkgs/nixos/tests/chromium.nix b/nixpkgs/nixos/tests/chromium.nix index 3815dca76220..6b296fe8a61a 100644 --- a/nixpkgs/nixos/tests/chromium.nix +++ b/nixpkgs/nixos/tests/chromium.nix @@ -45,12 +45,14 @@ mapAttrs (channel: chromiumPkg: makeTest { enableOCR = true; - machine.imports = [ ./common/user-account.nix ./common/x11.nix ]; - machine.virtualisation.memorySize = 2047; - machine.test-support.displayManager.auto.user = user; - machine.environment = { - systemPackages = [ chromiumPkg ]; - variables."XAUTHORITY" = "/home/alice/.Xauthority"; + nodes.machine = { ... }: { + imports = [ ./common/user-account.nix ./common/x11.nix ]; + virtualisation.memorySize = 2047; + test-support.displayManager.auto.user = user; + environment = { + systemPackages = [ chromiumPkg ]; + variables."XAUTHORITY" = "/home/alice/.Xauthority"; + }; }; testScript = let diff --git a/nixpkgs/nixos/tests/clickhouse.nix b/nixpkgs/nixos/tests/clickhouse.nix index 017f2ee35dab..043263ec05dd 100644 --- a/nixpkgs/nixos/tests/clickhouse.nix +++ b/nixpkgs/nixos/tests/clickhouse.nix @@ -2,7 +2,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { name = "clickhouse"; meta.maintainers = with pkgs.lib.maintainers; [ ma27 ]; - machine = { + nodes.machine = { services.clickhouse.enable = true; virtualisation.memorySize = 4096; }; diff --git a/nixpkgs/nixos/tests/cloud-init.nix b/nixpkgs/nixos/tests/cloud-init.nix index 3f191ff5616e..9feb8d5c1526 100644 --- a/nixpkgs/nixos/tests/cloud-init.nix +++ b/nixpkgs/nixos/tests/cloud-init.nix @@ -61,7 +61,7 @@ in makeTest { meta = with pkgs.lib.maintainers; { maintainers = [ lewo ]; }; - machine = { ... }: + nodes.machine = { ... }: { virtualisation.qemu.options = [ "-cdrom" "${metadataDrive}/metadata.iso" ]; services.cloud-init = { diff --git a/nixpkgs/nixos/tests/cntr.nix b/nixpkgs/nixos/tests/cntr.nix index e4e13545b876..598143beb6c0 100644 --- a/nixpkgs/nixos/tests/cntr.nix +++ b/nixpkgs/nixos/tests/cntr.nix @@ -46,7 +46,7 @@ let meta = with pkgs.lib.maintainers; { maintainers = [ sorki mic92 ]; }; - machine = { lib, ... }: { + nodes.machine = { lib, ... }: { environment.systemPackages = [ pkgs.cntr ]; containers.test = { autoStart = true; diff --git a/nixpkgs/nixos/tests/collectd.nix b/nixpkgs/nixos/tests/collectd.nix index cb196224a231..2480bdb5f917 100644 --- a/nixpkgs/nixos/tests/collectd.nix +++ b/nixpkgs/nixos/tests/collectd.nix @@ -2,12 +2,15 @@ import ./make-test-python.nix ({ pkgs, ... }: { name = "collectd"; meta = { }; - machine = - { pkgs, ... }: + nodes.machine = + { pkgs, lib, ... }: { services.collectd = { enable = true; + extraConfig = lib.mkBefore '' + Interval 30 + ''; plugins = { rrdtool = '' DataDir "/var/lib/collectd/rrd" @@ -26,6 +29,8 @@ import ./make-test-python.nix ({ pkgs, ... }: { machine.succeed(f"rrdinfo {file} | logger") # check that this file contains a shortterm metric machine.succeed(f"rrdinfo {file} | grep -F 'ds[shortterm].min = '") + # check that interval was set before the plugins + machine.succeed(f"rrdinfo {file} | grep -F 'step = 30'") # check that there are frequent updates machine.succeed(f"cp {file} before") machine.wait_until_fails(f"cmp before {file}") diff --git a/nixpkgs/nixos/tests/common/lxd/config.yaml b/nixpkgs/nixos/tests/common/lxd/config.yaml new file mode 100644 index 000000000000..3bb667ed43f7 --- /dev/null +++ b/nixpkgs/nixos/tests/common/lxd/config.yaml @@ -0,0 +1,24 @@ +storage_pools: + - name: default + driver: dir + config: + source: /var/lxd-pool + +networks: + - name: lxdbr0 + type: bridge + config: + ipv4.address: auto + ipv6.address: none + +profiles: + - name: default + devices: + eth0: + name: eth0 + network: lxdbr0 + type: nic + root: + path: / + pool: default + type: disk diff --git a/nixpkgs/nixos/tests/containers-bridge.nix b/nixpkgs/nixos/tests/containers-bridge.nix index b8661fd7997c..d2e16299edaa 100644 --- a/nixpkgs/nixos/tests/containers-bridge.nix +++ b/nixpkgs/nixos/tests/containers-bridge.nix @@ -11,7 +11,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { maintainers = with lib.maintainers; [ aristid aszlig eelco kampfschlaefer ]; }; - machine = + nodes.machine = { pkgs, ... }: { imports = [ ../modules/installer/cd-dvd/channel.nix ]; virtualisation.writableStore = true; diff --git a/nixpkgs/nixos/tests/containers-custom-pkgs.nix b/nixpkgs/nixos/tests/containers-custom-pkgs.nix index 1627a2c70c3c..e8740ac63134 100644 --- a/nixpkgs/nixos/tests/containers-custom-pkgs.nix +++ b/nixpkgs/nixos/tests/containers-custom-pkgs.nix @@ -9,10 +9,10 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: let in { name = "containers-custom-pkgs"; meta = { - maintainers = with lib.maintainers; [ adisbladis earvstedt ]; + maintainers = with lib.maintainers; [ adisbladis erikarvstedt ]; }; - machine = { config, ... }: { + nodes.machine = { config, ... }: { assertions = let helloName = (builtins.head config.containers.test.config.system.extraDependencies).name; in [ { diff --git a/nixpkgs/nixos/tests/containers-ephemeral.nix b/nixpkgs/nixos/tests/containers-ephemeral.nix index db1631cf5b5d..cb4b7d4eba0f 100644 --- a/nixpkgs/nixos/tests/containers-ephemeral.nix +++ b/nixpkgs/nixos/tests/containers-ephemeral.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { maintainers = with lib.maintainers; [ patryk27 ]; }; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { virtualisation.writableStore = true; containers.webserver = { @@ -33,10 +33,10 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { machine.succeed("nixos-container start webserver") with subtest("Container got its own root folder"): - machine.succeed("ls /run/containers/webserver") + machine.succeed("ls /run/nixos-containers/webserver") with subtest("Container persistent directory is not created"): - machine.fail("ls /var/lib/containers/webserver") + machine.fail("ls /var/lib/nixos-containers/webserver") # Since "start" returns after the container has reached # multi-user.target, we should now be able to access it. @@ -49,6 +49,6 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { machine.fail(f"curl --fail --connect-timeout 2 http://{ip}/ > /dev/null") with subtest("Container's root folder was removed"): - machine.fail("ls /run/containers/webserver") + machine.fail("ls /run/nixos-containers/webserver") ''; }) diff --git a/nixpkgs/nixos/tests/containers-extra_veth.nix b/nixpkgs/nixos/tests/containers-extra_veth.nix index b8f3d9844064..f3e62265f6c4 100644 --- a/nixpkgs/nixos/tests/containers-extra_veth.nix +++ b/nixpkgs/nixos/tests/containers-extra_veth.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { maintainers = with lib.maintainers; [ kampfschlaefer ]; }; - machine = + nodes.machine = { pkgs, ... }: { imports = [ ../modules/installer/cd-dvd/channel.nix ]; virtualisation.writableStore = true; diff --git a/nixpkgs/nixos/tests/containers-hosts.nix b/nixpkgs/nixos/tests/containers-hosts.nix index 3c6a15710027..7bce7c997efe 100644 --- a/nixpkgs/nixos/tests/containers-hosts.nix +++ b/nixpkgs/nixos/tests/containers-hosts.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { maintainers = with lib.maintainers; [ montag451 ]; }; - machine = + nodes.machine = { lib, ... }: { virtualisation.vlans = []; diff --git a/nixpkgs/nixos/tests/containers-imperative.nix b/nixpkgs/nixos/tests/containers-imperative.nix index 14001657bee0..3007efaf8871 100644 --- a/nixpkgs/nixos/tests/containers-imperative.nix +++ b/nixpkgs/nixos/tests/containers-imperative.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { maintainers = with lib.maintainers; [ aristid aszlig eelco kampfschlaefer ]; }; - machine = + nodes.machine = { config, pkgs, lib, ... }: { imports = [ ../modules/installer/cd-dvd/channel.nix ]; @@ -18,8 +18,9 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { # container available within the VM, because we don't have network access. virtualisation.additionalPaths = let emptyContainer = import ../lib/eval-config.nix { - inherit (config.nixpkgs.localSystem) system; modules = lib.singleton { + nixpkgs = { inherit (config.nixpkgs) localSystem; }; + containers.foo.config = { system.stateVersion = "18.03"; }; @@ -69,8 +70,8 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { with subtest(f"Put the root of {id2} into a bind mount"): machine.succeed( - f"mv /var/lib/containers/{id2} /id2-bindmount", - f"mount --bind /id2-bindmount /var/lib/containers/{id1}", + f"mv /var/lib/nixos-containers/{id2} /id2-bindmount", + f"mount --bind /id2-bindmount /var/lib/nixos-containers/{id1}", ) ip1 = machine.succeed(f"nixos-container show-ip {id1}").rstrip() @@ -88,7 +89,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { "Create a directory with a dummy file and bind-mount it into both containers." ): for id in id1, id2: - important_path = f"/var/lib/containers/{id}/very/important/data" + important_path = f"/var/lib/nixos-containers/{id}/very/important/data" machine.succeed( f"mkdir -p {important_path}", f"mount --bind /nested-bindmount {important_path}", @@ -154,13 +155,13 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { machine.succeed("grep -qF 'important data' /nested-bindmount/dummy") with subtest("Ensure that the container path is gone"): - print(machine.succeed("ls -lsa /var/lib/containers")) - machine.succeed(f"test ! -e /var/lib/containers/{id1}") + print(machine.succeed("ls -lsa /var/lib/nixos-containers")) + machine.succeed(f"test ! -e /var/lib/nixos-containers/{id1}") with subtest("Ensure that a failed container creation doesn'leave any state"): machine.fail( "nixos-container create b0rk --config-file ${brokenCfg}" ) - machine.succeed("test ! -e /var/lib/containers/b0rk") + machine.succeed("test ! -e /var/lib/nixos-containers/b0rk") ''; }) diff --git a/nixpkgs/nixos/tests/containers-ip.nix b/nixpkgs/nixos/tests/containers-ip.nix index 91fdda0392a9..ecead5c22f75 100644 --- a/nixpkgs/nixos/tests/containers-ip.nix +++ b/nixpkgs/nixos/tests/containers-ip.nix @@ -17,7 +17,7 @@ in import ./make-test-python.nix ({ pkgs, lib, ... }: { maintainers = with lib.maintainers; [ aristid aszlig eelco kampfschlaefer ]; }; - machine = + nodes.machine = { pkgs, ... }: { imports = [ ../modules/installer/cd-dvd/channel.nix ]; virtualisation = { diff --git a/nixpkgs/nixos/tests/containers-names.nix b/nixpkgs/nixos/tests/containers-names.nix index 9ad2bfb748a8..721f64990724 100644 --- a/nixpkgs/nixos/tests/containers-names.nix +++ b/nixpkgs/nixos/tests/containers-names.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { maintainers = with lib.maintainers; [ patryk27 ]; }; - machine = { ... }: { + nodes.machine = { ... }: { # We're using the newest kernel, so that we can test containers with long names. # Please see https://github.com/NixOS/nixpkgs/issues/38509 for details. boot.kernelPackages = pkgs.linuxPackages_latest; diff --git a/nixpkgs/nixos/tests/containers-nested.nix b/nixpkgs/nixos/tests/containers-nested.nix index a653361494f9..4a9fb8f01e24 100644 --- a/nixpkgs/nixos/tests/containers-nested.nix +++ b/nixpkgs/nixos/tests/containers-nested.nix @@ -5,7 +5,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { meta = with pkgs.lib.maintainers; { maintainers = [ sorki ]; }; - machine = { lib, ... }: + nodes.machine = { lib, ... }: let makeNested = subConf: { containers.nested = { diff --git a/nixpkgs/nixos/tests/containers-portforward.nix b/nixpkgs/nixos/tests/containers-portforward.nix index 6cecd72f1bda..b8c7aabc5a50 100644 --- a/nixpkgs/nixos/tests/containers-portforward.nix +++ b/nixpkgs/nixos/tests/containers-portforward.nix @@ -11,7 +11,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { maintainers = with lib.maintainers; [ aristid aszlig eelco kampfschlaefer ianwookim ]; }; - machine = + nodes.machine = { pkgs, ... }: { imports = [ ../modules/installer/cd-dvd/channel.nix ]; virtualisation.writableStore = true; diff --git a/nixpkgs/nixos/tests/containers-tmpfs.nix b/nixpkgs/nixos/tests/containers-tmpfs.nix index d95178d1ff58..cf5b81656afe 100644 --- a/nixpkgs/nixos/tests/containers-tmpfs.nix +++ b/nixpkgs/nixos/tests/containers-tmpfs.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { maintainers = with lib.maintainers; [ patryk27 ]; }; - machine = + nodes.machine = { pkgs, ... }: { imports = [ ../modules/installer/cd-dvd/channel.nix ]; virtualisation.writableStore = true; @@ -62,7 +62,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { machine.succeed( tmpfs_cmd("touch /root/test.file"), tmpfs_cmd("ls -l /root | grep -q test.file"), - "test -e /var/lib/containers/tmpfs/root/test.file", + "test -e /var/lib/nixos-containers/tmpfs/root/test.file", ) with subtest( @@ -73,7 +73,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { tmpfs_cmd("touch /some/random/path/test.file"), tmpfs_cmd("test -e /some/random/path/test.file"), ) - machine.fail("test -e /var/lib/containers/tmpfs/some/random/path/test.file") + machine.fail("test -e /var/lib/nixos-containers/tmpfs/some/random/path/test.file") with subtest( "files created in the hosts container dir in a path where a tmpfs " @@ -81,9 +81,9 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { + "the do not exist in the tmpfs" ): machine.succeed( - "touch /var/lib/containers/tmpfs/var/test.file", - "test -e /var/lib/containers/tmpfs/var/test.file", - "ls -l /var/lib/containers/tmpfs/var/ | grep -q test.file 2>/dev/null", + "touch /var/lib/nixos-containers/tmpfs/var/test.file", + "test -e /var/lib/nixos-containers/tmpfs/var/test.file", + "ls -l /var/lib/nixos-containers/tmpfs/var/ | grep -q test.file 2>/dev/null", ) machine.fail(tmpfs_cmd("ls -l /var | grep -q test.file")) ''; diff --git a/nixpkgs/nixos/tests/convos.nix b/nixpkgs/nixos/tests/convos.nix index a13870d17084..a5dafed8f6f0 100644 --- a/nixpkgs/nixos/tests/convos.nix +++ b/nixpkgs/nixos/tests/convos.nix @@ -23,8 +23,8 @@ in testScript = '' machine.wait_for_unit("convos") - machine.wait_for_open_port("${toString port}") - machine.succeed("journalctl -u convos | grep -q 'Listening at.*${toString port}'") + machine.wait_for_open_port(${toString port}) + machine.succeed("journalctl -u convos | grep -q 'application available at.*${toString port}'") machine.succeed("curl -f http://localhost:${toString port}/") ''; }) diff --git a/nixpkgs/nixos/tests/couchdb.nix b/nixpkgs/nixos/tests/couchdb.nix index 453f5dcd66e8..b57072d6be2d 100644 --- a/nixpkgs/nixos/tests/couchdb.nix +++ b/nixpkgs/nixos/tests/couchdb.nix @@ -20,7 +20,7 @@ with lib; { name = "couchdb"; meta = with pkgs.lib.maintainers; { - maintainers = [ fpletz ]; + maintainers = [ ]; }; nodes = { diff --git a/nixpkgs/nixos/tests/cryptpad.nix b/nixpkgs/nixos/tests/cryptpad.nix deleted file mode 100644 index 895f291abaca..000000000000 --- a/nixpkgs/nixos/tests/cryptpad.nix +++ /dev/null @@ -1,18 +0,0 @@ -import ./make-test-python.nix ({ lib, ... }: - -with lib; - -{ - name = "cryptpad"; - meta.maintainers = with maintainers; [ davhau ]; - - nodes.machine = - { pkgs, ... }: - { services.cryptpad.enable = true; }; - - testScript = '' - machine.wait_for_unit("cryptpad.service") - machine.wait_for_open_port("3000") - machine.succeed("curl -L --fail http://localhost:3000/sheet") - ''; -}) diff --git a/nixpkgs/nixos/tests/custom-ca.nix b/nixpkgs/nixos/tests/custom-ca.nix index a55449a397a7..73e47c3c9d0d 100644 --- a/nixpkgs/nixos/tests/custom-ca.nix +++ b/nixpkgs/nixos/tests/custom-ca.nix @@ -1,11 +1,18 @@ # Checks that `security.pki` options are working in curl and the main browser -# engines: Gecko (via Firefox), Chromium, QtWebEngine (Falkon) and WebKitGTK -# (via Midori). The test checks that certificates issued by a custom trusted -# CA are accepted but those from an unknown CA are rejected. +# engines: Gecko (via Firefox), Chromium, QtWebEngine (via qutebrowser) and +# WebKitGTK (via Midori). The test checks that certificates issued by a custom +# trusted CA are accepted but those from an unknown CA are rejected. -import ./make-test-python.nix ({ pkgs, lib, ... }: +{ system ? builtins.currentSystem, + config ? {}, + pkgs ? import ../.. { inherit system config; } +}: + +with import ../lib/testing-python.nix { inherit system pkgs; }; let + inherit (pkgs) lib; + makeCert = { caName, domain }: pkgs.runCommand "example-cert" { buildInputs = [ pkgs.gnutls ]; } '' @@ -68,24 +75,8 @@ let domain = "bad.example.com"; }; -in - -{ - name = "custom-ca"; - meta.maintainers = with lib.maintainers; [ rnhmjoj ]; - - enableOCR = true; - - machine = { pkgs, ... }: - { imports = [ ./common/user-account.nix ./common/x11.nix ]; - - # chromium-based browsers refuse to run as root - test-support.displayManager.auto.user = "alice"; - - # browsers may hang with the default memory - virtualisation.memorySize = 600; - - networking.hosts."127.0.0.1" = [ "good.example.com" "bad.example.com" ]; + webserverConfig = + { networking.hosts."127.0.0.1" = [ "good.example.com" "bad.example.com" ]; security.pki.certificateFiles = [ "${example-good-cert}/ca.crt" ]; services.nginx.enable = true; @@ -107,73 +98,98 @@ in return 200 'It does not work!'; ''; }; - - environment.systemPackages = with pkgs; [ - xdotool - firefox - chromium - qutebrowser - midori - ]; }; - testScript = '' - from typing import Tuple - def execute_as(user: str, cmd: str) -> Tuple[int, str]: - """ - Run a shell command as a specific user. - """ - return machine.execute(f"sudo -u {user} {cmd}") - - - def wait_for_window_as(user: str, cls: str) -> None: - """ - Wait until a X11 window of a given user appears. - """ - - def window_is_visible(last_try: bool) -> bool: - ret, stdout = execute_as(user, f"xdotool search --onlyvisible --class {cls}") - if last_try: - machine.log(f"Last chance to match {cls} on the window list") - return ret == 0 - - with machine.nested("Waiting for a window to appear"): - retry(window_is_visible) - - - machine.start() - - with subtest("Good certificate is trusted in curl"): - machine.wait_for_unit("nginx") - machine.wait_for_open_port(443) - machine.succeed("curl -fv https://good.example.com") - - with subtest("Unknown CA is untrusted in curl"): - machine.fail("curl -fv https://bad.example.com") - - browsers = { - "firefox": "Security Risk", - "chromium": "not private", - "qutebrowser -T": "Certificate error", - "midori": "Security" - } - - machine.wait_for_x() - for command, error in browsers.items(): - browser = command.split()[0] - with subtest("Good certificate is trusted in " + browser): - execute_as( - "alice", f"{command} https://good.example.com >&2 &" - ) - wait_for_window_as("alice", browser) - machine.wait_for_text("It works!") - machine.screenshot("good" + browser) - execute_as("alice", "xdotool key ctrl+w") # close tab - - with subtest("Unknown CA is untrusted in " + browser): - execute_as("alice", f"{command} https://bad.example.com >&2 &") - machine.wait_for_text(error) - machine.screenshot("bad" + browser) - machine.succeed("pkill -f " + browser) - ''; -}) + curlTest = makeTest { + name = "custom-ca-curl"; + meta.maintainers = with lib.maintainers; [ rnhmjoj ]; + nodes.machine = { ... }: webserverConfig; + testScript = '' + with subtest("Good certificate is trusted in curl"): + machine.wait_for_unit("nginx") + machine.wait_for_open_port(443) + machine.succeed("curl -fv https://good.example.com") + + with subtest("Unknown CA is untrusted in curl"): + machine.fail("curl -fv https://bad.example.com") + ''; + }; + + mkBrowserTest = browser: testParams: makeTest { + name = "custom-ca-${browser}"; + meta.maintainers = with lib.maintainers; [ rnhmjoj ]; + + enableOCR = true; + + nodes.machine = { pkgs, ... }: + { imports = + [ ./common/user-account.nix + ./common/x11.nix + webserverConfig + ]; + + # chromium-based browsers refuse to run as root + test-support.displayManager.auto.user = "alice"; + + # browsers may hang with the default memory + virtualisation.memorySize = 600; + + environment.systemPackages = [ pkgs.xdotool pkgs.${browser} ]; + }; + + testScript = '' + from typing import Tuple + def execute_as(user: str, cmd: str) -> Tuple[int, str]: + """ + Run a shell command as a specific user. + """ + return machine.execute(f"sudo -u {user} {cmd}") + + + def wait_for_window_as(user: str, cls: str) -> None: + """ + Wait until a X11 window of a given user appears. + """ + + def window_is_visible(last_try: bool) -> bool: + ret, stdout = execute_as(user, f"xdotool search --onlyvisible --class {cls}") + if last_try: + machine.log(f"Last chance to match {cls} on the window list") + return ret == 0 + + with machine.nested("Waiting for a window to appear"): + retry(window_is_visible) + + + machine.start() + machine.wait_for_x() + + command = "${browser} ${testParams.args or ""}" + with subtest("Good certificate is trusted in ${browser}"): + execute_as( + "alice", f"{command} https://good.example.com >&2 &" + ) + wait_for_window_as("alice", "${browser}") + machine.sleep(4) + execute_as("alice", "xdotool key ctrl+r") # reload to be safe + machine.wait_for_text("It works!") + machine.screenshot("good${browser}") + execute_as("alice", "xdotool key ctrl+w") # close tab + + with subtest("Unknown CA is untrusted in ${browser}"): + execute_as("alice", f"{command} https://bad.example.com >&2 &") + machine.wait_for_text("${testParams.error}") + machine.screenshot("bad${browser}") + ''; + }; + +in + +{ + curl = curlTest; +} // pkgs.lib.mapAttrs mkBrowserTest { + firefox = { error = "Security Risk"; }; + chromium = { error = "not private"; }; + qutebrowser = { args = "-T"; error = "Certificate error"; }; + midori = { error = "Security"; }; +} diff --git a/nixpkgs/nixos/tests/deluge.nix b/nixpkgs/nixos/tests/deluge.nix index 33c57ce7c36c..0cd1d21870ad 100644 --- a/nixpkgs/nixos/tests/deluge.nix +++ b/nixpkgs/nixos/tests/deluge.nix @@ -47,7 +47,7 @@ import ./make-test-python.nix ({ pkgs, ...} : { simple.wait_for_unit("deluged") simple.wait_for_unit("delugeweb") - simple.wait_for_open_port("8112") + simple.wait_for_open_port(8112) declarative.wait_for_unit("network.target") declarative.wait_until_succeeds("curl --fail http://simple:8112") diff --git a/nixpkgs/nixos/tests/disable-installer-tools.nix b/nixpkgs/nixos/tests/disable-installer-tools.nix index 23c15faa8d33..69f99122753a 100644 --- a/nixpkgs/nixos/tests/disable-installer-tools.nix +++ b/nixpkgs/nixos/tests/disable-installer-tools.nix @@ -3,7 +3,7 @@ import ./make-test-python.nix ({ pkgs, latestKernel ? false, ... }: { name = "disable-installer-tools"; - machine = + nodes.machine = { pkgs, lib, ... }: { system.disableInstallerTools = true; diff --git a/nixpkgs/nixos/tests/discourse.nix b/nixpkgs/nixos/tests/discourse.nix index cfac5f84a62f..35ca083c6c4e 100644 --- a/nixpkgs/nixos/tests/discourse.nix +++ b/nixpkgs/nixos/tests/discourse.nix @@ -30,6 +30,7 @@ import ./make-test-python.nix ( virtualisation.memorySize = 2048; virtualisation.cores = 4; virtualisation.useNixStoreImage = true; + virtualisation.writableStore = false; imports = [ common/user-account.nix ]; diff --git a/nixpkgs/nixos/tests/dnsdist.nix b/nixpkgs/nixos/tests/dnsdist.nix index cfc41c13864e..e72fa05ff282 100644 --- a/nixpkgs/nixos/tests/dnsdist.nix +++ b/nixpkgs/nixos/tests/dnsdist.nix @@ -5,7 +5,7 @@ import ./make-test-python.nix ( maintainers = with maintainers; [ jojosch ]; }; - machine = { pkgs, lib, ... }: { + nodes.machine = { pkgs, lib, ... }: { services.bind = { enable = true; extraOptions = "empty-zones-enable no;"; diff --git a/nixpkgs/nixos/tests/doas.nix b/nixpkgs/nixos/tests/doas.nix index 7f038b2bee29..3713c728195c 100644 --- a/nixpkgs/nixos/tests/doas.nix +++ b/nixpkgs/nixos/tests/doas.nix @@ -6,7 +6,7 @@ import ./make-test-python.nix ( maintainers = [ cole-h ]; }; - machine = + nodes.machine = { ... }: { users.groups = { foobar = {}; barfoo = {}; baz = { gid = 1337; }; }; diff --git a/nixpkgs/nixos/tests/docker-edge.nix b/nixpkgs/nixos/tests/docker-edge.nix deleted file mode 100644 index c6a1a0830189..000000000000 --- a/nixpkgs/nixos/tests/docker-edge.nix +++ /dev/null @@ -1,49 +0,0 @@ -# This test runs docker and checks if simple container starts - -import ./make-test-python.nix ({ pkgs, ...} : { - name = "docker"; - meta = with pkgs.lib.maintainers; { - maintainers = [ nequissimus offline ]; - }; - - nodes = { - docker = - { pkgs, ... }: - { - virtualisation.docker.enable = true; - virtualisation.docker.package = pkgs.docker-edge; - - users.users = { - noprivs = { - isNormalUser = true; - description = "Can't access the docker daemon"; - password = "foobar"; - }; - - hasprivs = { - isNormalUser = true; - description = "Can access the docker daemon"; - password = "foobar"; - extraGroups = [ "docker" ]; - }; - }; - }; - }; - - testScript = '' - start_all() - - docker.wait_for_unit("sockets.target") - docker.succeed("tar cv --files-from /dev/null | docker import - scratchimg") - docker.succeed( - "docker run -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10" - ) - docker.succeed("docker ps | grep sleeping") - docker.succeed("sudo -u hasprivs docker ps") - docker.fail("sudo -u noprivs docker ps") - docker.succeed("docker stop sleeping") - - # Must match version 4 times to ensure client and server git commits and versions are correct - docker.succeed('[ $(docker version | grep ${pkgs.docker-edge.version} | wc -l) = "4" ]') - ''; -}) diff --git a/nixpkgs/nixos/tests/docker-registry.nix b/nixpkgs/nixos/tests/docker-registry.nix index 1d449db45191..316b7c9b9727 100644 --- a/nixpkgs/nixos/tests/docker-registry.nix +++ b/nixpkgs/nixos/tests/docker-registry.nix @@ -35,7 +35,7 @@ import ./make-test-python.nix ({ pkgs, ...} : { registry.start() registry.wait_for_unit("docker-registry.service") - registry.wait_for_open_port("8080") + registry.wait_for_open_port(8080) client1.succeed("docker push registry:8080/scratch") client2.start() diff --git a/nixpkgs/nixos/tests/docker-tools-cross.nix b/nixpkgs/nixos/tests/docker-tools-cross.nix index a7a6a31475d6..14cb14ceeaea 100644 --- a/nixpkgs/nixos/tests/docker-tools-cross.nix +++ b/nixpkgs/nixos/tests/docker-tools-cross.nix @@ -7,7 +7,7 @@ import ./make-test-python.nix ({ pkgs, ... }: let remoteSystem = - if pkgs.system == "aarch64-linux" + if pkgs.stdenv.hostPlatform.system == "aarch64-linux" then "x86_64-linux" else "aarch64-linux"; @@ -18,13 +18,17 @@ let # NOTE: Since this file can't control where the test will be _run_ we don't # cross-compile _to_ a different system but _from_ a different system - crossSystem = pkgs.system; + crossSystem = pkgs.stdenv.hostPlatform.system; }; hello1 = remoteCrossPkgs.dockerTools.buildImage { name = "hello1"; tag = "latest"; - contents = remoteCrossPkgs.hello; + copyToRoot = remoteCrossPkgs.buildEnv { + name = "image-root"; + pathsToLink = [ "/bin" ]; + paths = [ remoteCrossPkgs.hello ]; + }; }; hello2 = remoteCrossPkgs.dockerTools.buildLayeredImage { diff --git a/nixpkgs/nixos/tests/docker-tools.nix b/nixpkgs/nixos/tests/docker-tools.nix index 8a240ddb17f2..d76f70b791ce 100644 --- a/nixpkgs/nixos/tests/docker-tools.nix +++ b/nixpkgs/nixos/tests/docker-tools.nix @@ -315,7 +315,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { "docker inspect ${pkgs.dockerTools.examples.cross.imageName} " + "| ${pkgs.jq}/bin/jq -r .[].Architecture" ).strip() - == "${if pkgs.system == "aarch64-linux" then "amd64" else "arm64"}" + == "${if pkgs.stdenv.hostPlatform.system == "aarch64-linux" then "amd64" else "arm64"}" ) with subtest("buildLayeredImage doesn't dereference /nix/store symlink layers"): @@ -346,7 +346,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { "docker load --input='${examples.layeredImageWithFakeRootCommands}'" ) docker.succeed( - "docker run --rm ${examples.layeredImageWithFakeRootCommands.imageName} sh -c 'stat -c '%u' /home/jane | grep -E ^1000$'" + "docker run --rm ${examples.layeredImageWithFakeRootCommands.imageName} sh -c 'stat -c '%u' /home/alice | grep -E ^1000$'" ) with subtest("Ensure docker load on merged images loads all of the constituent images"): @@ -389,7 +389,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { "docker load --input='${examples.mergedBashFakeRoot}'" ) docker.succeed( - "docker run --rm ${examples.layeredImageWithFakeRootCommands.imageName} sh -c 'stat -c '%u' /home/jane | grep -E ^1000$'" + "docker run --rm ${examples.layeredImageWithFakeRootCommands.imageName} sh -c 'stat -c '%u' /home/alice | grep -E ^1000$'" ) with subtest("The image contains store paths referenced by the fakeRootCommands output"): @@ -419,5 +419,10 @@ import ./make-test-python.nix ({ pkgs, ... }: { "docker rmi layered-image-with-path", ) + with subtest("etc"): + docker.succeed("${examples.etc} | docker load") + docker.succeed("docker run --rm etc | grep localhost") + docker.succeed("docker image rm etc:latest") + ''; }) diff --git a/nixpkgs/nixos/tests/documize.nix b/nixpkgs/nixos/tests/documize.nix index d5a77ffcd4f2..fda79b1a0931 100644 --- a/nixpkgs/nixos/tests/documize.nix +++ b/nixpkgs/nixos/tests/documize.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, lib, ...} : { maintainers = [ ma27 ]; }; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { environment.systemPackages = [ pkgs.jq ]; services.documize = { @@ -47,9 +47,9 @@ import ./make-test-python.nix ({ pkgs, lib, ...} : { " --data 'dbhash={}'" " --data 'title=NixOS'" " --data 'message=Docs'" - " --data 'firstname=John'" - " --data 'lastname=Doe'" - " --data 'email=john.doe@nixos.org'" + " --data 'firstname=Bob'" + " --data 'lastname=Foobar'" + " --data 'email=bob.foobar@nixos.org'" " --data 'password=verysafe'" " -f localhost:3000/api/setup" ).format(dbhash) diff --git a/nixpkgs/nixos/tests/domination.nix b/nixpkgs/nixos/tests/domination.nix index c76d4ed8c61b..09027740ab8d 100644 --- a/nixpkgs/nixos/tests/domination.nix +++ b/nixpkgs/nixos/tests/domination.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { maintainers = [ fgaz ]; }; - machine = { config, pkgs, ... }: { + nodes.machine = { config, pkgs, ... }: { imports = [ ./common/x11.nix ]; diff --git a/nixpkgs/nixos/tests/dovecot.nix b/nixpkgs/nixos/tests/dovecot.nix index 8913c2a6a7e8..5439387807fd 100644 --- a/nixpkgs/nixos/tests/dovecot.nix +++ b/nixpkgs/nixos/tests/dovecot.nix @@ -1,7 +1,7 @@ import ./make-test-python.nix { name = "dovecot"; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { imports = [ common/user-account.nix ]; services.postfix.enable = true; services.dovecot2 = { diff --git a/nixpkgs/nixos/tests/ecryptfs.nix b/nixpkgs/nixos/tests/ecryptfs.nix index ef7bd13eb92c..1c67d307a00e 100644 --- a/nixpkgs/nixos/tests/ecryptfs.nix +++ b/nixpkgs/nixos/tests/ecryptfs.nix @@ -2,7 +2,7 @@ import ./make-test-python.nix ({ ... }: { name = "ecryptfs"; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { imports = [ ./common/user-account.nix ]; boot.kernelModules = [ "ecryptfs" ]; security.pam.enableEcryptfs = true; @@ -11,16 +11,16 @@ import ./make-test-python.nix ({ ... }: testScript = '' def login_as_alice(): - machine.wait_until_tty_matches(1, "login: ") + machine.wait_until_tty_matches("1", "login: ") machine.send_chars("alice\n") - machine.wait_until_tty_matches(1, "Password: ") + machine.wait_until_tty_matches("1", "Password: ") machine.send_chars("foobar\n") - machine.wait_until_tty_matches(1, "alice\@machine") + machine.wait_until_tty_matches("1", "alice\@machine") def logout(): machine.send_chars("logout\n") - machine.wait_until_tty_matches(1, "login: ") + machine.wait_until_tty_matches("1", "login: ") machine.wait_for_unit("default.target") @@ -36,7 +36,7 @@ import ./make-test-python.nix ({ ... }: with subtest("Log alice in (ecryptfs passwhrase is wrapped during first login)"): login_as_alice() machine.send_chars("logout\n") - machine.wait_until_tty_matches(1, "login: ") + machine.wait_until_tty_matches("1", "login: ") # Why do I need to do this?? machine.succeed("su alice -c ecryptfs-umount-private || true") diff --git a/nixpkgs/nixos/tests/emacs-daemon.nix b/nixpkgs/nixos/tests/emacs-daemon.nix index e12da56021da..310e93e19b0b 100644 --- a/nixpkgs/nixos/tests/emacs-daemon.nix +++ b/nixpkgs/nixos/tests/emacs-daemon.nix @@ -6,7 +6,7 @@ import ./make-test-python.nix ({ pkgs, ...} : { enableOCR = true; - machine = + nodes.machine = { ... }: { imports = [ ./common/x11.nix ]; @@ -33,7 +33,7 @@ import ./make-test-python.nix ({ pkgs, ...} : { ) # connects to the daemon - machine.succeed("emacsclient --create-frame $EDITOR >&2 &") + machine.succeed("emacsclient --no-wait --frame-parameters='((display . \"'\"$DISPLAY\"'\"))' --create-frame $EDITOR >&2") # checks that Emacs shows the edited filename machine.wait_for_text("emacseditor") diff --git a/nixpkgs/nixos/tests/enlightenment.nix b/nixpkgs/nixos/tests/enlightenment.nix index 8506c348246d..2e06eedd9915 100644 --- a/nixpkgs/nixos/tests/enlightenment.nix +++ b/nixpkgs/nixos/tests/enlightenment.nix @@ -6,7 +6,7 @@ import ./make-test-python.nix ({ pkgs, ...} : maintainers = [ romildo ]; }; - machine = { ... }: + nodes.machine = { ... }: { imports = [ ./common/user-account.nix ]; services.xserver.enable = true; diff --git a/nixpkgs/nixos/tests/env.nix b/nixpkgs/nixos/tests/env.nix index fc96ace6b2d2..dec17b6b565a 100644 --- a/nixpkgs/nixos/tests/env.nix +++ b/nixpkgs/nixos/tests/env.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, ...} : { maintainers = [ nequissimus ]; }; - machine = { pkgs, ... }: + nodes.machine = { pkgs, ... }: { boot.kernelPackages = pkgs.linuxPackages; environment.etc.plainFile.text = '' diff --git a/nixpkgs/nixos/tests/envoy.nix b/nixpkgs/nixos/tests/envoy.nix new file mode 100644 index 000000000000..9d2c32ce102f --- /dev/null +++ b/nixpkgs/nixos/tests/envoy.nix @@ -0,0 +1,33 @@ +import ./make-test-python.nix ({ pkgs, lib, ...} : { + name = "envoy"; + meta = with pkgs.lib.maintainers; { + maintainers = [ cameronnemo ]; + }; + + nodes.machine = { pkgs, ... }: { + services.envoy.enable = true; + services.envoy.settings = { + admin = { + access_log_path = "/dev/null"; + address = { + socket_address = { + protocol = "TCP"; + address = "127.0.0.1"; + port_value = 9901; + }; + }; + }; + static_resources = { + listeners = []; + clusters = []; + }; + }; + }; + + testScript = '' + machine.start() + machine.wait_for_unit("envoy.service") + machine.wait_for_open_port(9901) + machine.wait_until_succeeds("curl -fsS localhost:9901/ready") + ''; +}) diff --git a/nixpkgs/nixos/tests/etebase-server.nix b/nixpkgs/nixos/tests/etebase-server.nix index 4fc3c1f6392f..49bfccf359e2 100644 --- a/nixpkgs/nixos/tests/etebase-server.nix +++ b/nixpkgs/nixos/tests/etebase-server.nix @@ -9,7 +9,7 @@ in { maintainers = [ felschr ]; }; - machine = { pkgs, ... }: + nodes.machine = { pkgs, ... }: { services.etebase-server = { inherit dataDir; diff --git a/nixpkgs/nixos/tests/etesync-dav.nix b/nixpkgs/nixos/tests/etesync-dav.nix index 6a747e23f76f..f49152c60991 100644 --- a/nixpkgs/nixos/tests/etesync-dav.nix +++ b/nixpkgs/nixos/tests/etesync-dav.nix @@ -5,7 +5,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { maintainers = [ _3699n ]; }; - machine = { config, pkgs, ... }: { + nodes.machine = { config, pkgs, ... }: { environment.systemPackages = [ pkgs.curl pkgs.etesync-dav ]; }; diff --git a/nixpkgs/nixos/tests/extra-python-packages.nix b/nixpkgs/nixos/tests/extra-python-packages.nix new file mode 100644 index 000000000000..7a48077cf98b --- /dev/null +++ b/nixpkgs/nixos/tests/extra-python-packages.nix @@ -0,0 +1,13 @@ +import ./make-test-python.nix ({ ... }: + { + name = "extra-python-packages"; + + extraPythonPackages = p: [ p.numpy ]; + + nodes = { }; + + testScript = '' + import numpy as np + assert str(np.zeros(4) == "array([0., 0., 0., 0.])") + ''; + }) diff --git a/nixpkgs/nixos/tests/fancontrol.nix b/nixpkgs/nixos/tests/fancontrol.nix index 296c68026415..ecb936097446 100644 --- a/nixpkgs/nixos/tests/fancontrol.nix +++ b/nixpkgs/nixos/tests/fancontrol.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, ... } : { maintainers = [ evils ]; }; - machine = { ... }: { + nodes.machine = { ... }: { imports = [ ../modules/profiles/minimal.nix ]; hardware.fancontrol.enable = true; hardware.fancontrol.config = '' diff --git a/nixpkgs/nixos/tests/fcitx/default.nix b/nixpkgs/nixos/tests/fcitx/default.nix index a243be8dc19b..c132249fcb24 100644 --- a/nixpkgs/nixos/tests/fcitx/default.nix +++ b/nixpkgs/nixos/tests/fcitx/default.nix @@ -5,7 +5,8 @@ import ../make-test-python.nix ( # copy_from_host works only for store paths rec { name = "fcitx"; - machine = + meta.broken = true; # takes hours to time out since October 2021 + nodes.machine = { pkgs, ... diff --git a/nixpkgs/nixos/tests/fenics.nix b/nixpkgs/nixos/tests/fenics.nix index f0a8c32c7cd8..1d182cfc4499 100644 --- a/nixpkgs/nixos/tests/fenics.nix +++ b/nixpkgs/nixos/tests/fenics.nix @@ -44,6 +44,6 @@ in { nodes, ... }: '' start_all() - node1.succeed("${fenicsScript}") + fenicsnode.succeed("${fenicsScript}") ''; }) diff --git a/nixpkgs/nixos/tests/firefox.nix b/nixpkgs/nixos/tests/firefox.nix index 6101fc973564..3f9cea6662fb 100644 --- a/nixpkgs/nixos/tests/firefox.nix +++ b/nixpkgs/nixos/tests/firefox.nix @@ -1,15 +1,24 @@ -import ./make-test-python.nix ({ pkgs, firefoxPackage, ... }: { - name = "firefox"; +import ./make-test-python.nix ({ pkgs, firefoxPackage, ... }: +let firefoxPackage' = firefoxPackage.override (args: { + extraPrefsFiles = (args.extraPrefsFiles or []) ++ [ + # make sure that autoplay is enabled by default for the audio test + (builtins.toString (builtins.toFile "autoplay-pref.js" ''defaultPref("media.autoplay.default",0);'')) + ]; + }); + +in +{ + name = firefoxPackage'.unwrapped.pname; meta = with pkgs.lib.maintainers; { maintainers = [ eelco shlevy ]; }; - machine = + nodes.machine = { pkgs, ... }: { imports = [ ./common/x11.nix ]; environment.systemPackages = [ - firefoxPackage + firefoxPackage' pkgs.xdotool ]; @@ -54,7 +63,7 @@ import ./make-test-python.nix ({ pkgs, firefoxPackage, ... }: { @contextmanager - def audio_recording(machine: Machine) -> None: + def record_audio(machine: Machine): """ Perform actions while recording the machine audio output. @@ -64,7 +73,7 @@ import ./make-test-python.nix ({ pkgs, firefoxPackage, ... }: { machine.systemctl("stop audio-recorder") - def wait_for_sound(machine: Machine) -> None: + def wait_for_sound(machine: Machine): """ Wait until any sound has been emitted. """ @@ -88,15 +97,15 @@ import ./make-test-python.nix ({ pkgs, firefoxPackage, ... }: { with subtest("Wait until Firefox has finished loading the Valgrind docs page"): machine.execute( - "xterm -e 'firefox file://${pkgs.valgrind.doc}/share/doc/valgrind/html/index.html' >&2 &" + "xterm -e '${firefoxPackage'.unwrapped.binaryName} file://${pkgs.valgrind.doc}/share/doc/valgrind/html/index.html' >&2 &" ) machine.wait_for_window("Valgrind") machine.sleep(40) with subtest("Check whether Firefox can play sound"): - with audio_recording(machine): + with record_audio(machine): machine.succeed( - "firefox file://${pkgs.sound-theme-freedesktop}/share/sounds/freedesktop/stereo/phone-incoming-call.oga >&2 &" + "${firefoxPackage'.unwrapped.binaryName} file://${pkgs.sound-theme-freedesktop}/share/sounds/freedesktop/stereo/phone-incoming-call.oga >&2 &" ) wait_for_sound(machine) machine.copy_from_vm("/tmp/record.wav") diff --git a/nixpkgs/nixos/tests/fish.nix b/nixpkgs/nixos/tests/fish.nix index 68fba428439b..3d9b13c6af70 100644 --- a/nixpkgs/nixos/tests/fish.nix +++ b/nixpkgs/nixos/tests/fish.nix @@ -1,7 +1,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { name = "fish"; - machine = + nodes.machine = { pkgs, ... }: { diff --git a/nixpkgs/nixos/tests/fluentd.nix b/nixpkgs/nixos/tests/fluentd.nix index 918f2f87db17..150638f246f2 100644 --- a/nixpkgs/nixos/tests/fluentd.nix +++ b/nixpkgs/nixos/tests/fluentd.nix @@ -1,7 +1,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { name = "fluentd"; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { services.fluentd = { enable = true; config = '' diff --git a/nixpkgs/nixos/tests/fontconfig-default-fonts.nix b/nixpkgs/nixos/tests/fontconfig-default-fonts.nix index 58d0f6227cc7..664afc9bf44c 100644 --- a/nixpkgs/nixos/tests/fontconfig-default-fonts.nix +++ b/nixpkgs/nixos/tests/fontconfig-default-fonts.nix @@ -6,7 +6,7 @@ import ./make-test-python.nix ({ lib, ... }: jtojnar ]; - machine = { config, pkgs, ... }: { + nodes.machine = { config, pkgs, ... }: { fonts.enableDefaultFonts = true; # Background fonts fonts.fonts = with pkgs; [ noto-fonts-emoji diff --git a/nixpkgs/nixos/tests/freeswitch.nix b/nixpkgs/nixos/tests/freeswitch.nix index bcc6a9cb3586..bfb7339ec3c0 100644 --- a/nixpkgs/nixos/tests/freeswitch.nix +++ b/nixpkgs/nixos/tests/freeswitch.nix @@ -24,6 +24,6 @@ import ./make-test-python.nix ({ pkgs, ...} : { testScript = '' node0.wait_for_unit("freeswitch.service") # Wait for SIP port to be open - node0.wait_for_open_port("5060") + node0.wait_for_open_port(5060) ''; }) diff --git a/nixpkgs/nixos/tests/fsck.nix b/nixpkgs/nixos/tests/fsck.nix index 5453f3bc48b5..5b8b09f433a2 100644 --- a/nixpkgs/nixos/tests/fsck.nix +++ b/nixpkgs/nixos/tests/fsck.nix @@ -1,7 +1,7 @@ import ./make-test-python.nix { name = "fsck"; - machine = { lib, ... }: { + nodes.machine = { lib, ... }: { virtualisation.emptyDiskImages = [ 1 ]; virtualisation.fileSystems = { diff --git a/nixpkgs/nixos/tests/ft2-clone.nix b/nixpkgs/nixos/tests/ft2-clone.nix index 71eda43e2b24..3c90b3d3fa20 100644 --- a/nixpkgs/nixos/tests/ft2-clone.nix +++ b/nixpkgs/nixos/tests/ft2-clone.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { maintainers = [ fgaz ]; }; - machine = { config, pkgs, ... }: { + nodes.machine = { config, pkgs, ... }: { imports = [ ./common/x11.nix ]; diff --git a/nixpkgs/nixos/tests/geth.nix b/nixpkgs/nixos/tests/geth.nix index af8230553bbb..11ad1ed2ea66 100644 --- a/nixpkgs/nixos/tests/geth.nix +++ b/nixpkgs/nixos/tests/geth.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { maintainers = with maintainers; [bachp ]; }; - machine = { ... }: { + nodes.machine = { ... }: { services.geth."mainnet" = { enable = true; http = { diff --git a/nixpkgs/nixos/tests/gitlab.nix b/nixpkgs/nixos/tests/gitlab.nix index dc3b889c8e8e..d9d75d1cbd89 100644 --- a/nixpkgs/nixos/tests/gitlab.nix +++ b/nixpkgs/nixos/tests/gitlab.nix @@ -1,12 +1,34 @@ -# This test runs gitlab and checks if it works +# This test runs gitlab and performs the following tests: +# - Creating users +# - Pushing commits +# - over the API +# - over SSH +# - Creating Merge Requests and merging them +# - Opening and closing issues. +# - Downloading repository archives as tar.gz and tar.bz2 +import ./make-test-python.nix ({ pkgs, lib, ... }: + +with lib; let + inherit (import ./ssh-keys.nix pkgs) snakeOilPrivateKey snakeOilPublicKey; initialRootPassword = "notproduction"; -in -import ./make-test-python.nix ({ pkgs, lib, ...} : with lib; { + rootProjectId = "2"; + + aliceUsername = "alice"; + aliceUserId = "2"; + alicePassword = "alicepassword"; + aliceProjectId = "2"; + aliceProjectName = "test-alice"; + + bobUsername = "bob"; + bobUserId = "3"; + bobPassword = "bobpassword"; + bobProjectId = "3"; +in { name = "gitlab"; meta = with pkgs.lib.maintainers; { - maintainers = [ globin ]; + maintainers = [ globin yayayayaka ]; }; nodes = { @@ -16,6 +38,8 @@ import ./make-test-python.nix ({ pkgs, lib, ...} : with lib; { virtualisation.memorySize = if pkgs.stdenv.is64bit then 4096 else 2047; virtualisation.cores = 4; virtualisation.useNixStoreImage = true; + virtualisation.writableStore = false; + systemd.services.gitlab.serviceConfig.Restart = mkForce "no"; systemd.services.gitlab-workhorse.serviceConfig.Restart = mkForce "no"; systemd.services.gitaly.serviceConfig.Restart = mkForce "no"; @@ -31,6 +55,8 @@ import ./make-test-python.nix ({ pkgs, lib, ...} : with lib; { }; }; + services.openssh.enable = true; + services.dovecot2 = { enable = true; enableImap = true; @@ -77,8 +103,43 @@ import ./make-test-python.nix ({ pkgs, lib, ...} : with lib; { password = initialRootPassword; }); - createProject = pkgs.writeText "create-project.json" (builtins.toJSON { - name = "test"; + createUserAlice = pkgs.writeText "create-user-alice.json" (builtins.toJSON rec { + username = aliceUsername; + name = username; + email = "alice@localhost"; + password = alicePassword; + skip_confirmation = true; + }); + + createUserBob = pkgs.writeText "create-user-bob.json" (builtins.toJSON rec { + username = bobUsername; + name = username; + email = "bob@localhost"; + password = bobPassword; + skip_confirmation = true; + }); + + aliceAuth = pkgs.writeText "alice-auth.json" (builtins.toJSON { + grant_type = "password"; + username = aliceUsername; + password = alicePassword; + }); + + bobAuth = pkgs.writeText "bob-auth.json" (builtins.toJSON { + grant_type = "password"; + username = bobUsername; + password = bobPassword; + }); + + aliceAddSSHKey = pkgs.writeText "alice-add-ssh-key.json" (builtins.toJSON { + id = aliceUserId; + title = "snakeoil@nixos"; + key = snakeOilPublicKey; + }); + + createProjectAlice = pkgs.writeText "create-project-alice.json" (builtins.toJSON { + name = aliceProjectName; + visibility = "public"; }); putFile = pkgs.writeText "put-file.json" (builtins.toJSON { @@ -89,6 +150,23 @@ import ./make-test-python.nix ({ pkgs, lib, ...} : with lib; { commit_message = "create a new file"; }); + mergeRequest = pkgs.writeText "merge-request.json" (builtins.toJSON { + id = bobProjectId; + target_project_id = aliceProjectId; + source_branch = "master"; + target_branch = "master"; + title = "Add some other file"; + }); + + newIssue = pkgs.writeText "new-issue.json" (builtins.toJSON { + title = "useful issue title"; + }); + + closeIssue = pkgs.writeText "close-issue.json" (builtins.toJSON { + issue_iid = 1; + state_event = "close"; + }); + # Wait for all GitLab services to be fully started. waitForServices = '' gitlab.wait_for_unit("gitaly.service") @@ -105,6 +183,8 @@ import ./make-test-python.nix ({ pkgs, lib, ...} : with lib; { # The actual test of GitLab. Only push data to GitLab if # `doSetup` is is true. test = doSetup: '' + GIT_SSH_COMMAND = "ssh -o StrictHostKeyChecking=accept-new -o UserKnownHostsFile=/dev/null" + gitlab.succeed( "curl -isSf http://gitlab | grep -i location | grep http://gitlab/users/sign_in" ) @@ -112,24 +192,225 @@ import ./make-test-python.nix ({ pkgs, lib, ...} : with lib; { "${pkgs.sudo}/bin/sudo -u gitlab -H gitlab-rake gitlab:check 1>&2" ) gitlab.succeed( - "echo \"Authorization: Bearer \$(curl -X POST -H 'Content-Type: application/json' -d @${auth} http://gitlab/oauth/token | ${pkgs.jq}/bin/jq -r '.access_token')\" >/tmp/headers" + "echo \"Authorization: Bearer $(curl -X POST -H 'Content-Type: application/json' -d @${auth} http://gitlab/oauth/token | ${pkgs.jq}/bin/jq -r '.access_token')\" >/tmp/headers" ) '' + optionalString doSetup '' - gitlab.succeed( - "curl -X POST -H 'Content-Type: application/json' -H @/tmp/headers -d @${createProject} http://gitlab/api/v4/projects" - ) - gitlab.succeed( - "curl -X POST -H 'Content-Type: application/json' -H @/tmp/headers -d @${putFile} http://gitlab/api/v4/projects/1/repository/files/some-file.txt" - ) + with subtest("Create user Alice"): + gitlab.succeed( + """[ "$(curl -o /dev/null -w '%{http_code}' -X POST -H 'Content-Type: application/json' -H @/tmp/headers -d @${createUserAlice} http://gitlab/api/v4/users)" = "201" ]""" + ) + gitlab.succeed( + "echo \"Authorization: Bearer $(curl -X POST -H 'Content-Type: application/json' -d @${aliceAuth} http://gitlab/oauth/token | ${pkgs.jq}/bin/jq -r '.access_token')\" >/tmp/headers-alice" + ) + + with subtest("Create user Bob"): + gitlab.succeed( + """ [ "$(curl -o /dev/null -w '%{http_code}' -X POST -H 'Content-Type: application/json' -H @/tmp/headers -d @${createUserBob} http://gitlab/api/v4/users)" = "201" ]""" + ) + gitlab.succeed( + "echo \"Authorization: Bearer $(curl -X POST -H 'Content-Type: application/json' -d @${bobAuth} http://gitlab/oauth/token | ${pkgs.jq}/bin/jq -r '.access_token')\" >/tmp/headers-bob" + ) + + with subtest("Setup Git and SSH for Alice"): + gitlab.succeed("git config --global user.name Alice") + gitlab.succeed("git config --global user.email alice@nixos.invalid") + gitlab.succeed("mkdir -m 700 /root/.ssh") + gitlab.succeed("cat ${snakeOilPrivateKey} > /root/.ssh/id_ecdsa") + gitlab.succeed("chmod 600 /root/.ssh/id_ecdsa") + gitlab.succeed( + """ + [ "$(curl \ + -o /dev/null \ + -w '%{http_code}' \ + -X POST \ + -H 'Content-Type: application/json' \ + -H @/tmp/headers-alice -d @${aliceAddSSHKey} \ + http://gitlab/api/v4/user/keys)" = "201" ] + """ + ) + + with subtest("Create a new repository"): + # Alice creates a new repository + gitlab.succeed( + """ + [ "$(curl \ + -o /dev/null \ + -w '%{http_code}' \ + -X POST \ + -H 'Content-Type: application/json' \ + -H @/tmp/headers-alice \ + -d @${createProjectAlice} \ + http://gitlab/api/v4/projects)" = "201" ] + """ + ) + + # Alice commits an initial commit + gitlab.succeed( + """ + [ "$(curl \ + -o /dev/null \ + -w '%{http_code}' \ + -X POST \ + -H 'Content-Type: application/json' \ + -H @/tmp/headers-alice \ + -d @${putFile} \ + http://gitlab/api/v4/projects/${aliceProjectId}/repository/files/some-file.txt)" = "201" ]""" + ) + + with subtest("git clone over HTTP"): + gitlab.succeed( + """git clone http://gitlab/alice/${aliceProjectName}.git clone-via-http""", + timeout=15 + ) + + with subtest("Push a commit via SSH"): + gitlab.succeed( + f"""GIT_SSH_COMMAND="{GIT_SSH_COMMAND}" git clone gitlab@gitlab:alice/${aliceProjectName}.git""", + timeout=15 + ) + gitlab.succeed( + """echo "a commit sent over ssh" > ${aliceProjectName}/ssh.txt""" + ) + gitlab.succeed( + """ + cd ${aliceProjectName} || exit 1 + git add . + """ + ) + gitlab.succeed( + """ + cd ${aliceProjectName} || exit 1 + git commit -m "Add a commit to be sent over ssh" + """ + ) + gitlab.succeed( + f""" + cd ${aliceProjectName} || exit 1 + GIT_SSH_COMMAND="{GIT_SSH_COMMAND}" git push --set-upstream origin master + """, + timeout=15 + ) + + with subtest("Fork a project"): + # Bob forks Alice's project + gitlab.succeed( + """ + [ "$(curl \ + -o /dev/null \ + -w '%{http_code}' \ + -X POST \ + -H 'Content-Type: application/json' \ + -H @/tmp/headers-bob \ + http://gitlab/api/v4/projects/${aliceProjectId}/fork)" = "201" ] + """ + ) + + # Bob creates a commit + gitlab.wait_until_succeeds( + """ + [ "$(curl \ + -o /dev/null \ + -w '%{http_code}' \ + -X POST \ + -H 'Content-Type: application/json' \ + -H @/tmp/headers-bob \ + -d @${putFile} \ + http://gitlab/api/v4/projects/${bobProjectId}/repository/files/some-other-file.txt)" = "201" ] + """ + ) + + with subtest("Create a Merge Request"): + # Bob opens a merge request against Alice's repository + gitlab.wait_until_succeeds( + """ + [ "$(curl \ + -o /dev/null \ + -w '%{http_code}' \ + -X POST \ + -H 'Content-Type: application/json' \ + -H @/tmp/headers-bob \ + -d @${mergeRequest} \ + http://gitlab/api/v4/projects/${bobProjectId}/merge_requests)" = "201" ] + """ + ) + + # Alice merges the MR + gitlab.wait_until_succeeds( + """ + [ "$(curl \ + -o /dev/null \ + -w '%{http_code}' \ + -X PUT \ + -H 'Content-Type: application/json' \ + -H @/tmp/headers-alice \ + -d @${mergeRequest} \ + http://gitlab/api/v4/projects/${aliceProjectId}/merge_requests/1/merge)" = "200" ] + """ + ) + + with subtest("Create an Issue"): + # Bob opens an issue on Alice's repository + gitlab.succeed( + """[ "$(curl \ + -o /dev/null \ + -w '%{http_code}' \ + -X POST \ + -H 'Content-Type: application/json' \ + -H @/tmp/headers-bob \ + -d @${newIssue} \ + http://gitlab/api/v4/projects/${aliceProjectId}/issues)" = "201" ] + """ + ) + + # Alice closes the issue + gitlab.wait_until_succeeds( + """ + [ "$(curl \ + -o /dev/null \ + -w '%{http_code}' \ + -X PUT \ + -H 'Content-Type: application/json' \ + -H @/tmp/headers-alice -d @${closeIssue} http://gitlab/api/v4/projects/${aliceProjectId}/issues/1)" = "200" ] + """ + ) '' + '' - gitlab.succeed( - "curl -H @/tmp/headers http://gitlab/api/v4/projects/1/repository/archive.tar.gz > /tmp/archive.tar.gz" - ) - gitlab.succeed( - "curl -H @/tmp/headers http://gitlab/api/v4/projects/1/repository/archive.tar.bz2 > /tmp/archive.tar.bz2" - ) - gitlab.succeed("test -s /tmp/archive.tar.gz") - gitlab.succeed("test -s /tmp/archive.tar.bz2") + with subtest("Download archive.tar.gz"): + gitlab.succeed( + """ + [ "$(curl \ + -o /dev/null \ + -w '%{http_code}' \ + -H @/tmp/headers-alice \ + http://gitlab/api/v4/projects/${aliceProjectId}/repository/archive.tar.gz)" = "200" ] + """ + ) + gitlab.succeed( + """ + curl \ + -H @/tmp/headers-alice \ + http://gitlab/api/v4/projects/${aliceProjectId}/repository/archive.tar.gz > /tmp/archive.tar.gz + """ + ) + gitlab.succeed("test -s /tmp/archive.tar.gz") + + with subtest("Download archive.tar.bz2"): + gitlab.succeed( + """ + [ "$(curl \ + -o /dev/null \ + -w '%{http_code}' \ + -H @/tmp/headers-alice \ + http://gitlab/api/v4/projects/${aliceProjectId}/repository/archive.tar.bz2)" = "200" ] + """ + ) + gitlab.succeed( + """ + curl \ + -H @/tmp/headers-alice \ + http://gitlab/api/v4/projects/${aliceProjectId}/repository/archive.tar.bz2 > /tmp/archive.tar.bz2 + """ + ) + gitlab.succeed("test -s /tmp/archive.tar.bz2") ''; in '' diff --git a/nixpkgs/nixos/tests/gitolite.nix b/nixpkgs/nixos/tests/gitolite.nix index 128677cebde3..9b3af59e4fbd 100644 --- a/nixpkgs/nixos/tests/gitolite.nix +++ b/nixpkgs/nixos/tests/gitolite.nix @@ -107,7 +107,7 @@ in with subtest("gitolite server starts"): server.wait_for_unit("gitolite-init.service") server.wait_for_unit("sshd.service") - client.succeed("ssh gitolite@server info") + client.succeed("ssh -n gitolite@server info") with subtest("admin can clone and configure gitolite-admin.git"): client.succeed( diff --git a/nixpkgs/nixos/tests/gnome-xorg.nix b/nixpkgs/nixos/tests/gnome-xorg.nix index d7be531e364e..618458b1f6b5 100644 --- a/nixpkgs/nixos/tests/gnome-xorg.nix +++ b/nixpkgs/nixos/tests/gnome-xorg.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, lib, ...} : { maintainers = teams.gnome.members; }; - machine = { nodes, ... }: let + nodes.machine = { nodes, ... }: let user = nodes.machine.config.users.users.alice; in diff --git a/nixpkgs/nixos/tests/gnome.nix b/nixpkgs/nixos/tests/gnome.nix index ca49183fe442..05619cbd7d82 100644 --- a/nixpkgs/nixos/tests/gnome.nix +++ b/nixpkgs/nixos/tests/gnome.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, lib, ...} : { maintainers = teams.gnome.members; }; - machine = + nodes.machine = { ... }: { imports = [ ./common/user-account.nix ]; diff --git a/nixpkgs/nixos/tests/gocd-agent.nix b/nixpkgs/nixos/tests/gocd-agent.nix index 686d0b971d30..9301a88ec05d 100644 --- a/nixpkgs/nixos/tests/gocd-agent.nix +++ b/nixpkgs/nixos/tests/gocd-agent.nix @@ -36,7 +36,7 @@ import ./make-test-python.nix ({ pkgs, ...} : { testScript = '' start_all() agent.wait_for_unit("gocd-server") - agent.wait_for_open_port("8153") + agent.wait_for_open_port(8153) agent.wait_for_unit("gocd-agent") agent.wait_until_succeeds( "curl ${serverUrl} -H '${header}' | ${pkgs.jq}/bin/jq -e ._embedded.agents[0].uuid" diff --git a/nixpkgs/nixos/tests/gotify-server.nix b/nixpkgs/nixos/tests/gotify-server.nix index 051666fbe72e..e7942b76d8e5 100644 --- a/nixpkgs/nixos/tests/gotify-server.nix +++ b/nixpkgs/nixos/tests/gotify-server.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, lib, ...} : { maintainers = [ ma27 ]; }; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { environment.systemPackages = [ pkgs.jq ]; services.gotify = { diff --git a/nixpkgs/nixos/tests/grafana-agent.nix b/nixpkgs/nixos/tests/grafana-agent.nix new file mode 100644 index 000000000000..a9f34d8cea31 --- /dev/null +++ b/nixpkgs/nixos/tests/grafana-agent.nix @@ -0,0 +1,32 @@ +import ./make-test-python.nix ({ lib, pkgs, ... }: + + let + nodes = { + machine = { + services.grafana-agent = { + enable = true; + }; + }; + }; + in + { + name = "grafana-agent"; + + meta = with lib.maintainers; { + maintainers = [ zimbatm ]; + }; + + inherit nodes; + + testScript = '' + start_all() + + with subtest("Grafana-agent is running"): + machine.wait_for_unit("grafana-agent.service") + machine.wait_for_open_port(12345) + machine.succeed( + "curl -sSfN http://127.0.0.1:12345/-/healthy" + ) + machine.shutdown() + ''; + }) diff --git a/nixpkgs/nixos/tests/graphite.nix b/nixpkgs/nixos/tests/graphite.nix index 496f16846ea6..c534d45428e1 100644 --- a/nixpkgs/nixos/tests/graphite.nix +++ b/nixpkgs/nixos/tests/graphite.nix @@ -12,14 +12,8 @@ import ./make-test-python.nix ({ pkgs, ... } : SECRET_KEY = "abcd"; ''; }; - api = { - enable = true; - port = 8082; - finders = [ ]; - }; carbon.enableCache = true; seyren.enable = false; # Implicitely requires openssl-1.0.2u which is marked insecure - beacon.enable = true; }; }; }; @@ -28,21 +22,15 @@ import ./make-test-python.nix ({ pkgs, ... } : start_all() one.wait_for_unit("default.target") one.wait_for_unit("graphiteWeb.service") - one.wait_for_unit("graphiteApi.service") - one.wait_for_unit("graphite-beacon.service") one.wait_for_unit("carbonCache.service") # The services above are of type "simple". systemd considers them active immediately # even if they're still in preStart (which takes quite long for graphiteWeb). # Wait for ports to open so we're sure the services are up and listening. one.wait_for_open_port(8080) - one.wait_for_open_port(8082) one.wait_for_open_port(2003) one.succeed('echo "foo 1 `date +%s`" | nc -N localhost 2003') one.wait_until_succeeds( "curl 'http://localhost:8080/metrics/find/?query=foo&format=treejson' --silent | grep foo >&2" ) - one.wait_until_succeeds( - "curl 'http://localhost:8082/metrics/find/?query=foo&format=treejson' --silent | grep foo >&2" - ) ''; }) diff --git a/nixpkgs/nixos/tests/graylog.nix b/nixpkgs/nixos/tests/graylog.nix index 572904f60d57..23f426fc7af9 100644 --- a/nixpkgs/nixos/tests/graylog.nix +++ b/nixpkgs/nixos/tests/graylog.nix @@ -2,7 +2,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { name = "graylog"; meta.maintainers = with lib.maintainers; [ ]; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { virtualisation.memorySize = 4096; virtualisation.diskSize = 4096; diff --git a/nixpkgs/nixos/tests/grocy.nix b/nixpkgs/nixos/tests/grocy.nix index 2be5c24ecb55..fe0ddd341486 100644 --- a/nixpkgs/nixos/tests/grocy.nix +++ b/nixpkgs/nixos/tests/grocy.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { maintainers = [ ma27 ]; }; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { services.grocy = { enable = true; hostName = "localhost"; diff --git a/nixpkgs/nixos/tests/grub.nix b/nixpkgs/nixos/tests/grub.nix index 84bfc90955b5..e0875e70f6a5 100644 --- a/nixpkgs/nixos/tests/grub.nix +++ b/nixpkgs/nixos/tests/grub.nix @@ -5,7 +5,7 @@ import ./make-test-python.nix ({ lib, ... }: { maintainers = [ rnhmjoj ]; }; - machine = { ... }: { + nodes.machine = { ... }: { virtualisation.useBootLoader = true; boot.loader.timeout = null; diff --git a/nixpkgs/nixos/tests/hadoop/default.nix b/nixpkgs/nixos/tests/hadoop/default.nix index d2a97cbeffb8..479690adc064 100644 --- a/nixpkgs/nixos/tests/hadoop/default.nix +++ b/nixpkgs/nixos/tests/hadoop/default.nix @@ -4,4 +4,5 @@ all = handleTestOn [ "x86_64-linux" "aarch64-linux" ] ./hadoop.nix { inherit package; }; hdfs = handleTestOn [ "x86_64-linux" "aarch64-linux" ] ./hdfs.nix { inherit package; }; yarn = handleTestOn [ "x86_64-linux" "aarch64-linux" ] ./yarn.nix { inherit package; }; + hbase = handleTestOn [ "x86_64-linux" "aarch64-linux" ] ./hbase.nix { inherit package; }; } diff --git a/nixpkgs/nixos/tests/hadoop/hbase.nix b/nixpkgs/nixos/tests/hadoop/hbase.nix new file mode 100644 index 000000000000..d9d2dac0f658 --- /dev/null +++ b/nixpkgs/nixos/tests/hadoop/hbase.nix @@ -0,0 +1,84 @@ +# Test a minimal hbase cluster +{ pkgs, ... }: +import ../make-test-python.nix ({ hadoop ? pkgs.hadoop, hbase ? pkgs.hbase, ... }: +with pkgs.lib; +{ + name = "hadoop-hbase"; + + nodes = let + coreSite = { + "fs.defaultFS" = "hdfs://namenode:8020"; + }; + defOpts = { + enable = true; + openFirewall = true; + }; + zookeeperQuorum = "zookeeper"; + in { + zookeeper = { ... }: { + services.zookeeper.enable = true; + networking.firewall.allowedTCPPorts = [ 2181 ]; + }; + namenode = { ... }: { + services.hadoop = { + hdfs = { + namenode = defOpts // { formatOnInit = true; }; + }; + inherit coreSite; + }; + }; + datanode = { ... }: { + virtualisation.diskSize = 8192; + services.hadoop = { + hdfs.datanode = defOpts; + inherit coreSite; + }; + }; + + master = { ... }:{ + services.hadoop = { + inherit coreSite; + hbase = { + inherit zookeeperQuorum; + master = defOpts // { initHDFS = true; }; + }; + }; + }; + regionserver = { ... }:{ + services.hadoop = { + inherit coreSite; + hbase = { + inherit zookeeperQuorum; + regionServer = defOpts; + }; + }; + }; + }; + + testScript = '' + start_all() + + # wait for HDFS cluster + namenode.wait_for_unit("hdfs-namenode") + namenode.wait_for_unit("network.target") + namenode.wait_for_open_port(8020) + namenode.wait_for_open_port(9870) + datanode.wait_for_unit("hdfs-datanode") + datanode.wait_for_unit("network.target") + datanode.wait_for_open_port(9864) + datanode.wait_for_open_port(9866) + datanode.wait_for_open_port(9867) + + # wait for ZK + zookeeper.wait_for_unit("zookeeper") + zookeeper.wait_for_open_port(2181) + + # wait for HBase to start up + master.wait_for_unit("hbase-master") + regionserver.wait_for_unit("hbase-regionserver") + + assert "1 active master, 0 backup masters, 1 servers" in master.succeed("echo status | HADOOP_USER_NAME=hbase hbase shell -n") + regionserver.wait_until_succeeds("echo \"create 't1','f1'\" | HADOOP_USER_NAME=hbase hbase shell -n") + assert "NAME => 'f1'" in regionserver.succeed("echo \"describe 't1'\" | HADOOP_USER_NAME=hbase hbase shell -n") + ''; +}) diff --git a/nixpkgs/nixos/tests/hadoop/yarn.nix b/nixpkgs/nixos/tests/hadoop/yarn.nix index 1bf8e3831f67..08c8ff857d8c 100644 --- a/nixpkgs/nixos/tests/hadoop/yarn.nix +++ b/nixpkgs/nixos/tests/hadoop/yarn.nix @@ -19,7 +19,7 @@ import ../make-test-python.nix ({ package, ... }: { enable = true; openFirewall = true; }; - yarnSite = options.services.hadoop.yarnSite.default // { + yarnSite = { "yarn.resourcemanager.hostname" = "resourcemanager"; "yarn.nodemanager.log-dirs" = "/tmp/userlogs"; }; diff --git a/nixpkgs/nixos/tests/hardened.nix b/nixpkgs/nixos/tests/hardened.nix index dc455f971f5c..ccb858168547 100644 --- a/nixpkgs/nixos/tests/hardened.nix +++ b/nixpkgs/nixos/tests/hardened.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, ... } : { maintainers = [ joachifm ]; }; - machine = + nodes.machine = { lib, pkgs, config, ... }: with lib; { users.users.alice = { isNormalUser = true; extraGroups = [ "proc" ]; }; @@ -12,6 +12,11 @@ import ./make-test-python.nix ({ pkgs, ... } : { imports = [ ../modules/profiles/hardened.nix ]; environment.memoryAllocator.provider = "graphene-hardened"; nix.settings.sandbox = false; + nixpkgs.overlays = [ + (final: super: { + dhcpcd = super.dhcpcd.override { enablePrivSep = false; }; + }) + ]; virtualisation.emptyDiskImages = [ 4096 ]; boot.initrd.postDeviceCommands = '' ${pkgs.dosfstools}/bin/mkfs.vfat -n EFISYS /dev/vdb @@ -85,8 +90,8 @@ import ./make-test-python.nix ({ pkgs, ... } : { # Test Nix dæmon usage with subtest("nix-daemon cannot be used by all users"): - machine.fail("su -l nobody -s /bin/sh -c 'nix ping-store'") - machine.succeed("su -l alice -c 'nix ping-store'") + machine.fail("su -l nobody -s /bin/sh -c 'nix --extra-experimental-features nix-command ping-store'") + machine.succeed("su -l alice -c 'nix --extra-experimental-features nix-command ping-store'") # Test kernel image protection diff --git a/nixpkgs/nixos/tests/haste-server.nix b/nixpkgs/nixos/tests/haste-server.nix new file mode 100644 index 000000000000..9097c992c548 --- /dev/null +++ b/nixpkgs/nixos/tests/haste-server.nix @@ -0,0 +1,23 @@ +import ./make-test-python.nix ({ pkgs, lib, ... }: + { + name = "haste-server"; + meta.maintainers = with lib.maintainers; [ mkg20001 ]; + + nodes.machine = { pkgs, ... }: { + environment.systemPackages = with pkgs; [ + curl + jq + ]; + + services.haste-server = { + enable = true; + }; + }; + + testScript = '' + machine.wait_for_unit("haste-server") + machine.wait_until_succeeds("curl -s localhost:7777") + machine.succeed('curl -s -X POST http://localhost:7777/documents -d "Hello World!" > bla') + machine.succeed('curl http://localhost:7777/raw/$(cat bla | jq -r .key) | grep "Hello World"') + ''; + }) diff --git a/nixpkgs/nixos/tests/hbase.nix b/nixpkgs/nixos/tests/hbase.nix new file mode 100644 index 000000000000..7d8e32f81603 --- /dev/null +++ b/nixpkgs/nixos/tests/hbase.nix @@ -0,0 +1,30 @@ +import ./make-test-python.nix ({ pkgs, lib, package ? pkgs.hbase, ... }: +{ + name = "hbase-standalone"; + + meta = with lib.maintainers; { + maintainers = [ illustris ]; + }; + + nodes = { + hbase = { pkgs, ... }: { + services.hbase-standalone = { + enable = true; + inherit package; + # Needed for standalone mode in hbase 2+ + # This setting and standalone mode are not suitable for production + settings."hbase.unsafe.stream.capability.enforce" = "false"; + }; + environment.systemPackages = with pkgs; [ + package + ]; + }; + }; + + testScript = '' + start_all() + hbase.wait_for_unit("hbase.service") + hbase.wait_until_succeeds("echo \"create 't1','f1'\" | sudo -u hbase hbase shell -n") + assert "NAME => 'f1'" in hbase.succeed("echo \"describe 't1'\" | sudo -u hbase hbase shell -n") + ''; +}) diff --git a/nixpkgs/nixos/tests/hedgedoc.nix b/nixpkgs/nixos/tests/hedgedoc.nix index 657d49c555e9..410350d83627 100644 --- a/nixpkgs/nixos/tests/hedgedoc.nix +++ b/nixpkgs/nixos/tests/hedgedoc.nix @@ -11,7 +11,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: services = { hedgedoc = { enable = true; - configuration.dbURL = "sqlite:///var/lib/hedgedoc/hedgedoc.db"; + settings.dbURL = "sqlite:///var/lib/hedgedoc/hedgedoc.db"; }; }; }; @@ -21,7 +21,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: services = { hedgedoc = { enable = true; - configuration.dbURL = "postgres://hedgedoc:\${DB_PASSWORD}@localhost:5432/hedgedocdb"; + settings.dbURL = "postgres://hedgedoc:\${DB_PASSWORD}@localhost:5432/hedgedocdb"; /* * Do not use pkgs.writeText for secrets as diff --git a/nixpkgs/nixos/tests/herbstluftwm.nix b/nixpkgs/nixos/tests/herbstluftwm.nix index 7d079f4bfb69..b6965914360e 100644 --- a/nixpkgs/nixos/tests/herbstluftwm.nix +++ b/nixpkgs/nixos/tests/herbstluftwm.nix @@ -5,7 +5,7 @@ import ./make-test-python.nix ({ lib, ...} : { maintainers = with lib.maintainers; [ thibautmarty ]; }; - machine = { pkgs, lib, ... }: { + nodes.machine = { pkgs, lib, ... }: { imports = [ ./common/x11.nix ./common/user-account.nix ]; test-support.displayManager.auto.user = "alice"; services.xserver.displayManager.defaultSession = lib.mkForce "none+herbstluftwm"; diff --git a/nixpkgs/nixos/tests/hibernate.nix b/nixpkgs/nixos/tests/hibernate.nix index 3880f1649bd3..7a4b331169a3 100644 --- a/nixpkgs/nixos/tests/hibernate.nix +++ b/nixpkgs/nixos/tests/hibernate.nix @@ -3,6 +3,7 @@ { system ? builtins.currentSystem , config ? {} , pkgs ? import ../.. { inherit system config; } +, systemdStage1 ? false }: with import ../lib/testing-python.nix { inherit system pkgs; }; @@ -29,6 +30,11 @@ let "/".device = "/dev/vda2"; }; swapDevices = mkOverride 0 [ { device = "/dev/vda1"; } ]; + boot.resumeDevice = mkIf systemdStage1 "/dev/vda1"; + boot.initrd.systemd = mkIf systemdStage1 { + enable = true; + emergencyAccess = true; + }; }; installedSystem = (import ../lib/eval-config.nix { inherit system; @@ -117,6 +123,11 @@ in makeTest { resume = create_named_machine("resume") resume.start() resume.succeed("grep 'not persisted to disk' /run/test/suspended") + + # Ensure we don't restore from hibernation when booting again + resume.crash() + resume.wait_for_unit("default.target") + resume.fail("grep 'not persisted to disk' /run/test/suspended") ''; } diff --git a/nixpkgs/nixos/tests/hitch/default.nix b/nixpkgs/nixos/tests/hitch/default.nix index a1d8e6162606..4283b9f7dffb 100644 --- a/nixpkgs/nixos/tests/hitch/default.nix +++ b/nixpkgs/nixos/tests/hitch/default.nix @@ -4,7 +4,7 @@ import ../make-test-python.nix ({ pkgs, ... }: meta = with pkgs.lib.maintainers; { maintainers = [ jflanglois ]; }; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { environment.systemPackages = [ pkgs.curl ]; services.hitch = { enable = true; diff --git a/nixpkgs/nixos/tests/hocker-fetchdocker/default.nix b/nixpkgs/nixos/tests/hocker-fetchdocker/default.nix index e3979db3c60b..b5c06126c2e8 100644 --- a/nixpkgs/nixos/tests/hocker-fetchdocker/default.nix +++ b/nixpkgs/nixos/tests/hocker-fetchdocker/default.nix @@ -5,7 +5,7 @@ import ../make-test-python.nix ({ pkgs, ...} : { broken = true; # tries to download from registry-1.docker.io - how did this ever work? }; - machine = import ./machine.nix; + nodes.machine = import ./machine.nix; testScript = '' start_all() diff --git a/nixpkgs/nixos/tests/hockeypuck.nix b/nixpkgs/nixos/tests/hockeypuck.nix index 19df9dee3d31..d1ef4cbf588a 100644 --- a/nixpkgs/nixos/tests/hockeypuck.nix +++ b/nixpkgs/nixos/tests/hockeypuck.nix @@ -24,7 +24,7 @@ in { name = "hockeypuck"; meta.maintainers = with lib.maintainers; [ etu ]; - machine = { ... }: { + nodes.machine = { ... }: { # Used for test environment.systemPackages = [ pkgs.gnupg ]; diff --git a/nixpkgs/nixos/tests/home-assistant.nix b/nixpkgs/nixos/tests/home-assistant.nix index 10f9cb05c9cb..0bbeffd18cf0 100644 --- a/nixpkgs/nixos/tests/home-assistant.nix +++ b/nixpkgs/nixos/tests/home-assistant.nix @@ -7,8 +7,6 @@ in { meta.maintainers = lib.teams.home-assistant.members; nodes.hass = { pkgs, ... }: { - environment.systemPackages = with pkgs; [ mosquitto ]; - services.postgresql = { enable = true; ensureDatabases = [ "hass" ]; @@ -98,10 +96,26 @@ in { }; lovelaceConfigWritable = true; }; + + # Cause a configuration change inside `configuration.yml` and verify that the process is being reloaded. + specialisation.differentName = { + inheritParentConfig = true; + configuration.services.home-assistant.config.homeassistant.name = lib.mkForce "Test Home"; + }; + + # Cause a configuration change that requires a service restart as we added a new runtime dependency + specialisation.newFeature = { + inheritParentConfig = true; + configuration.services.home-assistant.config.esphome = {}; + }; }; - testScript = '' + testScript = { nodes, ... }: let + system = nodes.hass.config.system.build.toplevel; + in + '' import re + import json start_all() @@ -111,9 +125,22 @@ in { pattern = re.compile(r"path=(?P<path>[\/a-z0-9-.]+)\/bin\/hass") response = hass.execute("systemctl show -p ExecStart home-assistant.service")[1] match = pattern.search(response) + assert match package = match.group('path') + + def get_journal_cursor(host) -> str: + exit, out = host.execute("journalctl -u home-assistant.service -n1 -o json-pretty --output-fields=__CURSOR") + assert exit == 0 + return json.loads(out)["__CURSOR"] + + + def wait_for_homeassistant(host, cursor): + host.wait_until_succeeds(f"journalctl --after-cursor='{cursor}' -u home-assistant.service | grep -q 'Home Assistant initialized in'") + + hass.wait_for_unit("home-assistant.service") + cursor = get_journal_cursor(hass) with subtest("Check that YAML configuration file is in place"): hass.succeed("test -L ${configDir}/configuration.yaml") @@ -130,7 +157,7 @@ in { hass.succeed(f"grep -q 'wake_on_lan' {package}/extra_components") with subtest("Check that Home Assistant's web interface and API can be reached"): - hass.wait_until_succeeds("journalctl -u home-assistant.service | grep -q 'Home Assistant initialized in'") + wait_for_homeassistant(hass, cursor) hass.wait_for_open_port(8123) hass.succeed("curl --fail http://localhost:8123/lovelace") @@ -141,12 +168,25 @@ in { with subtest("Check extra components are considered in systemd unit hardening"): hass.succeed("systemctl show -p DeviceAllow home-assistant.service | grep -q char-ttyUSB") - with subtest("Print log to ease debugging"): - output_log = hass.succeed("cat ${configDir}/home-assistant.log") - print("\n### home-assistant.log ###\n") - print(output_log + "\n") + with subtest("Check service reloads when configuration changes"): + # store the old pid of the process + pid = hass.succeed("systemctl show --property=MainPID home-assistant.service") + cursor = get_journal_cursor(hass) + hass.succeed("${system}/specialisation/differentName/bin/switch-to-configuration test") + new_pid = hass.succeed("systemctl show --property=MainPID home-assistant.service") + assert pid == new_pid, "The PID of the process should not change between process reloads" + wait_for_homeassistant(hass, cursor) + + with subtest("check service restarts when package changes"): + pid = new_pid + cursor = get_journal_cursor(hass) + hass.succeed("${system}/specialisation/newFeature/bin/switch-to-configuration test") + new_pid = hass.succeed("systemctl show --property=MainPID home-assistant.service") + assert pid != new_pid, "The PID of the process shoudl change when the HA binary changes" + wait_for_homeassistant(hass, cursor) with subtest("Check that no errors were logged"): + output_log = hass.succeed("cat ${configDir}/home-assistant.log") assert "ERROR" not in output_log with subtest("Check systemd unit hardening"): diff --git a/nixpkgs/nixos/tests/hostname.nix b/nixpkgs/nixos/tests/hostname.nix index 2e92b4259a6a..1de8f19267af 100644 --- a/nixpkgs/nixos/tests/hostname.nix +++ b/nixpkgs/nixos/tests/hostname.nix @@ -20,7 +20,7 @@ let maintainers = [ primeos blitz ]; }; - machine = { lib, ... }: { + nodes.machine = { lib, ... }: { networking.hostName = hostName; networking.domain = domain; diff --git a/nixpkgs/nixos/tests/hound.nix b/nixpkgs/nixos/tests/hound.nix index 4f51db1de9de..a9b036deb0dd 100644 --- a/nixpkgs/nixos/tests/hound.nix +++ b/nixpkgs/nixos/tests/hound.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, ... } : { meta = with pkgs.lib.maintainers; { maintainers = [ grahamc ]; }; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { services.hound = { enable = true; config = '' diff --git a/nixpkgs/nixos/tests/hydra/default.nix b/nixpkgs/nixos/tests/hydra/default.nix index ef5e677953dc..baf18afbc569 100644 --- a/nixpkgs/nixos/tests/hydra/default.nix +++ b/nixpkgs/nixos/tests/hydra/default.nix @@ -11,7 +11,7 @@ let inherit (import ./common.nix { inherit system; }) baseConfig; hydraPkgs = { - inherit (pkgs) hydra-unstable; + inherit (pkgs) hydra_unstable; }; makeHydraTest = with pkgs.lib; name: package: makeTest { @@ -20,7 +20,7 @@ let maintainers = [ lewo ma27 ]; }; - machine = { pkgs, lib, ... }: { + nodes.machine = { pkgs, lib, ... }: { imports = [ baseConfig ]; services.hydra = { inherit package; }; }; diff --git a/nixpkgs/nixos/tests/i3wm.nix b/nixpkgs/nixos/tests/i3wm.nix index 59b4ffe3986e..b216650d8192 100644 --- a/nixpkgs/nixos/tests/i3wm.nix +++ b/nixpkgs/nixos/tests/i3wm.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, ...} : { maintainers = [ aszlig ]; }; - machine = { lib, ... }: { + nodes.machine = { lib, ... }: { imports = [ ./common/x11.nix ./common/user-account.nix ]; test-support.displayManager.auto.user = "alice"; services.xserver.displayManager.defaultSession = lib.mkForce "none+i3"; diff --git a/nixpkgs/nixos/tests/ihatemoney/default.nix b/nixpkgs/nixos/tests/ihatemoney/default.nix index 78278d2e8699..894a97d43d35 100644 --- a/nixpkgs/nixos/tests/ihatemoney/default.nix +++ b/nixpkgs/nixos/tests/ihatemoney/default.nix @@ -7,7 +7,7 @@ let inherit (import ../../lib/testing-python.nix { inherit system pkgs; }) makeTest; f = backend: makeTest { name = "ihatemoney-${backend}"; - machine = { nodes, lib, ... }: { + nodes.machine = { nodes, lib, ... }: { services.ihatemoney = { enable = true; enablePublicProjectCreation = true; @@ -32,14 +32,7 @@ let }; }; # ihatemoney needs a local smtp server otherwise project creation just crashes - services.opensmtpd = { - enable = true; - serverConfiguration = '' - listen on lo - action foo relay - match from any for any action foo - ''; - }; + services.postfix.enable = true; }; testScript = '' machine.wait_for_open_port(8000) diff --git a/nixpkgs/nixos/tests/incron.nix b/nixpkgs/nixos/tests/incron.nix index b22ee4c9a037..c978ff27dfad 100644 --- a/nixpkgs/nixos/tests/incron.nix +++ b/nixpkgs/nixos/tests/incron.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: name = "incron"; meta.maintainers = [ lib.maintainers.aanderse ]; - machine = + nodes.machine = { ... }: { services.incron.enable = true; services.incron.extraPackages = [ pkgs.coreutils ]; diff --git a/nixpkgs/nixos/tests/initrd-network.nix b/nixpkgs/nixos/tests/initrd-network.nix index 14e7e7d40bc5..f2483b7393de 100644 --- a/nixpkgs/nixos/tests/initrd-network.nix +++ b/nixpkgs/nixos/tests/initrd-network.nix @@ -3,7 +3,7 @@ import ./make-test-python.nix ({ pkgs, lib, ...} : { meta.maintainers = [ pkgs.lib.maintainers.eelco ]; - machine = { ... }: { + nodes.machine = { ... }: { imports = [ ../modules/profiles/minimal.nix ]; boot.initrd.network.enable = true; boot.initrd.network.postCommands = diff --git a/nixpkgs/nixos/tests/initrd-secrets.nix b/nixpkgs/nixos/tests/initrd-secrets.nix index 113a9cebf788..0f3f83b0904e 100644 --- a/nixpkgs/nixos/tests/initrd-secrets.nix +++ b/nixpkgs/nixos/tests/initrd-secrets.nix @@ -11,7 +11,7 @@ let meta.maintainers = [ lib.maintainers.lheckemann ]; - machine = { ... }: { + nodes.machine = { ... }: { virtualisation.useBootLoader = true; boot.initrd.secrets = { "/test" = secretInStore; diff --git a/nixpkgs/nixos/tests/input-remapper.nix b/nixpkgs/nixos/tests/input-remapper.nix index f692564caa57..1b0350063f7f 100644 --- a/nixpkgs/nixos/tests/input-remapper.nix +++ b/nixpkgs/nixos/tests/input-remapper.nix @@ -6,7 +6,7 @@ import ./make-test-python.nix ({ pkgs, ... }: maintainers = with pkgs.lib.maintainers; [ LunNova ]; }; - machine = { config, ... }: + nodes.machine = { config, ... }: let user = config.users.users.sybil; in { imports = [ diff --git a/nixpkgs/nixos/tests/installed-tests/default.nix b/nixpkgs/nixos/tests/installed-tests/default.nix index 079fd54e71e5..b81384aa8c0b 100644 --- a/nixpkgs/nixos/tests/installed-tests/default.nix +++ b/nixpkgs/nixos/tests/installed-tests/default.nix @@ -43,7 +43,7 @@ let maintainers = tested.meta.maintainers; }; - machine = { ... }: { + nodes.machine = { ... }: { imports = [ testConfig ] ++ optional withX11 ../common/x11.nix; @@ -92,6 +92,7 @@ in fwupd = callInstalledTest ./fwupd.nix {}; gcab = callInstalledTest ./gcab.nix {}; gdk-pixbuf = callInstalledTest ./gdk-pixbuf.nix {}; + geocode-glib = callInstalledTest ./geocode-glib.nix {}; gjs = callInstalledTest ./gjs.nix {}; glib-networking = callInstalledTest ./glib-networking.nix {}; gnome-photos = callInstalledTest ./gnome-photos.nix {}; @@ -106,6 +107,5 @@ in malcontent = callInstalledTest ./malcontent.nix {}; ostree = callInstalledTest ./ostree.nix {}; pipewire = callInstalledTest ./pipewire.nix {}; - power-profiles-daemon = callInstalledTest ./power-profiles-daemon.nix {}; xdg-desktop-portal = callInstalledTest ./xdg-desktop-portal.nix {}; } diff --git a/nixpkgs/nixos/tests/installed-tests/flatpak-builder.nix b/nixpkgs/nixos/tests/installed-tests/flatpak-builder.nix index 31b9f2b258fd..41f4060fb69e 100644 --- a/nixpkgs/nixos/tests/installed-tests/flatpak-builder.nix +++ b/nixpkgs/nixos/tests/installed-tests/flatpak-builder.nix @@ -6,6 +6,7 @@ makeInstalledTest { testConfig = { services.flatpak.enable = true; xdg.portal.enable = true; + xdg.portal.extraPortals = with pkgs; [ xdg-desktop-portal-gtk ]; environment.systemPackages = with pkgs; [ flatpak-builder ] ++ flatpak-builder.installedTestsDependencies; virtualisation.diskSize = 2048; }; diff --git a/nixpkgs/nixos/tests/installed-tests/geocode-glib.nix b/nixpkgs/nixos/tests/installed-tests/geocode-glib.nix new file mode 100644 index 000000000000..fcb38c96ab0f --- /dev/null +++ b/nixpkgs/nixos/tests/installed-tests/geocode-glib.nix @@ -0,0 +1,13 @@ +{ pkgs, makeInstalledTest, ... }: + +makeInstalledTest { + testConfig = { + i18n.supportedLocales = [ + "en_US.UTF-8/UTF-8" + # The tests require this locale available. + "en_GB.UTF-8/UTF-8" + ]; + }; + + tested = pkgs.geocode-glib; +} diff --git a/nixpkgs/nixos/tests/installed-tests/power-profiles-daemon.nix b/nixpkgs/nixos/tests/installed-tests/power-profiles-daemon.nix deleted file mode 100644 index 43629a0155d2..000000000000 --- a/nixpkgs/nixos/tests/installed-tests/power-profiles-daemon.nix +++ /dev/null @@ -1,9 +0,0 @@ -{ pkgs, lib, makeInstalledTest, ... }: - -makeInstalledTest { - tested = pkgs.power-profiles-daemon; - - testConfig = { - services.power-profiles-daemon.enable = true; - }; -} diff --git a/nixpkgs/nixos/tests/installer-systemd-stage-1.nix b/nixpkgs/nixos/tests/installer-systemd-stage-1.nix new file mode 100644 index 000000000000..d02387ee80e0 --- /dev/null +++ b/nixpkgs/nixos/tests/installer-systemd-stage-1.nix @@ -0,0 +1,33 @@ +{ system ? builtins.currentSystem +, config ? {} +, pkgs ? import ../.. { inherit system config; } +}: + +{ + # Some of these tests don't work with systemd stage 1 yet. Uncomment + # them when fixed. + inherit (import ./installer.nix { inherit system config pkgs; systemdStage1 = true; }) + # bcache + # btrfsSimple + # btrfsSubvolDefault + # btrfsSubvols + # encryptedFSWithKeyfile + # grub1 + # luksroot + # luksroot-format1 + # luksroot-format2 + # lvm + separateBoot + separateBootFat + simple + simpleLabels + simpleProvided + simpleSpecialised + simpleUefiGrub + simpleUefiGrubSpecialisation + simpleUefiSystemdBoot + # swraid + zfsroot + ; + +} diff --git a/nixpkgs/nixos/tests/installer.nix b/nixpkgs/nixos/tests/installer.nix index 2cfadf85c935..8bef4fad3dd2 100644 --- a/nixpkgs/nixos/tests/installer.nix +++ b/nixpkgs/nixos/tests/installer.nix @@ -1,6 +1,7 @@ { system ? builtins.currentSystem, config ? {}, - pkgs ? import ../.. { inherit system config; } + pkgs ? import ../.. { inherit system config; }, + systemdStage1 ? false }: with import ../lib/testing-python.nix { inherit system pkgs; }; @@ -23,6 +24,8 @@ let # To ensure that we can rebuild the grub configuration on the nixos-rebuild system.extraDependencies = with pkgs; [ stdenvNoCC ]; + ${optionalString systemdStage1 "boot.initrd.systemd.enable = true;"} + ${optionalString (bootLoader == "grub") '' boot.loader.grub.version = ${toString grubVersion}; ${optionalString (grubVersion == 1) '' @@ -290,6 +293,8 @@ let virtualisation.cores = 8; virtualisation.memorySize = 1536; + boot.initrd.systemd.enable = systemdStage1; + # Use a small /dev/vdb as the root disk for the # installer. This ensures the target disk (/dev/vda) is # the same during and after installation. @@ -299,6 +304,13 @@ let virtualisation.qemu.diskInterface = if grubVersion == 1 then "scsi" else "virtio"; + # We don't want to have any networking in the guest whatsoever. + # Also, if any vlans are enabled, the guest will reboot + # (with a different configuration for legacy reasons), + # and spend 5 minutes waiting for the vlan interface to show up + # (which will never happen). + virtualisation.vlans = []; + boot.loader.systemd-boot.enable = mkIf (bootLoader == "systemd-boot") true; hardware.enableAllFirmware = mkForce false; @@ -312,6 +324,8 @@ let desktop-file-utils docbook5 docbook_xsl_ns + kmod.dev + libarchive.dev libxml2.bin libxslt.bin nixos-artwork.wallpapers.simple-dark-gray-bottom @@ -687,6 +701,85 @@ in { ''; }; + bcachefsSimple = makeInstallerTest "bcachefs-simple" { + extraInstallerConfig = { + boot.supportedFilesystems = [ "bcachefs" ]; + }; + + createPartitions = '' + machine.succeed( + "flock /dev/vda parted --script /dev/vda -- mklabel msdos" + + " mkpart primary ext2 1M 100MB" # /boot + + " mkpart primary linux-swap 100M 1024M" # swap + + " mkpart primary 1024M -1s", # / + "udevadm settle", + "mkswap /dev/vda2 -L swap", + "swapon -L swap", + "mkfs.bcachefs -L root /dev/vda3", + "mount -t bcachefs /dev/vda3 /mnt", + "mkfs.ext3 -L boot /dev/vda1", + "mkdir -p /mnt/boot", + "mount /dev/vda1 /mnt/boot", + ) + ''; + }; + + bcachefsEncrypted = makeInstallerTest "bcachefs-encrypted" { + extraInstallerConfig = { + boot.supportedFilesystems = [ "bcachefs" ]; + environment.systemPackages = with pkgs; [ keyutils ]; + }; + + # We don't want to use the normal way of unlocking bcachefs defined in tasks/filesystems/bcachefs.nix. + # So, override initrd.postDeviceCommands completely and simply unlock with the predefined password. + extraConfig = '' + boot.initrd.postDeviceCommands = lib.mkForce "echo password | bcachefs unlock /dev/vda3"; + ''; + + createPartitions = '' + machine.succeed( + "flock /dev/vda parted --script /dev/vda -- mklabel msdos" + + " mkpart primary ext2 1M 100MB" # /boot + + " mkpart primary linux-swap 100M 1024M" # swap + + " mkpart primary 1024M -1s", # / + "udevadm settle", + "mkswap /dev/vda2 -L swap", + "swapon -L swap", + "keyctl link @u @s", + "echo password | mkfs.bcachefs -L root --encrypted /dev/vda3", + "echo password | bcachefs unlock /dev/vda3", + "mount -t bcachefs /dev/vda3 /mnt", + "mkfs.ext3 -L boot /dev/vda1", + "mkdir -p /mnt/boot", + "mount /dev/vda1 /mnt/boot", + ) + ''; + }; + + bcachefsMulti = makeInstallerTest "bcachefs-multi" { + extraInstallerConfig = { + boot.supportedFilesystems = [ "bcachefs" ]; + }; + + createPartitions = '' + machine.succeed( + "flock /dev/vda parted --script /dev/vda -- mklabel msdos" + + " mkpart primary ext2 1M 100MB" # /boot + + " mkpart primary linux-swap 100M 1024M" # swap + + " mkpart primary 1024M 4096M" # / + + " mkpart primary 4096M -1s", # / + "udevadm settle", + "mkswap /dev/vda2 -L swap", + "swapon -L swap", + "mkfs.bcachefs -L root --metadata_replicas 2 --foreground_target ssd --promote_target ssd --background_target hdd --label ssd /dev/vda3 --label hdd /dev/vda4", + "mount -t bcachefs /dev/vda3:/dev/vda4 /mnt", + "mkfs.ext3 -L boot /dev/vda1", + "mkdir -p /mnt/boot", + "mount /dev/vda1 /mnt/boot", + ) + ''; + }; + # Test a basic install using GRUB 1. grub1 = makeInstallerTest "grub1" rec { createPartitions = '' diff --git a/nixpkgs/nixos/tests/invidious.nix b/nixpkgs/nixos/tests/invidious.nix index 8b831715a441..582d1550fff1 100644 --- a/nixpkgs/nixos/tests/invidious.nix +++ b/nixpkgs/nixos/tests/invidious.nix @@ -5,7 +5,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { maintainers = [ sbruder ]; }; - machine = { config, lib, pkgs, ... }: { + nodes.machine = { config, lib, pkgs, ... }: { services.invidious = { enable = true; }; diff --git a/nixpkgs/nixos/tests/ipfs.nix b/nixpkgs/nixos/tests/ipfs.nix index 5e7c967028e4..024822745ada 100644 --- a/nixpkgs/nixos/tests/ipfs.nix +++ b/nixpkgs/nixos/tests/ipfs.nix @@ -14,6 +14,14 @@ import ./make-test-python.nix ({ pkgs, ...} : { }; }; + nodes.fuse = { ... }: { + services.ipfs = { + enable = true; + apiAddress = "/ip4/127.0.0.1/tcp/2324"; + autoMount = true; + }; + }; + testScript = '' start_all() @@ -40,5 +48,14 @@ import ./make-test-python.nix ({ pkgs, ...} : { # Test if setting dataDir works properly with the hardened systemd unit machine.succeed("test -e /mnt/ipfs/config") machine.succeed("test ! -e /var/lib/ipfs/") + + # Test FUSE mountpoint + ipfs_hash = fuse.succeed( + "echo fnord3 | ipfs --api /ip4/127.0.0.1/tcp/2324 add --quieter" + ) + + # The FUSE mount functionality is broken as of v0.13.0. + # See https://github.com/ipfs/kubo/issues/9044. + # fuse.succeed(f"cat /ipfs/{ipfs_hash.strip()} | grep fnord3") ''; }) diff --git a/nixpkgs/nixos/tests/isso.nix b/nixpkgs/nixos/tests/isso.nix index 99dc8009ae06..575e1c52eccf 100644 --- a/nixpkgs/nixos/tests/isso.nix +++ b/nixpkgs/nixos/tests/isso.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { maintainers = [ asbachb ]; }; - machine = { config, pkgs, ... }: { + nodes.machine = { config, pkgs, ... }: { services.isso = { enable = true; settings = { @@ -22,7 +22,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { '' machine.wait_for_unit("isso.service") - machine.wait_for_open_port("${toString port}") + machine.wait_for_open_port(${toString port}) machine.succeed("curl --fail http://localhost:${toString port}/?uri") machine.succeed("curl --fail http://localhost:${toString port}/js/embed.min.js") diff --git a/nixpkgs/nixos/tests/jellyfin.nix b/nixpkgs/nixos/tests/jellyfin.nix index cae31a719258..7d3097b58629 100644 --- a/nixpkgs/nixos/tests/jellyfin.nix +++ b/nixpkgs/nixos/tests/jellyfin.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ lib, pkgs, ... }: name = "jellyfin"; meta.maintainers = with lib.maintainers; [ minijackson ]; - machine = + nodes.machine = { ... }: { services.jellyfin.enable = true; @@ -52,18 +52,18 @@ import ./make-test-python.nix ({ lib, pkgs, ... }: machine.succeed(api_post("/Startup/Complete")) with machine.nested("Can login"): - auth_result = machine.succeed( + auth_result_str = machine.succeed( api_post( "/Users/AuthenticateByName", "${payloads.auth}", ) ) - auth_result = json.loads(auth_result) + auth_result = json.loads(auth_result_str) auth_token = auth_result["AccessToken"] auth_header += f", Token={auth_token}" - sessions_result = machine.succeed(api_get("/Sessions")) - sessions_result = json.loads(sessions_result) + sessions_result_str = machine.succeed(api_get("/Sessions")) + sessions_result = json.loads(sessions_result_str) this_session = [ session for session in sessions_result if session["DeviceId"] == "1337" @@ -71,8 +71,8 @@ import ./make-test-python.nix ({ lib, pkgs, ... }: if len(this_session) != 1: raise Exception("Session not created") - me = machine.succeed(api_get("/Users/Me")) - me = json.loads(me)["Id"] + me_str = machine.succeed(api_get("/Users/Me")) + me = json.loads(me_str)["Id"] with machine.nested("Can add library"): tempdir = machine.succeed("mktemp -d -p /var/lib/jellyfin").strip() @@ -100,8 +100,8 @@ import ./make-test-python.nix ({ lib, pkgs, ... }: def is_refreshed(_): - folders = machine.succeed(api_get("/Library/VirtualFolders")) - folders = json.loads(folders) + folders_str = machine.succeed(api_get("/Library/VirtualFolders")) + folders = json.loads(folders_str) print(folders) return all(folder["RefreshStatus"] == "Idle" for folder in folders) @@ -116,10 +116,10 @@ import ./make-test-python.nix ({ lib, pkgs, ... }: def has_movie(_): global items - items = machine.succeed( + items_str = machine.succeed( api_get(f"/Users/{me}/Items?IncludeItemTypes=Movie&Recursive=true") ) - items = json.loads(items)["Items"] + items = json.loads(items_str)["Items"] return len(items) == 1 @@ -127,8 +127,8 @@ import ./make-test-python.nix ({ lib, pkgs, ... }: video = items[0]["Id"] - item_info = machine.succeed(api_get(f"/Users/{me}/Items/{video}")) - item_info = json.loads(item_info) + item_info_str = machine.succeed(api_get(f"/Users/{me}/Items/{video}")) + item_info = json.loads(item_info_str) if item_info["Name"] != "Big Buck Bunny": raise Exception("Jellyfin failed to properly identify file") diff --git a/nixpkgs/nixos/tests/jenkins.nix b/nixpkgs/nixos/tests/jenkins.nix index cb4207c6e773..3f111426db38 100644 --- a/nixpkgs/nixos/tests/jenkins.nix +++ b/nixpkgs/nixos/tests/jenkins.nix @@ -18,6 +18,8 @@ import ./make-test-python.nix ({ pkgs, ...} : { enable = true; jobBuilder = { enable = true; + accessUser = "admin"; + accessTokenFile = "/var/lib/jenkins/secrets/initialAdminPassword"; nixJobs = [ { job = { name = "job-1"; @@ -79,7 +81,7 @@ import ./make-test-python.nix ({ pkgs, ...} : { in '' start_all() - master.wait_for_unit("jenkins") + master.wait_for_unit("default.target") assert "Authentication required" in master.succeed("curl http://localhost:8080") @@ -90,20 +92,16 @@ import ./make-test-python.nix ({ pkgs, ...} : { slave.fail("systemctl is-enabled jenkins.service") + slave.succeed("java -fullversion") + with subtest("jobs are declarative"): # Check that jobs are created on disk. - master.wait_for_unit("jenkins-job-builder") - master.wait_until_fails("systemctl is-active jenkins-job-builder") master.wait_until_succeeds("test -f /var/lib/jenkins/jobs/job-1/config.xml") master.wait_until_succeeds("test -f /var/lib/jenkins/jobs/folder-1/config.xml") master.wait_until_succeeds("test -f /var/lib/jenkins/jobs/folder-1/jobs/job-2/config.xml") - # Wait until jenkins is ready, reload configuration and verify it also - # sees the jobs. - master.succeed("curl --fail ${jenkinsUrl}/cli") - master.succeed("curl ${jenkinsUrl}/jnlpJars/jenkins-cli.jar -O") - master.succeed("${pkgs.jre}/bin/java -jar jenkins-cli.jar -s ${jenkinsUrl} -auth admin:$(cat /var/lib/jenkins/secrets/initialAdminPassword) reload-configuration") - out = master.succeed("${pkgs.jre}/bin/java -jar jenkins-cli.jar -s ${jenkinsUrl} -auth admin:$(cat /var/lib/jenkins/secrets/initialAdminPassword) list-jobs") + # Verify that jenkins also sees the jobs. + out = master.succeed("${pkgs.jenkins}/bin/jenkins-cli -s ${jenkinsUrl} -auth admin:$(cat /var/lib/jenkins/secrets/initialAdminPassword) list-jobs") jobs = [x.strip() for x in out.splitlines()] # Seeing jobs inside folders requires the Folders plugin # (https://plugins.jenkins.io/cloudbees-folder/), which we don't have @@ -115,15 +113,12 @@ import ./make-test-python.nix ({ pkgs, ...} : { ) # Check that jobs are removed from disk. - master.wait_for_unit("jenkins-job-builder") - master.wait_until_fails("systemctl is-active jenkins-job-builder") master.wait_until_fails("test -f /var/lib/jenkins/jobs/job-1/config.xml") master.wait_until_fails("test -f /var/lib/jenkins/jobs/folder-1/config.xml") master.wait_until_fails("test -f /var/lib/jenkins/jobs/folder-1/jobs/job-2/config.xml") - # Reload jenkins' configuration and verify it also sees the jobs as removed. - master.succeed("${pkgs.jre}/bin/java -jar jenkins-cli.jar -s ${jenkinsUrl} -auth admin:$(cat /var/lib/jenkins/secrets/initialAdminPassword) reload-configuration") - out = master.succeed("${pkgs.jre}/bin/java -jar jenkins-cli.jar -s ${jenkinsUrl} -auth admin:$(cat /var/lib/jenkins/secrets/initialAdminPassword) list-jobs") + # Verify that jenkins also sees the jobs as removed. + out = master.succeed("${pkgs.jenkins}/bin/jenkins-cli -s ${jenkinsUrl} -auth admin:$(cat /var/lib/jenkins/secrets/initialAdminPassword) list-jobs") jobs = [x.strip() for x in out.splitlines()] assert jobs == [], f"jobs != []: {jobs}" ''; diff --git a/nixpkgs/nixos/tests/jibri.nix b/nixpkgs/nixos/tests/jibri.nix index af20e639d30e..223120cdb229 100644 --- a/nixpkgs/nixos/tests/jibri.nix +++ b/nixpkgs/nixos/tests/jibri.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { maintainers = teams.jitsi.members; }; - machine = { config, pkgs, ... }: { + nodes.machine = { config, pkgs, ... }: { virtualisation.memorySize = 5120; services.jitsi-meet = { diff --git a/nixpkgs/nixos/tests/jitsi-meet.nix b/nixpkgs/nixos/tests/jitsi-meet.nix index 41d53bc73800..c39cd19e1f0a 100644 --- a/nixpkgs/nixos/tests/jitsi-meet.nix +++ b/nixpkgs/nixos/tests/jitsi-meet.nix @@ -34,9 +34,6 @@ import ./make-test-python.nix ({ pkgs, ... }: { server.wait_for_unit("prosody.service") server.wait_until_succeeds( - "journalctl -b -u jitsi-videobridge2 -o cat | grep -q 'Performed a successful health check'" - ) - server.wait_until_succeeds( "journalctl -b -u prosody -o cat | grep -q 'Authenticated as focus@auth.server'" ) server.wait_until_succeeds( diff --git a/nixpkgs/nixos/tests/k3s-single-node-docker.nix b/nixpkgs/nixos/tests/k3s-single-node-docker.nix deleted file mode 100644 index 7f3d15788b04..000000000000 --- a/nixpkgs/nixos/tests/k3s-single-node-docker.nix +++ /dev/null @@ -1,84 +0,0 @@ -import ./make-test-python.nix ({ pkgs, ... }: - - let - imageEnv = pkgs.buildEnv { - name = "k3s-pause-image-env"; - paths = with pkgs; [ tini (hiPrio coreutils) busybox ]; - }; - pauseImage = pkgs.dockerTools.streamLayeredImage { - name = "test.local/pause"; - tag = "local"; - contents = imageEnv; - config.Entrypoint = [ "/bin/tini" "--" "/bin/sleep" "inf" ]; - }; - # Don't use the default service account because there's a race where it may - # not be created yet; make our own instead. - testPodYaml = pkgs.writeText "test.yml" '' - apiVersion: v1 - kind: ServiceAccount - metadata: - name: test - --- - apiVersion: v1 - kind: Pod - metadata: - name: test - spec: - serviceAccountName: test - containers: - - name: test - image: test.local/pause:local - imagePullPolicy: Never - command: ["sh", "-c", "sleep inf"] - ''; - in - { - name = "k3s"; - meta = with pkgs.lib.maintainers; { - maintainers = [ euank ]; - }; - - machine = { pkgs, ... }: { - environment.systemPackages = with pkgs; [ k3s gzip ]; - - # k3s uses enough resources the default vm fails. - virtualisation.memorySize = 1536; - virtualisation.diskSize = 4096; - - services.k3s = { - enable = true; - role = "server"; - docker = true; - # Slightly reduce resource usage - extraFlags = "--no-deploy coredns,servicelb,traefik,local-storage,metrics-server --pause-image test.local/pause:local"; - }; - - users.users = { - noprivs = { - isNormalUser = true; - description = "Can't access k3s by default"; - password = "*"; - }; - }; - }; - - testScript = '' - start_all() - - machine.wait_for_unit("k3s") - machine.succeed("k3s kubectl cluster-info") - machine.fail("sudo -u noprivs k3s kubectl cluster-info") - # FIXME: this fails with the current nixos kernel config; once it passes, we should uncomment it - # machine.succeed("k3s check-config") - - machine.succeed( - "${pauseImage} | docker load" - ) - - machine.succeed("k3s kubectl apply -f ${testPodYaml}") - machine.succeed("k3s kubectl wait --for 'condition=Ready' pod/test") - machine.succeed("k3s kubectl delete -f ${testPodYaml}") - - machine.shutdown() - ''; - }) diff --git a/nixpkgs/nixos/tests/k3s/default.nix b/nixpkgs/nixos/tests/k3s/default.nix new file mode 100644 index 000000000000..07d93c41c7a6 --- /dev/null +++ b/nixpkgs/nixos/tests/k3s/default.nix @@ -0,0 +1,9 @@ +{ system ? builtins.currentSystem +, pkgs ? import ../../.. { inherit system; } +}: +{ + # Run a single node k3s cluster and verify a pod can run + single-node = import ./single-node.nix { inherit system pkgs; }; + # Run a multi-node k3s cluster and verify pod networking works across nodes + multi-node = import ./multi-node.nix { inherit system pkgs; }; +} diff --git a/nixpkgs/nixos/tests/k3s/multi-node.nix b/nixpkgs/nixos/tests/k3s/multi-node.nix new file mode 100644 index 000000000000..afb8c78f2339 --- /dev/null +++ b/nixpkgs/nixos/tests/k3s/multi-node.nix @@ -0,0 +1,137 @@ +import ../make-test-python.nix ({ pkgs, ... }: + let + imageEnv = pkgs.buildEnv { + name = "k3s-pause-image-env"; + paths = with pkgs; [ tini bashInteractive coreutils socat ]; + }; + pauseImage = pkgs.dockerTools.streamLayeredImage { + name = "test.local/pause"; + tag = "local"; + contents = imageEnv; + config.Entrypoint = [ "/bin/tini" "--" "/bin/sleep" "inf" ]; + }; + # A daemonset that responds 'server' on port 8000 + networkTestDaemonset = pkgs.writeText "test.yml" '' + apiVersion: apps/v1 + kind: DaemonSet + metadata: + name: test + labels: + name: test + spec: + selector: + matchLabels: + name: test + template: + metadata: + labels: + name: test + spec: + containers: + - name: test + image: test.local/pause:local + imagePullPolicy: Never + resources: + limits: + memory: 20Mi + command: ["socat", "TCP4-LISTEN:8000,fork", "EXEC:echo server"] + ''; + tokenFile = pkgs.writeText "token" "p@s$w0rd"; + in + { + name = "k3s-multi-node"; + + nodes = { + server = { pkgs, ... }: { + environment.systemPackages = with pkgs; [ gzip jq ]; + # k3s uses enough resources the default vm fails. + virtualisation.memorySize = 1536; + virtualisation.diskSize = 4096; + + services.k3s = { + inherit tokenFile; + enable = true; + role = "server"; + package = pkgs.k3s; + extraFlags = "--no-deploy coredns,servicelb,traefik,local-storage,metrics-server --pause-image test.local/pause:local --node-ip 192.168.1.1"; + }; + networking.firewall.allowedTCPPorts = [ 6443 ]; + networking.firewall.allowedUDPPorts = [ 8472 ]; + networking.firewall.trustedInterfaces = [ "flannel.1" ]; + networking.useDHCP = false; + networking.defaultGateway = "192.168.1.1"; + networking.interfaces.eth1.ipv4.addresses = pkgs.lib.mkForce [ + { address = "192.168.1.1"; prefixLength = 24; } + ]; + }; + + agent = { pkgs, ... }: { + virtualisation.memorySize = 1024; + virtualisation.diskSize = 2048; + services.k3s = { + inherit tokenFile; + enable = true; + role = "agent"; + serverAddr = "https://192.168.1.1:6443"; + extraFlags = "--pause-image test.local/pause:local --node-ip 192.168.1.2"; + }; + networking.firewall.allowedTCPPorts = [ 6443 ]; + networking.firewall.allowedUDPPorts = [ 8472 ]; + networking.firewall.trustedInterfaces = [ "flannel.1" ]; + networking.useDHCP = false; + networking.defaultGateway = "192.168.1.2"; + networking.interfaces.eth1.ipv4.addresses = pkgs.lib.mkForce [ + { address = "192.168.1.2"; prefixLength = 24; } + ]; + }; + }; + + meta = with pkgs.lib.maintainers; { + maintainers = [ euank ]; + }; + + testScript = '' + start_all() + machines = [server, agent] + for m in machines: + m.wait_for_unit("k3s") + + # wait for the agent to show up + server.wait_until_succeeds("k3s kubectl get node agent") + + for m in machines: + m.succeed("k3s check-config") + m.succeed( + "${pauseImage} | k3s ctr image import -" + ) + + server.succeed("k3s kubectl cluster-info") + # Also wait for our service account to show up; it takes a sec + server.wait_until_succeeds("k3s kubectl get serviceaccount default") + + # Now create a pod on each node via a daemonset and verify they can talk to each other. + server.succeed("k3s kubectl apply -f ${networkTestDaemonset}") + server.wait_until_succeeds(f'[ "$(k3s kubectl get ds test -o json | jq .status.numberReady)" -eq {len(machines)} ]') + + # Get pod IPs + pods = server.succeed("k3s kubectl get po -o json | jq '.items[].metadata.name' -r").splitlines() + pod_ips = [server.succeed(f"k3s kubectl get po {name} -o json | jq '.status.podIP' -cr").strip() for name in pods] + + # Verify each server can ping each pod ip + for pod_ip in pod_ips: + server.succeed(f"ping -c 1 {pod_ip}") + agent.succeed(f"ping -c 1 {pod_ip}") + + # Verify the pods can talk to each other + resp = server.wait_until_succeeds(f"k3s kubectl exec {pods[0]} -- socat TCP:{pod_ips[1]}:8000 -") + assert resp.strip() == "server" + resp = server.wait_until_succeeds(f"k3s kubectl exec {pods[1]} -- socat TCP:{pod_ips[0]}:8000 -") + assert resp.strip() == "server" + + # Cleanup + server.succeed("k3s kubectl delete -f ${networkTestDaemonset}") + + for m in machines: + m.shutdown() + ''; + }) diff --git a/nixpkgs/nixos/tests/k3s-single-node.nix b/nixpkgs/nixos/tests/k3s/single-node.nix index d98f20d468cb..27e1e455e641 100644 --- a/nixpkgs/nixos/tests/k3s-single-node.nix +++ b/nixpkgs/nixos/tests/k3s/single-node.nix @@ -1,5 +1,4 @@ -import ./make-test-python.nix ({ pkgs, ... }: - +import ../make-test-python.nix ({ pkgs, ... }: let imageEnv = pkgs.buildEnv { name = "k3s-pause-image-env"; @@ -11,20 +10,12 @@ import ./make-test-python.nix ({ pkgs, ... }: contents = imageEnv; config.Entrypoint = [ "/bin/tini" "--" "/bin/sleep" "inf" ]; }; - # Don't use the default service account because there's a race where it may - # not be created yet; make our own instead. testPodYaml = pkgs.writeText "test.yml" '' apiVersion: v1 - kind: ServiceAccount - metadata: - name: test - --- - apiVersion: v1 kind: Pod metadata: name: test spec: - serviceAccountName: test containers: - name: test image: test.local/pause:local @@ -38,7 +29,7 @@ import ./make-test-python.nix ({ pkgs, ... }: maintainers = [ euank ]; }; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { environment.systemPackages = with pkgs; [ k3s gzip ]; # k3s uses enough resources the default vm fails. @@ -66,13 +57,14 @@ import ./make-test-python.nix ({ pkgs, ... }: machine.wait_for_unit("k3s") machine.succeed("k3s kubectl cluster-info") machine.fail("sudo -u noprivs k3s kubectl cluster-info") - # FIXME: this fails with the current nixos kernel config; once it passes, we should uncomment it - # machine.succeed("k3s check-config") + machine.succeed("k3s check-config") machine.succeed( "${pauseImage} | k3s ctr image import -" ) + # Also wait for our service account to show up; it takes a sec + machine.wait_until_succeeds("k3s kubectl get serviceaccount default") machine.succeed("k3s kubectl apply -f ${testPodYaml}") machine.succeed("k3s kubectl wait --for 'condition=Ready' pod/test") machine.succeed("k3s kubectl delete -f ${testPodYaml}") diff --git a/nixpkgs/nixos/tests/kanidm.nix b/nixpkgs/nixos/tests/kanidm.nix new file mode 100644 index 000000000000..d34f680f5224 --- /dev/null +++ b/nixpkgs/nixos/tests/kanidm.nix @@ -0,0 +1,75 @@ +import ./make-test-python.nix ({ pkgs, ... }: + let + certs = import ./common/acme/server/snakeoil-certs.nix; + serverDomain = certs.domain; + in + { + name = "kanidm"; + meta.maintainers = with pkgs.lib.maintainers; [ erictapen Flakebi ]; + + nodes.server = { config, pkgs, lib, ... }: { + services.kanidm = { + enableServer = true; + serverSettings = { + origin = "https://${serverDomain}"; + domain = serverDomain; + bindaddress = "[::1]:8443"; + ldapbindaddress = "[::1]:636"; + }; + }; + + services.nginx = { + enable = true; + recommendedProxySettings = true; + virtualHosts."${serverDomain}" = { + forceSSL = true; + sslCertificate = certs."${serverDomain}".cert; + sslCertificateKey = certs."${serverDomain}".key; + locations."/".proxyPass = "http://[::1]:8443"; + }; + }; + + security.pki.certificateFiles = [ certs.ca.cert ]; + + networking.hosts."::1" = [ serverDomain ]; + networking.firewall.allowedTCPPorts = [ 80 443 ]; + + users.users.kanidm.shell = pkgs.bashInteractive; + + environment.systemPackages = with pkgs; [ kanidm openldap ripgrep ]; + }; + + nodes.client = { pkgs, nodes, ... }: { + services.kanidm = { + enableClient = true; + clientSettings = { + uri = "https://${serverDomain}"; + }; + }; + + networking.hosts."${nodes.server.config.networking.primaryIPAddress}" = [ serverDomain ]; + + security.pki.certificateFiles = [ certs.ca.cert ]; + }; + + testScript = { nodes, ... }: + let + ldapBaseDN = builtins.concatStringsSep "," (map (s: "dc=" + s) (pkgs.lib.splitString "." serverDomain)); + + # We need access to the config file in the test script. + filteredConfig = pkgs.lib.converge + (pkgs.lib.filterAttrsRecursive (_: v: v != null)) + nodes.server.config.services.kanidm.serverSettings; + serverConfigFile = (pkgs.formats.toml { }).generate "server.toml" filteredConfig; + + in + '' + start_all() + server.wait_for_unit("kanidm.service") + server.wait_until_succeeds("curl -sf https://${serverDomain} | grep Kanidm") + server.wait_until_succeeds("ldapsearch -H ldap://[::1]:636 -b '${ldapBaseDN}' -x '(name=test)'") + client.wait_until_succeeds("kanidm login -D anonymous && kanidm self whoami | grep anonymous@${serverDomain}") + (rv, result) = server.execute("kanidmd recover_account -d quiet -c ${serverConfigFile} -n admin 2>&1 | rg -o '[A-Za-z0-9]{48}'") + assert rv == 0 + ''; + }) diff --git a/nixpkgs/nixos/tests/kbd-setfont-decompress.nix b/nixpkgs/nixos/tests/kbd-setfont-decompress.nix index c3a495afac84..810ef39cc11a 100644 --- a/nixpkgs/nixos/tests/kbd-setfont-decompress.nix +++ b/nixpkgs/nixos/tests/kbd-setfont-decompress.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ lib, pkgs, ... }: meta.maintainers = with lib.maintainers; [ oxalica ]; - machine = { ... }: {}; + nodes.machine = { ... }: {}; testScript = '' machine.succeed("gzip -cd ${pkgs.terminus_font}/share/consolefonts/ter-v16b.psf.gz >font.psf") diff --git a/nixpkgs/nixos/tests/kbd-update-search-paths-patch.nix b/nixpkgs/nixos/tests/kbd-update-search-paths-patch.nix index 2cdb12340b1b..746a809c4cdf 100644 --- a/nixpkgs/nixos/tests/kbd-update-search-paths-patch.nix +++ b/nixpkgs/nixos/tests/kbd-update-search-paths-patch.nix @@ -1,7 +1,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { name = "kbd-update-search-paths-patch"; - machine = { pkgs, options, ... }: { + nodes.machine = { pkgs, options, ... }: { console = { packages = options.console.packages.default ++ [ pkgs.terminus_font ]; }; diff --git a/nixpkgs/nixos/tests/kea.nix b/nixpkgs/nixos/tests/kea.nix index 6b345893108f..b1d5894cc7cd 100644 --- a/nixpkgs/nixos/tests/kea.nix +++ b/nixpkgs/nixos/tests/kea.nix @@ -1,6 +1,8 @@ import ./make-test-python.nix ({ pkgs, lib, ...}: { meta.maintainers = with lib.maintainers; [ hexa ]; + name = "kea"; + nodes = { router = { config, pkgs, ... }: { virtualisation.vlans = [ 1 ]; diff --git a/nixpkgs/nixos/tests/keepassxc.nix b/nixpkgs/nixos/tests/keepassxc.nix index 924c137a9032..303be1330405 100644 --- a/nixpkgs/nixos/tests/keepassxc.nix +++ b/nixpkgs/nixos/tests/keepassxc.nix @@ -6,7 +6,7 @@ import ./make-test-python.nix ({ pkgs, ...} : maintainers = [ turion ]; }; - machine = { ... }: + nodes.machine = { ... }: { imports = [ @@ -62,7 +62,7 @@ import ./make-test-python.nix ({ pkgs, ...} : machine.send_key("tab") machine.send_chars("/home/alice/foo.keyfile") machine.send_key("ret") - # Passwords folder is displayed - machine.wait_for_text("Passwords") + # Database is unlocked (doesn't have "[Locked]" in the title anymore) + machine.wait_for_text("foo.kdbx - KeePassXC") ''; }) diff --git a/nixpkgs/nixos/tests/kerberos/heimdal.nix b/nixpkgs/nixos/tests/kerberos/heimdal.nix index 391a61cc9a90..47f9d0285aef 100644 --- a/nixpkgs/nixos/tests/kerberos/heimdal.nix +++ b/nixpkgs/nixos/tests/kerberos/heimdal.nix @@ -1,6 +1,6 @@ import ../make-test-python.nix ({pkgs, ...}: { name = "kerberos_server-heimdal"; - machine = { config, libs, pkgs, ...}: + nodes.machine = { config, libs, pkgs, ...}: { services.kerberos_server = { enable = true; realms = { diff --git a/nixpkgs/nixos/tests/kerberos/mit.nix b/nixpkgs/nixos/tests/kerberos/mit.nix index 93b4020d4994..b475b7e4c92b 100644 --- a/nixpkgs/nixos/tests/kerberos/mit.nix +++ b/nixpkgs/nixos/tests/kerberos/mit.nix @@ -1,6 +1,6 @@ import ../make-test-python.nix ({pkgs, ...}: { name = "kerberos_server-mit"; - machine = { config, libs, pkgs, ...}: + nodes.machine = { config, libs, pkgs, ...}: { services.kerberos_server = { enable = true; realms = { diff --git a/nixpkgs/nixos/tests/kernel-generic.nix b/nixpkgs/nixos/tests/kernel-generic.nix index 45c5c1963a0d..04d52cf82e42 100644 --- a/nixpkgs/nixos/tests/kernel-generic.nix +++ b/nixpkgs/nixos/tests/kernel-generic.nix @@ -12,7 +12,7 @@ let maintainers = [ nequissimus atemu ]; }; - machine = { ... }: + nodes.machine = { ... }: { boot.kernelPackages = linuxPackages; }; @@ -30,6 +30,7 @@ let linux_5_4_hardened linux_5_10_hardened linux_5_15_hardened + linux_5_18_hardened linux_testing; }; diff --git a/nixpkgs/nixos/tests/kernel-latest-ath-user-regd.nix b/nixpkgs/nixos/tests/kernel-latest-ath-user-regd.nix index 11a3959e692e..09e1da9d2aff 100644 --- a/nixpkgs/nixos/tests/kernel-latest-ath-user-regd.nix +++ b/nixpkgs/nixos/tests/kernel-latest-ath-user-regd.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, ...} : { maintainers = [ veehaitch ]; }; - machine = { pkgs, ... }: + nodes.machine = { pkgs, ... }: { boot.kernelPackages = pkgs.linuxPackages_latest; networking.wireless.athUserRegulatoryDomain = true; diff --git a/nixpkgs/nixos/tests/keter.nix b/nixpkgs/nixos/tests/keter.nix new file mode 100644 index 000000000000..0bfb96e1c324 --- /dev/null +++ b/nixpkgs/nixos/tests/keter.nix @@ -0,0 +1,42 @@ +import ./make-test-python.nix ({ pkgs, ... }: +let + port = 81; +in +{ + name = "keter"; + meta = with pkgs.lib.maintainers; { + maintainers = [ jappie ]; + }; + + + nodes.machine = { config, pkgs, ... }: { + services.keter = { + enable = true; + + globalKeterConfig = { + listeners = [{ + host = "*4"; + inherit port; + }]; + }; + bundle = { + appName = "test-bundle"; + domain = "localhost"; + executable = pkgs.writeShellScript "run" '' + ${pkgs.python3}/bin/python -m http.server $PORT + ''; + }; + }; + }; + + testScript = + '' + machine.wait_for_unit("keter.service") + + machine.wait_for_open_port(${toString port}) + machine.wait_for_console_text("Activating app test-bundle with hosts: localhost") + + + machine.succeed("curl --fail http://localhost:${toString port}/") + ''; +}) diff --git a/nixpkgs/nixos/tests/kexec.nix b/nixpkgs/nixos/tests/kexec.nix index 010f3da49846..3f5a6f521af0 100644 --- a/nixpkgs/nixos/tests/kexec.nix +++ b/nixpkgs/nixos/tests/kexec.nix @@ -1,22 +1,49 @@ -# Test whether fast reboots via kexec work. - -import ./make-test-python.nix ({ pkgs, lib, ...} : { +import ./make-test-python.nix ({ pkgs, lib, ... }: { name = "kexec"; meta = with lib.maintainers; { - maintainers = [ eelco ]; + maintainers = [ flokli lassulus ]; + }; + + nodes = { + node1 = { ... }: { + virtualisation.vlans = [ ]; + virtualisation.memorySize = 4 * 1024; + virtualisation.useBootLoader = true; + virtualisation.useEFIBoot = true; + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + }; + + node2 = { modulesPath, ... }: { + virtualisation.vlans = [ ]; + environment.systemPackages = [ pkgs.hello ]; + imports = [ + "${modulesPath}/installer/netboot/netboot-minimal.nix" + ]; + }; }; - machine = { ... }: - { virtualisation.vlans = [ ]; }; + testScript = { nodes, ... }: '' + # Test whether reboot via kexec works. + node1.wait_for_unit("multi-user.target") + node1.succeed('kexec --load /run/current-system/kernel --initrd /run/current-system/initrd --command-line "$(</proc/cmdline)"') + node1.execute("systemctl kexec >&2 &", check_return=False) + node1.connected = False + node1.connect() + node1.wait_for_unit("multi-user.target") + + # Check if the machine with netboot-minimal.nix profile boots up + node2.wait_for_unit("multi-user.target") + node2.shutdown() + + # Kexec node1 to the toplevel of node2 via the kexec-boot script + node1.succeed('touch /run/foo') + node1.fail('hello') + node1.execute('${nodes.node2.config.system.build.kexecTree}/kexec-boot', check_return=False) + node1.succeed('! test -e /run/foo') + node1.succeed('hello') + node1.succeed('[ "$(hostname)" = "node2" ]') - testScript = - '' - machine.wait_for_unit("multi-user.target") - machine.succeed('kexec --load /run/current-system/kernel --initrd /run/current-system/initrd --command-line "$(</proc/cmdline)"') - machine.execute("systemctl kexec >&2 &", check_return=False) - machine.connected = False - machine.connect() - machine.wait_for_unit("multi-user.target") - machine.shutdown() - ''; + node1.shutdown() + ''; }) diff --git a/nixpkgs/nixos/tests/keycloak.nix b/nixpkgs/nixos/tests/keycloak.nix index fce8df2b7e3a..6ce136330d43 100644 --- a/nixpkgs/nixos/tests/keycloak.nix +++ b/nixpkgs/nixos/tests/keycloak.nix @@ -4,7 +4,7 @@ let certs = import ./common/acme/server/snakeoil-certs.nix; - frontendUrl = "https://${certs.domain}/auth"; + frontendUrl = "https://${certs.domain}"; initialAdminPassword = "h4IhoJFnt2iQIR9"; keycloakTest = import ./make-test-python.nix ( @@ -27,20 +27,23 @@ let services.keycloak = { enable = true; - inherit frontendUrl initialAdminPassword; - sslCertificate = certs.${certs.domain}.cert; - sslCertificateKey = certs.${certs.domain}.key; + settings = { + hostname = certs.domain; + }; + inherit initialAdminPassword; + sslCertificate = "${certs.${certs.domain}.cert}"; + sslCertificateKey = "${certs.${certs.domain}.key}"; database = { type = databaseType; username = "bogus"; - passwordFile = pkgs.writeText "dbPassword" "wzf6vOCbPp6cqTH"; + name = "also bogus"; + passwordFile = "${pkgs.writeText "dbPassword" "wzf6vOCbPp6cqTH"}"; }; plugins = with config.services.keycloak.package.plugins; [ keycloak-discord keycloak-metrics-spi ]; }; - environment.systemPackages = with pkgs; [ xmlstarlet html-tidy @@ -99,9 +102,9 @@ let in '' keycloak.start() keycloak.wait_for_unit("keycloak.service") + keycloak.wait_for_open_port(443) keycloak.wait_until_succeeds("curl -sSf ${frontendUrl}") - ### Realm Setup ### # Get an admin interface access token @@ -117,8 +120,8 @@ let # Register the metrics SPI keycloak.succeed( "${pkgs.jre}/bin/keytool -import -alias snakeoil -file ${certs.ca.cert} -storepass aaaaaa -keystore cacert.jks -noprompt", - "KC_OPTS='-Djavax.net.ssl.trustStore=cacert.jks -Djavax.net.ssl.trustStorePassword=aaaaaa' ${pkgs.keycloak}/bin/kcadm.sh config credentials --server '${frontendUrl}' --realm master --user admin --password '${initialAdminPassword}'", - "KC_OPTS='-Djavax.net.ssl.trustStore=cacert.jks -Djavax.net.ssl.trustStorePassword=aaaaaa' ${pkgs.keycloak}/bin/kcadm.sh update events/config -s 'eventsEnabled=true' -s 'adminEventsEnabled=true' -s 'eventsListeners+=metrics-listener'", + "KC_OPTS='-Djavax.net.ssl.trustStore=cacert.jks -Djavax.net.ssl.trustStorePassword=aaaaaa' kcadm.sh config credentials --server '${frontendUrl}' --realm master --user admin --password '${initialAdminPassword}'", + "KC_OPTS='-Djavax.net.ssl.trustStore=cacert.jks -Djavax.net.ssl.trustStorePassword=aaaaaa' kcadm.sh update events/config -s 'eventsEnabled=true' -s 'adminEventsEnabled=true' -s 'eventsListeners+=metrics-listener'", "curl -sSf '${frontendUrl}/realms/master/metrics' | grep '^keycloak_admin_event_UPDATE'" ) @@ -143,7 +146,7 @@ let # post url. keycloak.succeed( "curl -sSf -c cookie '${frontendUrl}/realms/${realm.realm}/protocol/openid-connect/auth?client_id=${client.name}&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&scope=openid+email&response_type=code&response_mode=query&nonce=qw4o89g3qqm' >login_form", - "tidy -q -m login_form || true", + "tidy -asxml -q -m login_form || true", "xml sel -T -t -m \"_:html/_:body/_:div/_:div/_:div/_:div/_:div/_:div/_:form[@id='kc-form-login']\" -v @action login_form >form_post_url", ) @@ -151,7 +154,7 @@ let # the HTML, then extract the authorization code. keycloak.succeed( "curl -sSf -L -b cookie -d 'username=${user.username}' -d 'password=${password}' -d 'credentialId=' \"$(<form_post_url)\" >auth_code_html", - "tidy -q -m auth_code_html || true", + "tidy -asxml -q -m auth_code_html || true", "xml sel -T -t -m \"_:html/_:body/_:div/_:div/_:div/_:div/_:div/_:input[@id='code']\" -v @value auth_code_html >auth_code", ) @@ -172,5 +175,6 @@ let in { postgres = keycloakTest { databaseType = "postgresql"; }; + mariadb = keycloakTest { databaseType = "mariadb"; }; mysql = keycloakTest { databaseType = "mysql"; }; } diff --git a/nixpkgs/nixos/tests/komga.nix b/nixpkgs/nixos/tests/komga.nix new file mode 100644 index 000000000000..02db50ef25f7 --- /dev/null +++ b/nixpkgs/nixos/tests/komga.nix @@ -0,0 +1,22 @@ +import ./make-test-python.nix ({ lib, ... }: + +with lib; + +{ + name = "komga"; + meta.maintainers = with maintainers; [ govanify ]; + + nodes.machine = + { pkgs, ... }: + { services.komga = { + enable = true; + port = 1234; + }; + }; + + testScript = '' + machine.wait_for_unit("komga.service") + machine.wait_for_open_port(1234) + machine.succeed("curl --fail http://localhost:1234/") + ''; +}) diff --git a/nixpkgs/nixos/tests/krb5/deprecated-config.nix b/nixpkgs/nixos/tests/krb5/deprecated-config.nix index 9a9cafd4b13e..aca29ae6ca2b 100644 --- a/nixpkgs/nixos/tests/krb5/deprecated-config.nix +++ b/nixpkgs/nixos/tests/krb5/deprecated-config.nix @@ -7,7 +7,7 @@ import ../make-test-python.nix ({ pkgs, ...} : { maintainers = [ eqyiel ]; }; - machine = + nodes.machine = { ... }: { krb5 = { enable = true; diff --git a/nixpkgs/nixos/tests/krb5/example-config.nix b/nixpkgs/nixos/tests/krb5/example-config.nix index 0932c71dd970..1125b02f01ca 100644 --- a/nixpkgs/nixos/tests/krb5/example-config.nix +++ b/nixpkgs/nixos/tests/krb5/example-config.nix @@ -7,7 +7,7 @@ import ../make-test-python.nix ({ pkgs, ...} : { maintainers = [ eqyiel ]; }; - machine = + nodes.machine = { pkgs, ... }: { krb5 = { enable = true; diff --git a/nixpkgs/nixos/tests/ksm.nix b/nixpkgs/nixos/tests/ksm.nix index 8f84b32020ab..026d2ee85a24 100644 --- a/nixpkgs/nixos/tests/ksm.nix +++ b/nixpkgs/nixos/tests/ksm.nix @@ -6,7 +6,7 @@ import ./make-test-python.nix ({ lib, ...} : maintainers = [ rnhmjoj ]; }; - machine = { ... }: { + nodes.machine = { ... }: { imports = [ ../modules/profiles/minimal.nix ]; hardware.ksm.enable = true; diff --git a/nixpkgs/nixos/tests/kubernetes/dns.nix b/nixpkgs/nixos/tests/kubernetes/dns.nix index 3fd1dd31f746..6299b7ff988a 100644 --- a/nixpkgs/nixos/tests/kubernetes/dns.nix +++ b/nixpkgs/nixos/tests/kubernetes/dns.nix @@ -33,7 +33,11 @@ let redisImage = pkgs.dockerTools.buildImage { name = "redis"; tag = "latest"; - contents = [ pkgs.redis pkgs.bind.host ]; + copyToRoot = pkgs.buildEnv { + name = "image-root"; + pathsToLink = [ "/bin" ]; + paths = [ pkgs.redis pkgs.bind.host ]; + }; config.Entrypoint = ["/bin/redis-server"]; }; @@ -54,7 +58,11 @@ let probeImage = pkgs.dockerTools.buildImage { name = "probe"; tag = "latest"; - contents = [ pkgs.bind.host pkgs.busybox ]; + copyToRoot = pkgs.buildEnv { + name = "image-root"; + pathsToLink = [ "/bin" ]; + paths = [ pkgs.bind.host pkgs.busybox ]; + }; config.Entrypoint = ["/bin/tail"]; }; diff --git a/nixpkgs/nixos/tests/kubernetes/rbac.nix b/nixpkgs/nixos/tests/kubernetes/rbac.nix index 9e73fbbd32a8..779eafbb1d24 100644 --- a/nixpkgs/nixos/tests/kubernetes/rbac.nix +++ b/nixpkgs/nixos/tests/kubernetes/rbac.nix @@ -84,7 +84,11 @@ let kubectlImage = pkgs.dockerTools.buildImage { name = "kubectl"; tag = "latest"; - contents = [ copyKubectl pkgs.busybox kubectlPod2 ]; + copyToRoot = pkgs.buildEnv { + name = "image-root"; + pathsToLink = [ "/bin" ]; + paths = [ copyKubectl pkgs.busybox kubectlPod2 ]; + }; config.Entrypoint = ["/bin/sh"]; }; diff --git a/nixpkgs/nixos/tests/libinput.nix b/nixpkgs/nixos/tests/libinput.nix index 2f84aaadcd0b..9b6fa159b999 100644 --- a/nixpkgs/nixos/tests/libinput.nix +++ b/nixpkgs/nixos/tests/libinput.nix @@ -3,7 +3,7 @@ import ./make-test-python.nix ({ ... }: { name = "libinput"; - machine = { ... }: + nodes.machine = { ... }: { imports = [ ./common/x11.nix diff --git a/nixpkgs/nixos/tests/libreddit.nix b/nixpkgs/nixos/tests/libreddit.nix index f7ef701d0865..82a44cb4e9cb 100644 --- a/nixpkgs/nixos/tests/libreddit.nix +++ b/nixpkgs/nixos/tests/libreddit.nix @@ -6,14 +6,16 @@ with lib; name = "libreddit"; meta.maintainers = with maintainers; [ fab ]; - nodes.machine = - { pkgs, ... }: - { services.libreddit.enable = true; }; + nodes.machine = { + services.libreddit.enable = true; + # Test CAP_NET_BIND_SERVICE + services.libreddit.port = 80; + }; testScript = '' machine.wait_for_unit("libreddit.service") - machine.wait_for_open_port("8080") - # The service wants to get data from https://www.reddit.com - machine.succeed("curl http://localhost:8080/") + machine.wait_for_open_port(80) + # Query a page that does not require Internet access + machine.succeed("curl --fail http://localhost:80/settings") ''; }) diff --git a/nixpkgs/nixos/tests/libresprite.nix b/nixpkgs/nixos/tests/libresprite.nix index 1a6210e3671a..16d272acfa0f 100644 --- a/nixpkgs/nixos/tests/libresprite.nix +++ b/nixpkgs/nixos/tests/libresprite.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { maintainers = [ fgaz ]; }; - machine = { config, pkgs, ... }: { + nodes.machine = { config, pkgs, ... }: { imports = [ ./common/x11.nix ]; diff --git a/nixpkgs/nixos/tests/libuiohook.nix b/nixpkgs/nixos/tests/libuiohook.nix new file mode 100644 index 000000000000..66c5033d9688 --- /dev/null +++ b/nixpkgs/nixos/tests/libuiohook.nix @@ -0,0 +1,21 @@ +import ./make-test-python.nix ({ pkgs, lib, ... }: { + name = "libuiohook"; + meta = with lib.maintainers; { maintainers = [ anoa ]; }; + + nodes.client = { nodes, ... }: + let user = nodes.client.config.users.users.alice; + in { + imports = [ ./common/user-account.nix ./common/x11.nix ]; + + environment.systemPackages = [ pkgs.libuiohook.test ]; + + test-support.displayManager.auto.user = user.name; + }; + + testScript = { nodes, ... }: + let user = nodes.client.config.users.users.alice; + in '' + client.wait_for_x() + client.succeed("su - alice -c ${pkgs.libuiohook.test}/share/uiohook_tests >&2 &") + ''; +}) diff --git a/nixpkgs/nixos/tests/lidarr.nix b/nixpkgs/nixos/tests/lidarr.nix index d3f83e5d9145..7fbaea62f80e 100644 --- a/nixpkgs/nixos/tests/lidarr.nix +++ b/nixpkgs/nixos/tests/lidarr.nix @@ -14,7 +14,7 @@ with lib; start_all() machine.wait_for_unit("lidarr.service") - machine.wait_for_open_port("8686") + machine.wait_for_open_port(8686) machine.succeed("curl --fail http://localhost:8686/") ''; }) diff --git a/nixpkgs/nixos/tests/lightdm.nix b/nixpkgs/nixos/tests/lightdm.nix index e98230ecb179..94cebd4a630a 100644 --- a/nixpkgs/nixos/tests/lightdm.nix +++ b/nixpkgs/nixos/tests/lightdm.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, ...} : { maintainers = [ aszlig ]; }; - machine = { ... }: { + nodes.machine = { ... }: { imports = [ ./common/user-account.nix ]; services.xserver.enable = true; services.xserver.displayManager.lightdm.enable = true; diff --git a/nixpkgs/nixos/tests/lighttpd.nix b/nixpkgs/nixos/tests/lighttpd.nix new file mode 100644 index 000000000000..36e2745c55c1 --- /dev/null +++ b/nixpkgs/nixos/tests/lighttpd.nix @@ -0,0 +1,21 @@ +import ./make-test-python.nix ({ lib, pkgs, ... }: { + name = "lighttpd"; + meta.maintainers = with lib.maintainers; [ bjornfor ]; + + nodes = { + server = { + services.lighttpd.enable = true; + services.lighttpd.document-root = pkgs.runCommand "document-root" {} '' + mkdir -p "$out" + echo "hello nixos test" > "$out/file.txt" + ''; + }; + }; + + testScript = '' + start_all() + server.wait_for_unit("lighttpd.service") + res = server.succeed("curl --fail http://localhost/file.txt") + assert "hello nixos test" in res, f"bad server response: '{res}'" + ''; +}) diff --git a/nixpkgs/nixos/tests/limesurvey.nix b/nixpkgs/nixos/tests/limesurvey.nix index b60e80be2444..9a3193991f35 100644 --- a/nixpkgs/nixos/tests/limesurvey.nix +++ b/nixpkgs/nixos/tests/limesurvey.nix @@ -2,7 +2,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { name = "limesurvey"; meta.maintainers = [ pkgs.lib.maintainers.aanderse ]; - machine = { ... }: { + nodes.machine = { ... }: { services.limesurvey = { enable = true; virtualHost = { diff --git a/nixpkgs/nixos/tests/litestream.nix b/nixpkgs/nixos/tests/litestream.nix index 886fbfef9cf5..f9d71c526e9e 100644 --- a/nixpkgs/nixos/tests/litestream.nix +++ b/nixpkgs/nixos/tests/litestream.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, ...} : { maintainers = [ jwygoda ]; }; - machine = + nodes.machine = { pkgs, ... }: { services.litestream = { enable = true; diff --git a/nixpkgs/nixos/tests/login.nix b/nixpkgs/nixos/tests/login.nix index 4d1dcc8cc32d..2cff38d20059 100644 --- a/nixpkgs/nixos/tests/login.nix +++ b/nixpkgs/nixos/tests/login.nix @@ -6,7 +6,7 @@ import ./make-test-python.nix ({ pkgs, latestKernel ? false, ... }: maintainers = [ eelco ]; }; - machine = + nodes.machine = { pkgs, lib, ... }: { boot.kernelPackages = lib.mkIf latestKernel pkgs.linuxPackages_latest; sound.enable = true; # needed for the factl test, /dev/snd/* exists without them but udev doesn't care then @@ -29,11 +29,11 @@ import ./make-test-python.nix ({ pkgs, latestKernel ? false, ... }: machine.wait_until_succeeds("pgrep -f 'agetty.*tty2'") with subtest("Log in as alice on a virtual console"): - machine.wait_until_tty_matches(2, "login: ") + machine.wait_until_tty_matches("2", "login: ") machine.send_chars("alice\n") - machine.wait_until_tty_matches(2, "login: alice") + machine.wait_until_tty_matches("2", "login: alice") machine.wait_until_succeeds("pgrep login") - machine.wait_until_tty_matches(2, "Password: ") + machine.wait_until_tty_matches("2", "Password: ") machine.send_chars("foobar\n") machine.wait_until_succeeds("pgrep -u alice bash") machine.send_chars("touch done\n") diff --git a/nixpkgs/nixos/tests/logrotate.nix b/nixpkgs/nixos/tests/logrotate.nix index 38da8d535275..b0685f3af9ff 100644 --- a/nixpkgs/nixos/tests/logrotate.nix +++ b/nixpkgs/nixos/tests/logrotate.nix @@ -1,26 +1,105 @@ # Test logrotate service works and is enabled by default -import ./make-test-python.nix ({ pkgs, ...} : rec { +let + importTest = { ... }: { + services.logrotate.settings.import = { + olddir = false; + }; + }; + +in + +import ./make-test-python.nix ({ pkgs, ... }: rec { name = "logrotate"; meta = with pkgs.lib.maintainers; { maintainers = [ martinetd ]; }; - # default machine - machine = { ... }: { + nodes = { + defaultMachine = { ... }: { }; + failingMachine = { ... }: { + services.logrotate.configFile = pkgs.writeText "logrotate.conf" '' + # self-written config file + su notarealuser notagroupeither + ''; + }; + machine = { config, ... }: { + imports = [ importTest ]; + + services.logrotate.settings = { + # remove default frequency header and add another + header = { + frequency = null; + delaycompress = true; + }; + # extra global setting... affecting nothing + last_line = { + global = true; + priority = 2000; + shred = true; + }; + # using mail somewhere should add --mail to logrotate invokation + sendmail = { + mail = "user@domain.tld"; + }; + # postrotate should be suffixed by 'endscript' + postrotate = { + postrotate = "touch /dev/null"; + }; + # check checkConfig works as expected: there is nothing to check here + # except that the file build passes + checkConf = { + su = "root utmp"; + createolddir = "0750 root utmp"; + create = "root utmp"; + "create " = "0750 root utmp"; + }; + # multiple paths should be aggregated + multipath = { + files = [ "file1" "file2" ]; + }; + # overriding imported path should keep existing attributes + # (e.g. olddir is still set) + import = { + notifempty = true; + }; + }; + # extraConfig compatibility - should be added to top level, early. + services.logrotate.extraConfig = '' + nomail + ''; + # paths compatibility + services.logrotate.paths = { + compat_path = { + path = "compat_test_path"; + }; + # user/group should be grouped as 'su user group' + compat_user = { + user = config.users.users.root.name; + group = "root"; + }; + # extraConfig in path should be added to block + compat_extraConfig = { + extraConfig = "dateext"; + }; + # keep -> rotate + compat_keep = { + keep = 1; + }; + }; + }; }; testScript = '' with subtest("whether logrotate works"): - machine.succeed( - # we must rotate once first to create logrotate stamp - "systemctl start logrotate.service") + # we must rotate once first to create logrotate stamp + defaultMachine.succeed("systemctl start logrotate.service") # we need to wait for console text once here to # clear console buffer up to this point for next wait - machine.wait_for_console_text('logrotate.service: Deactivated successfully') + defaultMachine.wait_for_console_text('logrotate.service: Deactivated successfully') - machine.succeed( + defaultMachine.succeed( # wtmp is present in default config. "rm -f /var/log/wtmp*", # we need to give it at least 1MB @@ -28,10 +107,46 @@ import ./make-test-python.nix ({ pkgs, ...} : rec { # move into the future and check rotation. "date -s 'now + 1 month + 1 day'") - machine.wait_for_console_text('logrotate.service: Deactivated successfully') - machine.succeed( + defaultMachine.wait_for_console_text('logrotate.service: Deactivated successfully') + defaultMachine.succeed( # check rotate worked "[ -e /var/log/wtmp.1 ]", ) + with subtest("default config does not have mail"): + defaultMachine.fail("systemctl cat logrotate.service | grep -- --mail") + with subtest("using mails adds mail option"): + machine.succeed("systemctl cat logrotate.service | grep -- --mail") + with subtest("check generated config matches expectation"): + machine.succeed( + # copy conf to /tmp/logrotate.conf for easy grep + "conf=$(systemctl cat logrotate | grep -oE '/nix/store[^ ]*logrotate.conf'); cp $conf /tmp/logrotate.conf", + "! grep weekly /tmp/logrotate.conf", + "grep -E '^delaycompress' /tmp/logrotate.conf", + "tail -n 1 /tmp/logrotate.conf | grep shred", + "sed -ne '/\"sendmail\" {/,/}/p' /tmp/logrotate.conf | grep 'mail user@domain.tld'", + "sed -ne '/\"postrotate\" {/,/}/p' /tmp/logrotate.conf | grep endscript", + "grep '\"file1\"\n\"file2\" {' /tmp/logrotate.conf", + "sed -ne '/\"import\" {/,/}/p' /tmp/logrotate.conf | grep noolddir", + "sed -ne '1,/^\"/p' /tmp/logrotate.conf | grep nomail", + "grep '\"compat_test_path\" {' /tmp/logrotate.conf", + "sed -ne '/\"compat_user\" {/,/}/p' /tmp/logrotate.conf | grep 'su root root'", + "sed -ne '/\"compat_extraConfig\" {/,/}/p' /tmp/logrotate.conf | grep dateext", + "[[ $(sed -ne '/\"compat_keep\" {/,/}/p' /tmp/logrotate.conf | grep -w rotate) = \" rotate 1\" ]]", + "! sed -ne '/\"compat_keep\" {/,/}/p' /tmp/logrotate.conf | grep -w keep", + ) + # also check configFile option + failingMachine.succeed( + "conf=$(systemctl cat logrotate | grep -oE '/nix/store[^ ]*logrotate.conf'); cp $conf /tmp/logrotate.conf", + "grep 'self-written config' /tmp/logrotate.conf", + ) + with subtest("Check logrotate-checkconf service"): + machine.wait_for_unit("logrotate-checkconf.service") + # wait_for_unit also asserts for success, so wait for + # parent target instead and check manually. + failingMachine.wait_for_unit("multi-user.target") + info = failingMachine.get_unit_info("logrotate-checkconf.service") + if info["ActiveState"] != "failed": + raise Exception('logrotate-checkconf.service was not failed') + ''; }) diff --git a/nixpkgs/nixos/tests/loki.nix b/nixpkgs/nixos/tests/loki.nix index 0c6dff3fdf13..470f80e9db63 100644 --- a/nixpkgs/nixos/tests/loki.nix +++ b/nixpkgs/nixos/tests/loki.nix @@ -7,7 +7,7 @@ import ./make-test-python.nix ({ lib, pkgs, ... }: maintainers = [ willibutz ]; }; - machine = { ... }: { + nodes.machine = { ... }: { services.loki = { enable = true; configFile = "${pkgs.grafana-loki.src}/cmd/loki/loki-local-config.yaml"; diff --git a/nixpkgs/nixos/tests/lorri/default.nix b/nixpkgs/nixos/tests/lorri/default.nix index c33c7503993d..209b87f9f26a 100644 --- a/nixpkgs/nixos/tests/lorri/default.nix +++ b/nixpkgs/nixos/tests/lorri/default.nix @@ -1,5 +1,5 @@ import ../make-test-python.nix { - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { imports = [ ../../modules/profiles/minimal.nix ]; environment.systemPackages = [ pkgs.lorri ]; }; diff --git a/nixpkgs/nixos/tests/lvm2/default.nix b/nixpkgs/nixos/tests/lvm2/default.nix new file mode 100644 index 000000000000..1eb9f572a4d6 --- /dev/null +++ b/nixpkgs/nixos/tests/lvm2/default.nix @@ -0,0 +1,45 @@ +{ system ? builtins.currentSystem +, config ? { } +, pkgs ? import ../../.. { inherit system config; } +, lib ? pkgs.lib +, kernelVersionsToTest ? [ "4.19" "5.4" "5.10" "5.15" "latest" ] +}: + +# For quickly running a test, the nixosTests.lvm2.lvm-thinpool-linux-latest attribute is recommended +let + tests = let callTest = p: lib.flip (import p) { inherit system pkgs; }; in { + thinpool = { test = callTest ./thinpool.nix; kernelFilter = lib.id; }; + # we would like to test all versions, but the kernel module currently does not compile against the other versions + vdo = { test = callTest ./vdo.nix; kernelFilter = lib.filter (v: v == "5.15"); }; + + + # systemd in stage 1 + raid-sd-stage-1 = { + test = callTest ./systemd-stage-1.nix; + kernelFilter = lib.id; + flavour = "raid"; + }; + thinpool-sd-stage-1 = { + test = callTest ./systemd-stage-1.nix; + kernelFilter = lib.id; + flavour = "thinpool"; + }; + vdo-sd-stage-1 = { + test = callTest ./systemd-stage-1.nix; + kernelFilter = lib.filter (v: v == "5.15"); + flavour = "vdo"; + }; + }; +in +lib.listToAttrs ( + lib.filter (x: x.value != {}) ( + lib.flip lib.concatMap kernelVersionsToTest (version: + let + v' = lib.replaceStrings [ "." ] [ "_" ] version; + in + lib.flip lib.mapAttrsToList tests (name: t: + lib.nameValuePair "lvm-${name}-linux-${v'}" (lib.optionalAttrs (builtins.elem version (t.kernelFilter kernelVersionsToTest)) (t.test ({ kernelPackages = pkgs."linuxPackages_${v'}"; } // builtins.removeAttrs t [ "test" "kernelFilter" ]))) + ) + ) + ) +) diff --git a/nixpkgs/nixos/tests/lvm2/systemd-stage-1.nix b/nixpkgs/nixos/tests/lvm2/systemd-stage-1.nix new file mode 100644 index 000000000000..617ba77b1796 --- /dev/null +++ b/nixpkgs/nixos/tests/lvm2/systemd-stage-1.nix @@ -0,0 +1,104 @@ +{ kernelPackages ? null, flavour }: let + preparationCode = { + raid = '' + machine.succeed("vgcreate test_vg /dev/vdc /dev/vdd") + machine.succeed("lvcreate -L 512M --type raid0 test_vg -n test_lv") + ''; + + thinpool = '' + machine.succeed("vgcreate test_vg /dev/vdc") + machine.succeed("lvcreate -L 512M -T test_vg/test_thin_pool") + machine.succeed("lvcreate -n test_lv -V 16G --thinpool test_thin_pool test_vg") + ''; + + vdo = '' + machine.succeed("vgcreate test_vg /dev/vdc") + machine.succeed("lvcreate --type vdo -n test_lv -L 6G -V 12G test_vg/vdo_pool_lv") + ''; + }.${flavour}; + + extraConfig = { + raid = { + boot.initrd.kernelModules = [ + "dm-raid" + "raid0" + ]; + }; + + thinpool = { + services.lvm = { + boot.thin.enable = true; + dmeventd.enable = true; + }; + }; + + vdo = { + services.lvm = { + boot.vdo.enable = true; + dmeventd.enable = true; + }; + }; + }.${flavour}; + + extraCheck = { + raid = '' + "test_lv" in machine.succeed("lvs --select segtype=raid0") + ''; + + thinpool = '' + "test_lv" in machine.succeed("lvs --select segtype=thin-pool") + ''; + + vdo = '' + "test_lv" in machine.succeed("lvs --select segtype=vdo") + ''; + }.${flavour}; + +in import ../make-test-python.nix ({ pkgs, ... }: { + name = "lvm2-${flavour}-systemd-stage-1"; + meta.maintainers = with pkgs.lib.maintainers; [ das_j ]; + + nodes.machine = { pkgs, lib, ... }: { + imports = [ extraConfig ]; + # Use systemd-boot + virtualisation = { + emptyDiskImages = [ 8192 8192 ]; + useBootLoader = true; + useEFIBoot = true; + }; + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + + environment.systemPackages = with pkgs; [ e2fsprogs ]; # for mkfs.ext4 + boot = { + initrd.systemd = { + enable = true; + emergencyAccess = true; + }; + initrd.services.lvm.enable = true; + kernelPackages = lib.mkIf (kernelPackages != null) kernelPackages; + }; + + specialisation.boot-lvm.configuration.virtualisation.bootDevice = "/dev/test_vg/test_lv"; + }; + + testScript = '' + machine.wait_for_unit("multi-user.target") + # Create a VG for the root + ${preparationCode} + machine.succeed("mkfs.ext4 /dev/test_vg/test_lv") + machine.succeed("mkdir -p /mnt && mount /dev/test_vg/test_lv /mnt && echo hello > /mnt/test && umount /mnt") + + # Boot from LVM + machine.succeed("bootctl set-default nixos-generation-1-specialisation-boot-lvm.conf") + machine.succeed("sync") + machine.crash() + machine.wait_for_unit("multi-user.target") + + # Ensure we have successfully booted from LVM + assert "(initrd)" in machine.succeed("systemd-analyze") # booted with systemd in stage 1 + assert "/dev/mapper/test_vg-test_lv on / type ext4" in machine.succeed("mount") + assert "hello" in machine.succeed("cat /test") + ${extraCheck} + ''; +}) diff --git a/nixpkgs/nixos/tests/lvm2/thinpool.nix b/nixpkgs/nixos/tests/lvm2/thinpool.nix new file mode 100644 index 000000000000..82c6460a890a --- /dev/null +++ b/nixpkgs/nixos/tests/lvm2/thinpool.nix @@ -0,0 +1,32 @@ +{ kernelPackages ? null }: +import ../make-test-python.nix ({ pkgs, ... }: { + name = "lvm2-thinpool"; + meta.maintainers = with pkgs.lib.maintainers; [ ajs124 ]; + + nodes.machine = { pkgs, lib, ... }: { + virtualisation.emptyDiskImages = [ 4096 ]; + services.lvm = { + boot.thin.enable = true; + dmeventd.enable = true; + }; + environment.systemPackages = with pkgs; [ xfsprogs ]; + environment.etc."lvm/lvm.conf".text = '' + activation/thin_pool_autoextend_percent = 10 + activation/thin_pool_autoextend_threshold = 80 + ''; + boot = lib.mkIf (kernelPackages != null) { inherit kernelPackages; }; + }; + + testScript = '' + machine.succeed("vgcreate test_vg /dev/vdb") + machine.succeed("lvcreate -L 512M -T test_vg/test_thin_pool") + machine.succeed("lvcreate -n test_lv -V 16G --thinpool test_thin_pool test_vg") + machine.succeed("mkfs.xfs /dev/test_vg/test_lv") + machine.succeed("mkdir /mnt; mount /dev/test_vg/test_lv /mnt") + assert "/dev/mapper/test_vg-test_lv" == machine.succeed("findmnt -no SOURCE /mnt").strip() + machine.succeed("dd if=/dev/zero of=/mnt/empty.file bs=1M count=1024") + machine.succeed("journalctl -u dm-event.service | grep \"successfully resized\"") + machine.succeed("umount /mnt") + machine.succeed("vgchange -a n") + ''; +}) diff --git a/nixpkgs/nixos/tests/lvm2/vdo.nix b/nixpkgs/nixos/tests/lvm2/vdo.nix new file mode 100644 index 000000000000..5b014c2f7222 --- /dev/null +++ b/nixpkgs/nixos/tests/lvm2/vdo.nix @@ -0,0 +1,27 @@ +{ kernelPackages ? null }: +import ../make-test-python.nix ({ pkgs, ... }: { + name = "lvm2-vdo"; + meta.maintainers = with pkgs.lib.maintainers; [ ajs124 ]; + + nodes.machine = { pkgs, lib, ... }: { + # Minimum required size for VDO volume: 5063921664 bytes + virtualisation.emptyDiskImages = [ 8192 ]; + services.lvm = { + boot.vdo.enable = true; + dmeventd.enable = true; + }; + environment.systemPackages = with pkgs; [ xfsprogs ]; + boot = lib.mkIf (kernelPackages != null) { inherit kernelPackages; }; + }; + + testScript = '' + machine.succeed("vgcreate test_vg /dev/vdb") + machine.succeed("lvcreate --type vdo -n vdo_lv -L 6G -V 12G test_vg/vdo_pool_lv") + machine.succeed("mkfs.xfs -K /dev/test_vg/vdo_lv") + machine.succeed("mkdir /mnt; mount /dev/test_vg/vdo_lv /mnt") + assert "/dev/mapper/test_vg-vdo_lv" == machine.succeed("findmnt -no SOURCE /mnt").strip() + machine.succeed("umount /mnt") + machine.succeed("vdostats") + machine.succeed("vgchange -a n") + ''; +}) diff --git a/nixpkgs/nixos/tests/lxd-image-server.nix b/nixpkgs/nixos/tests/lxd-image-server.nix index 9f060fed38d8..072f4570c2c9 100644 --- a/nixpkgs/nixos/tests/lxd-image-server.nix +++ b/nixpkgs/nixos/tests/lxd-image-server.nix @@ -1,57 +1,24 @@ -import ./make-test-python.nix ({ pkgs, ...} : +import ./make-test-python.nix ({ pkgs, lib, ... } : let - # Since we don't have access to the internet during the tests, we have to - # pre-fetch lxd containers beforehand. - # - # I've chosen to import Alpine Linux, because its image is turbo-tiny and, - # generally, sufficient for our tests. - alpine-meta = pkgs.fetchurl { - url = "https://tarballs.nixos.org/alpine/3.12/lxd.tar.xz"; - hash = "sha256-1tcKaO9lOkvqfmG/7FMbfAEToAuFy2YMewS8ysBKuLA="; - }; - - alpine-rootfs = pkgs.fetchurl { - url = "https://tarballs.nixos.org/alpine/3.12/rootfs.tar.xz"; - hash = "sha256-Tba9sSoaiMtQLY45u7p5DMqXTSDgs/763L/SQp0bkCA="; + lxd-image = import ../release.nix { + configuration = { + # Building documentation makes the test unnecessarily take a longer time: + documentation.enable = lib.mkForce false; + }; }; - lxd-config = pkgs.writeText "config.yaml" '' - storage_pools: - - name: default - driver: dir - config: - source: /var/lxd-pool - - networks: - - name: lxdbr0 - type: bridge - config: - ipv4.address: auto - ipv6.address: none - - profiles: - - name: default - devices: - eth0: - name: eth0 - network: lxdbr0 - type: nic - root: - path: / - pool: default - type: disk - ''; - + lxd-image-metadata = lxd-image.lxdMeta.${pkgs.system}; + lxd-image-rootfs = lxd-image.lxdImage.${pkgs.system}; in { name = "lxd-image-server"; meta = with pkgs.lib.maintainers; { - maintainers = [ mkg20001 ]; + maintainers = [ mkg20001 patryk27 ]; }; - machine = { lib, ... }: { + nodes.machine = { lib, ... }: { virtualisation = { cores = 2; @@ -100,20 +67,20 @@ in { # lxd expects the pool's directory to already exist machine.succeed("mkdir /var/lxd-pool") - machine.succeed( - "cat ${lxd-config} | lxd init --preseed" + "cat ${./common/lxd/config.yaml} | lxd init --preseed" ) machine.succeed( - "lxc image import ${alpine-meta} ${alpine-rootfs} --alias alpine" + "lxc image import ${lxd-image-metadata}/*/*.tar.xz ${lxd-image-rootfs}/*/*.tar.xz --alias nixos" ) - loc = "/var/www/simplestreams/images/iats/alpine/amd64/default/v1" + loc = "/var/www/simplestreams/images/iats/nixos/amd64/default/v1" with subtest("push image to server"): - machine.succeed("lxc launch alpine test") - machine.succeed("lxc stop test") + machine.succeed("lxc launch nixos test") + machine.sleep(5) + machine.succeed("lxc stop -f test") machine.succeed("lxc publish --public test --alias=testimg") machine.succeed("lxc image export testimg") machine.succeed("ls >&2") diff --git a/nixpkgs/nixos/tests/lxd-image.nix b/nixpkgs/nixos/tests/lxd-image.nix deleted file mode 100644 index 096b9d9aba90..000000000000 --- a/nixpkgs/nixos/tests/lxd-image.nix +++ /dev/null @@ -1,89 +0,0 @@ -# This test ensures that the nixOS lxd images builds and functions properly -# It has been extracted from `lxd.nix` to seperate failures of just the image and the lxd software - -import ./make-test-python.nix ({ pkgs, ...} : let - release = import ../release.nix { - /* configuration = { - environment.systemPackages = with pkgs; [ stdenv ]; # inject stdenv so rebuild test works - }; */ - }; - - metadata = release.lxdMeta.${pkgs.system}; - image = release.lxdImage.${pkgs.system}; - - lxd-config = pkgs.writeText "config.yaml" '' - storage_pools: - - name: default - driver: dir - config: - source: /var/lxd-pool - - networks: - - name: lxdbr0 - type: bridge - config: - ipv4.address: auto - ipv6.address: none - - profiles: - - name: default - devices: - eth0: - name: eth0 - network: lxdbr0 - type: nic - root: - path: / - pool: default - type: disk - ''; -in { - name = "lxd-image"; - - meta = with pkgs.lib.maintainers; { - maintainers = [ mkg20001 ]; - }; - - machine = { lib, ... }: { - virtualisation = { - # disk full otherwise - diskSize = 2048; - - lxc.lxcfs.enable = true; - lxd.enable = true; - }; - }; - - testScript = '' - machine.wait_for_unit("sockets.target") - machine.wait_for_unit("lxd.service") - machine.wait_for_file("/var/lib/lxd/unix.socket") - - # It takes additional second for lxd to settle - machine.sleep(1) - - # lxd expects the pool's directory to already exist - machine.succeed("mkdir /var/lxd-pool") - - machine.succeed( - "cat ${lxd-config} | lxd init --preseed" - ) - - # TODO: test custom built container aswell - - with subtest("importing container works"): - machine.succeed("lxc image import ${metadata}/*/*.tar.xz ${image}/*/*.tar.xz --alias nixos") - - with subtest("launching container works"): - machine.succeed("lxc launch nixos machine -c security.nesting=true") - # make sure machine boots up properly - machine.sleep(5) - - with subtest("container shell works"): - machine.succeed("echo true | lxc exec machine /run/current-system/sw/bin/bash -") - machine.succeed("lxc exec machine /run/current-system/sw/bin/true") - - # with subtest("rebuilding works"): - # machine.succeed("lxc exec machine /run/current-system/sw/bin/nixos-rebuild switch") - ''; -}) diff --git a/nixpkgs/nixos/tests/lxd-nftables.nix b/nixpkgs/nixos/tests/lxd-nftables.nix index a62d5a3064df..293065001567 100644 --- a/nixpkgs/nixos/tests/lxd-nftables.nix +++ b/nixpkgs/nixos/tests/lxd-nftables.nix @@ -12,7 +12,7 @@ import ./make-test-python.nix ({ pkgs, ...} : { maintainers = [ patryk27 ]; }; - machine = { lib, ... }: { + nodes.machine = { lib, ... }: { virtualisation = { lxd.enable = true; }; diff --git a/nixpkgs/nixos/tests/lxd.nix b/nixpkgs/nixos/tests/lxd.nix index 1a3b84a85cf6..15d16564d641 100644 --- a/nixpkgs/nixos/tests/lxd.nix +++ b/nixpkgs/nixos/tests/lxd.nix @@ -1,48 +1,18 @@ -import ./make-test-python.nix ({ pkgs, ...} : +import ./make-test-python.nix ({ pkgs, lib, ... } : let - # Since we don't have access to the internet during the tests, we have to - # pre-fetch lxd containers beforehand. - # - # I've chosen to import Alpine Linux, because its image is turbo-tiny and, - # generally, sufficient for our tests. - alpine-meta = pkgs.fetchurl { - url = "https://tarballs.nixos.org/alpine/3.12/lxd.tar.xz"; - hash = "sha256-1tcKaO9lOkvqfmG/7FMbfAEToAuFy2YMewS8ysBKuLA="; - }; + lxd-image = import ../release.nix { + configuration = { + # Building documentation makes the test unnecessarily take a longer time: + documentation.enable = lib.mkForce false; - alpine-rootfs = pkgs.fetchurl { - url = "https://tarballs.nixos.org/alpine/3.12/rootfs.tar.xz"; - hash = "sha256-Tba9sSoaiMtQLY45u7p5DMqXTSDgs/763L/SQp0bkCA="; + # Our tests require `grep` & friends: + environment.systemPackages = with pkgs; [ busybox ]; + }; }; - lxd-config = pkgs.writeText "config.yaml" '' - storage_pools: - - name: default - driver: dir - config: - source: /var/lxd-pool - - networks: - - name: lxdbr0 - type: bridge - config: - ipv4.address: auto - ipv6.address: none - - profiles: - - name: default - devices: - eth0: - name: eth0 - network: lxdbr0 - type: nic - root: - path: / - pool: default - type: disk - ''; - + lxd-image-metadata = lxd-image.lxdMeta.${pkgs.system}; + lxd-image-rootfs = lxd-image.lxdImage.${pkgs.system}; in { name = "lxd"; @@ -51,8 +21,10 @@ in { maintainers = [ patryk27 ]; }; - machine = { lib, ... }: { + nodes.machine = { lib, ... }: { virtualisation = { + diskSize = 2048; + # Since we're testing `limits.cpu`, we've gotta have a known number of # cores to lean on cores = 2; @@ -77,61 +49,66 @@ in { machine.succeed("mkdir /var/lxd-pool") machine.succeed( - "cat ${lxd-config} | lxd init --preseed" + "cat ${./common/lxd/config.yaml} | lxd init --preseed" ) machine.succeed( - "lxc image import ${alpine-meta} ${alpine-rootfs} --alias alpine" + "lxc image import ${lxd-image-metadata}/*/*.tar.xz ${lxd-image-rootfs}/*/*.tar.xz --alias nixos" ) - with subtest("Containers can be launched and destroyed"): - machine.succeed("lxc launch alpine test") - machine.succeed("lxc exec test true") - machine.succeed("lxc delete -f test") + with subtest("Container can be managed"): + machine.succeed("lxc launch nixos container") + machine.sleep(5) + machine.succeed("echo true | lxc exec container /run/current-system/sw/bin/bash -") + machine.succeed("lxc exec container true") + machine.succeed("lxc delete -f container") - with subtest("Containers are being mounted with lxcfs inside"): - machine.succeed("lxc launch alpine test") + with subtest("Container is mounted with lxcfs inside"): + machine.succeed("lxc launch nixos container") + machine.sleep(5) ## ---------- ## ## limits.cpu ## - machine.succeed("lxc config set test limits.cpu 1") - machine.succeed("lxc restart test") + machine.succeed("lxc config set container limits.cpu 1") + machine.succeed("lxc restart container") + machine.sleep(5) - # Since Alpine doesn't have `nproc` pre-installed, we've gotta resort - # to the primal methods assert ( "1" - == machine.succeed("lxc exec test grep -- -c ^processor /proc/cpuinfo").strip() + == machine.succeed("lxc exec container grep -- -c ^processor /proc/cpuinfo").strip() ) - machine.succeed("lxc config set test limits.cpu 2") - machine.succeed("lxc restart test") + machine.succeed("lxc config set container limits.cpu 2") + machine.succeed("lxc restart container") + machine.sleep(5) assert ( "2" - == machine.succeed("lxc exec test grep -- -c ^processor /proc/cpuinfo").strip() + == machine.succeed("lxc exec container grep -- -c ^processor /proc/cpuinfo").strip() ) ## ------------- ## ## limits.memory ## - machine.succeed("lxc config set test limits.memory 64MB") - machine.succeed("lxc restart test") + machine.succeed("lxc config set container limits.memory 64MB") + machine.succeed("lxc restart container") + machine.sleep(5) assert ( "MemTotal: 62500 kB" - == machine.succeed("lxc exec test grep -- MemTotal /proc/meminfo").strip() + == machine.succeed("lxc exec container grep -- MemTotal /proc/meminfo").strip() ) - machine.succeed("lxc config set test limits.memory 128MB") - machine.succeed("lxc restart test") + machine.succeed("lxc config set container limits.memory 128MB") + machine.succeed("lxc restart container") + machine.sleep(5) assert ( "MemTotal: 125000 kB" - == machine.succeed("lxc exec test grep -- MemTotal /proc/meminfo").strip() + == machine.succeed("lxc exec container grep -- MemTotal /proc/meminfo").strip() ) - machine.succeed("lxc delete -f test") + machine.succeed("lxc delete -f container") ''; }) diff --git a/nixpkgs/nixos/tests/maddy.nix b/nixpkgs/nixos/tests/maddy.nix index 581748c1fa59..b9d0416482da 100644 --- a/nixpkgs/nixos/tests/maddy.nix +++ b/nixpkgs/nixos/tests/maddy.nix @@ -49,7 +49,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { server.wait_for_open_port(143) server.wait_for_open_port(587) - server.succeed("echo test | maddyctl creds create postmaster@server") + server.succeed("maddyctl creds create --password test postmaster@server") server.succeed("maddyctl imap-acct create postmaster@server") client.succeed("send-testmail") diff --git a/nixpkgs/nixos/tests/maestral.nix b/nixpkgs/nixos/tests/maestral.nix new file mode 100644 index 000000000000..ba2e0b2f3baa --- /dev/null +++ b/nixpkgs/nixos/tests/maestral.nix @@ -0,0 +1,72 @@ +import ./make-test-python.nix ({ pkgs, ... }: { + name = "maestral"; + meta = with pkgs.lib.maintainers; { + maintainers = [ peterhoeg ]; + }; + + nodes = + let + common = attrs: + pkgs.lib.recursiveUpdate + { + imports = [ ./common/user-account.nix ]; + systemd.user.services.maestral = { + description = "Maestral Dropbox Client"; + serviceConfig.Type = "exec"; + }; + } + attrs; + + in + { + cli = { ... }: common { + systemd.user.services.maestral = { + wantedBy = [ "default.target" ]; + serviceConfig.ExecStart = "${pkgs.maestral}/bin/maestral start --foreground"; + }; + }; + + gui = { ... }: common { + services.xserver = { + enable = true; + displayManager.sddm.enable = true; + displayManager.defaultSession = "plasma"; + desktopManager.plasma5.enable = true; + desktopManager.plasma5.runUsingSystemd = true; + displayManager.autoLogin = { + enable = true; + user = "alice"; + }; + }; + + systemd.user.services = { + maestral = { + wantedBy = [ "graphical-session.target" ]; + serviceConfig.ExecStart = "${pkgs.maestral-gui}/bin/maestral_qt"; + }; + # PowerDevil doesn't like our VM + plasma-powerdevil.enable = false; + }; + }; + }; + + testScript = { nodes, ... }: + let + user = nodes.cli.config.users.users.alice; + in + '' + start_all() + + with subtest("CLI"): + # we need SOME way to give the user an active login session + cli.execute("loginctl enable-linger ${user.name}") + cli.systemctl("start user@${toString user.uid}") + cli.wait_for_unit("maestral.service", "${user.name}") + + with subtest("GUI"): + gui.wait_for_x() + gui.succeed("xauth merge ${user.home}/.Xauthority") + gui.wait_for_window("^Desktop ") + gui.wait_for_unit("maestral.service", "${user.name}") + ''; +}) diff --git a/nixpkgs/nixos/tests/magnetico.nix b/nixpkgs/nixos/tests/magnetico.nix index 8433a974f453..ee84aacaf7a7 100644 --- a/nixpkgs/nixos/tests/magnetico.nix +++ b/nixpkgs/nixos/tests/magnetico.nix @@ -9,7 +9,7 @@ in maintainers = [ rnhmjoj ]; }; - machine = { ... }: { + nodes.machine = { ... }: { imports = [ ../modules/profiles/minimal.nix ]; networking.firewall.allowedTCPPorts = [ 9000 ]; diff --git a/nixpkgs/nixos/tests/mailcatcher.nix b/nixpkgs/nixos/tests/mailcatcher.nix index a55fba8a9950..627ef56617e9 100644 --- a/nixpkgs/nixos/tests/mailcatcher.nix +++ b/nixpkgs/nixos/tests/mailcatcher.nix @@ -4,13 +4,18 @@ import ./make-test-python.nix ({ lib, ... }: name = "mailcatcher"; meta.maintainers = [ lib.maintainers.aanderse ]; - machine = + nodes.machine = { pkgs, ... }: { services.mailcatcher.enable = true; - services.ssmtp.enable = true; - services.ssmtp.hostName = "localhost:1025"; + programs.msmtp = { + enable = true; + accounts.default = { + host = "localhost"; + port = 1025; + }; + }; environment.systemPackages = [ pkgs.mailutils ]; }; @@ -19,7 +24,7 @@ import ./make-test-python.nix ({ lib, ... }: start_all() machine.wait_for_unit("mailcatcher.service") - machine.wait_for_open_port("1025") + machine.wait_for_open_port(1025) machine.succeed( 'echo "this is the body of the email" | mail -s "subject" root@example.org' ) diff --git a/nixpkgs/nixos/tests/mailhog.nix b/nixpkgs/nixos/tests/mailhog.nix index aece57178dd1..e3c2da37a3c8 100644 --- a/nixpkgs/nixos/tests/mailhog.nix +++ b/nixpkgs/nixos/tests/mailhog.nix @@ -2,7 +2,7 @@ import ./make-test-python.nix ({ lib, ... }: { name = "mailhog"; meta.maintainers = with lib.maintainers; [ jojosch ]; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { services.mailhog.enable = true; environment.systemPackages = with pkgs; [ swaks ]; @@ -12,8 +12,8 @@ import ./make-test-python.nix ({ lib, ... }: { start_all() machine.wait_for_unit("mailhog.service") - machine.wait_for_open_port("1025") - machine.wait_for_open_port("8025") + machine.wait_for_open_port(1025) + machine.wait_for_open_port(8025) machine.succeed( 'echo "this is the body of the email" | swaks --to root@example.org --body - --server localhost:1025' ) diff --git a/nixpkgs/nixos/tests/matomo.nix b/nixpkgs/nixos/tests/matomo.nix index f6b0845749cd..526a24fc4db7 100644 --- a/nixpkgs/nixos/tests/matomo.nix +++ b/nixpkgs/nixos/tests/matomo.nix @@ -7,7 +7,7 @@ with pkgs.lib; let matomoTest = package: makeTest { - machine = { config, pkgs, ... }: { + nodes.machine = { config, pkgs, ... }: { services.matomo = { package = package; enable = true; diff --git a/nixpkgs/nixos/tests/matrix-appservice-irc.nix b/nixpkgs/nixos/tests/matrix/appservice-irc.nix index d1c561f95dbf..78c53024ca6c 100644 --- a/nixpkgs/nixos/tests/matrix-appservice-irc.nix +++ b/nixpkgs/nixos/tests/matrix/appservice-irc.nix @@ -1,4 +1,4 @@ -import ./make-test-python.nix ({ pkgs, ... }: +import ../make-test-python.nix ({ pkgs, ... }: let homeserverUrl = "http://homeserver:8008"; in @@ -20,6 +20,9 @@ import ./make-test-python.nix ({ pkgs, ... }: enable_registration = true; + # don't use this in production, always use some form of verification + enable_registration_without_verification = true; + listeners = [ { # The default but tls=false bind_addresses = [ @@ -190,6 +193,7 @@ import ./make-test-python.nix ({ pkgs, ... }: testScript = '' import pathlib + import os start_all() @@ -203,7 +207,7 @@ import ./make-test-python.nix ({ pkgs, ... }: with subtest("copy the registration file"): appservice.copy_from_vm("/var/lib/matrix-appservice-irc/registration.yml") homeserver.copy_from_host( - pathlib.Path(os.environ.get("out", os.getcwd())) / "registration.yml", "/" + str(pathlib.Path(os.environ.get("out", os.getcwd())) / "registration.yml"), "/" ) homeserver.succeed("chmod 444 /registration.yml") diff --git a/nixpkgs/nixos/tests/matrix-conduit.nix b/nixpkgs/nixos/tests/matrix/conduit.nix index d159fbaa4800..780837f962fa 100644 --- a/nixpkgs/nixos/tests/matrix-conduit.nix +++ b/nixpkgs/nixos/tests/matrix/conduit.nix @@ -1,4 +1,4 @@ -import ./make-test-python.nix ({ pkgs, ... }: +import ../make-test-python.nix ({ pkgs, ... }: let name = "conduit"; in diff --git a/nixpkgs/nixos/tests/dendrite.nix b/nixpkgs/nixos/tests/matrix/dendrite.nix index a444c9b20018..82e71d912130 100644 --- a/nixpkgs/nixos/tests/dendrite.nix +++ b/nixpkgs/nixos/tests/matrix/dendrite.nix @@ -1,4 +1,4 @@ -import ./make-test-python.nix ( +import ../make-test-python.nix ( { pkgs, ... }: let homeserverUrl = "http://homeserver:8008"; @@ -17,9 +17,11 @@ import ./make-test-python.nix ( homeserver = { pkgs, ... }: { services.dendrite = { enable = true; + loadCredential = [ "test_private_key:${private_key}" ]; + openRegistration = true; settings = { global.server_name = "test-dendrite-server.com"; - global.private_key = private_key; + global.private_key = "$CREDENTIALS_DIRECTORY/test_private_key"; client_api.registration_disabled = false; }; }; diff --git a/nixpkgs/nixos/tests/matrix/mjolnir.nix b/nixpkgs/nixos/tests/matrix/mjolnir.nix index 54094ab9d611..cb843e2e9e3e 100644 --- a/nixpkgs/nixos/tests/matrix/mjolnir.nix +++ b/nixpkgs/nixos/tests/matrix/mjolnir.nix @@ -43,6 +43,7 @@ import ../make-test-python.nix ( tls_certificate_path = "${cert}"; tls_private_key_path = "${key}"; enable_registration = true; + enable_registration_without_verification = true; registration_shared_secret = "supersecret-registration"; listeners = [ { diff --git a/nixpkgs/nixos/tests/matrix/pantalaimon.nix b/nixpkgs/nixos/tests/matrix/pantalaimon.nix index 1a9894dd2159..b5d649e6517a 100644 --- a/nixpkgs/nixos/tests/matrix/pantalaimon.nix +++ b/nixpkgs/nixos/tests/matrix/pantalaimon.nix @@ -36,7 +36,7 @@ import ../make-test-python.nix ( maintainers = teams.matrix.members; }; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { services.pantalaimon-headless.instances.${pantalaimonInstanceName} = { homeserver = "https://localhost:8448"; listenAddress = "0.0.0.0"; diff --git a/nixpkgs/nixos/tests/matrix-synapse.nix b/nixpkgs/nixos/tests/matrix/synapse.nix index 1ff1e47b2840..756a8d5de49a 100644 --- a/nixpkgs/nixos/tests/matrix-synapse.nix +++ b/nixpkgs/nixos/tests/matrix/synapse.nix @@ -1,4 +1,4 @@ -import ./make-test-python.nix ({ pkgs, ... } : let +import ../make-test-python.nix ({ pkgs, ... } : let runWithOpenSSL = file: cmd: pkgs.runCommand file { @@ -27,7 +27,7 @@ import ./make-test-python.nix ({ pkgs, ... } : let ''; - mailerCerts = import ./common/acme/server/snakeoil-certs.nix; + mailerCerts = import ../common/acme/server/snakeoil-certs.nix; mailerDomain = mailerCerts.domain; registrationSharedSecret = "unsecure123"; testUser = "alice"; diff --git a/nixpkgs/nixos/tests/mediawiki.nix b/nixpkgs/nixos/tests/mediawiki.nix index 702fefefa161..7f31d6aadfa2 100644 --- a/nixpkgs/nixos/tests/mediawiki.nix +++ b/nixpkgs/nixos/tests/mediawiki.nix @@ -2,7 +2,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { name = "mediawiki"; meta.maintainers = [ lib.maintainers.aanderse ]; - machine = + nodes.machine = { ... }: { services.mediawiki.enable = true; services.mediawiki.virtualHost.hostName = "localhost"; diff --git a/nixpkgs/nixos/tests/meilisearch.nix b/nixpkgs/nixos/tests/meilisearch.nix index c379bda74c59..6d7514a1cc0a 100644 --- a/nixpkgs/nixos/tests/meilisearch.nix +++ b/nixpkgs/nixos/tests/meilisearch.nix @@ -5,14 +5,15 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: apiUrl = "http://${listenAddress}:${toString listenPort}"; uid = "movies"; indexJSON = pkgs.writeText "index.json" (builtins.toJSON { inherit uid; }); - moviesJSON = pkgs.runCommand "movies.json" {} '' - sed -n '1,5p;$p' ${pkgs.meilisearch.src}/datasets/movies/movies.json > $out - ''; + moviesJSON = pkgs.fetchurl { + url = "https://github.com/meilisearch/meilisearch/raw/v0.23.1/datasets/movies/movies.json"; + sha256 = "1r3srld63dpmg9yrmysm6xl175661j5cspi93mk5q2wf8xwn50c5"; + }; in { name = "meilisearch"; meta.maintainers = with lib.maintainers; [ Br1ght0ne ]; - machine = { ... }: { + nodes.machine = { ... }: { environment.systemPackages = with pkgs; [ curl jq ]; services.meilisearch = { enable = true; @@ -26,7 +27,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: start_all() machine.wait_for_unit("meilisearch") - machine.wait_for_open_port("7700") + machine.wait_for_open_port(7700) with subtest("check version"): version = json.loads(machine.succeed("curl ${apiUrl}/version")) @@ -34,7 +35,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: with subtest("create index"): machine.succeed( - "curl -XPOST ${apiUrl}/indexes --data @${indexJSON}" + "curl -XPOST --header 'Content-Type: application/json' ${apiUrl}/indexes --data @${indexJSON}" ) indexes = json.loads(machine.succeed("curl ${apiUrl}/indexes")) assert len(indexes) == 1, "index wasn't created" @@ -42,7 +43,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: with subtest("add documents"): response = json.loads( machine.succeed( - "curl -XPOST ${apiUrl}/indexes/${uid}/documents --data @${moviesJSON}" + "curl -XPOST --header 'Content-Type: application/json' ${apiUrl}/indexes/${uid}/documents --data @${moviesJSON}" ) ) update_id = response["updateId"] diff --git a/nixpkgs/nixos/tests/memcached.nix b/nixpkgs/nixos/tests/memcached.nix index 31f5627d25ce..6549995110d7 100644 --- a/nixpkgs/nixos/tests/memcached.nix +++ b/nixpkgs/nixos/tests/memcached.nix @@ -1,7 +1,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { name = "memcached"; - machine = { + nodes.machine = { imports = [ ../modules/profiles/minimal.nix ]; services.memcached.enable = true; }; diff --git a/nixpkgs/nixos/tests/mimir.nix b/nixpkgs/nixos/tests/mimir.nix new file mode 100644 index 000000000000..f1b30d261472 --- /dev/null +++ b/nixpkgs/nixos/tests/mimir.nix @@ -0,0 +1,50 @@ +import ./make-test-python.nix ({ pkgs, ... }: { + name = "mimir"; + nodes = { + server = { ... }: { + environment.systemPackages = [ pkgs.jq ]; + services.mimir.enable = true; + services.mimir.configuration = { + ingester.ring.replication_factor = 1; + }; + + services.telegraf.enable = true; + services.telegraf.extraConfig = { + agent.interval = "1s"; + agent.flush_interval = "1s"; + inputs.exec = { + commands = [ + "${pkgs.coreutils}/bin/echo 'foo i=42i'" + ]; + data_format = "influx"; + }; + outputs = { + http = { + # test remote write + url = "http://localhost:8080/api/v1/push"; + + # Data format to output. + data_format = "prometheusremotewrite"; + + headers = { + Content-Type = "application/x-protobuf"; + Content-Encoding = "snappy"; + X-Scope-OrgID = "nixos"; + X-Prometheus-Remote-Write-Version = "0.1.0"; + }; + }; + }; + }; + }; + }; + + testScript = '' + start_all() + server.wait_for_unit("mimir.service") + server.wait_for_unit("telegraf.service") + server.wait_for_open_port(8080) + server.wait_until_succeeds( + "curl -H 'X-Scope-OrgID: nixos' http://127.0.0.1:8080/prometheus/api/v1/label/host/values | jq -r '.data[0]' | grep server" + ) + ''; +}) diff --git a/nixpkgs/nixos/tests/minecraft-server.nix b/nixpkgs/nixos/tests/minecraft-server.nix index dbe2cd6d56fe..a51b36ff5308 100644 --- a/nixpkgs/nixos/tests/minecraft-server.nix +++ b/nixpkgs/nixos/tests/minecraft-server.nix @@ -33,5 +33,6 @@ in import ./make-test-python.nix ({ pkgs, ... }: { assert "${seed}" in server.succeed( "mcrcon -H localhost -P ${toString rcon-port} -p '${rcon-pass}' -c 'seed'" ) + server.succeed("systemctl stop minecraft-server") ''; }) diff --git a/nixpkgs/nixos/tests/minidlna.nix b/nixpkgs/nixos/tests/minidlna.nix index 104b79078fd5..76039b0bb42c 100644 --- a/nixpkgs/nixos/tests/minidlna.nix +++ b/nixpkgs/nixos/tests/minidlna.nix @@ -32,7 +32,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { start_all() server.succeed("mkdir -p /tmp/stuff && chown minidlna: /tmp/stuff") server.wait_for_unit("minidlna") - server.wait_for_open_port("8200") + server.wait_for_open_port(8200) # requests must be made *by IP* to avoid triggering minidlna's # DNS-rebinding protection server.succeed("curl --fail http://$(getent ahostsv4 localhost | head -n1 | cut -f 1 -d ' '):8200/") diff --git a/nixpkgs/nixos/tests/misc.nix b/nixpkgs/nixos/tests/misc.nix index 02513c4726c1..0d5f0fe2f044 100644 --- a/nixpkgs/nixos/tests/misc.nix +++ b/nixpkgs/nixos/tests/misc.nix @@ -8,7 +8,7 @@ in { maintainers = [ eelco ]; }; - machine = + nodes.machine = { lib, ... }: with lib; { swapDevices = mkOverride 0 diff --git a/nixpkgs/nixos/tests/mod_perl.nix b/nixpkgs/nixos/tests/mod_perl.nix index 29a1eb6503fd..f29d79ea6206 100644 --- a/nixpkgs/nixos/tests/mod_perl.nix +++ b/nixpkgs/nixos/tests/mod_perl.nix @@ -5,7 +5,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { maintainers = [ sgo ]; }; - machine = { config, lib, pkgs, ... }: { + nodes.machine = { config, lib, pkgs, ... }: { services.httpd = { enable = true; adminAddr = "admin@localhost"; diff --git a/nixpkgs/nixos/tests/mongodb.nix b/nixpkgs/nixos/tests/mongodb.nix index 9c6fdfb1ca76..edd074f5163c 100644 --- a/nixpkgs/nixos/tests/mongodb.nix +++ b/nixpkgs/nixos/tests/mongodb.nix @@ -37,6 +37,8 @@ import ./make-test-python.nix ({ pkgs, ... }: mongodb-3_6 mongodb-4_0 mongodb-4_2 + mongodb-4_4 + mongodb-5_0 ]; }; }; @@ -48,6 +50,8 @@ import ./make-test-python.nix ({ pkgs, ... }: + runMongoDBTest pkgs.mongodb-3_6 + runMongoDBTest pkgs.mongodb-4_0 + runMongoDBTest pkgs.mongodb-4_2 + + runMongoDBTest pkgs.mongodb-4_4 + + runMongoDBTest pkgs.mongodb-5_0 + '' node.shutdown() ''; diff --git a/nixpkgs/nixos/tests/moodle.nix b/nixpkgs/nixos/tests/moodle.nix index 56aa62596c07..4570e8963882 100644 --- a/nixpkgs/nixos/tests/moodle.nix +++ b/nixpkgs/nixos/tests/moodle.nix @@ -2,7 +2,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { name = "moodle"; meta.maintainers = [ lib.maintainers.aanderse ]; - machine = + nodes.machine = { ... }: { services.moodle.enable = true; services.moodle.virtualHost.hostName = "localhost"; diff --git a/nixpkgs/nixos/tests/mosquitto.nix b/nixpkgs/nixos/tests/mosquitto.nix index 36cc8e3e3d9b..d516d3373d9f 100644 --- a/nixpkgs/nixos/tests/mosquitto.nix +++ b/nixpkgs/nixos/tests/mosquitto.nix @@ -4,6 +4,7 @@ let port = 1888; tlsPort = 1889; anonPort = 1890; + bindTestPort = 1891; password = "VERY_secret"; hashedPassword = "$7$101$/WJc4Mp+I+uYE9sR$o7z9rD1EYXHPwEP5GqQj6A7k4W1yVbePlb8TqNcuOLV9WNCiDgwHOB0JHC1WCtdkssqTBduBNUnUGd6kmZvDSw=="; topic = "test/foo"; @@ -125,6 +126,10 @@ in { }; }; } + { + settings.bind_interface = "eth0"; + port = bindTestPort; + } ]; }; }; @@ -134,6 +139,8 @@ in { }; testScript = '' + import json + def mosquitto_cmd(binary, user, topic, port): return ( "mosquitto_{} " @@ -162,6 +169,27 @@ in { start_all() server.wait_for_unit("mosquitto.service") + with subtest("bind_interface"): + addrs = dict() + for iface in json.loads(server.succeed("ip -json address show")): + for addr in iface['addr_info']: + # don't want to deal with multihoming here + assert addr['local'] not in addrs + addrs[addr['local']] = (iface['ifname'], addr['family']) + + # mosquitto grabs *one* random address per type for bind_interface + (has4, has6) = (False, False) + for line in server.succeed("ss -HlptnO sport = ${toString bindTestPort}").splitlines(): + items = line.split() + if "mosquitto" not in items[5]: continue + listener = items[3].rsplit(':', maxsplit=1)[0].strip('[]') + assert listener in addrs + assert addrs[listener][0] == "eth0" + has4 |= addrs[listener][1] == 'inet' + has6 |= addrs[listener][1] == 'inet6' + assert has4 + assert has6 + with subtest("check passwords"): client1.succeed(publish("-m test", "password_store")) client1.succeed(publish("-m test", "password_file")) diff --git a/nixpkgs/nixos/tests/mtp.nix b/nixpkgs/nixos/tests/mtp.nix new file mode 100644 index 000000000000..8f0835d75d3f --- /dev/null +++ b/nixpkgs/nixos/tests/mtp.nix @@ -0,0 +1,109 @@ +import ./make-test-python.nix ({ pkgs, ... }: { + name = "mtp"; + meta = with pkgs.lib.maintainers; { + maintainers = [ matthewcroughan nixinator ]; + }; + + nodes = + { + client = { config, pkgs, ... }: { + # DBUS runs only once a user session is created, which means a user has to + # login. Here, we log in as root. Once logged in, the gvfs-daemon service runs + # as UID 0 in User-0.service + services.getty.autologinUser = "root"; + + # XDG_RUNTIME_DIR is needed for running systemd-user services such as + # gvfs-daemon as root. + environment.variables.XDG_RUNTIME_DIR = "/run/user/0"; + + environment.systemPackages = with pkgs; [ usbutils glib jmtpfs tree ]; + services.gvfs.enable = true; + + # Creates a usb-mtp device inside the VM, which is mapped to the host's + # /tmp folder, it is able to write files to this location, but only has + # permissions to read its own creations. + virtualisation.qemu.options = [ + "-usb" + "-device usb-mtp,rootdir=/tmp,readonly=false" + ]; + }; + }; + + + testScript = { nodes, ... }: + let + # Creates a list of QEMU MTP devices matching USB ID (46f4:0004). This + # value can be sourced in a shell script. This is so we can loop over the + # devices we find, as this test may want to use more than one MTP device + # in future. + mtpDevices = pkgs.writeScript "mtpDevices.sh" '' + export mtpDevices=$(lsusb -d 46f4:0004 | awk {'print $2","$4'} | sed 's/[:-]/ /g') + ''; + # Qemu is only capable of creating an MTP device with Picture Transfer + # Protocol. This means that gvfs must use gphoto2:// rather than mtp:// + # when mounting. + # https://github.com/qemu/qemu/blob/970bc16f60937bcfd334f14c614bd4407c247961/hw/usb/dev-mtp.c#L278 + gvfs = rec { + mountAllMtpDevices = pkgs.writeScript "mountAllMtpDevices.sh" '' + set -e + source ${mtpDevices} + for i in $mtpDevices + do + gio mount "gphoto2://[usb:$i]/" + done + ''; + unmountAllMtpDevices = pkgs.writeScript "unmountAllMtpDevices.sh" '' + set -e + source ${mtpDevices} + for i in $mtpDevices + do + gio mount -u "gphoto2://[usb:$i]/" + done + ''; + # gvfsTest: + # 1. Creates a 10M test file + # 2. Copies it to the device using GIO tools + # 3. Checks for corruption with `diff` + # 4. Removes the file, then unmounts the disks. + gvfsTest = pkgs.writeScript "gvfsTest.sh" '' + set -e + source ${mtpDevices} + ${mountAllMtpDevices} + dd if=/dev/urandom of=testFile10M bs=1M count=10 + for i in $mtpDevices + do + gio copy ./testFile10M gphoto2://[usb:$i]/ + ls -lah /run/user/0/gvfs/*/testFile10M + gio remove gphoto2://[usb:$i]/testFile10M + done + ${unmountAllMtpDevices} + ''; + }; + jmtpfs = { + # jmtpfsTest: + # 1. Mounts the device on a dir named `phone` using jmtpfs + # 2. Puts the current Nixpkgs libmtp version into a file + # 3. Checks for corruption with `diff` + # 4. Prints the directory tree + jmtpfsTest = pkgs.writeScript "jmtpfsTest.sh" '' + set -e + mkdir phone + jmtpfs phone + echo "${pkgs.libmtp.version}" > phone/tmp/testFile + echo "${pkgs.libmtp.version}" > testFile + diff phone/tmp/testFile testFile + tree phone + ''; + }; + in + # Using >&2 allows the results of the scripts to be printed to the terminal + # when building this test with Nix. Scripts would otherwise complete + # silently. + '' + start_all() + client.wait_for_unit("multi-user.target") + client.wait_for_unit("dbus.service") + client.succeed("${gvfs.gvfsTest} >&2") + client.succeed("${jmtpfs.jmtpfsTest} >&2") + ''; +}) diff --git a/nixpkgs/nixos/tests/musescore.nix b/nixpkgs/nixos/tests/musescore.nix index 7fd80d70df12..18de0a550239 100644 --- a/nixpkgs/nixos/tests/musescore.nix +++ b/nixpkgs/nixos/tests/musescore.nix @@ -17,7 +17,7 @@ in maintainers = [ turion ]; }; - machine = { ... }: + nodes.machine = { ... }: { imports = [ diff --git a/nixpkgs/nixos/tests/mysql/mysql-autobackup.nix b/nixpkgs/nixos/tests/mysql/mysql-autobackup.nix index 101122f7bdef..b49466db0a9c 100644 --- a/nixpkgs/nixos/tests/mysql/mysql-autobackup.nix +++ b/nixpkgs/nixos/tests/mysql/mysql-autobackup.nix @@ -17,7 +17,7 @@ let name = "${name}-automysqlbackup"; meta.maintainers = [ lib.maintainers.aanderse ]; - machine = { + nodes.machine = { services.mysql = { inherit package; enable = true; diff --git a/nixpkgs/nixos/tests/mysql/mysql-backup.nix b/nixpkgs/nixos/tests/mysql/mysql-backup.nix index 9335b233327a..968f56dd3c9b 100644 --- a/nixpkgs/nixos/tests/mysql/mysql-backup.nix +++ b/nixpkgs/nixos/tests/mysql/mysql-backup.nix @@ -51,7 +51,6 @@ let # Do a backup and wait for it to start master.start_job("mysql-backup.service") - master.wait_for_unit("mysql-backup.service") # wait for backup to fail, because of database 'doesnotexist' master.wait_until_fails("systemctl is-active -q mysql-backup.service") diff --git a/nixpkgs/nixos/tests/n8n.nix b/nixpkgs/nixos/tests/n8n.nix index ed93639f2a42..c1753a418f67 100644 --- a/nixpkgs/nixos/tests/n8n.nix +++ b/nixpkgs/nixos/tests/n8n.nix @@ -7,7 +7,7 @@ let in { name = "n8n"; - meta.maintainers = with maintainers; [ freezeboy ]; + meta.maintainers = with maintainers; [ freezeboy k900 ]; nodes.machine = { pkgs, ... }: @@ -19,7 +19,7 @@ in testScript = '' machine.wait_for_unit("n8n.service") - machine.wait_for_open_port("${toString port}") + machine.wait_for_open_port(${toString port}) machine.succeed("curl --fail http://localhost:${toString port}/") ''; }) diff --git a/nixpkgs/nixos/tests/nagios.nix b/nixpkgs/nixos/tests/nagios.nix index e4d8dabedf72..b6e45fc103af 100644 --- a/nixpkgs/nixos/tests/nagios.nix +++ b/nixpkgs/nixos/tests/nagios.nix @@ -5,7 +5,7 @@ import ./make-test-python.nix ( maintainers = [ symphorien ]; }; - machine = { lib, ... }: let + nodes.machine = { lib, ... }: let writer = pkgs.writeShellScript "write" '' set -x echo "$@" >> /tmp/notifications diff --git a/nixpkgs/nixos/tests/nar-serve.nix b/nixpkgs/nixos/tests/nar-serve.nix index 9ee738ffb170..bb95ccb36911 100644 --- a/nixpkgs/nixos/tests/nar-serve.nix +++ b/nixpkgs/nixos/tests/nar-serve.nix @@ -31,7 +31,7 @@ import ./make-test-python.nix ( # Create a fake cache with Nginx service the static files server.succeed( - "nix copy --to file:///var/www ${pkgs.hello}" + "nix --experimental-features nix-command copy --to file:///var/www ${pkgs.hello}" ) server.wait_for_unit("nginx.service") server.wait_for_open_port(80) diff --git a/nixpkgs/nixos/tests/navidrome.nix b/nixpkgs/nixos/tests/navidrome.nix index 42e14720b2ed..7315aef62401 100644 --- a/nixpkgs/nixos/tests/navidrome.nix +++ b/nixpkgs/nixos/tests/navidrome.nix @@ -1,12 +1,12 @@ import ./make-test-python.nix ({ pkgs, ... }: { name = "navidrome"; - machine = { ... }: { + nodes.machine = { ... }: { services.navidrome.enable = true; }; testScript = '' machine.wait_for_unit("navidrome") - machine.wait_for_open_port("4533") + machine.wait_for_open_port(4533) ''; }) diff --git a/nixpkgs/nixos/tests/nbd.nix b/nixpkgs/nixos/tests/nbd.nix index 16255e68e8a1..b4aaf29ee4e5 100644 --- a/nixpkgs/nixos/tests/nbd.nix +++ b/nixpkgs/nixos/tests/nbd.nix @@ -28,6 +28,11 @@ import ./make-test-python.nix ({ pkgs, ... }: ## It's also a loopback device to test exporting /dev/... systemd.services.create-priv-file = mkCreateSmallFileService { path = "/vault-priv.disk"; loop = true; }; + ## `aaa.disk` is just here because "[aaa]" sorts before + ## "[generic]" lexicographically, and nbd-server breaks if + ## "[generic]" isn't the first section. + systemd.services.create-aaa-file = + mkCreateSmallFileService { path = "/aaa.disk"; }; # Needed only for nbd-client used in the tests. environment.systemPackages = [ pkgs.nbd ]; @@ -39,6 +44,9 @@ import ./make-test-python.nix ({ pkgs, ... }: services.nbd.server = { enable = true; exports = { + aaa = { + path = "/aaa.disk"; + }; vault-pub = { path = "/vault-pub.disk"; }; @@ -83,5 +91,13 @@ import ./make-test-python.nix ({ pkgs, ... }: if foundString != testString: raise Exception(f"Read the wrong string from nbd disk. Expected: '{testString}'. Found: '{foundString}'") server.succeed("nbd-client -d /dev/nbd0") + + # Server: Successfully connect to the aaa disk + server.succeed("nbd-client localhost ${toString listenPort} /dev/nbd0 -name aaa -persist") + server.succeed(f"echo '{testString}' | dd of=/dev/nbd0 conv=notrunc") + foundString = server.succeed(f"dd status=none if=/aaa.disk count={len(testString)}")[:len(testString)] + if foundString != testString: + raise Exception(f"Read the wrong string from nbd disk. Expected: '{testString}'. Found: '{foundString}'") + server.succeed("nbd-client -d /dev/nbd0") ''; }) diff --git a/nixpkgs/nixos/tests/ncdns.nix b/nixpkgs/nixos/tests/ncdns.nix index 50193676f34f..3ce39ed3cb55 100644 --- a/nixpkgs/nixos/tests/ncdns.nix +++ b/nixpkgs/nixos/tests/ncdns.nix @@ -29,10 +29,10 @@ in }; nodes.server = { ... }: { - networking.nameservers = [ "127.0.0.1" ]; + networking.nameservers = [ "::1" ]; services.namecoind.rpc = { - address = "127.0.0.1"; + address = "::1"; user = "namecoin"; password = "secret"; port = 8332; @@ -45,7 +45,7 @@ in script = '' while true; do echo -e "HTTP/1.1 200 OK\n\n $(<${fakeReply})\n" \ - | ${pkgs.netcat}/bin/nc -N -l 127.0.0.1 8332 + | ${pkgs.netcat}/bin/nc -N -l ::1 8332 done ''; }; @@ -58,14 +58,10 @@ in identity.address = "1.0.0.1"; }; - services.pdns-recursor = { - enable = true; - dns.allowFrom = [ "127.0.0.0/8" ]; - resolveNamecoin = true; - }; + services.pdns-recursor.enable = true; + services.pdns-recursor.resolveNamecoin = true; environment.systemPackages = [ pkgs.dnsutils ]; - }; testScript = @@ -77,20 +73,21 @@ in with subtest("DNSKEY bit record is present"): server.wait_for_unit("pdns-recursor") - server.wait_for_open_port("53") + server.wait_for_open_port(53) server.succeed("host -t DNSKEY bit") '') + '' with subtest("can resolve a .bit name"): server.wait_for_unit("namecoind") server.wait_for_unit("ncdns") - server.wait_for_open_port("8332") + server.wait_for_open_port(8332) assert "1.2.3.4" in server.succeed("dig @localhost -p 5333 test.bit") with subtest("SOA record has identity information"): assert "example.com" in server.succeed("dig SOA @localhost -p 5333 bit") with subtest("bit. zone forwarding works"): + server.wait_for_unit("pdns-recursor") assert "1.2.3.4" in server.succeed("host test.bit") ''; }) diff --git a/nixpkgs/nixos/tests/neo4j.nix b/nixpkgs/nixos/tests/neo4j.nix index 8329e5630d7a..0b57f5b2e038 100644 --- a/nixpkgs/nixos/tests/neo4j.nix +++ b/nixpkgs/nixos/tests/neo4j.nix @@ -2,19 +2,25 @@ import ./make-test-python.nix { name = "neo4j"; nodes = { - master = + server = { ... }: { + virtualisation.memorySize = 4096; + virtualisation.diskSize = 1024; + services.neo4j.enable = true; + # require tls certs to be available + services.neo4j.https.enable = false; + services.neo4j.bolt.enable = false; }; }; testScript = '' start_all() - master.wait_for_unit("neo4j") - master.wait_for_open_port(7474) - master.succeed("curl -f http://localhost:7474/") + server.wait_for_unit("neo4j.service") + server.wait_for_open_port(7474) + server.succeed("curl -f http://localhost:7474/") ''; } diff --git a/nixpkgs/nixos/tests/networking.nix b/nixpkgs/nixos/tests/networking.nix index dc7938a436aa..71b82b871270 100644 --- a/nixpkgs/nixos/tests/networking.nix +++ b/nixpkgs/nixos/tests/networking.nix @@ -77,12 +77,14 @@ let testCases = { loopback = { name = "Loopback"; - machine.networking.useDHCP = false; - machine.networking.useNetworkd = networkd; + nodes.client = { pkgs, ... }: with pkgs.lib; { + networking.useDHCP = false; + networking.useNetworkd = networkd; + }; testScript = '' start_all() - machine.wait_for_unit("network.target") - loopback_addresses = machine.succeed("ip addr show lo") + client.wait_for_unit("network.target") + loopback_addresses = client.succeed("ip addr show lo") assert "inet 127.0.0.1/8" in loopback_addresses assert "inet6 ::1/128" in loopback_addresses ''; @@ -96,6 +98,7 @@ let useNetworkd = networkd; useDHCP = false; defaultGateway = "192.168.1.1"; + defaultGateway6 = "fd00:1234:5678:1::1"; interfaces.eth1.ipv4.addresses = mkOverride 0 [ { address = "192.168.1.2"; prefixLength = 24; } { address = "192.168.1.3"; prefixLength = 32; } @@ -137,8 +140,49 @@ let with subtest("Test default gateway"): router.wait_until_succeeds("ping -c 1 192.168.3.1") client.wait_until_succeeds("ping -c 1 192.168.3.1") + router.wait_until_succeeds("ping -c 1 fd00:1234:5678:3::1") + client.wait_until_succeeds("ping -c 1 fd00:1234:5678:3::1") ''; }; + routeType = { + name = "RouteType"; + nodes.client = { pkgs, ... }: with pkgs.lib; { + networking = { + useDHCP = false; + useNetworkd = networkd; + interfaces.eth1.ipv4.routes = [{ + address = "192.168.1.127"; + prefixLength = 32; + type = "local"; + }]; + }; + }; + testScript = '' + start_all() + client.wait_for_unit("network.target") + client.succeed("ip -4 route list table local | grep 'local 192.168.1.127'") + ''; + }; + dhcpDefault = { + name = "useDHCP-by-default"; + nodes.router = router; + nodes.client = { lib, ... }: { + # Disable test driver default config + networking.interfaces = lib.mkForce {}; + networking.useNetworkd = networkd; + virtualisation.vlans = [ 1 ]; + }; + testScript = '' + start_all() + client.wait_for_unit("multi-user.target") + client.wait_until_succeeds("ip addr show dev eth1 | grep '192.168.1'") + client.shell_interact() + client.succeed("ping -c 1 192.168.1.1") + router.succeed("ping -c 1 192.168.1.1") + router.succeed("ping -c 1 192.168.1.2") + client.succeed("ping -c 1 192.168.1.2") + ''; + }; dhcpSimple = { name = "SimpleDHCP"; nodes.router = router; @@ -638,9 +682,49 @@ let client2.succeed("ip addr show dev vlan >&2") ''; }; + vlan-ping = let + baseIP = number: "10.10.10.${number}"; + vlanIP = number: "10.1.1.${number}"; + baseInterface = "eth1"; + vlanInterface = "vlan42"; + node = number: {pkgs, ... }: with pkgs.lib; { + virtualisation.vlans = [ 1 ]; + networking = { + #useNetworkd = networkd; + useDHCP = false; + vlans.${vlanInterface} = { id = 42; interface = baseInterface; }; + interfaces.${baseInterface}.ipv4.addresses = mkOverride 0 [{ address = baseIP number; prefixLength = 24; }]; + interfaces.${vlanInterface}.ipv4.addresses = mkOverride 0 [{ address = vlanIP number; prefixLength = 24; }]; + }; + }; + + serverNodeNum = "1"; + clientNodeNum = "2"; + + in { + name = "vlan-ping"; + nodes.server = node serverNodeNum; + nodes.client = node clientNodeNum; + testScript = { ... }: + '' + start_all() + + with subtest("Wait for networking to be configured"): + server.wait_for_unit("network.target") + client.wait_for_unit("network.target") + + with subtest("Test ping on base interface in setup"): + client.succeed("ping -I ${baseInterface} -c 1 ${baseIP serverNodeNum}") + server.succeed("ping -I ${baseInterface} -c 1 ${baseIP clientNodeNum}") + + with subtest("Test ping on vlan subinterface in setup"): + client.succeed("ping -I ${vlanInterface} -c 1 ${vlanIP serverNodeNum}") + server.succeed("ping -I ${vlanInterface} -c 1 ${vlanIP clientNodeNum}") + ''; + }; virtual = { name = "Virtual"; - machine = { + nodes.machine = { networking.useNetworkd = networkd; networking.useDHCP = false; networking.interfaces.tap0 = { @@ -784,7 +868,7 @@ let }; routes = { name = "routes"; - machine = { + nodes.machine = { networking.useNetworkd = networkd; networking.useDHCP = false; networking.interfaces.eth0 = { @@ -865,7 +949,7 @@ let }; rename = { name = "RenameInterface"; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { virtualisation.vlans = [ 1 ]; networking = { useNetworkd = networkd; @@ -878,7 +962,7 @@ let linkConfig.Name = "custom_name"; }; } - else { services.udev.initrdRules = '' + else { boot.initrd.services.udev.rules = '' SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="52:54:00:12:01:01", KERNEL=="eth*", NAME="custom_name" ''; }); @@ -916,7 +1000,7 @@ let testMac = "06:00:00:00:02:00"; in { name = "WlanInterface"; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { boot.kernelModules = [ "mac80211_hwsim" ]; networking.wlanInterfaces = { wlan0 = { device = "wlan0"; }; diff --git a/nixpkgs/nixos/tests/nextcloud/default.nix b/nixpkgs/nixos/tests/nextcloud/default.nix index b7b1c5c66002..9e378fe6a52d 100644 --- a/nixpkgs/nixos/tests/nextcloud/default.nix +++ b/nixpkgs/nixos/tests/nextcloud/default.nix @@ -16,6 +16,10 @@ foldl inherit system pkgs; nextcloudVersion = ver; }; + "with-declarative-redis-and-secrets${toString ver}" = import ./with-declarative-redis-and-secrets.nix { + inherit system pkgs; + nextcloudVersion = ver; + }; }) { } - [ 22 23 ] + [ 23 24 ] diff --git a/nixpkgs/nixos/tests/nextcloud/with-declarative-redis-and-secrets.nix b/nixpkgs/nixos/tests/nextcloud/with-declarative-redis-and-secrets.nix new file mode 100644 index 000000000000..fda05bacb4fe --- /dev/null +++ b/nixpkgs/nixos/tests/nextcloud/with-declarative-redis-and-secrets.nix @@ -0,0 +1,118 @@ +import ../make-test-python.nix ({ pkgs, ...}: let + adminpass = "hunter2"; + adminuser = "custom-admin-username"; +in { + name = "nextcloud-with-declarative-redis"; + meta = with pkgs.lib.maintainers; { + maintainers = [ eqyiel ]; + }; + + nodes = { + # The only thing the client needs to do is download a file. + client = { ... }: {}; + + nextcloud = { config, pkgs, ... }: { + networking.firewall.allowedTCPPorts = [ 80 ]; + + services.nextcloud = { + enable = true; + hostName = "nextcloud"; + caching = { + apcu = false; + redis = true; + memcached = false; + }; + config = { + dbtype = "pgsql"; + dbname = "nextcloud"; + dbuser = "nextcloud"; + dbhost = "/run/postgresql"; + inherit adminuser; + adminpassFile = toString (pkgs.writeText "admin-pass-file" '' + ${adminpass} + ''); + }; + secretFile = "/etc/nextcloud-secrets.json"; + + extraOptions.redis = { + host = "/run/redis/redis.sock"; + port = 0; + dbindex = 0; + timeout = 1.5; + # password handled via secretfile below + }; + extraOptions.memcache = { + local = "\OC\Memcache\Redis"; + locking = "\OC\Memcache\Redis"; + }; + }; + + services.redis = { + enable = true; + }; + + systemd.services.nextcloud-setup= { + requires = ["postgresql.service"]; + after = [ + "postgresql.service" + ]; + }; + + services.postgresql = { + enable = true; + ensureDatabases = [ "nextcloud" ]; + ensureUsers = [ + { name = "nextcloud"; + ensurePermissions."DATABASE nextcloud" = "ALL PRIVILEGES"; + } + ]; + }; + + # This file is meant to contain secret options which should + # not go into the nix store. Here it is just used to set the + # databyse type to postgres. + environment.etc."nextcloud-secrets.json".text = '' + { + "redis": { + "password": "secret" + } + } + ''; + }; + }; + + testScript = let + withRcloneEnv = pkgs.writeScript "with-rclone-env" '' + #!${pkgs.runtimeShell} + export RCLONE_CONFIG_NEXTCLOUD_TYPE=webdav + export RCLONE_CONFIG_NEXTCLOUD_URL="http://nextcloud/remote.php/webdav/" + export RCLONE_CONFIG_NEXTCLOUD_VENDOR="nextcloud" + export RCLONE_CONFIG_NEXTCLOUD_USER="${adminuser}" + export RCLONE_CONFIG_NEXTCLOUD_PASS="$(${pkgs.rclone}/bin/rclone obscure ${adminpass})" + "''${@}" + ''; + copySharedFile = pkgs.writeScript "copy-shared-file" '' + #!${pkgs.runtimeShell} + echo 'hi' | ${pkgs.rclone}/bin/rclone rcat nextcloud:test-shared-file + ''; + + diffSharedFile = pkgs.writeScript "diff-shared-file" '' + #!${pkgs.runtimeShell} + diff <(echo 'hi') <(${pkgs.rclone}/bin/rclone cat nextcloud:test-shared-file) + ''; + in '' + start_all() + nextcloud.wait_for_unit("multi-user.target") + nextcloud.succeed("curl -sSf http://nextcloud/login") + nextcloud.succeed( + "${withRcloneEnv} ${copySharedFile}" + ) + client.wait_for_unit("multi-user.target") + client.succeed( + "${withRcloneEnv} ${diffSharedFile}" + ) + + # redis cache should not be empty + nextcloud.fail("redis-cli KEYS * | grep -q 'empty array'") + ''; +}) diff --git a/nixpkgs/nixos/tests/nextcloud/with-mysql-and-memcached.nix b/nixpkgs/nixos/tests/nextcloud/with-mysql-and-memcached.nix index 891001e30b23..63e0e2c59639 100644 --- a/nixpkgs/nixos/tests/nextcloud/with-mysql-and-memcached.nix +++ b/nixpkgs/nixos/tests/nextcloud/with-mysql-and-memcached.nix @@ -26,6 +26,7 @@ in { redis = false; memcached = true; }; + database.createLocally = true; config = { dbtype = "mysql"; dbname = "nextcloud"; @@ -38,28 +39,6 @@ in { }; }; - services.mysql = { - enable = true; - settings.mysqld = { - bind-address = "127.0.0.1"; - - # FIXME(@Ma27) Nextcloud isn't compatible with mariadb 10.6, - # this is a workaround. - # See https://help.nextcloud.com/t/update-to-next-cloud-21-0-2-has-get-an-error/117028/22 - innodb_read_only_compressed = 0; - }; - package = pkgs.mariadb; - - initialScript = pkgs.writeText "mysql-init" '' - CREATE USER 'nextcloud'@'localhost' IDENTIFIED BY 'hunter2'; - CREATE DATABASE IF NOT EXISTS nextcloud; - GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, - CREATE TEMPORARY TABLES ON nextcloud.* TO 'nextcloud'@'localhost' - IDENTIFIED BY 'hunter2'; - FLUSH privileges; - ''; - }; - systemd.services.nextcloud-setup= { requires = ["mysql.service"]; after = ["mysql.service"]; diff --git a/nixpkgs/nixos/tests/nghttpx.nix b/nixpkgs/nixos/tests/nghttpx.nix index d83c1c4cae63..11cac332827d 100644 --- a/nixpkgs/nixos/tests/nghttpx.nix +++ b/nixpkgs/nixos/tests/nghttpx.nix @@ -54,8 +54,8 @@ in testScript = '' start_all() - webserver.wait_for_open_port("80") - proxy.wait_for_open_port("80") + webserver.wait_for_open_port(80) + proxy.wait_for_open_port(80) client.wait_until_succeeds("curl -s --fail http://proxy/hello-world.txt") ''; }) diff --git a/nixpkgs/nixos/tests/nginx-auth.nix b/nixpkgs/nixos/tests/nginx-auth.nix index c0d24a20ddbc..a85426dda871 100644 --- a/nixpkgs/nixos/tests/nginx-auth.nix +++ b/nixpkgs/nixos/tests/nginx-auth.nix @@ -13,14 +13,14 @@ import ./make-test-python.nix ({ pkgs, ... }: { virtualHosts.lockedroot = { inherit root; - basicAuth.alice = "jane"; + basicAuth.alice = "pwofa"; }; virtualHosts.lockedsubdir = { inherit root; locations."/sublocation/" = { alias = "${root}/"; - basicAuth.bob = "john"; + basicAuth.bob = "pwofb"; }; }; }; @@ -33,7 +33,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { webserver.fail("curl --fail --resolve lockedroot:80:127.0.0.1 http://lockedroot") webserver.succeed( - "curl --fail --resolve lockedroot:80:127.0.0.1 http://alice:jane@lockedroot" + "curl --fail --resolve lockedroot:80:127.0.0.1 http://alice:pwofa@lockedroot" ) webserver.succeed("curl --fail --resolve lockedsubdir:80:127.0.0.1 http://lockedsubdir") @@ -41,7 +41,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { "curl --fail --resolve lockedsubdir:80:127.0.0.1 http://lockedsubdir/sublocation/index.html" ) webserver.succeed( - "curl --fail --resolve lockedsubdir:80:127.0.0.1 http://bob:john@lockedsubdir/sublocation/index.html" + "curl --fail --resolve lockedsubdir:80:127.0.0.1 http://bob:pwofb@lockedsubdir/sublocation/index.html" ) ''; }) diff --git a/nixpkgs/nixos/tests/nginx-etag.nix b/nixpkgs/nixos/tests/nginx-etag.nix index b69511d081d4..6f45eacf8b41 100644 --- a/nixpkgs/nixos/tests/nginx-etag.nix +++ b/nixpkgs/nixos/tests/nginx-etag.nix @@ -53,14 +53,14 @@ import ./make-test-python.nix { driver.implicitly_wait(20) driver.get('http://server/') - driver.find_element_by_xpath('//div[@foo="bar"]') + driver.find_element('xpath', '//div[@foo="bar"]') open('/tmp/passed_stage1', 'w') while not os.path.exists('/tmp/proceed'): time.sleep(0.5) driver.get('http://server/') - driver.find_element_by_xpath('//div[@foo="yay"]') + driver.find_element('xpath', '//div[@foo="yay"]') open('/tmp/passed', 'w') ''; in [ pkgs.firefox-unwrapped pkgs.geckodriver testRunner ]; diff --git a/nixpkgs/nixos/tests/nginx-http3.nix b/nixpkgs/nixos/tests/nginx-http3.nix new file mode 100644 index 000000000000..319f6aac184a --- /dev/null +++ b/nixpkgs/nixos/tests/nginx-http3.nix @@ -0,0 +1,93 @@ +import ./make-test-python.nix ({lib, pkgs, ...}: +let + hosts = '' + 192.168.2.101 acme.test + ''; + +in +{ + name = "nginx-http3"; + meta.maintainers = with pkgs.lib.maintainers; [ izorkin ]; + + nodes = { + server = { pkgs, ... }: { + networking = { + interfaces.eth1 = { + ipv4.addresses = [ + { address = "192.168.2.101"; prefixLength = 24; } + ]; + }; + extraHosts = hosts; + firewall.allowedTCPPorts = [ 443 ]; + firewall.allowedUDPPorts = [ 443 ]; + }; + + security.pki.certificates = [ + (builtins.readFile ./common/acme/server/ca.cert.pem) + ]; + + services.nginx = { + enable = true; + package = pkgs.nginxQuic; + + virtualHosts."acme.test" = { + onlySSL = true; + sslCertificate = ./common/acme/server/acme.test.cert.pem; + sslCertificateKey = ./common/acme/server/acme.test.key.pem; + http2 = true; + http3 = true; + reuseport = true; + root = lib.mkForce (pkgs.runCommandLocal "testdir2" {} '' + mkdir "$out" + cat > "$out/index.html" <<EOF + <html><body>Hello World!</body></html> + EOF + cat > "$out/example.txt" <<EOF + Check http3 protocol. + EOF + ''); + }; + }; + }; + + client = { pkgs, ... }: { + environment.systemPackages = [ pkgs.curlHTTP3 ]; + networking = { + interfaces.eth1 = { + ipv4.addresses = [ + { address = "192.168.2.201"; prefixLength = 24; } + ]; + }; + extraHosts = hosts; + }; + + security.pki.certificates = [ + (builtins.readFile ./common/acme/server/ca.cert.pem) + ]; + }; + }; + + testScript = '' + start_all() + + server.wait_for_unit("nginx") + server.wait_for_open_port(443) + + # Check http connections + client.succeed("curl --verbose --http3 https://acme.test | grep 'Hello World!'") + + # Check downloadings + client.succeed("curl --verbose --http3 https://acme.test/example.txt --output /tmp/example.txt") + client.succeed("cat /tmp/example.txt | grep 'Check http3 protocol.'") + + # Check header reading + client.succeed("curl --verbose --http3 --head https://acme.test | grep 'content-type'") + + # Check change User-Agent + client.succeed("curl --verbose --http3 --user-agent 'Curl test 3.0' https://acme.test") + server.succeed("cat /var/log/nginx/access.log | grep 'Curl test 3.0'") + + server.shutdown() + client.shutdown() + ''; +}) diff --git a/nixpkgs/nixos/tests/nginx-modsecurity.nix b/nixpkgs/nixos/tests/nginx-modsecurity.nix index 8c53c0196d4c..5ceee3787297 100644 --- a/nixpkgs/nixos/tests/nginx-modsecurity.nix +++ b/nixpkgs/nixos/tests/nginx-modsecurity.nix @@ -1,7 +1,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { name = "nginx-modsecurity"; - machine = { config, lib, pkgs, ... }: { + nodes.machine = { config, lib, pkgs, ... }: { services.nginx = { enable = true; additionalModules = [ pkgs.nginxModules.modsecurity-nginx ]; diff --git a/nixpkgs/nixos/tests/nginx-pubhtml.nix b/nixpkgs/nixos/tests/nginx-pubhtml.nix index 6e1e605628e9..bff24c99d41a 100644 --- a/nixpkgs/nixos/tests/nginx-pubhtml.nix +++ b/nixpkgs/nixos/tests/nginx-pubhtml.nix @@ -1,7 +1,7 @@ import ./make-test-python.nix { name = "nginx-pubhtml"; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { systemd.services.nginx.serviceConfig.ProtectHome = "read-only"; services.nginx.enable = true; services.nginx.virtualHosts.localhost = { diff --git a/nixpkgs/nixos/tests/nginx-sandbox.nix b/nixpkgs/nixos/tests/nginx-sandbox.nix index 2d512725f265..92ba30a09cf9 100644 --- a/nixpkgs/nixos/tests/nginx-sandbox.nix +++ b/nixpkgs/nixos/tests/nginx-sandbox.nix @@ -6,7 +6,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { # This test checks the creation and reading of a file in sandbox mode. Used simple lua script. - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { nixpkgs.overlays = [ (self: super: { nginx-lua = super.nginx.override { diff --git a/nixpkgs/nixos/tests/nginx-sso.nix b/nixpkgs/nixos/tests/nginx-sso.nix index aeb89859c73f..221c5f4ed905 100644 --- a/nixpkgs/nixos/tests/nginx-sso.nix +++ b/nixpkgs/nixos/tests/nginx-sso.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { maintainers = with pkgs.lib.maintainers; [ delroth ]; }; - machine = { + nodes.machine = { services.nginx.sso = { enable = true; configuration = { diff --git a/nixpkgs/nixos/tests/nginx-variants.nix b/nixpkgs/nixos/tests/nginx-variants.nix index 96a9a2c3b8c1..0faa0127669d 100644 --- a/nixpkgs/nixos/tests/nginx-variants.nix +++ b/nixpkgs/nixos/tests/nginx-variants.nix @@ -13,7 +13,7 @@ builtins.listToAttrs ( value = makeTest { name = "nginx-variant-${nginxName}"; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { services.nginx = { enable = true; virtualHosts.localhost.locations."/".return = "200 'foo'"; diff --git a/nixpkgs/nixos/tests/nitter.nix b/nixpkgs/nixos/tests/nitter.nix index 0e1a6d150f38..8bc55ba8c69f 100644 --- a/nixpkgs/nixos/tests/nitter.nix +++ b/nixpkgs/nixos/tests/nitter.nix @@ -12,7 +12,7 @@ import ./make-test-python.nix ({ pkgs, ... }: testScript = '' machine.wait_for_unit("nitter.service") - machine.wait_for_open_port("80") + machine.wait_for_open_port(80) machine.succeed("curl --fail http://localhost:80/") ''; }) diff --git a/nixpkgs/nixos/tests/nix-ld.nix b/nixpkgs/nixos/tests/nix-ld.nix index 5c886182d969..ae5297ab87ea 100644 --- a/nixpkgs/nixos/tests/nix-ld.nix +++ b/nixpkgs/nixos/tests/nix-ld.nix @@ -6,7 +6,7 @@ import ./make-test-python.nix ({ lib, pkgs, ...} : environment.systemPackages = [ (pkgs.runCommand "patched-hello" {} '' install -D -m755 ${pkgs.hello}/bin/hello $out/bin/hello - patchelf $out/bin/hello --set-interpreter ${pkgs.nix-ld.ldPath} + patchelf $out/bin/hello --set-interpreter $(cat ${pkgs.nix-ld}/nix-support/ldpath) '') ]; }; diff --git a/nixpkgs/nixos/tests/nix-serve.nix b/nixpkgs/nixos/tests/nix-serve.nix index ab82f4be43e6..3aa913f81107 100644 --- a/nixpkgs/nixos/tests/nix-serve.nix +++ b/nixpkgs/nixos/tests/nix-serve.nix @@ -1,7 +1,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { name = "nix-serve"; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { services.nix-serve.enable = true; environment.systemPackages = [ pkgs.hello diff --git a/nixpkgs/nixos/tests/nixops/default.nix b/nixpkgs/nixos/tests/nixops/default.nix index f0834c51f0b4..227b38815073 100644 --- a/nixpkgs/nixos/tests/nixops/default.nix +++ b/nixpkgs/nixos/tests/nixops/default.nix @@ -97,7 +97,7 @@ let derivations and all build dependency outputs, all the way down. */ allDrvOutputs = pkg: - let name = lib.strings.sanitizeDerivationName "allDrvOutputs-${pkg.pname or pkg.name or "unknown"}"; + let name = "allDrvOutputs-${pkg.pname or pkg.name or "unknown"}"; in pkgs.runCommand name { refs = pkgs.writeReferencesToFile pkg.drvPath; } '' touch $out diff --git a/nixpkgs/nixos/tests/nixos-generate-config.nix b/nixpkgs/nixos/tests/nixos-generate-config.nix index 1dadf4992ed0..e1c2f29e0673 100644 --- a/nixpkgs/nixos/tests/nixos-generate-config.nix +++ b/nixpkgs/nixos/tests/nixos-generate-config.nix @@ -1,7 +1,7 @@ import ./make-test-python.nix ({ lib, ... } : { name = "nixos-generate-config"; meta.maintainers = with lib.maintainers; [ basvandijk ]; - machine = { + nodes.machine = { system.nixos-generate-config.configuration = '' # OVERRIDDEN { config, pkgs, ... }: { diff --git a/nixpkgs/nixos/tests/node-red.nix b/nixpkgs/nixos/tests/node-red.nix index 7660bc32f4c9..5f5960d68295 100644 --- a/nixpkgs/nixos/tests/node-red.nix +++ b/nixpkgs/nixos/tests/node-red.nix @@ -19,7 +19,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { testScript = '' start_all() nodered.wait_for_unit("node-red.service") - nodered.wait_for_open_port("1880") + nodered.wait_for_open_port(1880) client.wait_for_unit("multi-user.target") diff --git a/nixpkgs/nixos/tests/non-default-filesystems.nix b/nixpkgs/nixos/tests/non-default-filesystems.nix new file mode 100644 index 000000000000..7fa75aaad724 --- /dev/null +++ b/nixpkgs/nixos/tests/non-default-filesystems.nix @@ -0,0 +1,54 @@ +import ./make-test-python.nix ({ lib, pkgs, ... }: +{ + name = "non-default-filesystems"; + + nodes.machine = + { config, pkgs, lib, ... }: + let + disk = config.virtualisation.bootDevice; + in + { + virtualisation.useDefaultFilesystems = false; + + boot.initrd.availableKernelModules = [ "btrfs" ]; + boot.supportedFilesystems = [ "btrfs" ]; + + boot.initrd.postDeviceCommands = '' + FSTYPE=$(blkid -o value -s TYPE ${disk} || true) + if test -z "$FSTYPE"; then + modprobe btrfs + ${pkgs.btrfs-progs}/bin/mkfs.btrfs ${disk} + + mkdir /nixos + mount -t btrfs ${disk} /nixos + + ${pkgs.btrfs-progs}/bin/btrfs subvolume create /nixos/root + ${pkgs.btrfs-progs}/bin/btrfs subvolume create /nixos/home + + umount /nixos + fi + ''; + + virtualisation.fileSystems = { + "/" = { + device = disk; + fsType = "btrfs"; + options = [ "subvol=/root" ]; + }; + + "/home" = { + device = disk; + fsType = "btrfs"; + options = [ "subvol=/home" ]; + }; + }; + }; + + testScript = '' + machine.wait_for_unit("multi-user.target") + + with subtest("BTRFS filesystems are mounted correctly"): + machine.succeed("grep -E '/dev/vda / btrfs rw,relatime,space_cache=v2,subvolid=[0-9]+,subvol=/root 0 0' /proc/mounts") + machine.succeed("grep -E '/dev/vda /home btrfs rw,relatime,space_cache=v2,subvolid=[0-9]+,subvol=/home 0 0' /proc/mounts") + ''; +}) diff --git a/nixpkgs/nixos/tests/noto-fonts.nix b/nixpkgs/nixos/tests/noto-fonts.nix index 049dc766bd3b..e4c33fe26a9e 100644 --- a/nixpkgs/nixos/tests/noto-fonts.nix +++ b/nixpkgs/nixos/tests/noto-fonts.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { maintainers = with lib.maintainers; [ nickcao midchildan ]; }; - machine = { + nodes.machine = { imports = [ ./common/x11.nix ]; environment.systemPackages = [ pkgs.gnome.gedit ]; fonts = { diff --git a/nixpkgs/nixos/tests/novacomd.nix b/nixpkgs/nixos/tests/novacomd.nix index b470c117e1e1..d47d212fb2ec 100644 --- a/nixpkgs/nixos/tests/novacomd.nix +++ b/nixpkgs/nixos/tests/novacomd.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, ...} : { maintainers = [ dtzWill ]; }; - machine = { ... }: { + nodes.machine = { ... }: { services.novacomd.enable = true; }; diff --git a/nixpkgs/nixos/tests/oh-my-zsh.nix b/nixpkgs/nixos/tests/oh-my-zsh.nix index 57a073b086e8..1d5227e36236 100644 --- a/nixpkgs/nixos/tests/oh-my-zsh.nix +++ b/nixpkgs/nixos/tests/oh-my-zsh.nix @@ -1,7 +1,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { name = "oh-my-zsh"; - machine = { pkgs, ... }: + nodes.machine = { pkgs, ... }: { programs.zsh = { diff --git a/nixpkgs/nixos/tests/ombi.nix b/nixpkgs/nixos/tests/ombi.nix index bfca86af8175..ce3064ce6ac6 100644 --- a/nixpkgs/nixos/tests/ombi.nix +++ b/nixpkgs/nixos/tests/ombi.nix @@ -12,7 +12,7 @@ with lib; testScript = '' machine.wait_for_unit("ombi.service") - machine.wait_for_open_port("5000") + machine.wait_for_open_port(5000) machine.succeed("curl --fail http://localhost:5000/") ''; }) diff --git a/nixpkgs/nixos/tests/openldap.nix b/nixpkgs/nixos/tests/openldap.nix index f1a39ad7dde2..075bb5d1f640 100644 --- a/nixpkgs/nixos/tests/openldap.nix +++ b/nixpkgs/nixos/tests/openldap.nix @@ -1,9 +1,4 @@ -{ pkgs ? (import ../.. { inherit system; config = { }; }) -, system ? builtins.currentSystem -, ... -}: - -let +import ./make-test-python.nix ({ pkgs, ... }: let dbContents = '' dn: dc=example objectClass: domain @@ -13,118 +8,149 @@ let objectClass: organizationalUnit ou: users ''; - testScript = '' - machine.wait_for_unit("openldap.service") - machine.succeed( - 'ldapsearch -LLL -D "cn=root,dc=example" -w notapassword -b "dc=example"', - ) + + ldifConfig = '' + dn: cn=config + cn: config + objectClass: olcGlobal + olcLogLevel: stats + + dn: cn=schema,cn=config + cn: schema + objectClass: olcSchemaConfig + + include: file://${pkgs.openldap}/etc/schema/core.ldif + include: file://${pkgs.openldap}/etc/schema/cosine.ldif + include: file://${pkgs.openldap}/etc/schema/inetorgperson.ldif + + dn: olcDatabase={0}config,cn=config + olcDatabase: {0}config + objectClass: olcDatabaseConfig + olcRootDN: cn=root,cn=config + olcRootPW: configpassword + + dn: olcDatabase={1}mdb,cn=config + objectClass: olcDatabaseConfig + objectClass: olcMdbConfig + olcDatabase: {1}mdb + olcDbDirectory: /var/db/openldap + olcDbIndex: objectClass eq + olcSuffix: dc=example + olcRootDN: cn=root,dc=example + olcRootPW: notapassword ''; + + ldapClientConfig = { + enable = true; + loginPam = false; + nsswitch = false; + server = "ldap://"; + base = "dc=example"; + }; + in { - # New-style configuration - current = import ./make-test-python.nix ({ pkgs, ... }: { - inherit testScript; - name = "openldap"; + name = "openldap"; + + nodes.machine = { pkgs, ... }: { + environment.etc."openldap/root_password".text = "notapassword"; - machine = { pkgs, ... }: { - environment.etc."openldap/root_password".text = "notapassword"; - services.openldap = { - enable = true; - settings = { - children = { - "cn=schema".includes = [ - "${pkgs.openldap}/etc/schema/core.ldif" - "${pkgs.openldap}/etc/schema/cosine.ldif" - "${pkgs.openldap}/etc/schema/inetorgperson.ldif" - "${pkgs.openldap}/etc/schema/nis.ldif" - ]; - "olcDatabase={1}mdb" = { - # This tests string, base64 and path values, as well as lists of string values - attrs = { - objectClass = [ "olcDatabaseConfig" "olcMdbConfig" ]; - olcDatabase = "{1}mdb"; - olcDbDirectory = "/var/db/openldap"; - olcSuffix = "dc=example"; - olcRootDN = { - # cn=root,dc=example - base64 = "Y249cm9vdCxkYz1leGFtcGxl"; - }; - olcRootPW = { - path = "/etc/openldap/root_password"; - }; + users.ldap = ldapClientConfig; + + services.openldap = { + enable = true; + urlList = [ "ldapi:///" "ldap://" ]; + settings = { + children = { + "cn=schema".includes = [ + "${pkgs.openldap}/etc/schema/core.ldif" + "${pkgs.openldap}/etc/schema/cosine.ldif" + "${pkgs.openldap}/etc/schema/inetorgperson.ldif" + "${pkgs.openldap}/etc/schema/nis.ldif" + ]; + "olcDatabase={0}config" = { + attrs = { + objectClass = [ "olcDatabaseConfig" ]; + olcDatabase = "{0}config"; + olcRootDN = "cn=root,cn=config"; + olcRootPW = "configpassword"; + }; + }; + "olcDatabase={1}mdb" = { + # This tests string, base64 and path values, as well as lists of string values + attrs = { + objectClass = [ "olcDatabaseConfig" "olcMdbConfig" ]; + olcDatabase = "{1}mdb"; + olcDbDirectory = "/var/lib/openldap/db"; + olcSuffix = "dc=example"; + olcRootDN = { + # cn=root,dc=example + base64 = "Y249cm9vdCxkYz1leGFtcGxl"; + }; + olcRootPW = { + path = "/etc/openldap/root_password"; }; }; }; }; - declarativeContents."dc=example" = dbContents; }; }; - }) { inherit pkgs system; }; - - # Old-style configuration - oldOptions = import ./make-test-python.nix ({ pkgs, ... }: { - inherit testScript; - name = "openldap"; - machine = { pkgs, ... }: { - services.openldap = { - enable = true; - logLevel = "stats acl"; - defaultSchemas = true; - database = "mdb"; - suffix = "dc=example"; - rootdn = "cn=root,dc=example"; - rootpw = "notapassword"; - declarativeContents."dc=example" = dbContents; + specialisation = { + declarativeContents.configuration = { ... }: { + services.openldap.declarativeContents."dc=example" = dbContents; }; - }; - }) { inherit system pkgs; }; - - # Manually managed configDir, for example if dynamic config is essential - manualConfigDir = import ./make-test-python.nix ({ pkgs, ... }: { - name = "openldap"; - - machine = { pkgs, ... }: { - services.openldap = { - enable = true; - configDir = "/var/db/slapd.d"; + mutableConfig.configuration = { ... }: { + services.openldap = { + declarativeContents."dc=example" = dbContents; + mutableConfig = true; + }; + }; + manualConfigDir = { + inheritParentConfig = false; + configuration = { ... }: { + users.ldap = ldapClientConfig; + services.openldap = { + enable = true; + configDir = "/var/db/slapd.d"; + }; + }; }; }; + }; + testScript = { nodes, ... }: let + specializations = "${nodes.machine.config.system.build.toplevel}/specialisation"; + changeRootPw = '' + dn: olcDatabase={1}mdb,cn=config + changetype: modify + replace: olcRootPW + olcRootPW: foobar + ''; + in '' + # Test startup with empty DB + machine.wait_for_unit("openldap.service") - testScript = let - contents = pkgs.writeText "data.ldif" dbContents; - config = pkgs.writeText "config.ldif" '' - dn: cn=config - cn: config - objectClass: olcGlobal - olcLogLevel: stats - olcPidFile: /run/slapd/slapd.pid - - dn: cn=schema,cn=config - cn: schema - objectClass: olcSchemaConfig + with subtest("declarative contents"): + machine.succeed('${specializations}/declarativeContents/bin/switch-to-configuration test') + machine.wait_for_unit("openldap.service") + machine.succeed('ldapsearch -LLL -D "cn=root,dc=example" -w notapassword') + machine.fail('ldapmodify -D cn=root,cn=config -w configpassword -f ${pkgs.writeText "rootpw.ldif" changeRootPw}') - include: file://${pkgs.openldap}/etc/schema/core.ldif - include: file://${pkgs.openldap}/etc/schema/cosine.ldif - include: file://${pkgs.openldap}/etc/schema/inetorgperson.ldif + with subtest("mutable config"): + machine.succeed('${specializations}/mutableConfig/bin/switch-to-configuration test') + machine.succeed('ldapsearch -LLL -D "cn=root,dc=example" -w notapassword') + machine.succeed('ldapmodify -D cn=root,cn=config -w configpassword -f ${pkgs.writeText "rootpw.ldif" changeRootPw}') + machine.succeed('ldapsearch -LLL -D "cn=root,dc=example" -w foobar') - dn: olcDatabase={1}mdb,cn=config - objectClass: olcDatabaseConfig - objectClass: olcMdbConfig - olcDatabase: {1}mdb - olcDbDirectory: /var/db/openldap - olcDbIndex: objectClass eq - olcSuffix: dc=example - olcRootDN: cn=root,dc=example - olcRootPW: notapassword - ''; - in '' + with subtest("manual config dir"): machine.succeed( - "mkdir -p /var/db/slapd.d /var/db/openldap", - "slapadd -F /var/db/slapd.d -n0 -l ${config}", - "slapadd -F /var/db/slapd.d -n1 -l ${contents}", - "chown -R openldap:openldap /var/db/slapd.d /var/db/openldap", - "systemctl restart openldap", + 'mkdir /var/db/slapd.d /var/db/openldap', + 'slapadd -F /var/db/slapd.d -n0 -l ${pkgs.writeText "config.ldif" ldifConfig}', + 'slapadd -F /var/db/slapd.d -n1 -l ${pkgs.writeText "contents.ldif" dbContents}', + 'chown -R openldap:openldap /var/db/slapd.d /var/db/openldap', + '${specializations}/manualConfigDir/bin/switch-to-configuration test', ) - '' + testScript; - }) { inherit system pkgs; }; -} + machine.succeed('ldapsearch -LLL -D "cn=root,dc=example" -w notapassword') + machine.succeed('ldapmodify -D cn=root,cn=config -w configpassword -f ${pkgs.writeText "rootpw.ldif" changeRootPw}') + machine.succeed('ldapsearch -LLL -D "cn=root,dc=example" -w foobar') + ''; +}) diff --git a/nixpkgs/nixos/tests/openssh.nix b/nixpkgs/nixos/tests/openssh.nix index 003813379e69..4083f5906d79 100644 --- a/nixpkgs/nixos/tests/openssh.nix +++ b/nixpkgs/nixos/tests/openssh.nix @@ -80,17 +80,21 @@ in { client.wait_for_unit("network.target") client.succeed( - "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no server 'echo hello world' >&2" + "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no server 'echo hello world' >&2", + timeout=30 ) client.succeed( - "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no server 'ulimit -l' | grep 1024" + "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no server 'ulimit -l' | grep 1024", + timeout=30 ) client.succeed( - "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no server_lazy 'echo hello world' >&2" + "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no server_lazy 'echo hello world' >&2", + timeout=30 ) client.succeed( - "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no server_lazy 'ulimit -l' | grep 1024" + "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no server_lazy 'ulimit -l' | grep 1024", + timeout=30 ) with subtest("configured-authkey"): @@ -99,10 +103,12 @@ in { ) client.succeed("chmod 600 privkey.snakeoil") client.succeed( - "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i privkey.snakeoil server true" + "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i privkey.snakeoil server true", + timeout=30 ) client.succeed( - "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i privkey.snakeoil server_lazy true" + "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i privkey.snakeoil server_lazy true", + timeout=30 ) with subtest("localhost-only"): diff --git a/nixpkgs/nixos/tests/opentabletdriver.nix b/nixpkgs/nixos/tests/opentabletdriver.nix index fe345a7bec73..b7583f6dd264 100644 --- a/nixpkgs/nixos/tests/opentabletdriver.nix +++ b/nixpkgs/nixos/tests/opentabletdriver.nix @@ -6,7 +6,7 @@ in { maintainers = with pkgs.lib.maintainers; [ thiagokokada ]; }; - machine = { pkgs, ... }: + nodes.machine = { pkgs, ... }: { imports = [ ./common/user-account.nix diff --git a/nixpkgs/nixos/tests/os-prober.nix b/nixpkgs/nixos/tests/os-prober.nix index 90375450fe1b..1c89cf8c1c67 100644 --- a/nixpkgs/nixos/tests/os-prober.nix +++ b/nixpkgs/nixos/tests/os-prober.nix @@ -65,7 +65,7 @@ let in { name = "os-prober"; - machine = { config, pkgs, ... }: (simpleConfig // { + nodes.machine = { config, pkgs, ... }: (simpleConfig // { imports = [ ../modules/profiles/installation-device.nix ../modules/profiles/base.nix ]; virtualisation.memorySize = 1300; @@ -75,21 +75,30 @@ in { # The test cannot access the network, so any packages # nixos-rebuild needs must be included in the VM. system.extraDependencies = with pkgs; - [ sudo - libxml2.bin - libxslt.bin + [ + brotli + brotli.dev + brotli.lib desktop-file-utils docbook5 docbook_xsl_ns - unionfs-fuse - ntp + grub2 + kmod.dev + libarchive + libarchive.dev + libxml2.bin + libxslt.bin nixos-artwork.wallpapers.simple-dark-gray-bottom - perlPackages.XMLLibXML + ntp perlPackages.ListCompare + perlPackages.XMLLibXML + python3Minimal shared-mime-info + stdenv + sudo texinfo + unionfs-fuse xorg.lndir - grub2 # add curl so that rather than seeing the test attempt to download # curl's tarball, we see what it's trying to download diff --git a/nixpkgs/nixos/tests/osrm-backend.nix b/nixpkgs/nixos/tests/osrm-backend.nix index 4067d5b1a239..b0e65a2ae1c1 100644 --- a/nixpkgs/nixos/tests/osrm-backend.nix +++ b/nixpkgs/nixos/tests/osrm-backend.nix @@ -5,7 +5,7 @@ in { name = "osrm-backend"; meta.maintainers = [ lib.maintainers.erictapen ]; - machine = { config, pkgs, ... }:{ + nodes.machine = { config, pkgs, ... }:{ services.osrm = { enable = true; diff --git a/nixpkgs/nixos/tests/overlayfs.nix b/nixpkgs/nixos/tests/overlayfs.nix index 1768f1fea1ed..6dab6760c5b9 100644 --- a/nixpkgs/nixos/tests/overlayfs.nix +++ b/nixpkgs/nixos/tests/overlayfs.nix @@ -2,7 +2,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { name = "overlayfs"; meta.maintainers = with pkgs.lib.maintainers; [ bachp ]; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { virtualisation.emptyDiskImages = [ 512 ]; networking.hostId = "deadbeef"; environment.systemPackages = with pkgs; [ parted ]; diff --git a/nixpkgs/nixos/tests/packagekit.nix b/nixpkgs/nixos/tests/packagekit.nix index 020a4e65e6d8..5769c6c9a8d4 100644 --- a/nixpkgs/nixos/tests/packagekit.nix +++ b/nixpkgs/nixos/tests/packagekit.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { maintainers = [ peterhoeg ]; }; - machine = { ... }: { + nodes.machine = { ... }: { environment.systemPackages = with pkgs; [ dbus ]; services.packagekit = { enable = true; diff --git a/nixpkgs/nixos/tests/pam/pam-oath-login.nix b/nixpkgs/nixos/tests/pam/pam-oath-login.nix index 597596b211b1..dd6ef4a0abcb 100644 --- a/nixpkgs/nixos/tests/pam/pam-oath-login.nix +++ b/nixpkgs/nixos/tests/pam/pam-oath-login.nix @@ -7,7 +7,7 @@ let # how many passwords have been made. In this env, we'll always be on # the 0th counter, so the password is static. # - # Generated in nix-shell -p oathToolkit + # Generated in nix-shell -p oath-toolkit # via: oathtool -v -d6 -w10 cdd4083ef8ff1fa9178c6d46bfb1a3 # and picking a the first 4: oathSnakeOilPassword1 = "143349"; @@ -21,7 +21,7 @@ in { name = "pam-oath-login"; - machine = + nodes.machine = { ... }: { security.pam.oath = { @@ -77,28 +77,28 @@ in machine.screenshot("postboot") with subtest("Invalid password"): - switch_to_tty(2) - enter_user_alice(2) + switch_to_tty("2") + enter_user_alice("2") machine.send_chars("${oathSnakeOilPassword1}\n") - machine.wait_until_tty_matches(2, "Password: ") + machine.wait_until_tty_matches("2", "Password: ") machine.send_chars("blorg\n") - machine.wait_until_tty_matches(2, "Login incorrect") + machine.wait_until_tty_matches("2", "Login incorrect") with subtest("Invalid oath token"): - switch_to_tty(3) - enter_user_alice(3) + switch_to_tty("3") + enter_user_alice("3") machine.send_chars("000000\n") - machine.wait_until_tty_matches(3, "Login incorrect") - machine.wait_until_tty_matches(3, "login:") + machine.wait_until_tty_matches("3", "Login incorrect") + machine.wait_until_tty_matches("3", "login:") with subtest("Happy path: Both passwords are mandatory to get us in"): - switch_to_tty(4) - enter_user_alice(4) + switch_to_tty("4") + enter_user_alice("4") machine.send_chars("${oathSnakeOilPassword2}\n") - machine.wait_until_tty_matches(4, "Password: ") + machine.wait_until_tty_matches("4", "Password: ") machine.send_chars("${alicePassword}\n") machine.wait_until_succeeds("pgrep -u alice bash") diff --git a/nixpkgs/nixos/tests/pam/pam-u2f.nix b/nixpkgs/nixos/tests/pam/pam-u2f.nix index 0ac6ac17be82..07408dea797e 100644 --- a/nixpkgs/nixos/tests/pam/pam-u2f.nix +++ b/nixpkgs/nixos/tests/pam/pam-u2f.nix @@ -3,7 +3,7 @@ import ../make-test-python.nix ({ ... }: { name = "pam-u2f"; - machine = + nodes.machine = { ... }: { security.pam.u2f = { @@ -12,6 +12,7 @@ import ../make-test-python.nix ({ ... }: debug = true; enable = true; interactive = true; + origin = "nixos-test"; }; }; @@ -19,7 +20,7 @@ import ../make-test-python.nix ({ ... }: '' machine.wait_for_unit("multi-user.target") machine.succeed( - 'egrep "auth required .*/lib/security/pam_u2f.so.*debug.*interactive.*cue" /etc/pam.d/ -R' + 'egrep "auth required .*/lib/security/pam_u2f.so.*debug.*interactive.*cue.*origin=nixos-test" /etc/pam.d/ -R' ) ''; }) diff --git a/nixpkgs/nixos/tests/pam/pam-ussh.nix b/nixpkgs/nixos/tests/pam/pam-ussh.nix new file mode 100644 index 000000000000..ba0570dbf97d --- /dev/null +++ b/nixpkgs/nixos/tests/pam/pam-ussh.nix @@ -0,0 +1,70 @@ +import ../make-test-python.nix ({ pkgs, lib, ... }: + +let + testOnlySSHCredentials = pkgs.runCommand "pam-ussh-test-ca" { + nativeBuildInputs = [ pkgs.openssh ]; + } '' + mkdir $out + ssh-keygen -t ed25519 -N "" -f $out/ca + + ssh-keygen -t ed25519 -N "" -f $out/alice + ssh-keygen -s $out/ca -I "alice user key" -n "alice,root" -V 19700101:forever $out/alice.pub + + ssh-keygen -t ed25519 -N "" -f $out/bob + ssh-keygen -s $out/ca -I "bob user key" -n "bob" -V 19700101:forever $out/bob.pub + ''; + makeTestScript = user: pkgs.writeShellScript "pam-ussh-${user}-test-script" '' + set -euo pipefail + + eval $(${pkgs.openssh}/bin/ssh-agent) + + mkdir -p $HOME/.ssh + chmod 700 $HOME/.ssh + cp ${testOnlySSHCredentials}/${user}{,.pub,-cert.pub} $HOME/.ssh + chmod 600 $HOME/.ssh/${user} + chmod 644 $HOME/.ssh/${user}{,-cert}.pub + + set -x + + ${pkgs.openssh}/bin/ssh-add $HOME/.ssh/${user} + ${pkgs.openssh}/bin/ssh-add -l &>2 + + exec sudo id -u -n + ''; +in { + name = "pam-ussh"; + meta.maintainers = with lib.maintainers; [ lukegb ]; + + machine = + { ... }: + { + users.users.alice = { isNormalUser = true; extraGroups = [ "wheel" ]; }; + users.users.bob = { isNormalUser = true; extraGroups = [ "wheel" ]; }; + + security.pam.ussh = { + enable = true; + authorizedPrincipals = "root"; + caFile = "${testOnlySSHCredentials}/ca.pub"; + }; + + security.sudo = { + enable = true; + extraConfig = '' + Defaults lecture="never" + ''; + }; + }; + + testScript = + '' + with subtest("alice should be allowed to escalate to root"): + machine.succeed( + 'su -c "${makeTestScript "alice"}" -l alice | grep root' + ) + + with subtest("bob should not be allowed to escalate to root"): + machine.fail( + 'su -c "${makeTestScript "bob"}" -l bob | grep root' + ) + ''; +}) diff --git a/nixpkgs/nixos/tests/pantheon.nix b/nixpkgs/nixos/tests/pantheon.nix index 989d29a966df..52f85f5c07da 100644 --- a/nixpkgs/nixos/tests/pantheon.nix +++ b/nixpkgs/nixos/tests/pantheon.nix @@ -7,7 +7,7 @@ import ./make-test-python.nix ({ pkgs, lib, ...} : maintainers = teams.pantheon.members; }; - machine = { ... }: + nodes.machine = { ... }: { imports = [ ./common/user-account.nix ]; diff --git a/nixpkgs/nixos/tests/paperless-ng.nix b/nixpkgs/nixos/tests/paperless.nix index 618eeec6b125..12883cd62c60 100644 --- a/nixpkgs/nixos/tests/paperless-ng.nix +++ b/nixpkgs/nixos/tests/paperless.nix @@ -1,30 +1,32 @@ import ./make-test-python.nix ({ lib, ... }: { - name = "paperless-ng"; - meta.maintainers = with lib.maintainers; [ earvstedt Flakebi ]; + name = "paperless"; + meta.maintainers = with lib.maintainers; [ erikarvstedt Flakebi ]; nodes.machine = { pkgs, ... }: { environment.systemPackages = with pkgs; [ imagemagick jq ]; - services.paperless-ng = { + services.paperless = { enable = true; passwordFile = builtins.toFile "password" "admin"; }; }; testScript = '' - machine.wait_for_unit("paperless-ng-consumer.service") + import json - with subtest("Create test doc"): + machine.wait_for_unit("paperless-consumer.service") + + with subtest("Add a document via the file system"): machine.succeed( "convert -size 400x40 xc:white -font 'DejaVu-Sans' -pointsize 20 -fill black " "-annotate +5+20 'hello world 16-10-2005' /var/lib/paperless/consume/doc.png" ) with subtest("Web interface gets ready"): - machine.wait_for_unit("paperless-ng-web.service") + machine.wait_for_unit("paperless-web.service") # Wait until server accepts connections machine.wait_until_succeeds("curl -fs localhost:28981") - with subtest("Create web test doc"): + with subtest("Add a document via the web interface"): machine.succeed( "convert -size 400x40 xc:white -font 'DejaVu-Sans' -pointsize 20 -fill black " "-annotate +5+20 'hello web 16-10-2005' /tmp/webdoc.png" @@ -35,11 +37,8 @@ import ./make-test-python.nix ({ lib, ... }: { machine.wait_until_succeeds( "(($(curl -u admin:admin -fs localhost:28981/api/documents/ | jq .count) == 2))" ) - assert "2005-10-16" in machine.succeed( - "curl -u admin:admin -fs localhost:28981/api/documents/ | jq '.results | .[0] | .created'" - ) - assert "2005-10-16" in machine.succeed( - "curl -u admin:admin -fs localhost:28981/api/documents/ | jq '.results | .[1] | .created'" - ) + docs = json.loads(machine.succeed("curl -u admin:admin -fs localhost:28981/api/documents/"))['results'] + assert "2005-10-16" in docs[0]['created'] + assert "2005-10-16" in docs[1]['created'] ''; }) diff --git a/nixpkgs/nixos/tests/pass-secret-service.nix b/nixpkgs/nixos/tests/pass-secret-service.nix new file mode 100644 index 000000000000..a85a508bfe16 --- /dev/null +++ b/nixpkgs/nixos/tests/pass-secret-service.nix @@ -0,0 +1,69 @@ +import ./make-test-python.nix ({ pkgs, lib, ... }: { + name = "pass-secret-service"; + meta.maintainers = with lib; [ aidalgol ]; + + nodes.machine = { nodes, pkgs, ... }: + { + imports = [ ./common/user-account.nix ]; + + services.passSecretService.enable = true; + + environment.systemPackages = [ + # Create a script that tries to make a request to the D-Bus secrets API. + (pkgs.writers.writePython3Bin "secrets-dbus-init" + { + libraries = [ pkgs.python3Packages.secretstorage ]; + } '' + import secretstorage + print("Initializing dbus connection...") + connection = secretstorage.dbus_init() + print("Requesting default collection...") + collection = secretstorage.get_default_collection(connection) + print("Done! dbus-org.freedesktop.secrets should now be active.") + '') + pkgs.pass + ]; + + programs.gnupg = { + agent.enable = true; + agent.pinentryFlavor = "tty"; + dirmngr.enable = true; + }; + }; + + # Some of the commands are run via a virtual console because they need to be + # run under a real login session, with D-Bus running in the environment. + testScript = { nodes, ... }: + let + user = nodes.machine.config.users.users.alice; + gpg-uid = "alice@example.net"; + gpg-pw = "foobar9000"; + ready-file = "/tmp/secrets-dbus-init.done"; + in + '' + # Initialise the pass(1) storage. + machine.succeed(""" + sudo -u alice gpg --pinentry-mode loopback --batch --passphrase ${gpg-pw} \ + --quick-gen-key ${gpg-uid} \ + """) + machine.succeed("sudo -u alice pass init ${gpg-uid}") + + with subtest("Service is not running on login"): + machine.wait_until_tty_matches("1", "login: ") + machine.send_chars("alice\n") + machine.wait_until_tty_matches("1", "login: alice") + machine.wait_until_succeeds("pgrep login") + machine.wait_until_tty_matches("1", "Password: ") + machine.send_chars("${user.password}\n") + machine.wait_until_succeeds("pgrep -u alice bash") + + _, output = machine.systemctl("status dbus-org.freedesktop.secrets --no-pager", "alice") + assert "Active: inactive (dead)" in output + + with subtest("Service starts after a client tries to talk to the D-Bus API"): + machine.send_chars("secrets-dbus-init; touch ${ready-file}\n") + machine.wait_for_file("${ready-file}") + _, output = machine.systemctl("status dbus-org.freedesktop.secrets --no-pager", "alice") + assert "Active: active (running)" in output + ''; +}) diff --git a/nixpkgs/nixos/tests/patroni.nix b/nixpkgs/nixos/tests/patroni.nix new file mode 100644 index 000000000000..f512fddcdbdd --- /dev/null +++ b/nixpkgs/nixos/tests/patroni.nix @@ -0,0 +1,204 @@ +import ./make-test-python.nix ({ pkgs, lib, ... }: + + let + nodesIps = [ + "192.168.1.1" + "192.168.1.2" + "192.168.1.3" + ]; + + createNode = index: { pkgs, ... }: + let + ip = builtins.elemAt nodesIps index; # since we already use IPs to identify servers + in + { + networking.interfaces.eth1.ipv4.addresses = pkgs.lib.mkOverride 0 [ + { address = ip; prefixLength = 16; } + ]; + + networking.firewall.allowedTCPPorts = [ 5432 8008 5010 ]; + + environment.systemPackages = [ pkgs.jq ]; + + services.patroni = { + + enable = true; + + postgresqlPackage = pkgs.postgresql_14.withPackages (p: [ p.pg_safeupdate ]); + + scope = "cluster1"; + name = "node${toString(index + 1)}"; + nodeIp = ip; + otherNodesIps = builtins.filter (h: h != ip) nodesIps; + softwareWatchdog = true; + + settings = { + bootstrap = { + dcs = { + ttl = 30; + loop_wait = 10; + retry_timeout = 10; + maximum_lag_on_failover = 1048576; + }; + initdb = [ + { encoding = "UTF8"; } + "data-checksums" + ]; + }; + + postgresql = { + use_pg_rewind = true; + use_slots = true; + authentication = { + replication = { + username = "replicator"; + }; + superuser = { + username = "postgres"; + }; + rewind = { + username = "rewind"; + }; + }; + parameters = { + listen_addresses = "${ip}"; + wal_level = "replica"; + hot_standby_feedback = "on"; + unix_socket_directories = "/tmp"; + }; + pg_hba = [ + "host replication replicator 192.168.1.0/24 md5" + # Unsafe, do not use for anything other than tests + "host all all 0.0.0.0/0 trust" + ]; + }; + + etcd3 = { + host = "192.168.1.4:2379"; + }; + }; + + environmentFiles = { + PATRONI_REPLICATION_PASSWORD = pkgs.writeText "replication-password" "postgres"; + PATRONI_SUPERUSER_PASSWORD = pkgs.writeText "superuser-password" "postgres"; + PATRONI_REWIND_PASSWORD = pkgs.writeText "rewind-password" "postgres"; + }; + }; + + # We always want to restart so the tests never hang + systemd.services.patroni.serviceConfig.StartLimitIntervalSec = 0; + }; + in + { + name = "patroni"; + + nodes = { + node1 = createNode 0; + node2 = createNode 1; + node3 = createNode 2; + + etcd = { pkgs, ... }: { + + networking.interfaces.eth1.ipv4.addresses = pkgs.lib.mkOverride 0 [ + { address = "192.168.1.4"; prefixLength = 16; } + ]; + + services.etcd = { + enable = true; + listenClientUrls = [ "http://192.168.1.4:2379" ]; + }; + + networking.firewall.allowedTCPPorts = [ 2379 ]; + }; + + client = { pkgs, ... }: { + environment.systemPackages = [ pkgs.postgresql_14 ]; + + networking.interfaces.eth1.ipv4.addresses = pkgs.lib.mkOverride 0 [ + { address = "192.168.2.1"; prefixLength = 16; } + ]; + + services.haproxy = { + enable = true; + config = '' + global + maxconn 100 + + defaults + log global + mode tcp + retries 2 + timeout client 30m + timeout connect 4s + timeout server 30m + timeout check 5s + + listen cluster1 + bind 127.0.0.1:5432 + option httpchk + http-check expect status 200 + default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions + ${builtins.concatStringsSep "\n" (map (ip: "server postgresql_${ip}_5432 ${ip}:5432 maxconn 100 check port 8008") nodesIps)} + ''; + }; + }; + }; + + + + testScript = '' + nodes = [node1, node2, node3] + + def wait_for_all_nodes_ready(expected_replicas=2): + booted_nodes = filter(lambda node: node.booted, nodes) + for node in booted_nodes: + print(node.succeed("patronictl list cluster1")) + node.wait_until_succeeds(f"[ $(patronictl list -f json cluster1 | jq 'length') == {expected_replicas + 1} ]") + node.wait_until_succeeds("[ $(patronictl list -f json cluster1 | jq 'map(select(.Role | test(\"^Leader$\"))) | map(select(.State | test(\"^running$\"))) | length') == 1 ]") + node.wait_until_succeeds(f"[ $(patronictl list -f json cluster1 | jq 'map(select(.Role | test(\"^Replica$\"))) | map(select(.State | test(\"^running$\"))) | length') == {expected_replicas} ]") + print(node.succeed("patronictl list cluster1")) + client.wait_until_succeeds("psql -h 127.0.0.1 -U postgres --command='select 1;'") + + def run_dummy_queries(): + client.succeed("psql -h 127.0.0.1 -U postgres --pset='pager=off' --tuples-only --command='insert into dummy(val) values (101);'") + client.succeed("test $(psql -h 127.0.0.1 -U postgres --pset='pager=off' --tuples-only --command='select val from dummy where val = 101;') -eq 101") + client.succeed("psql -h 127.0.0.1 -U postgres --pset='pager=off' --tuples-only --command='delete from dummy where val = 101;'") + + start_all() + + with subtest("should bootstrap a new patroni cluster"): + wait_for_all_nodes_ready() + + with subtest("should be able to insert and select"): + client.succeed("psql -h 127.0.0.1 -U postgres --command='create table dummy as select * from generate_series(1, 100) as val;'") + client.succeed("test $(psql -h 127.0.0.1 -U postgres --pset='pager=off' --tuples-only --command='select count(distinct val) from dummy;') -eq 100") + + with subtest("should restart after all nodes are crashed"): + for node in nodes: + node.crash() + for node in nodes: + node.start() + wait_for_all_nodes_ready() + + with subtest("should be able to run queries while any one node is crashed"): + masterNodeName = node1.succeed("patronictl list -f json cluster1 | jq '.[] | select(.Role | test(\"^Leader$\")) | .Member' -r").strip() + masterNodeIndex = int(masterNodeName[len(masterNodeName)-1]) - 1 + + # Move master node at the end of the list to avoid multiple failovers (makes the test faster and more consistent) + nodes.append(nodes.pop(masterNodeIndex)) + + for node in nodes: + node.crash() + wait_for_all_nodes_ready(1) + + # Execute some queries while a node is down. + run_dummy_queries() + + # Restart crashed node. + node.start() + wait_for_all_nodes_ready() + + # Execute some queries with the node back up. + run_dummy_queries() + ''; + }) diff --git a/nixpkgs/nixos/tests/pdns-recursor.nix b/nixpkgs/nixos/tests/pdns-recursor.nix index de1b60e0b1c7..14f1b7ea8a35 100644 --- a/nixpkgs/nixos/tests/pdns-recursor.nix +++ b/nixpkgs/nixos/tests/pdns-recursor.nix @@ -1,12 +1,15 @@ import ./make-test-python.nix ({ pkgs, ... }: { - name = "powerdns"; + name = "powerdns-recursor"; nodes.server = { ... }: { services.pdns-recursor.enable = true; + services.pdns-recursor.exportHosts= true; + networking.hosts."192.0.2.1" = [ "example.com" ]; }; testScript = '' server.wait_for_unit("pdns-recursor") - server.wait_for_open_port("53") + server.wait_for_open_port(53) + assert "192.0.2.1" in server.succeed("host example.com localhost") ''; }) diff --git a/nixpkgs/nixos/tests/pgadmin4.nix b/nixpkgs/nixos/tests/pgadmin4.nix index 658315d3ac0c..9f5ac3d8d922 100644 --- a/nixpkgs/nixos/tests/pgadmin4.nix +++ b/nixpkgs/nixos/tests/pgadmin4.nix @@ -1,52 +1,27 @@ -import ./make-test-python.nix ({ pkgs, lib, ... }: +import ./make-test-python.nix ({ pkgs, lib, buildDeps ? [ ], pythonEnv ? [ ], ... }: + + /* + This test suite replaces the typical pytestCheckHook function in python + packages. Pgadmin4 test suite needs a running and configured postgresql + server. This is why this test exists. + + To not repeat all the python dependencies needed, this test is called directly + from the pgadmin4 derivation, which also passes the currently + used propagatedBuildInputs and any python overrides. + + Unfortunately, there doesn't seem to be an easy way to otherwise include + the needed packages here. + + Due the the needed parameters a direct call to "nixosTests.pgadmin4" fails + and needs to be called as "pgadmin4.tests" + + */ let pgadmin4SrcDir = "/pgadmin"; pgadmin4Dir = "/var/lib/pgadmin"; pgadmin4LogDir = "/var/log/pgadmin"; - python-with-needed-packages = pkgs.python3.withPackages (ps: with ps; [ - selenium - testtools - testscenarios - flask - flask-babelex - flask-babel - flask-gravatar - flask_login - flask_mail - flask_migrate - flask_sqlalchemy - flask_wtf - flask-compress - passlib - pytz - simplejson - six - sqlparse - wtforms - flask-paranoid - psutil - psycopg2 - python-dateutil - sqlalchemy - itsdangerous - flask-security-too - bcrypt - cryptography - sshtunnel - ldap3 - gssapi - flask-socketio - eventlet - httpagentparser - user-agents - wheel - authlib - qrcode - pillow - pyotp - ]); in { name = "pgadmin4"; @@ -54,12 +29,27 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: nodes.machine = { pkgs, ... }: { imports = [ ./common/x11.nix ]; + # needed because pgadmin 6.8 will fail, if those dependencies get updated + nixpkgs.overlays = [ + (self: super: { + pythonPackages = pythonEnv; + }) + ]; + environment.systemPackages = with pkgs; [ pgadmin4 postgresql - python-with-needed-packages chromedriver chromium + # include the same packages as in pgadmin minus speaklater3 + (python3.withPackages + (ps: buildDeps ++ + [ + # test suite package requirements + pythonPackages.testscenarios + pythonPackages.selenium + ]) + ) ]; services.postgresql = { enable = true; @@ -117,11 +107,14 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: ) # don't bother to test LDAP authentification + # exclude resql test due to recent postgres 14.4 update + # see bugreport here https://redmine.postgresql.org/issues/7527 with subtest("run browser test"): machine.succeed( 'cd ${pgadmin4SrcDir}/pgadmin4-${pkgs.pgadmin4.version}/web \ - && ${python-with-needed-packages.interpreter} regression/runtests.py --pkg browser --exclude \ - browser.tests.test_ldap_login.LDAPLoginTestCase,browser.tests.test_ldap_login' + && python regression/runtests.py \ + --pkg browser \ + --exclude browser.tests.test_ldap_login.LDAPLoginTestCase,browser.tests.test_ldap_login,resql' ) # fontconfig is necessary for chromium to run @@ -130,13 +123,14 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: machine.succeed( 'cd ${pgadmin4SrcDir}/pgadmin4-${pkgs.pgadmin4.version}/web \ && export FONTCONFIG_FILE=${pkgs.makeFontsConf { fontDirectories = [];}} \ - && ${python-with-needed-packages.interpreter} regression/runtests.py --pkg feature_tests' + && python regression/runtests.py --pkg feature_tests' ) - with subtest("run resql test"): - machine.succeed( - 'cd ${pgadmin4SrcDir}/pgadmin4-${pkgs.pgadmin4.version}/web \ - && ${python-with-needed-packages.interpreter} regression/runtests.py --pkg resql' - ) + # reactivate this test again, when the postgres 14.4 test has been fixed + # with subtest("run resql test"): + # machine.succeed( + # 'cd ${pgadmin4SrcDir}/pgadmin4-${pkgs.pgadmin4.version}/web \ + # && python regression/runtests.py --pkg resql' + # ) ''; }) diff --git a/nixpkgs/nixos/tests/php/fpm.nix b/nixpkgs/nixos/tests/php/fpm.nix index 718a635a6c7c..64b61a377e28 100644 --- a/nixpkgs/nixos/tests/php/fpm.nix +++ b/nixpkgs/nixos/tests/php/fpm.nix @@ -2,7 +2,7 @@ import ../make-test-python.nix ({ pkgs, lib, php, ... }: { name = "php-${php.version}-fpm-nginx-test"; meta.maintainers = lib.teams.php.members; - machine = { config, lib, pkgs, ... }: { + nodes.machine = { config, lib, pkgs, ... }: { environment.systemPackages = [ php ]; services.nginx = { diff --git a/nixpkgs/nixos/tests/php/httpd.nix b/nixpkgs/nixos/tests/php/httpd.nix index 36d90e72d7d1..b6dfbeeaed52 100644 --- a/nixpkgs/nixos/tests/php/httpd.nix +++ b/nixpkgs/nixos/tests/php/httpd.nix @@ -2,7 +2,7 @@ import ../make-test-python.nix ({ pkgs, lib, php, ... }: { name = "php-${php.version}-httpd-test"; meta.maintainers = lib.teams.php.members; - machine = { config, lib, pkgs, ... }: { + nodes.machine = { config, lib, pkgs, ... }: { services.httpd = { enable = true; adminAddr = "admin@phpfpm"; diff --git a/nixpkgs/nixos/tests/php/pcre.nix b/nixpkgs/nixos/tests/php/pcre.nix index 917184b975ec..57407477f4b8 100644 --- a/nixpkgs/nixos/tests/php/pcre.nix +++ b/nixpkgs/nixos/tests/php/pcre.nix @@ -5,7 +5,7 @@ import ../make-test-python.nix ({ lib, php, ... }: { name = "php-${php.version}-httpd-pcre-jit-test"; meta.maintainers = lib.teams.php.members; - machine = { lib, pkgs, ... }: { + nodes.machine = { lib, pkgs, ... }: { time.timeZone = "UTC"; services.httpd = { enable = true; diff --git a/nixpkgs/nixos/tests/pict-rs.nix b/nixpkgs/nixos/tests/pict-rs.nix index 432fd6a50ccd..4315e9fb6e90 100644 --- a/nixpkgs/nixos/tests/pict-rs.nix +++ b/nixpkgs/nixos/tests/pict-rs.nix @@ -3,7 +3,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: name = "pict-rs"; meta.maintainers = with lib.maintainers; [ happysalada ]; - machine = { ... }: { + nodes.machine = { ... }: { environment.systemPackages = with pkgs; [ curl jq ]; services.pict-rs.enable = true; }; @@ -12,6 +12,6 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: start_all() machine.wait_for_unit("pict-rs") - machine.wait_for_open_port("8080") + machine.wait_for_open_port(8080) ''; }) diff --git a/nixpkgs/nixos/tests/plasma5-systemd-start.nix b/nixpkgs/nixos/tests/plasma5-systemd-start.nix index 72de19af70ce..f584c1ec137a 100644 --- a/nixpkgs/nixos/tests/plasma5-systemd-start.nix +++ b/nixpkgs/nixos/tests/plasma5-systemd-start.nix @@ -6,7 +6,7 @@ import ./make-test-python.nix ({ pkgs, ...} : maintainers = [ oxalica ]; }; - machine = { ... }: + nodes.machine = { ... }: { imports = [ ./common/user-account.nix ]; diff --git a/nixpkgs/nixos/tests/plasma5.nix b/nixpkgs/nixos/tests/plasma5.nix index 5c7ea602f79e..b3836cf641d4 100644 --- a/nixpkgs/nixos/tests/plasma5.nix +++ b/nixpkgs/nixos/tests/plasma5.nix @@ -6,14 +6,17 @@ import ./make-test-python.nix ({ pkgs, ...} : maintainers = [ ttuegel ]; }; - machine = { ... }: + nodes.machine = { ... }: { imports = [ ./common/user-account.nix ]; services.xserver.enable = true; services.xserver.displayManager.sddm.enable = true; services.xserver.displayManager.defaultSession = "plasma"; - services.xserver.desktopManager.plasma5.enable = true; + services.xserver.desktopManager.plasma5 = { + enable = true; + excludePackages = [ pkgs.plasma5Packages.elisa ]; + }; services.xserver.displayManager.autoLogin = { enable = true; user = "alice"; @@ -40,6 +43,9 @@ import ./make-test-python.nix ({ pkgs, ...} : with subtest("Check that logging in has given the user ownership of devices"): machine.succeed("getfacl -p /dev/snd/timer | grep -q ${user.name}") + with subtest("Ensure Elisa is not installed"): + machine.fail("which elisa") + with subtest("Run Dolphin"): machine.execute("su - ${user.name} -c 'DISPLAY=:0.0 dolphin >&2 &'") machine.wait_for_window(" Dolphin") diff --git a/nixpkgs/nixos/tests/plausible.nix b/nixpkgs/nixos/tests/plausible.nix index 58c1dd5cf4a8..ab91e08beb34 100644 --- a/nixpkgs/nixos/tests/plausible.nix +++ b/nixpkgs/nixos/tests/plausible.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { maintainers = [ ma27 ]; }; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { virtualisation.memorySize = 4096; services.plausible = { enable = true; diff --git a/nixpkgs/nixos/tests/pleroma.nix b/nixpkgs/nixos/tests/pleroma.nix index 90a9a2511044..8998716243a2 100644 --- a/nixpkgs/nixos/tests/pleroma.nix +++ b/nixpkgs/nixos/tests/pleroma.nix @@ -158,7 +158,9 @@ import ./make-test-python.nix ({ pkgs, ... }: # Waiting for pleroma to be up. timeout 5m bash -c 'while [[ "$(curl -s -o /dev/null -w '%{http_code}' https://pleroma.nixos.test/api/v1/instance)" != "200" ]]; do sleep 2; done' - pleroma_ctl user new jamy jamy@nixos.test --password 'jamy-password' --moderator --admin -y + # Toremove the RELEASE_COOKIE bit when https://github.com/NixOS/nixpkgs/issues/166229 gets fixed. + RELEASE_COOKIE="/var/lib/pleroma/.cookie" \ + pleroma_ctl user new jamy jamy@nixos.test --password 'jamy-password' --moderator --admin -y ''; tls-cert = pkgs.runCommand "selfSignedCerts" { buildInputs = [ pkgs.openssl ]; } '' diff --git a/nixpkgs/nixos/tests/plikd.nix b/nixpkgs/nixos/tests/plikd.nix index 8fec93c01f6b..97c254a5f7b0 100644 --- a/nixpkgs/nixos/tests/plikd.nix +++ b/nixpkgs/nixos/tests/plikd.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ lib, ... }: { maintainers = [ freezeboy ]; }; - machine = { pkgs, ... }: let + nodes.machine = { pkgs, ... }: let in { services.plikd.enable = true; environment.systemPackages = [ pkgs.plik ]; @@ -15,7 +15,7 @@ import ./make-test-python.nix ({ lib, ... }: { machine.wait_for_unit("plikd") # Network test - machine.wait_for_open_port("8080") + machine.wait_for_open_port(8080) machine.succeed("curl --fail -v http://localhost:8080") # Application test diff --git a/nixpkgs/nixos/tests/plotinus.nix b/nixpkgs/nixos/tests/plotinus.nix index af38b41813b7..b6ebab9b0198 100644 --- a/nixpkgs/nixos/tests/plotinus.nix +++ b/nixpkgs/nixos/tests/plotinus.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { maintainers = pkgs.plotinus.meta.maintainers; }; - machine = + nodes.machine = { pkgs, ... }: { imports = [ ./common/x11.nix ]; diff --git a/nixpkgs/nixos/tests/podgrab.nix b/nixpkgs/nixos/tests/podgrab.nix index e927e25fea56..dc9dfebaf49b 100644 --- a/nixpkgs/nixos/tests/podgrab.nix +++ b/nixpkgs/nixos/tests/podgrab.nix @@ -22,11 +22,11 @@ import ./make-test-python.nix ({ pkgs, ... }: { start_all() default.wait_for_unit("podgrab") - default.wait_for_open_port("${toString defaultPort}") + default.wait_for_open_port(${toString defaultPort}) default.succeed("curl --fail http://localhost:${toString defaultPort}") customized.wait_for_unit("podgrab") - customized.wait_for_open_port("${toString customPort}") + customized.wait_for_open_port(${toString customPort}) customized.succeed("curl --fail http://localhost:${toString customPort}") ''; diff --git a/nixpkgs/nixos/tests/polaris.nix b/nixpkgs/nixos/tests/polaris.nix new file mode 100644 index 000000000000..fb2e67f075aa --- /dev/null +++ b/nixpkgs/nixos/tests/polaris.nix @@ -0,0 +1,31 @@ +import ./make-test-python.nix ({ lib, ... }: + +with lib; + +{ + name = "polaris"; + meta.maintainers = with maintainers; [ pbsds ]; + + nodes.machine = + { pkgs, ... }: { + environment.systemPackages = [ pkgs.jq ]; + services.polaris = { + enable = true; + port = 5050; + settings.users = [ + { + name = "test_user"; + password = "very_secret_password"; + admin = true; + } + ]; + }; + }; + + testScript = '' + machine.wait_for_unit("polaris.service") + machine.wait_for_open_port(5050) + machine.succeed("curl http://localhost:5050/api/version") + machine.succeed("curl -X GET http://localhost:5050/api/initial_setup -H 'accept: application/json' | jq -e '.has_any_users == true'") + ''; +}) diff --git a/nixpkgs/nixos/tests/postfix-raise-smtpd-tls-security-level.nix b/nixpkgs/nixos/tests/postfix-raise-smtpd-tls-security-level.nix index 5fad1fed75b2..2a6c85a3a920 100644 --- a/nixpkgs/nixos/tests/postfix-raise-smtpd-tls-security-level.nix +++ b/nixpkgs/nixos/tests/postfix-raise-smtpd-tls-security-level.nix @@ -1,7 +1,7 @@ import ./make-test-python.nix { name = "postfix"; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { imports = [ common/user-account.nix ]; services.postfix = { enable = true; diff --git a/nixpkgs/nixos/tests/postfix.nix b/nixpkgs/nixos/tests/postfix.nix index 6d22b4edba0a..1dbe6a4c5193 100644 --- a/nixpkgs/nixos/tests/postfix.nix +++ b/nixpkgs/nixos/tests/postfix.nix @@ -5,7 +5,7 @@ in import ./make-test-python.nix { name = "postfix"; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { imports = [ common/user-account.nix ]; services.postfix = { enable = true; diff --git a/nixpkgs/nixos/tests/postgresql-wal-receiver.nix b/nixpkgs/nixos/tests/postgresql-wal-receiver.nix index 0e8b3bfd6c34..ae2708546f5d 100644 --- a/nixpkgs/nixos/tests/postgresql-wal-receiver.nix +++ b/nixpkgs/nixos/tests/postgresql-wal-receiver.nix @@ -31,7 +31,7 @@ let name = "postgresql-wal-receiver-${postgresqlPackage}"; meta.maintainers = with lib.maintainers; [ pacien ]; - machine = { ... }: { + nodes.machine = { ... }: { services.postgresql = { package = pkg; enable = true; diff --git a/nixpkgs/nixos/tests/postgresql.nix b/nixpkgs/nixos/tests/postgresql.nix index 2b487c20a625..7864f5d6ff32 100644 --- a/nixpkgs/nixos/tests/postgresql.nix +++ b/nixpkgs/nixos/tests/postgresql.nix @@ -27,7 +27,7 @@ let maintainers = [ zagy ]; }; - machine = {...}: + nodes.machine = {...}: { services.postgresql = { enable = true; diff --git a/nixpkgs/nixos/tests/power-profiles-daemon.nix b/nixpkgs/nixos/tests/power-profiles-daemon.nix index e073677bee9d..278e94711830 100644 --- a/nixpkgs/nixos/tests/power-profiles-daemon.nix +++ b/nixpkgs/nixos/tests/power-profiles-daemon.nix @@ -5,7 +5,7 @@ import ./make-test-python.nix ({ pkgs, ... }: meta = with pkgs.lib.maintainers; { maintainers = [ mvnetbiz ]; }; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { services.power-profiles-daemon.enable = true; environment.systemPackages = [ pkgs.glib ]; }; diff --git a/nixpkgs/nixos/tests/powerdns.nix b/nixpkgs/nixos/tests/powerdns.nix index 70060bad87b6..d3708d25f0fb 100644 --- a/nixpkgs/nixos/tests/powerdns.nix +++ b/nixpkgs/nixos/tests/powerdns.nix @@ -47,7 +47,9 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { with subtest("Adding an example zone works"): # Extract configuration file needed by pdnsutil unit = server.succeed("systemctl cat pdns") - conf = re.search("(--config-dir=[^ ]+)", unit).group(1) + match = re.search("(--config-dir=[^ ]+)", unit) + assert(match is not None) + conf = match.group(1) pdnsutil = "sudo -u pdns pdnsutil " + conf server.succeed(f"{pdnsutil} create-zone example.com ns1.example.com") server.succeed(f"{pdnsutil} add-record example.com ns1 A 192.168.1.2") diff --git a/nixpkgs/nixos/tests/predictable-interface-names.nix b/nixpkgs/nixos/tests/predictable-interface-names.nix index c0b472638a14..08773120bc12 100644 --- a/nixpkgs/nixos/tests/predictable-interface-names.nix +++ b/nixpkgs/nixos/tests/predictable-interface-names.nix @@ -16,7 +16,7 @@ in pkgs.lib.listToAttrs (builtins.map ({ predictable, withNetworkd }: { name = "${if predictable then "" else "un"}predictableInterfaceNames${if withNetworkd then "-with-networkd" else ""}"; meta = {}; - machine = { lib, ... }: { + nodes.machine = { lib, ... }: { networking.usePredictableInterfaceNames = lib.mkForce predictable; networking.useNetworkd = withNetworkd; networking.dhcpcd.enable = !withNetworkd; diff --git a/nixpkgs/nixos/tests/privacyidea.nix b/nixpkgs/nixos/tests/privacyidea.nix index c1141465ec24..401ad72c37b7 100644 --- a/nixpkgs/nixos/tests/privacyidea.nix +++ b/nixpkgs/nixos/tests/privacyidea.nix @@ -3,10 +3,10 @@ import ./make-test-python.nix ({ pkgs, ...} : rec { name = "privacyidea"; meta = with pkgs.lib.maintainers; { - maintainers = [ fpletz ]; + maintainers = [ ]; }; - machine = { ... }: { + nodes.machine = { ... }: { virtualisation.cores = 2; services.privacyidea = { diff --git a/nixpkgs/nixos/tests/privoxy.nix b/nixpkgs/nixos/tests/privoxy.nix index d16cc498691f..2d95c4522a01 100644 --- a/nixpkgs/nixos/tests/privoxy.nix +++ b/nixpkgs/nixos/tests/privoxy.nix @@ -33,7 +33,7 @@ in maintainers = [ rnhmjoj ]; }; - machine = { ... }: { + nodes.machine = { ... }: { services.nginx.enable = true; services.nginx.virtualHosts."example.com" = { addSSL = true; @@ -81,23 +81,23 @@ in '' with subtest("Privoxy is running"): machine.wait_for_unit("privoxy") - machine.wait_for_open_port("8118") + machine.wait_for_open_port(8118) machine.succeed("curl -f http://config.privoxy.org") with subtest("Privoxy can filter http requests"): - machine.wait_for_open_port("80") + machine.wait_for_open_port(80) assert "great day" in machine.succeed( "curl -sfL http://example.com/how-are-you? | tee /dev/stderr" ) with subtest("Privoxy can filter https requests"): - machine.wait_for_open_port("443") + machine.wait_for_open_port(443) assert "great day" in machine.succeed( "curl -sfL https://example.com/how-are-you? | tee /dev/stderr" ) with subtest("Blocks are working"): - machine.wait_for_open_port("443") + machine.wait_for_open_port(443) machine.fail("curl -f https://example.com/ads 1>&2") machine.succeed("curl -f https://example.com/PRIVOXY-FORCE/ads 1>&2") diff --git a/nixpkgs/nixos/tests/prometheus-exporters.nix b/nixpkgs/nixos/tests/prometheus-exporters.nix index ce3b3fbf3bf3..4fdff7dbdab8 100644 --- a/nixpkgs/nixos/tests/prometheus-exporters.nix +++ b/nixpkgs/nixos/tests/prometheus-exporters.nix @@ -35,7 +35,7 @@ let * }; * exporterTest = '' * wait_for_unit("prometheus-<exporterName>-exporter.service") - * wait_for_open_port("1234") + * wait_for_open_port(1234) * succeed("curl -sSf 'localhost:1234/metrics'") * ''; * }; @@ -52,7 +52,7 @@ let * testScript = '' * <exporterName>.start() * <exporterName>.wait_for_unit("prometheus-<exporterName>-exporter.service") - * <exporterName>.wait_for_open_port("1234") + * <exporterName>.wait_for_open_port(1234) * <exporterName>.succeed("curl -sSf 'localhost:1234/metrics'") * <exporterName>.shutdown() * ''; @@ -557,10 +557,12 @@ let systemd.services.prometheus-mail-exporter = { after = [ "postfix.service" ]; requires = [ "postfix.service" ]; - preStart = '' - mkdir -p -m 0700 mail-exporter/new - ''; serviceConfig = { + ExecStartPre = [ + "${pkgs.writeShellScript "create-maildir" '' + mkdir -p -m 0700 mail-exporter/new + ''}" + ]; ProtectHome = true; ReadOnlyPaths = "/"; ReadWritePaths = "/var/spool/mail"; @@ -1061,7 +1063,7 @@ let }; exporterTest = '' wait_for_unit("prometheus-smartctl-exporter.service") - wait_for_open_port("9633") + wait_for_open_port(9633) wait_until_succeeds( "curl -sSf 'localhost:9633/metrics'" ) @@ -1179,21 +1181,21 @@ let enable = true; extraFlags = [ - "--collector.enable-restart-count" + "--systemd.collector.enable-restart-count" ]; }; metricProvider = { }; exporterTest = '' wait_for_unit("prometheus-systemd-exporter.service") wait_for_open_port(9558) - succeed( + wait_until_succeeds( "curl -sSf localhost:9558/metrics | grep '{}'".format( 'systemd_unit_state{name="basic.target",state="active",type="target"} 1' ) ) succeed( "curl -sSf localhost:9558/metrics | grep '{}'".format( - 'systemd_service_restart_total{state="prometheus-systemd-exporter.service"} 0' + 'systemd_service_restart_total{name="prometheus-systemd-exporter.service"} 0' ) ) ''; @@ -1335,7 +1337,7 @@ mapAttrs ''; meta = with maintainers; { - maintainers = [ willibutz elseym ]; + maintainers = [ willibutz ]; }; } ))) diff --git a/nixpkgs/nixos/tests/prowlarr.nix b/nixpkgs/nixos/tests/prowlarr.nix index 4cbca107568f..144cbd5fc95d 100644 --- a/nixpkgs/nixos/tests/prowlarr.nix +++ b/nixpkgs/nixos/tests/prowlarr.nix @@ -12,7 +12,7 @@ with lib; testScript = '' machine.wait_for_unit("prowlarr.service") - machine.wait_for_open_port("9696") + machine.wait_for_open_port(9696) machine.succeed("curl --fail http://localhost:9696/") ''; }) diff --git a/nixpkgs/nixos/tests/pt2-clone.nix b/nixpkgs/nixos/tests/pt2-clone.nix index 364920c39871..ea4329c4a980 100644 --- a/nixpkgs/nixos/tests/pt2-clone.nix +++ b/nixpkgs/nixos/tests/pt2-clone.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { maintainers = [ fgaz ]; }; - machine = { config, pkgs, ... }: { + nodes.machine = { config, pkgs, ... }: { imports = [ ./common/x11.nix ]; diff --git a/nixpkgs/nixos/tests/public-inbox.nix b/nixpkgs/nixos/tests/public-inbox.nix new file mode 100644 index 000000000000..7de40400fcbf --- /dev/null +++ b/nixpkgs/nixos/tests/public-inbox.nix @@ -0,0 +1,227 @@ +import ./make-test-python.nix ({ pkgs, lib, ... }: +let + orga = "example"; + domain = "${orga}.localdomain"; + + tls-cert = pkgs.runCommand "selfSignedCert" { buildInputs = [ pkgs.openssl ]; } '' + openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -nodes -days 36500 \ + -subj '/CN=machine.${domain}' + install -D -t $out key.pem cert.pem + ''; +in +{ + name = "public-inbox"; + + meta.maintainers = with pkgs.lib.maintainers; [ julm ]; + + machine = { config, pkgs, nodes, ... }: let + inherit (config.services) gitolite public-inbox; + # Git repositories paths in Gitolite. + # Only their baseNameOf is used for configuring public-inbox. + repositories = [ + "user/repo1" + "user/repo2" + ]; + in + { + virtualisation.diskSize = 1 * 1024; + virtualisation.memorySize = 1 * 1024; + networking.domain = domain; + + security.pki.certificateFiles = [ "${tls-cert}/cert.pem" ]; + # If using security.acme: + #security.acme.certs."${domain}".postRun = '' + # systemctl try-restart public-inbox-nntpd public-inbox-imapd + #''; + + services.public-inbox = { + enable = true; + postfix.enable = true; + openFirewall = true; + settings.publicinbox = { + css = [ "href=https://machine.${domain}/style/light.css" ]; + nntpserver = [ "nntps://machine.${domain}" ]; + wwwlisting = "match=domain"; + }; + mda = { + enable = true; + args = [ "--no-precheck" ]; # Allow Bcc: + }; + http = { + enable = true; + port = "/run/public-inbox-http.sock"; + #port = 8080; + args = ["-W0"]; + mounts = [ + "https://machine.${domain}/inbox" + ]; + }; + nntp = { + enable = true; + #port = 563; + args = ["-W0"]; + cert = "${tls-cert}/cert.pem"; + key = "${tls-cert}/key.pem"; + }; + imap = { + enable = true; + #port = 993; + args = ["-W0"]; + cert = "${tls-cert}/cert.pem"; + key = "${tls-cert}/key.pem"; + }; + inboxes = lib.recursiveUpdate (lib.genAttrs (map baseNameOf repositories) (repo: { + address = [ + # Routed to the "public-inbox:" transport in services.postfix.transport + "${repo}@${domain}" + ]; + description = '' + ${repo}@${domain} : + discussions about ${repo}. + ''; + url = "https://machine.${domain}/inbox/${repo}"; + newsgroup = "inbox.comp.${orga}.${repo}"; + coderepo = [ repo ]; + })) + { + repo2 = { + hide = [ + "imap" # FIXME: doesn't work for IMAP as of public-inbox 1.6.1 + "manifest" + "www" + ]; + }; + }; + settings.coderepo = lib.listToAttrs (map (path: lib.nameValuePair (baseNameOf path) { + dir = "/var/lib/gitolite/repositories/${path}.git"; + cgitUrl = "https://git.${domain}/${path}.git"; + }) repositories); + }; + + # Use gitolite to store Git repositories listed in coderepo entries + services.gitolite = { + enable = true; + adminPubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJmoTOQnGqX+//us5oye8UuE+tQBx9QEM7PN13jrwgqY root@localhost"; + }; + systemd.services.public-inbox-httpd = { + serviceConfig.SupplementaryGroups = [ gitolite.group ]; + }; + + # Use nginx as a reverse proxy for public-inbox-httpd + services.nginx = { + enable = true; + recommendedGzipSettings = true; + recommendedOptimisation = true; + recommendedTlsSettings = true; + recommendedProxySettings = true; + virtualHosts."machine.${domain}" = { + forceSSL = true; + sslCertificate = "${tls-cert}/cert.pem"; + sslCertificateKey = "${tls-cert}/key.pem"; + locations."/".return = "302 /inbox"; + locations."= /inbox".return = "302 /inbox/"; + locations."/inbox".proxyPass = "http://unix:${public-inbox.http.port}:/inbox"; + # If using TCP instead of a Unix socket: + #locations."/inbox".proxyPass = "http://127.0.0.1:${toString public-inbox.http.port}/inbox"; + # Referred to by settings.publicinbox.css + # See http://public-inbox.org/meta/_/text/color/ + locations."= /style/light.css".alias = pkgs.writeText "light.css" '' + * { background:#fff; color:#000 } + + a { color:#00f; text-decoration:none } + a:visited { color:#808 } + + *.q { color:#008 } + + *.add { color:#060 } + *.del {color:#900 } + *.head { color:#000 } + *.hunk { color:#960 } + + .hl.num { color:#f30 } /* number */ + .hl.esc { color:#f0f } /* escape character */ + .hl.str { color:#f30 } /* string */ + .hl.ppc { color:#c3c } /* preprocessor */ + .hl.pps { color:#f30 } /* preprocessor string */ + .hl.slc { color:#099 } /* single-line comment */ + .hl.com { color:#099 } /* multi-line comment */ + /* .hl.opt { color:#ccc } */ /* operator */ + /* .hl.ipl { color:#ccc } */ /* interpolation */ + + /* keyword groups kw[a-z] */ + .hl.kwa { color:#f90 } + .hl.kwb { color:#060 } + .hl.kwc { color:#f90 } + /* .hl.kwd { color:#ccc } */ + ''; + }; + }; + + services.postfix = { + enable = true; + setSendmail = true; + #sslCert = "${tls-cert}/cert.pem"; + #sslKey = "${tls-cert}/key.pem"; + recipientDelimiter = "+"; + }; + + environment.systemPackages = [ + pkgs.mailutils + pkgs.openssl + ]; + + }; + + testScript = '' + start_all() + machine.wait_for_unit("multi-user.target") + machine.wait_for_unit("public-inbox-init.service") + + # Very basic check that Gitolite can work; + # Gitolite is not needed for the rest of this testScript + machine.wait_for_unit("gitolite-init.service") + + # List inboxes through public-inbox-httpd + machine.wait_for_unit("nginx.service") + machine.succeed("curl -L https://machine.${domain} | grep repo1@${domain}") + # The repo2 inbox is hidden + machine.fail("curl -L https://machine.${domain} | grep repo2@${domain}") + machine.wait_for_unit("public-inbox-httpd.service") + + # Send a mail and read it through public-inbox-httpd + # Must work too when using a recipientDelimiter. + machine.wait_for_unit("postfix.service") + machine.succeed("mail -t <${pkgs.writeText "mail" '' + Subject: Testing mail + From: root@localhost + To: repo1+extension@${domain} + Message-ID: <repo1@root-1> + Content-Type: text/plain; charset=utf-8 + Content-Disposition: inline + + This is a testing mail. + ''}") + machine.sleep(5) + machine.succeed("curl -L 'https://machine.${domain}/inbox/repo1/repo1@root-1/T/#u' | grep 'This is a testing mail.'") + + # Read a mail through public-inbox-imapd + machine.wait_for_open_port(993) + machine.wait_for_unit("public-inbox-imapd.service") + machine.succeed("openssl s_client -ign_eof -crlf -connect machine.${domain}:993 <${pkgs.writeText "imap-commands" '' + tag login anonymous@${domain} anonymous + tag SELECT INBOX.comp.${orga}.repo1.0 + tag FETCH 1 (BODY[HEADER]) + tag LOGOUT + ''} | grep '^Message-ID: <repo1@root-1>'") + + # TODO: Read a mail through public-inbox-nntpd + #machine.wait_for_open_port(563) + #machine.wait_for_unit("public-inbox-nntpd.service") + + # Delete a mail. + # Note that the use of an extension not listed in the addresses + # require to use --all + machine.succeed("curl -L https://machine.example.localdomain/inbox/repo1/repo1@root-1/raw | sudo -u public-inbox public-inbox-learn rm --all") + machine.fail("curl -L https://machine.example.localdomain/inbox/repo1/repo1@root-1/T/#u | grep 'This is a testing mail.'") + ''; +}) diff --git a/nixpkgs/nixos/tests/pulseaudio.nix b/nixpkgs/nixos/tests/pulseaudio.nix index 4e2ce679acd7..cfdc61bc6c2b 100644 --- a/nixpkgs/nixos/tests/pulseaudio.nix +++ b/nixpkgs/nixos/tests/pulseaudio.nix @@ -27,7 +27,7 @@ let maintainers = [ synthetica ] ++ pkgs.pulseaudio.meta.maintainers; }; - machine = { ... }: + nodes.machine = { ... }: { imports = [ ./common/wayland-cage.nix ]; diff --git a/nixpkgs/nixos/tests/pykms.nix b/nixpkgs/nixos/tests/pykms.nix new file mode 100644 index 000000000000..14d776a2f113 --- /dev/null +++ b/nixpkgs/nixos/tests/pykms.nix @@ -0,0 +1,14 @@ +import ./make-test-python.nix ({ pkgs, ... }: + { + name = "pykms-test"; + meta.maintainers = with pkgs.lib.maintainers; [ zopieux ]; + + nodes.machine = { config, lib, pkgs, ... }: { + services.pykms.enable = true; + }; + + testScript = '' + machine.wait_for_unit("pykms.service") + machine.succeed("${pkgs.pykms}/bin/client") + ''; + }) diff --git a/nixpkgs/nixos/tests/qboot.nix b/nixpkgs/nixos/tests/qboot.nix index 12aef6decfae..29d999be58e5 100644 --- a/nixpkgs/nixos/tests/qboot.nix +++ b/nixpkgs/nixos/tests/qboot.nix @@ -1,7 +1,7 @@ import ./make-test-python.nix ({ pkgs, ...} : { name = "qboot"; - machine = { ... }: { + nodes.machine = { ... }: { virtualisation.bios = pkgs.qboot; }; diff --git a/nixpkgs/nixos/tests/rabbitmq.nix b/nixpkgs/nixos/tests/rabbitmq.nix index 03f1fa46d29e..f8e8e61c47d2 100644 --- a/nixpkgs/nixos/tests/rabbitmq.nix +++ b/nixpkgs/nixos/tests/rabbitmq.nix @@ -6,7 +6,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { maintainers = [ eelco offline ]; }; - machine = { + nodes.machine = { services.rabbitmq = { enable = true; managementPlugin.enable = true; @@ -22,6 +22,6 @@ import ./make-test-python.nix ({ pkgs, ... }: { machine.wait_until_succeeds( 'su -s ${pkgs.runtimeShell} rabbitmq -c "rabbitmqctl status"' ) - machine.wait_for_open_port("15672") + machine.wait_for_open_port(15672) ''; }) diff --git a/nixpkgs/nixos/tests/radarr.nix b/nixpkgs/nixos/tests/radarr.nix index ed90025ac420..85fd6572f061 100644 --- a/nixpkgs/nixos/tests/radarr.nix +++ b/nixpkgs/nixos/tests/radarr.nix @@ -12,7 +12,7 @@ with lib; testScript = '' machine.wait_for_unit("radarr.service") - machine.wait_for_open_port("7878") + machine.wait_for_open_port(7878) machine.succeed("curl --fail http://localhost:7878/") ''; }) diff --git a/nixpkgs/nixos/tests/radicale.nix b/nixpkgs/nixos/tests/radicale.nix index 5101628a682c..66650dce4a00 100644 --- a/nixpkgs/nixos/tests/radicale.nix +++ b/nixpkgs/nixos/tests/radicale.nix @@ -11,7 +11,7 @@ in { name = "radicale3"; meta.maintainers = with lib.maintainers; [ dotlambda ]; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { services.radicale = { enable = true; settings = { diff --git a/nixpkgs/nixos/tests/rasdaemon.nix b/nixpkgs/nixos/tests/rasdaemon.nix index e4bd8d96a8d5..7f30a3b81ab5 100644 --- a/nixpkgs/nixos/tests/rasdaemon.nix +++ b/nixpkgs/nixos/tests/rasdaemon.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, ... } : { maintainers = [ evils ]; }; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { imports = [ ../modules/profiles/minimal.nix ]; hardware.rasdaemon = { enable = true; diff --git a/nixpkgs/nixos/tests/redis.nix b/nixpkgs/nixos/tests/redis.nix index 7b70c239ad6e..abea1657f3ea 100644 --- a/nixpkgs/nixos/tests/redis.nix +++ b/nixpkgs/nixos/tests/redis.nix @@ -30,7 +30,7 @@ import ./make-test-python.nix ({ pkgs, ... }: machine.wait_for_unit("redis-test") # The unnamed Redis server still opens a port for backward-compatibility - machine.wait_for_open_port("6379") + machine.wait_for_open_port(6379) machine.wait_for_file("${redis.servers."".unixSocket}") machine.wait_for_file("${redis.servers."test".unixSocket}") diff --git a/nixpkgs/nixos/tests/redmine.nix b/nixpkgs/nixos/tests/redmine.nix index 3866a1f528c0..621b3e6a36ee 100644 --- a/nixpkgs/nixos/tests/redmine.nix +++ b/nixpkgs/nixos/tests/redmine.nix @@ -9,7 +9,7 @@ with pkgs.lib; let redmineTest = { name, type }: makeTest { name = "redmine-${name}"; - machine = { config, pkgs, ... }: { + nodes.machine = { config, pkgs, ... }: { services.redmine = { enable = true; package = pkgs.redmine; diff --git a/nixpkgs/nixos/tests/restart-by-activation-script.nix b/nixpkgs/nixos/tests/restart-by-activation-script.nix index 0eec292ea9e2..0ac079e0101e 100644 --- a/nixpkgs/nixos/tests/restart-by-activation-script.nix +++ b/nixpkgs/nixos/tests/restart-by-activation-script.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, ...} : { maintainers = [ das_j ]; }; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { imports = [ ../modules/profiles/minimal.nix ]; systemd.services.restart-me = { diff --git a/nixpkgs/nixos/tests/restic.nix b/nixpkgs/nixos/tests/restic.nix index 16979eab8217..75fffe9d9a84 100644 --- a/nixpkgs/nixos/tests/restic.nix +++ b/nixpkgs/nixos/tests/restic.nix @@ -1,96 +1,128 @@ import ./make-test-python.nix ( { pkgs, ... }: - let - password = "some_password"; - repository = "/tmp/restic-backup"; - rcloneRepository = "rclone:local:/tmp/restic-rclone-backup"; + let + password = "some_password"; + repository = "/tmp/restic-backup"; + repositoryFile = "${pkgs.writeText "repositoryFile" "/tmp/restic-backup-from-file"}"; + rcloneRepository = "rclone:local:/tmp/restic-rclone-backup"; - passwordFile = "${pkgs.writeText "password" "correcthorsebatterystaple"}"; - initialize = true; - paths = [ "/opt" ]; - pruneOpts = [ - "--keep-daily 2" - "--keep-weekly 1" - "--keep-monthly 1" - "--keep-yearly 99" - ]; - in - { - name = "restic"; + backupPrepareCommand = '' + touch /opt/backupPrepareCommand + test ! -e /opt/backupCleanupCommand + ''; - meta = with pkgs.lib.maintainers; { - maintainers = [ bbigras i077 ]; - }; + backupCleanupCommand = '' + rm /opt/backupPrepareCommand + touch /opt/backupCleanupCommand + ''; - nodes = { - server = - { pkgs, ... }: - { - services.restic.backups = { - remotebackup = { - inherit repository passwordFile initialize paths pruneOpts; - }; - rclonebackup = { - repository = rcloneRepository; - rcloneConfig = { - type = "local"; - one_file_system = true; - }; + passwordFile = "${pkgs.writeText "password" "correcthorsebatterystaple"}"; + initialize = true; + paths = [ "/opt" ]; + pruneOpts = [ + "--keep-daily 2" + "--keep-weekly 1" + "--keep-monthly 1" + "--keep-yearly 99" + ]; + in + { + name = "restic"; - # This gets overridden by rcloneConfig.type - rcloneConfigFile = pkgs.writeText "rclone.conf" '' - [local] - type=ftp - ''; - inherit passwordFile initialize paths pruneOpts; - }; - remoteprune = { - inherit repository passwordFile; - pruneOpts = [ "--keep-last 1" ]; - }; - }; + meta = with pkgs.lib.maintainers; { + maintainers = [ bbigras i077 ]; + }; - environment.sessionVariables.RCLONE_CONFIG_LOCAL_TYPE = "local"; + nodes = { + server = + { pkgs, ... }: + { + services.restic.backups = { + remotebackup = { + inherit repository passwordFile initialize paths pruneOpts backupPrepareCommand backupCleanupCommand; + }; + remotebackup-from-file = { + inherit repositoryFile passwordFile initialize paths pruneOpts; + }; + rclonebackup = { + repository = rcloneRepository; + rcloneConfig = { + type = "local"; + one_file_system = true; }; + + # This gets overridden by rcloneConfig.type + rcloneConfigFile = pkgs.writeText "rclone.conf" '' + [local] + type=ftp + ''; + inherit passwordFile initialize paths pruneOpts; + }; + remoteprune = { + inherit repository passwordFile; + pruneOpts = [ "--keep-last 1" ]; + }; + custompackage = { + inherit repository passwordFile paths; + package = pkgs.writeShellScriptBin "restic" '' + echo "$@" >> /tmp/fake-restic.log; + ''; + }; + }; + + environment.sessionVariables.RCLONE_CONFIG_LOCAL_TYPE = "local"; }; + }; - testScript = '' - server.start() - server.wait_for_unit("dbus.socket") - server.fail( - "${pkgs.restic}/bin/restic -r ${repository} -p ${passwordFile} snapshots", - "${pkgs.restic}/bin/restic -r ${rcloneRepository} -p ${passwordFile} snapshots", - ) - server.succeed( - "mkdir -p /opt", - "touch /opt/some_file", - "mkdir -p /tmp/restic-rclone-backup", - "timedatectl set-time '2016-12-13 13:45'", - "systemctl start restic-backups-remotebackup.service", - "systemctl start restic-backups-rclonebackup.service", - '${pkgs.restic}/bin/restic -r ${repository} -p ${passwordFile} snapshots -c | grep -e "^1 snapshot"', - '${pkgs.restic}/bin/restic -r ${rcloneRepository} -p ${passwordFile} snapshots -c | grep -e "^1 snapshot"', - "timedatectl set-time '2017-12-13 13:45'", - "systemctl start restic-backups-remotebackup.service", - "systemctl start restic-backups-rclonebackup.service", - "timedatectl set-time '2018-12-13 13:45'", - "systemctl start restic-backups-remotebackup.service", - "systemctl start restic-backups-rclonebackup.service", - "timedatectl set-time '2018-12-14 13:45'", - "systemctl start restic-backups-remotebackup.service", - "systemctl start restic-backups-rclonebackup.service", - "timedatectl set-time '2018-12-15 13:45'", - "systemctl start restic-backups-remotebackup.service", - "systemctl start restic-backups-rclonebackup.service", - "timedatectl set-time '2018-12-16 13:45'", - "systemctl start restic-backups-remotebackup.service", - "systemctl start restic-backups-rclonebackup.service", - '${pkgs.restic}/bin/restic -r ${repository} -p ${passwordFile} snapshots -c | grep -e "^4 snapshot"', - '${pkgs.restic}/bin/restic -r ${rcloneRepository} -p ${passwordFile} snapshots -c | grep -e "^4 snapshot"', - "systemctl start restic-backups-remoteprune.service", - '${pkgs.restic}/bin/restic -r ${repository} -p ${passwordFile} snapshots -c | grep -e "^1 snapshot"', - ) - ''; - } + testScript = '' + server.start() + server.wait_for_unit("dbus.socket") + server.fail( + "${pkgs.restic}/bin/restic -r ${repository} -p ${passwordFile} snapshots", + '${pkgs.restic}/bin/restic --repository-file ${repositoryFile} -p ${passwordFile} snapshots"', + "${pkgs.restic}/bin/restic -r ${rcloneRepository} -p ${passwordFile} snapshots", + "grep 'backup .* /opt' /tmp/fake-restic.log", + ) + server.succeed( + "mkdir -p /opt", + "touch /opt/some_file", + "mkdir -p /tmp/restic-rclone-backup", + "timedatectl set-time '2016-12-13 13:45'", + "systemctl start restic-backups-remotebackup.service", + "rm /opt/backupCleanupCommand", + "systemctl start restic-backups-remotebackup-from-file.service", + "systemctl start restic-backups-rclonebackup.service", + '${pkgs.restic}/bin/restic -r ${repository} -p ${passwordFile} snapshots -c | grep -e "^1 snapshot"', + '${pkgs.restic}/bin/restic --repository-file ${repositoryFile} -p ${passwordFile} snapshots -c | grep -e "^1 snapshot"', + '${pkgs.restic}/bin/restic -r ${rcloneRepository} -p ${passwordFile} snapshots -c | grep -e "^1 snapshot"', + "systemctl start restic-backups-custompackage.service", + "grep 'backup .* /opt' /tmp/fake-restic.log", + "timedatectl set-time '2017-12-13 13:45'", + "systemctl start restic-backups-remotebackup.service", + "rm /opt/backupCleanupCommand", + "systemctl start restic-backups-rclonebackup.service", + "timedatectl set-time '2018-12-13 13:45'", + "systemctl start restic-backups-remotebackup.service", + "rm /opt/backupCleanupCommand", + "systemctl start restic-backups-rclonebackup.service", + "timedatectl set-time '2018-12-14 13:45'", + "systemctl start restic-backups-remotebackup.service", + "rm /opt/backupCleanupCommand", + "systemctl start restic-backups-rclonebackup.service", + "timedatectl set-time '2018-12-15 13:45'", + "systemctl start restic-backups-remotebackup.service", + "rm /opt/backupCleanupCommand", + "systemctl start restic-backups-rclonebackup.service", + "timedatectl set-time '2018-12-16 13:45'", + "systemctl start restic-backups-remotebackup.service", + "rm /opt/backupCleanupCommand", + "systemctl start restic-backups-rclonebackup.service", + '${pkgs.restic}/bin/restic -r ${repository} -p ${passwordFile} snapshots -c | grep -e "^4 snapshot"', + '${pkgs.restic}/bin/restic -r ${rcloneRepository} -p ${passwordFile} snapshots -c | grep -e "^4 snapshot"', + "systemctl start restic-backups-remoteprune.service", + '${pkgs.restic}/bin/restic -r ${repository} -p ${passwordFile} snapshots -c | grep -e "^1 snapshot"', + ) + ''; + } ) diff --git a/nixpkgs/nixos/tests/retroarch.nix b/nixpkgs/nixos/tests/retroarch.nix index 4c96f9eabc82..c506ed02da89 100644 --- a/nixpkgs/nixos/tests/retroarch.nix +++ b/nixpkgs/nixos/tests/retroarch.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, ... }: name = "retroarch"; meta = with pkgs.lib.maintainers; { maintainers = [ j0hax ]; }; - machine = { ... }: + nodes.machine = { ... }: { imports = [ ./common/user-account.nix ]; diff --git a/nixpkgs/nixos/tests/riak.nix b/nixpkgs/nixos/tests/riak.nix deleted file mode 100644 index 3dd4e333d669..000000000000 --- a/nixpkgs/nixos/tests/riak.nix +++ /dev/null @@ -1,18 +0,0 @@ -import ./make-test-python.nix ({ lib, pkgs, ... }: { - name = "riak"; - meta = with lib.maintainers; { - maintainers = [ Br1ght0ne ]; - }; - - machine = { - services.riak.enable = true; - services.riak.package = pkgs.riak; - }; - - testScript = '' - machine.start() - - machine.wait_for_unit("riak") - machine.wait_until_succeeds("riak ping 2>&1") - ''; -}) diff --git a/nixpkgs/nixos/tests/rspamd.nix b/nixpkgs/nixos/tests/rspamd.nix index f0ccfe7ea0e6..26895fbad3f3 100644 --- a/nixpkgs/nixos/tests/rspamd.nix +++ b/nixpkgs/nixos/tests/rspamd.nix @@ -22,7 +22,7 @@ let ''; simple = name: enableIPv6: makeTest { name = "rspamd-${name}"; - machine = { + nodes.machine = { services.rspamd.enable = true; networking.enableIPv6 = enableIPv6; }; @@ -52,7 +52,7 @@ in ipv4only = simple "ipv4only" false; deprecated = makeTest { name = "rspamd-deprecated"; - machine = { + nodes.machine = { services.rspamd = { enable = true; workers.normal.bindSockets = [{ @@ -91,7 +91,7 @@ in bindports = makeTest { name = "rspamd-bindports"; - machine = { + nodes.machine = { services.rspamd = { enable = true; workers.normal.bindSockets = [{ @@ -152,7 +152,7 @@ in }; customLuaRules = makeTest { name = "rspamd-custom-lua-rules"; - machine = { + nodes.machine = { environment.etc."tests/no-muh.eml".text = '' From: Sheep1<bah@example.com> To: Sheep2<mah@example.com> @@ -256,7 +256,7 @@ in }; postfixIntegration = makeTest { name = "rspamd-postfix-integration"; - machine = { + nodes.machine = { environment.systemPackages = with pkgs; [ msmtp ]; environment.etc."tests/gtube.eml".text = '' From: Sheep1<bah@example.com> diff --git a/nixpkgs/nixos/tests/rsyslogd.nix b/nixpkgs/nixos/tests/rsyslogd.nix index f35db3bd44b8..049acdcd4393 100644 --- a/nixpkgs/nixos/tests/rsyslogd.nix +++ b/nixpkgs/nixos/tests/rsyslogd.nix @@ -11,7 +11,7 @@ with pkgs.lib; name = "rsyslogd-test1"; meta.maintainers = [ pkgs.lib.maintainers.aanderse ]; - machine = { config, pkgs, ... }: { + nodes.machine = { config, pkgs, ... }: { services.rsyslogd.enable = true; services.journald.forwardToSyslog = false; }; @@ -27,7 +27,7 @@ with pkgs.lib; name = "rsyslogd-test2"; meta.maintainers = [ pkgs.lib.maintainers.aanderse ]; - machine = { config, pkgs, ... }: { + nodes.machine = { config, pkgs, ... }: { services.rsyslogd.enable = true; }; diff --git a/nixpkgs/nixos/tests/sabnzbd.nix b/nixpkgs/nixos/tests/sabnzbd.nix index fb35b212b493..075bd0b1fe09 100644 --- a/nixpkgs/nixos/tests/sabnzbd.nix +++ b/nixpkgs/nixos/tests/sabnzbd.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { maintainers = with maintainers; [ jojosch ]; }; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { services.sabnzbd = { enable = true; }; diff --git a/nixpkgs/nixos/tests/sanoid.nix b/nixpkgs/nixos/tests/sanoid.nix index 3bdbe0a8d8db..97833c37e6ef 100644 --- a/nixpkgs/nixos/tests/sanoid.nix +++ b/nixpkgs/nixos/tests/sanoid.nix @@ -48,6 +48,9 @@ in { }; # Take snapshot and sync "pool/syncoid".target = "root@target:pool/syncoid"; + + # Test pool without parent (regression test for https://github.com/NixOS/nixpkgs/pull/180111) + "pool".target = "root@target:pool/full-pool"; }; }; }; @@ -105,6 +108,9 @@ in { source.systemctl("start --wait syncoid-pool-syncoid.service") target.succeed("cat /mnt/pool/syncoid/test.txt") + source.systemctl("start --wait syncoid-pool.service") + target.succeed("[[ -d /mnt/pool/full-pool/syncoid ]]") + assert len(source.succeed("zfs allow pool")) == 0, "Pool shouldn't have delegated permissions set after syncing snapshots" assert len(source.succeed("zfs allow pool/sanoid")) == 0, "Sanoid dataset shouldn't have delegated permissions set after syncing snapshots" assert len(source.succeed("zfs allow pool/syncoid")) == 0, "Syncoid dataset shouldn't have delegated permissions set after syncing snapshots" diff --git a/nixpkgs/nixos/tests/schleuder.nix b/nixpkgs/nixos/tests/schleuder.nix new file mode 100644 index 000000000000..a9e4cc325bc7 --- /dev/null +++ b/nixpkgs/nixos/tests/schleuder.nix @@ -0,0 +1,128 @@ +let + certs = import ./common/acme/server/snakeoil-certs.nix; + domain = certs.domain; +in +import ./make-test-python.nix { + name = "schleuder"; + nodes.machine = { pkgs, ... }: { + imports = [ ./common/user-account.nix ]; + services.postfix = { + enable = true; + enableSubmission = true; + tlsTrustedAuthorities = "${certs.ca.cert}"; + sslCert = "${certs.${domain}.cert}"; + sslKey = "${certs.${domain}.key}"; + inherit domain; + destination = [ domain ]; + localRecipients = [ "root" "alice" "bob" ]; + }; + services.schleuder = { + enable = true; + # Don't do it like this in production! The point of this setting + # is to allow loading secrets from _outside_ the world-readable + # Nix store. + extraSettingsFile = pkgs.writeText "schleuder-api-keys.yml" '' + api: + valid_api_keys: + - fnord + ''; + lists = [ "security@${domain}" ]; + settings.api = { + tls_cert_file = "${certs.${domain}.cert}"; + tls_key_file = "${certs.${domain}.key}"; + }; + }; + + environment.systemPackages = [ + pkgs.gnupg + pkgs.msmtp + (pkgs.writeScriptBin "do-test" '' + #!${pkgs.runtimeShell} + set -exuo pipefail + + # Generate a GPG key with no passphrase and export it + sudo -u alice gpg --passphrase-fd 0 --batch --yes --quick-generate-key 'alice@${domain}' rsa4096 sign,encr < <(echo) + sudo -u alice gpg --armor --export alice@${domain} > alice.asc + # Create a new mailing list with alice as the owner, and alice's key + schleuder-cli list new security@${domain} alice@${domain} alice.asc + + # Send an email from a non-member of the list. Use --auto-from so we don't have to specify who it's from twice. + msmtp --auto-from security@${domain} --host=${domain} --port=25 --tls --tls-starttls <<EOF + Subject: really big security issue!! + From: root@${domain} + + I found a big security problem! + EOF + + # Wait for delivery + (set +o pipefail; journalctl -f -n 1000 -u postfix | grep -m 1 'delivered to maildir') + + # There should be exactly one email + mail=(/var/spool/mail/alice/new/*) + [[ "''${#mail[@]}" = 1 ]] + + # Find the fingerprint of the mailing list key + read list_key_fp address < <(schleuder-cli keys list security@${domain} | grep security@) + schleuder-cli keys export security@${domain} $list_key_fp > list.asc + + # Import the key into alice's keyring, so we can verify it as well as decrypting + sudo -u alice gpg --import <list.asc + # And perform the decryption. + sudo -u alice gpg -d $mail >decrypted + # And check that the text matches. + grep "big security problem" decrypted + '') + + # For debugging: + # pkgs.vim pkgs.openssl pkgs.sqliteinteractive + ]; + + security.pki.certificateFiles = [ certs.ca.cert ]; + + # Since we don't have internet here, use dnsmasq to provide MX records from /etc/hosts + services.dnsmasq = { + enable = true; + extraConfig = '' + selfmx + ''; + }; + + networking.extraHosts = '' + 127.0.0.1 ${domain} + ''; + + # schleuder-cli's config is not quite optimal in several ways: + # - A fingerprint _must_ be pinned, it doesn't even have an option + # to trust the PKI + # - It compares certificate fingerprints rather than key + # fingerprints, so renewals break the pin (though that's not + # relevant for this test) + # - It compares them as strings, which means we need to match the + # expected format exactly. This means removing the :s and + # lowercasing it. + # Refs: + # https://0xacab.org/schleuder/schleuder-cli/-/issues/16 + # https://0xacab.org/schleuder/schleuder-cli/-/blob/f8895b9f47083d8c7b99a2797c93f170f3c6a3c0/lib/schleuder-cli/helper.rb#L230-238 + systemd.tmpfiles.rules = let cliconfig = pkgs.runCommand "schleuder-cli.yml" + { + nativeBuildInputs = [ pkgs.jq pkgs.openssl ]; + } '' + fp=$(openssl x509 -in ${certs.${domain}.cert} -noout -fingerprint -sha256 | cut -d = -f 2 | tr -d : | tr 'A-Z' 'a-z') + cat > $out <<EOF + host: localhost + port: 4443 + tls_fingerprint: "$fp" + api_key: fnord + EOF + ''; in + [ + "L+ /root/.schleuder-cli/schleuder-cli.yml - - - - ${cliconfig}" + ]; + }; + + testScript = '' + machine.wait_for_unit("multi-user.target") + machine.wait_until_succeeds("nc -z localhost 4443") + machine.succeed("do-test") + ''; +} diff --git a/nixpkgs/nixos/tests/sddm.nix b/nixpkgs/nixos/tests/sddm.nix index d7c65fa33d67..c76a9683e66d 100644 --- a/nixpkgs/nixos/tests/sddm.nix +++ b/nixpkgs/nixos/tests/sddm.nix @@ -12,7 +12,7 @@ let default = { name = "sddm"; - machine = { ... }: { + nodes.machine = { ... }: { imports = [ ./common/user-account.nix ]; services.xserver.enable = true; services.xserver.displayManager.sddm.enable = true; @@ -41,7 +41,7 @@ let maintainers = [ ttuegel ]; }; - machine = { ... }: { + nodes.machine = { ... }: { imports = [ ./common/user-account.nix ]; services.xserver.enable = true; services.xserver.displayManager = { diff --git a/nixpkgs/nixos/tests/shadow.nix b/nixpkgs/nixos/tests/shadow.nix index dd2a575b1935..50a9f7124646 100644 --- a/nixpkgs/nixos/tests/shadow.nix +++ b/nixpkgs/nixos/tests/shadow.nix @@ -39,9 +39,9 @@ in import ./make-test-python.nix ({ pkgs, ... }: { shadow.wait_until_succeeds("[ $(fgconsole) = 2 ]") shadow.wait_for_unit("getty@tty2.service") shadow.wait_until_succeeds("pgrep -f 'agetty.*tty2'") - shadow.wait_until_tty_matches(2, "login: ") + shadow.wait_until_tty_matches("2", "login: ") shadow.send_chars("emma\n") - shadow.wait_until_tty_matches(2, "login: emma") + shadow.wait_until_tty_matches("2", "login: emma") shadow.wait_until_succeeds("pgrep login") shadow.sleep(2) shadow.send_chars("${password1}\n") @@ -63,9 +63,9 @@ in import ./make-test-python.nix ({ pkgs, ... }: { shadow.wait_until_succeeds("[ $(fgconsole) = 3 ]") shadow.wait_for_unit("getty@tty3.service") shadow.wait_until_succeeds("pgrep -f 'agetty.*tty3'") - shadow.wait_until_tty_matches(3, "login: ") + shadow.wait_until_tty_matches("3", "login: ") shadow.send_chars("emma\n") - shadow.wait_until_tty_matches(3, "login: emma") + shadow.wait_until_tty_matches("3", "login: emma") shadow.wait_until_succeeds("pgrep login") shadow.sleep(2) shadow.send_chars("${password1}\n") @@ -81,16 +81,16 @@ in import ./make-test-python.nix ({ pkgs, ... }: { shadow.wait_until_succeeds("[ $(fgconsole) = 4 ]") shadow.wait_for_unit("getty@tty4.service") shadow.wait_until_succeeds("pgrep -f 'agetty.*tty4'") - shadow.wait_until_tty_matches(4, "login: ") + shadow.wait_until_tty_matches("4", "login: ") shadow.send_chars("emma\n") - shadow.wait_until_tty_matches(4, "login: emma") + shadow.wait_until_tty_matches("4", "login: emma") shadow.wait_until_succeeds("pgrep login") shadow.sleep(2) shadow.send_chars("${password1}\n") - shadow.wait_until_tty_matches(4, "Login incorrect") - shadow.wait_until_tty_matches(4, "login:") + shadow.wait_until_tty_matches("4", "Login incorrect") + shadow.wait_until_tty_matches("4", "login:") shadow.send_chars("emma\n") - shadow.wait_until_tty_matches(4, "login: emma") + shadow.wait_until_tty_matches("4", "login: emma") shadow.wait_until_succeeds("pgrep login") shadow.sleep(2) shadow.send_chars("${password3}\n") @@ -109,11 +109,11 @@ in import ./make-test-python.nix ({ pkgs, ... }: { shadow.wait_until_succeeds("[ $(fgconsole) = 5 ]") shadow.wait_for_unit("getty@tty5.service") shadow.wait_until_succeeds("pgrep -f 'agetty.*tty5'") - shadow.wait_until_tty_matches(5, "login: ") + shadow.wait_until_tty_matches("5", "login: ") shadow.send_chars("layla\n") - shadow.wait_until_tty_matches(5, "login: layla") + shadow.wait_until_tty_matches("5", "login: layla") shadow.wait_until_succeeds("pgrep login") shadow.send_chars("${password2}\n") - shadow.wait_until_tty_matches(5, "login:") + shadow.wait_until_tty_matches("5", "login:") ''; }) diff --git a/nixpkgs/nixos/tests/shattered-pixel-dungeon.nix b/nixpkgs/nixos/tests/shattered-pixel-dungeon.nix index d4e5de22ab9d..a256bbdfd735 100644 --- a/nixpkgs/nixos/tests/shattered-pixel-dungeon.nix +++ b/nixpkgs/nixos/tests/shattered-pixel-dungeon.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { maintainers = [ fgaz ]; }; - machine = { config, pkgs, ... }: { + nodes.machine = { config, pkgs, ... }: { imports = [ ./common/x11.nix ]; diff --git a/nixpkgs/nixos/tests/shiori.nix b/nixpkgs/nixos/tests/shiori.nix index 6c59c394009e..d0f68b903f8c 100644 --- a/nixpkgs/nixos/tests/shiori.nix +++ b/nixpkgs/nixos/tests/shiori.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, lib, ...}: name = "shiori"; meta.maintainers = with lib.maintainers; [ minijackson ]; - machine = + nodes.machine = { ... }: { services.shiori.enable = true; }; diff --git a/nixpkgs/nixos/tests/signal-desktop.nix b/nixpkgs/nixos/tests/signal-desktop.nix index 8c7230629923..5e2b648c7cf5 100644 --- a/nixpkgs/nixos/tests/signal-desktop.nix +++ b/nixpkgs/nixos/tests/signal-desktop.nix @@ -16,7 +16,7 @@ in { maintainers = [ flokli primeos ]; }; - machine = { ... }: + nodes.machine = { ... }: { imports = [ @@ -60,7 +60,7 @@ in { ) # Only SQLCipher should be able to read the encrypted DB: machine.fail( - "su - alice -c 'sqlite3 ~/.config/Signal/sql/db.sqlite .databases'" + "su - alice -c 'sqlite3 ~/.config/Signal/sql/db.sqlite .tables'" ) print(machine.succeed( "su - alice -c 'sqlcipher ~/.config/Signal/sql/db.sqlite'" diff --git a/nixpkgs/nixos/tests/simple.nix b/nixpkgs/nixos/tests/simple.nix index b4d90f750ecf..c36287b4e843 100644 --- a/nixpkgs/nixos/tests/simple.nix +++ b/nixpkgs/nixos/tests/simple.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, ...} : { maintainers = [ eelco ]; }; - machine = { ... }: { + nodes.machine = { ... }: { imports = [ ../modules/profiles/minimal.nix ]; }; diff --git a/nixpkgs/nixos/tests/snapcast.nix b/nixpkgs/nixos/tests/snapcast.nix index 30b8343e2ffe..9b62e4724e75 100644 --- a/nixpkgs/nixos/tests/snapcast.nix +++ b/nixpkgs/nixos/tests/snapcast.nix @@ -19,6 +19,7 @@ in { port = port; tcp.port = tcpPort; http.port = httpPort; + openFirewall = true; buffer = bufferSize; streams = { mpd = { diff --git a/nixpkgs/nixos/tests/snapper.nix b/nixpkgs/nixos/tests/snapper.nix index 098d8d9d72f5..651adc8934d3 100644 --- a/nixpkgs/nixos/tests/snapper.nix +++ b/nixpkgs/nixos/tests/snapper.nix @@ -2,7 +2,7 @@ import ./make-test-python.nix ({ ... }: { name = "snapper"; - machine = { pkgs, lib, ... }: { + nodes.machine = { pkgs, lib, ... }: { boot.initrd.postDeviceCommands = '' ${pkgs.btrfs-progs}/bin/mkfs.btrfs -f -L aux /dev/vdb ''; diff --git a/nixpkgs/nixos/tests/soapui.nix b/nixpkgs/nixos/tests/soapui.nix index 76a87ed5efa1..e4ce3888fd43 100644 --- a/nixpkgs/nixos/tests/soapui.nix +++ b/nixpkgs/nixos/tests/soapui.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { maintainers = [ asbachb ]; }; - machine = { config, pkgs, ... }: { + nodes.machine = { config, pkgs, ... }: { imports = [ ./common/x11.nix ]; diff --git a/nixpkgs/nixos/tests/solr.nix b/nixpkgs/nixos/tests/solr.nix index 86efe87c7078..33afe9d788f7 100644 --- a/nixpkgs/nixos/tests/solr.nix +++ b/nixpkgs/nixos/tests/solr.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, ... }: name = "solr"; meta.maintainers = [ pkgs.lib.maintainers.aanderse ]; - machine = + nodes.machine = { config, pkgs, ... }: { # Ensure the virtual machine has enough memory for Solr to avoid the following error: diff --git a/nixpkgs/nixos/tests/sonarr.nix b/nixpkgs/nixos/tests/sonarr.nix index 764a4d05b381..bdfc8916cb7f 100644 --- a/nixpkgs/nixos/tests/sonarr.nix +++ b/nixpkgs/nixos/tests/sonarr.nix @@ -12,7 +12,7 @@ with lib; testScript = '' machine.wait_for_unit("sonarr.service") - machine.wait_for_open_port("8989") + machine.wait_for_open_port(8989) machine.succeed("curl --fail http://localhost:8989/") ''; }) diff --git a/nixpkgs/nixos/tests/sourcehut.nix b/nixpkgs/nixos/tests/sourcehut.nix index 55757e35f9b4..d52fbddd20f3 100644 --- a/nixpkgs/nixos/tests/sourcehut.nix +++ b/nixpkgs/nixos/tests/sourcehut.nix @@ -119,7 +119,7 @@ in meta.maintainers = [ pkgs.lib.maintainers.tomberek ]; - machine = { config, pkgs, nodes, ... }: { + nodes.machine = { config, pkgs, nodes, ... }: { # buildsrht needs space virtualisation.diskSize = 4 * 1024; virtualisation.memorySize = 2 * 1024; @@ -169,6 +169,45 @@ in oauth-client-id = "d07cb713d920702e"; }; settings.webhooks.private-key = pkgs.writeText "webhook-key" "Ra3IjxgFiwG9jxgp4WALQIZw/BMYt30xWiOsqD0J7EA="; + settings.mail = { + smtp-from = "root+hut@${domain}"; + # WARNING: take care to keep pgp-privkey outside the Nix store in production, + # or use LoadCredentialEncrypted= + pgp-privkey = toString (pkgs.writeText "sourcehut.pgp-privkey" '' + -----BEGIN PGP PRIVATE KEY BLOCK----- + + lFgEYqDRORYJKwYBBAHaRw8BAQdAehGoy36FUx2OesYm07be2rtLyvR5Pb/ltstd + Gk7hYQoAAP9X4oPmxxrHN8LewBpWITdBomNqlHoiP7mI0nz/BOPJHxEktDZuaXhv + cy90ZXN0cy9zb3VyY2VodXQgPHJvb3QraHV0QHNvdXJjZWh1dC5sb2NhbGRvbWFp + bj6IlwQTFgoAPxYhBPqjgjnL8RHN4JnADNicgXaYm0jJBQJioNE5AhsDBQkDwmcA + BgsJCAcDCgUVCgkICwUWAwIBAAIeBQIXgAAKCRDYnIF2mJtIySVCAP9e2nHsVHSi + 2B1YGZpVG7Xf36vxljmMkbroQy+0gBPwRwEAq+jaiQqlbGhQ7R/HMFcAxBIVsq8h + Aw1rngsUd0o3dAicXQRioNE5EgorBgEEAZdVAQUBAQdAXZV2Sd5ZNBVTBbTGavMv + D6ORrUh8z7TI/3CsxCE7+yADAQgHAAD/c1RU9xH+V/uI1fE7HIn/zL0LUPpsuce2 + cH++g4u3kBgTOYh+BBgWCgAmFiEE+qOCOcvxEc3gmcAM2JyBdpibSMkFAmKg0TkC + GwwFCQPCZwAACgkQ2JyBdpibSMlKagD/cTre6p1m8QuJ7kwmCFRSz5tBzIuYMMgN + xtT7dmS91csA/35fWsOykSiFRojQ7ccCSUTHL7ApF2EbL968tP/D2hIG + =Hjoc + -----END PGP PRIVATE KEY BLOCK----- + ''); + pgp-pubkey = pkgs.writeText "sourcehut.pgp-pubkey" '' + -----BEGIN PGP PUBLIC KEY BLOCK----- + + mDMEYqDRORYJKwYBBAHaRw8BAQdAehGoy36FUx2OesYm07be2rtLyvR5Pb/ltstd + Gk7hYQq0Nm5peG9zL3Rlc3RzL3NvdXJjZWh1dCA8cm9vdCtodXRAc291cmNlaHV0 + LmxvY2FsZG9tYWluPoiXBBMWCgA/FiEE+qOCOcvxEc3gmcAM2JyBdpibSMkFAmKg + 0TkCGwMFCQPCZwAGCwkIBwMKBRUKCQgLBRYDAgEAAh4FAheAAAoJENicgXaYm0jJ + JUIA/17acexUdKLYHVgZmlUbtd/fq/GWOYyRuuhDL7SAE/BHAQCr6NqJCqVsaFDt + H8cwVwDEEhWyryEDDWueCxR3Sjd0CLg4BGKg0TkSCisGAQQBl1UBBQEBB0BdlXZJ + 3lk0FVMFtMZq8y8Po5GtSHzPtMj/cKzEITv7IAMBCAeIfgQYFgoAJhYhBPqjgjnL + 8RHN4JnADNicgXaYm0jJBQJioNE5AhsMBQkDwmcAAAoJENicgXaYm0jJSmoA/3E6 + 3uqdZvELie5MJghUUs+bQcyLmDDIDcbU+3ZkvdXLAP9+X1rDspEohUaI0O3HAklE + xy+wKRdhGy/evLT/w9oSBg== + =pJD7 + -----END PGP PUBLIC KEY BLOCK----- + ''; + pgp-key-id = "0xFAA38239CBF111CDE099C00CD89C8176989B48C9"; + }; }; networking.firewall.allowedTCPPorts = [ 443 ]; @@ -195,6 +234,7 @@ in # Testing metasrht machine.wait_for_unit("metasrht-api.service") machine.wait_for_unit("metasrht.service") + machine.wait_for_unit("metasrht-webhooks.service") machine.wait_for_open_port(5000) machine.succeed("curl -sL http://localhost:5000 | grep meta.${domain}") machine.succeed("curl -sL http://meta.${domain} | grep meta.${domain}") @@ -206,7 +246,9 @@ in #machine.wait_for_unit("buildsrht-worker.service") # Testing gitsrht + machine.wait_for_unit("gitsrht-api.service") machine.wait_for_unit("gitsrht.service") + machine.wait_for_unit("gitsrht-webhooks.service") machine.succeed("curl -sL http://git.${domain} | grep git.${domain}") ''; }) diff --git a/nixpkgs/nixos/tests/sssd-ldap.nix b/nixpkgs/nixos/tests/sssd-ldap.nix index 5c58eaef7146..27dce6ceb98c 100644 --- a/nixpkgs/nixos/tests/sssd-ldap.nix +++ b/nixpkgs/nixos/tests/sssd-ldap.nix @@ -13,7 +13,7 @@ in import ./make-test-python.nix ({pkgs, ...}: { maintainers = [ bbigras ]; }; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { services.openldap = { enable = true; settings = { @@ -28,7 +28,7 @@ in import ./make-test-python.nix ({pkgs, ...}: { attrs = { objectClass = [ "olcDatabaseConfig" "olcMdbConfig" ]; olcDatabase = "{1}mdb"; - olcDbDirectory = "/var/db/openldap"; + olcDbDirectory = "/var/lib/openldap/db"; olcSuffix = dbSuffix; olcRootDN = "cn=${ldapRootUser},${dbSuffix}"; olcRootPW = ldapRootPassword; @@ -67,6 +67,8 @@ in import ./make-test-python.nix ({pkgs, ...}: { services.sssd = { enable = true; + # just for testing purposes, don't put this into the Nix store in production! + environmentFile = "${pkgs.writeText "ldap-root" "LDAP_BIND_PW=${ldapRootPassword}"}"; config = '' [sssd] config_file_version = 2 @@ -80,7 +82,7 @@ in import ./make-test-python.nix ({pkgs, ...}: { ldap_search_base = ${dbSuffix} ldap_default_bind_dn = cn=${ldapRootUser},${dbSuffix} ldap_default_authtok_type = password - ldap_default_authtok = ${ldapRootPassword} + ldap_default_authtok = $LDAP_BIND_PW ''; }; }; diff --git a/nixpkgs/nixos/tests/sssd.nix b/nixpkgs/nixos/tests/sssd.nix index 5c1abdca6aef..25527cb59a59 100644 --- a/nixpkgs/nixos/tests/sssd.nix +++ b/nixpkgs/nixos/tests/sssd.nix @@ -5,7 +5,7 @@ import ./make-test-python.nix ({ pkgs, ... }: meta = with pkgs.lib.maintainers; { maintainers = [ bbigras ]; }; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { services.sssd.enable = true; }; diff --git a/nixpkgs/nixos/tests/starship.nix b/nixpkgs/nixos/tests/starship.nix index 33e9a72f7000..48a4be6caf17 100644 --- a/nixpkgs/nixos/tests/starship.nix +++ b/nixpkgs/nixos/tests/starship.nix @@ -2,7 +2,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { name = "starship"; meta.maintainers = pkgs.starship.meta.maintainers; - machine = { + nodes.machine = { programs = { fish.enable = true; zsh.enable = true; diff --git a/nixpkgs/nixos/tests/step-ca.nix b/nixpkgs/nixos/tests/step-ca.nix index f21bd5366266..a855b590232d 100644 --- a/nixpkgs/nixos/tests/step-ca.nix +++ b/nixpkgs/nixos/tests/step-ca.nix @@ -9,6 +9,7 @@ import ./make-test-python.nix ({ pkgs, ... }: ''; in { + name = "step-ca"; nodes = { caserver = diff --git a/nixpkgs/nixos/tests/stunnel.nix b/nixpkgs/nixos/tests/stunnel.nix new file mode 100644 index 000000000000..22c087290fc7 --- /dev/null +++ b/nixpkgs/nixos/tests/stunnel.nix @@ -0,0 +1,174 @@ +{ system ? builtins.currentSystem, config ? { } +, pkgs ? import ../.. { inherit system config; } }: + +with import ../lib/testing-python.nix { inherit system pkgs; }; +with pkgs.lib; + +let + stunnelCommon = { + services.stunnel = { + enable = true; + user = "stunnel"; + }; + users.groups.stunnel = { }; + users.users.stunnel = { + isSystemUser = true; + group = "stunnel"; + }; + }; + makeCert = { config, pkgs, ... }: { + system.activationScripts.create-test-cert = stringAfter [ "users" ] '' + ${pkgs.openssl}/bin/openssl req -batch -x509 -newkey rsa -nodes -out /test-cert.pem -keyout /test-key.pem -subj /CN=${config.networking.hostName} + ( umask 077; cat /test-key.pem /test-cert.pem > /test-key-and-cert.pem ) + chown stunnel /test-key.pem /test-key-and-cert.pem + ''; + }; + serverCommon = { pkgs, ... }: { + networking.firewall.allowedTCPPorts = [ 443 ]; + services.stunnel.servers.https = { + accept = "443"; + connect = 80; + cert = "/test-key-and-cert.pem"; + }; + systemd.services.simple-webserver = { + wantedBy = [ "multi-user.target" ]; + script = '' + cd /etc/webroot + ${pkgs.python3}/bin/python -m http.server 80 + ''; + }; + }; + copyCert = src: dest: filename: '' + from shlex import quote + ${src}.wait_for_file("/test-key-and-cert.pem") + server_cert = ${src}.succeed("cat /test-cert.pem") + ${dest}.succeed("echo %s > ${filename}" % quote(server_cert)) + ''; + +in { + basicServer = makeTest { + name = "basicServer"; + + nodes = { + client = { }; + server = { + imports = [ makeCert serverCommon stunnelCommon ]; + environment.etc."webroot/index.html".text = "well met"; + }; + }; + + testScript = '' + start_all() + + ${copyCert "server" "client" "/authorized-server-cert.crt"} + + server.wait_for_unit("simple-webserver") + server.wait_for_unit("stunnel") + + client.succeed("curl --fail --cacert /authorized-server-cert.crt https://server/ > out") + client.succeed('[[ "$(< out)" == "well met" ]]') + ''; + }; + + serverAndClient = makeTest { + name = "serverAndClient"; + + nodes = { + client = { + imports = [ stunnelCommon ]; + services.stunnel.clients = { + httpsClient = { + accept = "80"; + connect = "server:443"; + CAFile = "/authorized-server-cert.crt"; + }; + httpsClientWithHostVerify = { + accept = "81"; + connect = "server:443"; + CAFile = "/authorized-server-cert.crt"; + verifyHostname = "server"; + }; + httpsClientWithHostVerifyFail = { + accept = "82"; + connect = "server:443"; + CAFile = "/authorized-server-cert.crt"; + verifyHostname = "wronghostname"; + }; + }; + }; + server = { + imports = [ makeCert serverCommon stunnelCommon ]; + environment.etc."webroot/index.html".text = "hello there"; + }; + }; + + testScript = '' + start_all() + + ${copyCert "server" "client" "/authorized-server-cert.crt"} + + server.wait_for_unit("simple-webserver") + server.wait_for_unit("stunnel") + + # In case stunnel came up before we got the server's cert copied over + client.succeed("systemctl reload-or-restart stunnel") + + client.succeed("curl --fail http://localhost/ > out") + client.succeed('[[ "$(< out)" == "hello there" ]]') + + client.succeed("curl --fail http://localhost:81/ > out") + client.succeed('[[ "$(< out)" == "hello there" ]]') + + client.fail("curl --fail http://localhost:82/ > out") + client.succeed('[[ "$(< out)" == "" ]]') + ''; + }; + + mutualAuth = makeTest { + name = "mutualAuth"; + + nodes = rec { + client = { + imports = [ makeCert stunnelCommon ]; + services.stunnel.clients.authenticated-https = { + accept = "80"; + connect = "server:443"; + verifyPeer = true; + CAFile = "/authorized-server-cert.crt"; + cert = "/test-cert.pem"; + key = "/test-key.pem"; + }; + }; + wrongclient = client; + server = { + imports = [ makeCert serverCommon stunnelCommon ]; + services.stunnel.servers.https = { + CAFile = "/authorized-client-certs.crt"; + verifyPeer = true; + }; + environment.etc."webroot/index.html".text = "secret handshake"; + }; + }; + + testScript = '' + start_all() + + ${copyCert "server" "client" "/authorized-server-cert.crt"} + ${copyCert "client" "server" "/authorized-client-certs.crt"} + ${copyCert "server" "wrongclient" "/authorized-server-cert.crt"} + + # In case stunnel came up before we got the cross-certs in place + client.succeed("systemctl reload-or-restart stunnel") + server.succeed("systemctl reload-or-restart stunnel") + wrongclient.succeed("systemctl reload-or-restart stunnel") + + server.wait_for_unit("simple-webserver") + client.fail("curl --fail --insecure https://server/ > out") + client.succeed('[[ "$(< out)" == "" ]]') + client.succeed("curl --fail http://localhost/ > out") + client.succeed('[[ "$(< out)" == "secret handshake" ]]') + wrongclient.fail("curl --fail http://localhost/ > out") + wrongclient.succeed('[[ "$(< out)" == "" ]]') + ''; + }; +} diff --git a/nixpkgs/nixos/tests/swap-partition.nix b/nixpkgs/nixos/tests/swap-partition.nix new file mode 100644 index 000000000000..2279630b57b8 --- /dev/null +++ b/nixpkgs/nixos/tests/swap-partition.nix @@ -0,0 +1,48 @@ +import ./make-test-python.nix ({ lib, pkgs, ... }: +{ + name = "swap-partition"; + + nodes.machine = + { config, pkgs, lib, ... }: + { + virtualisation.useDefaultFilesystems = false; + + virtualisation.bootDevice = "/dev/vda1"; + + boot.initrd.postDeviceCommands = '' + if ! test -b /dev/vda1; then + ${pkgs.parted}/bin/parted --script /dev/vda -- mklabel msdos + ${pkgs.parted}/bin/parted --script /dev/vda -- mkpart primary 1MiB -250MiB + ${pkgs.parted}/bin/parted --script /dev/vda -- mkpart primary -250MiB 100% + sync + fi + + FSTYPE=$(blkid -o value -s TYPE /dev/vda1 || true) + if test -z "$FSTYPE"; then + ${pkgs.e2fsprogs}/bin/mke2fs -t ext4 -L root /dev/vda1 + ${pkgs.util-linux}/bin/mkswap --label swap /dev/vda2 + fi + ''; + + virtualisation.fileSystems = { + "/" = { + device = "/dev/disk/by-label/root"; + fsType = "ext4"; + }; + }; + + swapDevices = [ + { + device = "/dev/disk/by-label/swap"; + } + ]; + }; + + testScript = '' + machine.wait_for_unit("multi-user.target") + + with subtest("Swap is active"): + # Doesn't matter if the numbers reported by `free` are slightly off due to unit conversions. + machine.succeed("free -h | grep -E 'Swap:\s+2[45][0-9]Mi'") + ''; +}) diff --git a/nixpkgs/nixos/tests/sway.nix b/nixpkgs/nixos/tests/sway.nix index 1e9e146c4b6c..52e2c7c99ec4 100644 --- a/nixpkgs/nixos/tests/sway.nix +++ b/nixpkgs/nixos/tests/sway.nix @@ -4,7 +4,13 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { maintainers = with lib.maintainers; [ primeos synthetica ]; }; - machine = { config, ... }: { + # testScriptWithTypes:49: error: Cannot call function of unknown type + # (machine.succeed if succeed else machine.execute)( + # ^ + # Found 1 error in 1 file (checked 1 source file) + skipTypeCheck = true; + + nodes.machine = { config, ... }: { # Automatically login on tty1 as a normal user: imports = [ ./common/user-account.nix ]; services.getty.autologinUser = "alice"; diff --git a/nixpkgs/nixos/tests/sympa.nix b/nixpkgs/nixos/tests/sympa.nix index aad7c95b6c99..80daa4134f75 100644 --- a/nixpkgs/nixos/tests/sympa.nix +++ b/nixpkgs/nixos/tests/sympa.nix @@ -2,7 +2,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { name = "sympa"; meta.maintainers = with lib.maintainers; [ mmilata ]; - machine = + nodes.machine = { ... }: { @@ -13,7 +13,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { webHost = "localhost"; }; }; - listMasters = [ "joe@example.org" ]; + listMasters = [ "bob@example.org" ]; web.enable = true; web.https = false; database = { diff --git a/nixpkgs/nixos/tests/syncthing-init.nix b/nixpkgs/nixos/tests/syncthing-init.nix index 8b60ad7faf09..fcd90739e6a5 100644 --- a/nixpkgs/nixos/tests/syncthing-init.nix +++ b/nixpkgs/nixos/tests/syncthing-init.nix @@ -6,7 +6,7 @@ in { name = "syncthing-init"; meta.maintainers = with pkgs.lib.maintainers; [ lassulus ]; - machine = { + nodes.machine = { services.syncthing = { enable = true; devices.testDevice = { diff --git a/nixpkgs/nixos/tests/syncthing-relay.nix b/nixpkgs/nixos/tests/syncthing-relay.nix index a0233c969ec0..3d70b1eda7b2 100644 --- a/nixpkgs/nixos/tests/syncthing-relay.nix +++ b/nixpkgs/nixos/tests/syncthing-relay.nix @@ -2,7 +2,7 @@ import ./make-test-python.nix ({ lib, pkgs, ... }: { name = "syncthing-relay"; meta.maintainers = with pkgs.lib.maintainers; [ delroth ]; - machine = { + nodes.machine = { environment.systemPackages = [ pkgs.jq ]; services.syncthing.relay = { enable = true; diff --git a/nixpkgs/nixos/tests/systemd-analyze.nix b/nixpkgs/nixos/tests/systemd-analyze.nix index 186f5aee7b85..31588e2b41aa 100644 --- a/nixpkgs/nixos/tests/systemd-analyze.nix +++ b/nixpkgs/nixos/tests/systemd-analyze.nix @@ -6,7 +6,7 @@ import ./make-test-python.nix ({ pkgs, latestKernel ? false, ... }: maintainers = [ raskin ]; }; - machine = + nodes.machine = { pkgs, lib, ... }: { boot.kernelPackages = lib.mkIf latestKernel pkgs.linuxPackages_latest; sound.enable = true; # needed for the factl test, /dev/snd/* exists without them but udev doesn't care then diff --git a/nixpkgs/nixos/tests/systemd-binfmt.nix b/nixpkgs/nixos/tests/systemd-binfmt.nix index a3a6efac3e4d..b16fda0ddb1a 100644 --- a/nixpkgs/nixos/tests/systemd-binfmt.nix +++ b/nixpkgs/nixos/tests/systemd-binfmt.nix @@ -31,7 +31,7 @@ let in { basic = makeTest { name = "systemd-binfmt"; - machine = { + nodes.machine = { boot.binfmt.emulatedSystems = [ "armv7l-linux" "aarch64-linux" @@ -56,7 +56,7 @@ in { preserveArgvZero = makeTest { name = "systemd-binfmt-preserve-argv0"; - machine = { + nodes.machine = { boot.binfmt.emulatedSystems = [ "aarch64-linux" ]; @@ -71,7 +71,7 @@ in { ldPreload = makeTest { name = "systemd-binfmt-ld-preload"; - machine = { + nodes.machine = { boot.binfmt.emulatedSystems = [ "aarch64-linux" ]; diff --git a/nixpkgs/nixos/tests/systemd-boot.nix b/nixpkgs/nixos/tests/systemd-boot.nix index 51cfd82e6c4b..039e6bdd9d5a 100644 --- a/nixpkgs/nixos/tests/systemd-boot.nix +++ b/nixpkgs/nixos/tests/systemd-boot.nix @@ -20,7 +20,7 @@ in name = "systemd-boot"; meta.maintainers = with pkgs.lib.maintainers; [ danielfullmer ]; - machine = common; + nodes.machine = common; testScript = '' machine.start() @@ -44,7 +44,7 @@ in name = "systemd-boot-specialisation"; meta.maintainers = with pkgs.lib.maintainers; [ lukegb ]; - machine = { pkgs, lib, ... }: { + nodes.machine = { pkgs, lib, ... }: { imports = [ common ]; specialisation.something.configuration = {}; }; @@ -67,7 +67,7 @@ in name = "systemd-boot-fallback"; meta.maintainers = with pkgs.lib.maintainers; [ danielfullmer ]; - machine = { pkgs, lib, ... }: { + nodes.machine = { pkgs, lib, ... }: { imports = [ common ]; boot.loader.efi.canTouchEfiVariables = mkForce false; }; @@ -93,7 +93,7 @@ in name = "systemd-boot-update"; meta.maintainers = with pkgs.lib.maintainers; [ danielfullmer ]; - machine = common; + nodes.machine = common; testScript = '' machine.succeed("mount -o remount,rw /boot") @@ -115,7 +115,7 @@ in name = "systemd-boot-memtest86"; meta.maintainers = with pkgs.lib.maintainers; [ Enzime ]; - machine = { pkgs, lib, ... }: { + nodes.machine = { pkgs, lib, ... }: { imports = [ common ]; boot.loader.systemd-boot.memtest86.enable = true; nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [ @@ -133,7 +133,7 @@ in name = "systemd-boot-netbootxyz"; meta.maintainers = with pkgs.lib.maintainers; [ Enzime ]; - machine = { pkgs, lib, ... }: { + nodes.machine = { pkgs, lib, ... }: { imports = [ common ]; boot.loader.systemd-boot.netbootxyz.enable = true; }; @@ -148,7 +148,7 @@ in name = "systemd-boot-entry-filename"; meta.maintainers = with pkgs.lib.maintainers; [ Enzime ]; - machine = { pkgs, lib, ... }: { + nodes.machine = { pkgs, lib, ... }: { imports = [ common ]; boot.loader.systemd-boot.memtest86.enable = true; boot.loader.systemd-boot.memtest86.entryFilename = "apple.conf"; @@ -168,7 +168,7 @@ in name = "systemd-boot-extra-entries"; meta.maintainers = with pkgs.lib.maintainers; [ Enzime ]; - machine = { pkgs, lib, ... }: { + nodes.machine = { pkgs, lib, ... }: { imports = [ common ]; boot.loader.systemd-boot.extraEntries = { "banana.conf" = '' @@ -187,7 +187,7 @@ in name = "systemd-boot-extra-files"; meta.maintainers = with pkgs.lib.maintainers; [ Enzime ]; - machine = { pkgs, lib, ... }: { + nodes.machine = { pkgs, lib, ... }: { imports = [ common ]; boot.loader.systemd-boot.extraFiles = { "efi/fruits/tomato.efi" = pkgs.netbootxyz-efi; diff --git a/nixpkgs/nixos/tests/systemd-confinement.nix b/nixpkgs/nixos/tests/systemd-confinement.nix index 3181af309a6e..bde5b770ea50 100644 --- a/nixpkgs/nixos/tests/systemd-confinement.nix +++ b/nixpkgs/nixos/tests/systemd-confinement.nix @@ -1,7 +1,7 @@ import ./make-test-python.nix { name = "systemd-confinement"; - machine = { pkgs, lib, ... }: let + nodes.machine = { pkgs, lib, ... }: let testServer = pkgs.writeScript "testserver.sh" '' #!${pkgs.runtimeShell} export PATH=${lib.escapeShellArg "${pkgs.coreutils}/bin"} diff --git a/nixpkgs/nixos/tests/systemd-coredump.nix b/nixpkgs/nixos/tests/systemd-coredump.nix new file mode 100644 index 000000000000..62137820878b --- /dev/null +++ b/nixpkgs/nixos/tests/systemd-coredump.nix @@ -0,0 +1,44 @@ +import ./make-test-python.nix ({ pkgs, ... }: + +let + + crasher = pkgs.writeCBin "crasher" "int main;"; + + commonConfig = { + systemd.services.crasher.serviceConfig = { + ExecStart = "${crasher}/bin/crasher"; + StateDirectory = "crasher"; + WorkingDirectory = "%S/crasher"; + Restart = "no"; + }; + }; + +in + +{ + name = "systemd-coredump"; + meta = with pkgs.lib.maintainers; { + maintainers = [ squalus ]; + }; + + nodes.machine1 = { pkgs, lib, ... }: commonConfig; + nodes.machine2 = { pkgs, lib, ... }: lib.recursiveUpdate commonConfig { + systemd.coredump.enable = false; + systemd.package = pkgs.systemd.override { + withCoredump = false; + }; + }; + + testScript = '' + with subtest("systemd-coredump enabled"): + machine1.wait_for_unit("multi-user.target") + machine1.wait_for_unit("systemd-coredump.socket") + machine1.systemctl("start crasher"); + machine1.wait_until_succeeds("coredumpctl list | grep crasher", timeout=10) + machine1.fail("stat /var/lib/crasher/core") + + with subtest("systemd-coredump disabled"): + machine2.systemctl("start crasher"); + machine2.wait_until_succeeds("stat /var/lib/crasher/core", timeout=10) + ''; +}) diff --git a/nixpkgs/nixos/tests/systemd-cryptenroll.nix b/nixpkgs/nixos/tests/systemd-cryptenroll.nix index 49634ef65672..055ae7d1681f 100644 --- a/nixpkgs/nixos/tests/systemd-cryptenroll.nix +++ b/nixpkgs/nixos/tests/systemd-cryptenroll.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { maintainers = [ ymatsiuk ]; }; - machine = { pkgs, lib, ... }: { + nodes.machine = { pkgs, lib, ... }: { environment.systemPackages = [ pkgs.cryptsetup ]; virtualisation = { emptyDiskImages = [ 512 ]; diff --git a/nixpkgs/nixos/tests/systemd-escaping.nix b/nixpkgs/nixos/tests/systemd-escaping.nix index 7f93eb5e4f70..29d2ed1aa352 100644 --- a/nixpkgs/nixos/tests/systemd-escaping.nix +++ b/nixpkgs/nixos/tests/systemd-escaping.nix @@ -14,7 +14,7 @@ in { name = "systemd-escaping"; - machine = { pkgs, lib, utils, ... }: { + nodes.machine = { pkgs, lib, utils, ... }: { systemd.services.echo = assert !(builtins.tryEval (utils.escapeSystemdExecArgs [ [] ])).success; assert !(builtins.tryEval (utils.escapeSystemdExecArgs [ {} ])).success; diff --git a/nixpkgs/nixos/tests/systemd-initrd-btrfs-raid.nix b/nixpkgs/nixos/tests/systemd-initrd-btrfs-raid.nix new file mode 100644 index 000000000000..40fd2d4dc611 --- /dev/null +++ b/nixpkgs/nixos/tests/systemd-initrd-btrfs-raid.nix @@ -0,0 +1,45 @@ +import ./make-test-python.nix ({ lib, pkgs, ... }: { + name = "systemd-initrd-btrfs-raid"; + + nodes.machine = { pkgs, ... }: { + # Use systemd-boot + virtualisation = { + emptyDiskImages = [ 512 512 ]; + useBootLoader = true; + useEFIBoot = true; + }; + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + + environment.systemPackages = with pkgs; [ btrfs-progs ]; + boot.initrd.systemd = { + enable = true; + emergencyAccess = true; + }; + + specialisation.boot-btrfs-raid.configuration = { + fileSystems = lib.mkVMOverride { + "/".fsType = lib.mkForce "btrfs"; + }; + virtualisation.bootDevice = "/dev/vdc"; + }; + }; + + testScript = '' + # Create RAID + machine.succeed("mkfs.btrfs -d raid0 /dev/vdc /dev/vdd") + machine.succeed("mkdir -p /mnt && mount /dev/vdc /mnt && echo hello > /mnt/test && umount /mnt") + + # Boot from the RAID + machine.succeed("bootctl set-default nixos-generation-1-specialisation-boot-btrfs-raid.conf") + machine.succeed("sync") + machine.crash() + machine.wait_for_unit("multi-user.target") + + # Ensure we have successfully booted from the RAID + assert "(initrd)" in machine.succeed("systemd-analyze") # booted with systemd in stage 1 + assert "/dev/vdc on / type btrfs" in machine.succeed("mount") + assert "hello" in machine.succeed("cat /test") + assert "Total devices 2" in machine.succeed("btrfs filesystem show") + ''; +}) diff --git a/nixpkgs/nixos/tests/systemd-initrd-luks-keyfile.nix b/nixpkgs/nixos/tests/systemd-initrd-luks-keyfile.nix new file mode 100644 index 000000000000..25c0c5bd866d --- /dev/null +++ b/nixpkgs/nixos/tests/systemd-initrd-luks-keyfile.nix @@ -0,0 +1,53 @@ +import ./make-test-python.nix ({ lib, pkgs, ... }: let + + keyfile = pkgs.writeText "luks-keyfile" '' + MIGHAoGBAJ4rGTSo/ldyjQypd0kuS7k2OSsmQYzMH6TNj3nQ/vIUjDn7fqa3slt2 + gV6EK3TmTbGc4tzC1v4SWx2m+2Bjdtn4Fs4wiBwn1lbRdC6i5ZYCqasTWIntWn+6 + FllUkMD5oqjOR/YcboxG8Z3B5sJuvTP9llsF+gnuveWih9dpbBr7AgEC + ''; + +in { + name = "systemd-initrd-luks-keyfile"; + + nodes.machine = { pkgs, ... }: { + # Use systemd-boot + virtualisation = { + emptyDiskImages = [ 512 ]; + useBootLoader = true; + useEFIBoot = true; + }; + boot.loader.systemd-boot.enable = true; + + environment.systemPackages = with pkgs; [ cryptsetup ]; + boot.initrd.systemd = { + enable = true; + emergencyAccess = true; + }; + + specialisation.boot-luks.configuration = { + boot.initrd.luks.devices = lib.mkVMOverride { + cryptroot = { + device = "/dev/vdc"; + keyFile = "/etc/cryptroot.key"; + }; + }; + virtualisation.bootDevice = "/dev/mapper/cryptroot"; + boot.initrd.secrets."/etc/cryptroot.key" = keyfile; + }; + }; + + testScript = '' + # Create encrypted volume + machine.wait_for_unit("multi-user.target") + machine.succeed("cryptsetup luksFormat -q --iter-time=1 -d ${keyfile} /dev/vdc") + + # Boot from the encrypted disk + machine.succeed("bootctl set-default nixos-generation-1-specialisation-boot-luks.conf") + machine.succeed("sync") + machine.crash() + + # Boot and decrypt the disk + machine.wait_for_unit("multi-user.target") + assert "/dev/mapper/cryptroot on / type ext4" in machine.succeed("mount") + ''; +}) diff --git a/nixpkgs/nixos/tests/systemd-initrd-luks-password.nix b/nixpkgs/nixos/tests/systemd-initrd-luks-password.nix new file mode 100644 index 000000000000..e8e651f7b35f --- /dev/null +++ b/nixpkgs/nixos/tests/systemd-initrd-luks-password.nix @@ -0,0 +1,48 @@ +import ./make-test-python.nix ({ lib, pkgs, ... }: { + name = "systemd-initrd-luks-password"; + + nodes.machine = { pkgs, ... }: { + # Use systemd-boot + virtualisation = { + emptyDiskImages = [ 512 512 ]; + useBootLoader = true; + useEFIBoot = true; + }; + boot.loader.systemd-boot.enable = true; + + environment.systemPackages = with pkgs; [ cryptsetup ]; + boot.initrd.systemd = { + enable = true; + emergencyAccess = true; + }; + + specialisation.boot-luks.configuration = { + boot.initrd.luks.devices = lib.mkVMOverride { + # We have two disks and only type one password - key reuse is in place + cryptroot.device = "/dev/vdc"; + cryptroot2.device = "/dev/vdd"; + }; + virtualisation.bootDevice = "/dev/mapper/cryptroot"; + }; + }; + + testScript = '' + # Create encrypted volume + machine.wait_for_unit("multi-user.target") + machine.succeed("echo -n supersecret | cryptsetup luksFormat -q --iter-time=1 /dev/vdc -") + machine.succeed("echo -n supersecret | cryptsetup luksFormat -q --iter-time=1 /dev/vdd -") + + # Boot from the encrypted disk + machine.succeed("bootctl set-default nixos-generation-1-specialisation-boot-luks.conf") + machine.succeed("sync") + machine.crash() + + # Boot and decrypt the disk + machine.start() + machine.wait_for_console_text("Please enter passphrase for disk cryptroot") + machine.send_console("supersecret\n") + machine.wait_for_unit("multi-user.target") + + assert "/dev/mapper/cryptroot on / type ext4" in machine.succeed("mount") + ''; +}) diff --git a/nixpkgs/nixos/tests/systemd-initrd-simple.nix b/nixpkgs/nixos/tests/systemd-initrd-simple.nix new file mode 100644 index 000000000000..5d98114304b7 --- /dev/null +++ b/nixpkgs/nixos/tests/systemd-initrd-simple.nix @@ -0,0 +1,44 @@ +import ./make-test-python.nix ({ lib, pkgs, ... }: { + name = "systemd-initrd-simple"; + + nodes.machine = { pkgs, ... }: { + boot.initrd.systemd = { + enable = true; + emergencyAccess = true; + }; + fileSystems = lib.mkVMOverride { + "/".autoResize = true; + }; + }; + + testScript = '' + import subprocess + + with subtest("handover to stage-2 systemd works"): + machine.wait_for_unit("multi-user.target") + machine.succeed("systemd-analyze | grep -q '(initrd)'") # direct handover + machine.succeed("touch /testfile") # / is writable + machine.fail("touch /nix/store/testfile") # /nix/store is not writable + # Special filesystems are mounted by systemd + machine.succeed("[ -e /run/booted-system ]") # /run + machine.succeed("[ -e /sys/class ]") # /sys + machine.succeed("[ -e /dev/null ]") # /dev + machine.succeed("[ -e /proc/1 ]") # /proc + # stage-2-init mounted more special filesystems + machine.succeed("[ -e /dev/shm ]") # /dev/shm + machine.succeed("[ -e /dev/pts/ptmx ]") # /dev/pts + machine.succeed("[ -e /run/keys ]") # /run/keys + + + with subtest("growfs works"): + oldAvail = machine.succeed("df --output=avail / | sed 1d") + machine.shutdown() + + subprocess.check_call(["qemu-img", "resize", "vm-state-machine/machine.qcow2", "+1G"]) + + machine.start() + newAvail = machine.succeed("df --output=avail / | sed 1d") + + assert int(oldAvail) < int(newAvail), "File system did not grow" + ''; +}) diff --git a/nixpkgs/nixos/tests/systemd-initrd-swraid.nix b/nixpkgs/nixos/tests/systemd-initrd-swraid.nix new file mode 100644 index 000000000000..28a0fb3192ae --- /dev/null +++ b/nixpkgs/nixos/tests/systemd-initrd-swraid.nix @@ -0,0 +1,50 @@ +import ./make-test-python.nix ({ lib, pkgs, ... }: { + name = "systemd-initrd-swraid"; + + nodes.machine = { pkgs, ... }: { + # Use systemd-boot + virtualisation = { + emptyDiskImages = [ 512 512 ]; + useBootLoader = true; + useEFIBoot = true; + }; + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + + environment.systemPackages = with pkgs; [ mdadm e2fsprogs ]; # for mdadm and mkfs.ext4 + boot.initrd = { + systemd = { + enable = true; + emergencyAccess = true; + }; + services.swraid = { + enable = true; + mdadmConf = '' + ARRAY /dev/md0 devices=/dev/vdc,/dev/vdd + ''; + }; + kernelModules = [ "raid0" ]; + }; + + specialisation.boot-swraid.configuration.virtualisation.bootDevice = "/dev/disk/by-label/testraid"; + }; + + testScript = '' + # Create RAID + machine.succeed("mdadm --create --force /dev/md0 -n 2 --level=raid0 /dev/vdc /dev/vdd") + machine.succeed("mkfs.ext4 -L testraid /dev/md0") + machine.succeed("mkdir -p /mnt && mount /dev/md0 /mnt && echo hello > /mnt/test && umount /mnt") + + # Boot from the RAID + machine.succeed("bootctl set-default nixos-generation-1-specialisation-boot-swraid.conf") + machine.succeed("sync") + machine.crash() + machine.wait_for_unit("multi-user.target") + + # Ensure we have successfully booted from the RAID + assert "(initrd)" in machine.succeed("systemd-analyze") # booted with systemd in stage 1 + assert "/dev/md0 on / type ext4" in machine.succeed("mount") + assert "hello" in machine.succeed("cat /test") + assert "md0" in machine.succeed("cat /proc/mdstat") + ''; +}) diff --git a/nixpkgs/nixos/tests/systemd-journal.nix b/nixpkgs/nixos/tests/systemd-journal.nix index 6ab7c7246318..d2063a3b9a44 100644 --- a/nixpkgs/nixos/tests/systemd-journal.nix +++ b/nixpkgs/nixos/tests/systemd-journal.nix @@ -6,7 +6,7 @@ import ./make-test-python.nix ({ pkgs, ... }: maintainers = [ lewo ]; }; - machine = { pkgs, lib, ... }: { + nodes.machine = { pkgs, lib, ... }: { services.journald.enableHttpGateway = true; }; diff --git a/nixpkgs/nixos/tests/systemd-machinectl.nix b/nixpkgs/nixos/tests/systemd-machinectl.nix index 4fc5864357c0..5c7926e24abf 100644 --- a/nixpkgs/nixos/tests/systemd-machinectl.nix +++ b/nixpkgs/nixos/tests/systemd-machinectl.nix @@ -28,18 +28,17 @@ import ./make-test-python.nix ( { name = "systemd-machinectl"; - machine = { lib, ... }: { + nodes.machine = { lib, ... }: { # use networkd to obtain systemd network setup networking.useNetworkd = true; networking.useDHCP = false; - services.resolved.enable = false; - - # open DHCP server on interface to container - networking.firewall.trustedInterfaces = [ "ve-+" ]; # do not try to access cache.nixos.org nix.settings.substituters = lib.mkForce [ ]; + # auto-start container + systemd.targets.machines.wants = [ "systemd-nspawn@${containerName}.service" ]; + virtualisation.additionalPaths = [ containerSystem ]; }; @@ -60,11 +59,17 @@ import ./make-test-python.nix ( machine.succeed("machinectl start ${containerName}"); machine.wait_until_succeeds("systemctl -M ${containerName} is-active default.target"); + # Test nss_mymachines without nscd + machine.succeed('LD_LIBRARY_PATH="/run/current-system/sw/lib" getent -s hosts:mymachines hosts ${containerName}'); + + # Test nss_mymachines via nscd + machine.succeed("getent hosts ${containerName}"); + # Test systemd-nspawn network configuration machine.succeed("ping -n -c 1 ${containerName}"); # Test systemd-nspawn uses a user namespace - machine.succeed("test `stat ${containerRoot}/var/empty -c %u%g` != 00"); + machine.succeed("test $(machinectl status ${containerName} | grep 'UID Shift: ' | wc -l) = 1") # Test systemd-nspawn reboot machine.succeed("machinectl shell ${containerName} /run/current-system/sw/bin/reboot"); @@ -74,8 +79,17 @@ import ./make-test-python.nix ( machine.succeed("machinectl reboot ${containerName}"); machine.wait_until_succeeds("systemctl -M ${containerName} is-active default.target"); + # Restart machine + machine.shutdown() + machine.start() + machine.wait_for_unit("default.target"); + + # Test auto-start + machine.succeed("machinectl show ${containerName}") + # Test machinectl stop machine.succeed("machinectl stop ${containerName}"); + machine.wait_until_succeeds("test $(systemctl is-active systemd-nspawn@${containerName}) = inactive"); # Show to to delete the container machine.succeed("chattr -i ${containerRoot}/var/empty"); diff --git a/nixpkgs/nixos/tests/systemd-misc.nix b/nixpkgs/nixos/tests/systemd-misc.nix index e416baa8b5f5..0ddd51100463 100644 --- a/nixpkgs/nixos/tests/systemd-misc.nix +++ b/nixpkgs/nixos/tests/systemd-misc.nix @@ -31,7 +31,7 @@ in { name = "systemd-misc"; - machine = { pkgs, lib, ... }: { + nodes.machine = { pkgs, lib, ... }: { boot.extraSystemdUnitPaths = [ "/etc/systemd-rw/system" ]; users.users.limited = { diff --git a/nixpkgs/nixos/tests/systemd-networkd-vrf.nix b/nixpkgs/nixos/tests/systemd-networkd-vrf.nix index 8a1580fc2ada..3c18f788e927 100644 --- a/nixpkgs/nixos/tests/systemd-networkd-vrf.nix +++ b/nixpkgs/nixos/tests/systemd-networkd-vrf.nix @@ -138,18 +138,18 @@ in { }; testScript = '' - def compare_tables(expected, actual): - assert ( - expected == actual - ), """ - Routing tables don't match! - Expected: - {} - Actual: - {} - """.format( - expected, actual - ) + import json + + def compare(raw_json, to_compare): + data = json.loads(raw_json) + assert len(raw_json) >= len(to_compare) + for i, row in enumerate(to_compare): + actual = data[i] + assert len(row.keys()) > 0 + for key, value in row.items(): + assert value == actual[key], f""" + In entry {i}, value {key}: got: {actual[key]}, expected {value} + """ start_all() @@ -159,23 +159,18 @@ in { node2.wait_for_unit("network.target") node3.wait_for_unit("network.target") - # NOTE: please keep in mind that the trailing whitespaces in the following strings - # are intentional as the output is compared against the raw `iproute2`-output. - # editorconfig-checker-disable client_ipv4_table = """ - 192.168.1.2 dev vrf1 proto static metric 100 + 192.168.1.2 dev vrf1 proto static metric 100\x20 192.168.2.3 dev vrf2 proto static metric 100 """.strip() vrf1_table = """ - broadcast 192.168.1.0 dev eth1 proto kernel scope link src 192.168.1.1 - 192.168.1.0/24 dev eth1 proto kernel scope link src 192.168.1.1 - local 192.168.1.1 dev eth1 proto kernel scope host src 192.168.1.1 + 192.168.1.0/24 dev eth1 proto kernel scope link src 192.168.1.1\x20 + local 192.168.1.1 dev eth1 proto kernel scope host src 192.168.1.1\x20 broadcast 192.168.1.255 dev eth1 proto kernel scope link src 192.168.1.1 """.strip() vrf2_table = """ - broadcast 192.168.2.0 dev eth2 proto kernel scope link src 192.168.2.1 - 192.168.2.0/24 dev eth2 proto kernel scope link src 192.168.2.1 - local 192.168.2.1 dev eth2 proto kernel scope host src 192.168.2.1 + 192.168.2.0/24 dev eth2 proto kernel scope link src 192.168.2.1\x20 + local 192.168.2.1 dev eth2 proto kernel scope host src 192.168.2.1\x20 broadcast 192.168.2.255 dev eth2 proto kernel scope link src 192.168.2.1 """.strip() # editorconfig-checker-enable @@ -183,14 +178,28 @@ in { # Check that networkd properly configures the main routing table # and the routing tables for the VRF. with subtest("check vrf routing tables"): - compare_tables( - client_ipv4_table, client.succeed("ip -4 route list | head -n2").strip() + compare( + client.succeed("ip --json -4 route list"), + [ + {"dst": "192.168.1.2", "dev": "vrf1", "metric": 100}, + {"dst": "192.168.2.3", "dev": "vrf2", "metric": 100} + ] ) - compare_tables( - vrf1_table, client.succeed("ip -4 route list table 23 | head -n4").strip() + compare( + client.succeed("ip --json -4 route list table 23"), + [ + {"dst": "192.168.1.0/24", "dev": "eth1", "prefsrc": "192.168.1.1"}, + {"type": "local", "dst": "192.168.1.1", "dev": "eth1", "prefsrc": "192.168.1.1"}, + {"type": "broadcast", "dev": "eth1", "prefsrc": "192.168.1.1", "dst": "192.168.1.255"} + ] ) - compare_tables( - vrf2_table, client.succeed("ip -4 route list table 42 | head -n4").strip() + compare( + client.succeed("ip --json -4 route list table 42"), + [ + {"dst": "192.168.2.0/24", "dev": "eth2", "prefsrc": "192.168.2.1"}, + {"type": "local", "dst": "192.168.2.1", "dev": "eth2", "prefsrc": "192.168.2.1"}, + {"type": "broadcast", "dev": "eth2", "prefsrc": "192.168.2.1", "dst": "192.168.2.255"} + ] ) # Ensure that other nodes are reachable via ICMP through the VRF. diff --git a/nixpkgs/nixos/tests/systemd-networkd.nix b/nixpkgs/nixos/tests/systemd-networkd.nix index 7faeae3704ec..6c423f4140b1 100644 --- a/nixpkgs/nixos/tests/systemd-networkd.nix +++ b/nixpkgs/nixos/tests/systemd-networkd.nix @@ -8,6 +8,9 @@ let generateNodeConf = { lib, pkgs, config, privk, pubk, peerId, nodeId, ...}: { environment.systemPackages = with pkgs; [ wireguard-tools ]; systemd.network = { enable = true; + config = { + routeTables.custom = 23; + }; netdevs = { "90-wg0" = { netdevConfig = { Kind = "wireguard"; Name = "wg0"; }; @@ -39,6 +42,7 @@ let generateNodeConf = { lib, pkgs, config, privk, pubk, peerId, nodeId, ...}: { address = [ "10.0.0.${nodeId}/32" ]; routes = [ { routeConfig = { Gateway = "10.0.0.${nodeId}"; Destination = "10.0.0.0/24"; }; } + { routeConfig = { Gateway = "10.0.0.${nodeId}"; Destination = "10.0.0.0/24"; Table = "custom"; }; } ]; }; "30-eth1" = { @@ -88,6 +92,12 @@ testScript = '' node2.wait_for_unit("systemd-networkd-wait-online.service") # ================================ + # Networkd Config + # ================================ + node1.succeed("grep RouteTable=custom:23 /etc/systemd/networkd.conf") + node1.succeed("sudo ip route show table custom | grep '10.0.0.0/24 via 10.0.0.1 dev wg0 proto static'") + + # ================================ # Wireguard # ================================ node1.succeed("ping -c 5 10.0.0.2") diff --git a/nixpkgs/nixos/tests/systemd-nspawn.nix b/nixpkgs/nixos/tests/systemd-nspawn.nix index 5bf55060d2e0..bc77ee2a4d15 100644 --- a/nixpkgs/nixos/tests/systemd-nspawn.nix +++ b/nixpkgs/nixos/tests/systemd-nspawn.nix @@ -10,8 +10,8 @@ let Key-Length: 1024 Subkey-Type: ELG-E Subkey-Length: 1024 - Name-Real: Joe Tester - Name-Email: joe@foo.bar + Name-Real: Bob Foobar + Name-Email: bob@foo.bar Expire-Date: 0 # Do a commit here, so that we can later print "done" %commit @@ -19,14 +19,21 @@ let EOF gpg --batch --generate-key foo rm $out/S.gpg-agent $out/S.gpg-agent.* - gpg --export joe@foo.bar -a > $out/pubkey.gpg + gpg --export bob@foo.bar -a > $out/pubkey.gpg ''); nspawnImages = (pkgs.runCommand "localhost" { buildInputs = [ pkgs.coreutils pkgs.gnupg ]; } '' mkdir -p $out cd $out + + # produce a testimage.raw dd if=/dev/urandom of=$out/testimage.raw bs=$((1024*1024+7)) count=5 - sha256sum testimage.raw > SHA256SUMS + + # produce a testimage2.tar.xz, containing the hello store path + tar cvJpf testimage2.tar.xz ${pkgs.hello} + + # produce signature(s) + sha256sum testimage* > SHA256SUMS export GNUPGHOME="$(mktemp -d)" cp -R ${gpgKeyring}/* $GNUPGHOME gpg --batch --sign --detach-sign --output SHA256SUMS.gpg SHA256SUMS @@ -56,5 +63,9 @@ in { client.succeed( "cmp /var/lib/machines/testimage.raw ${nspawnImages}/testimage.raw" ) + client.succeed("machinectl pull-tar --verify=signature http://server/testimage2.tar.xz") + client.succeed( + "cmp /var/lib/machines/testimage2/${pkgs.hello}/bin/hello ${pkgs.hello}/bin/hello" + ) ''; }) diff --git a/nixpkgs/nixos/tests/systemd-shutdown.nix b/nixpkgs/nixos/tests/systemd-shutdown.nix new file mode 100644 index 000000000000..688cd6dd2c17 --- /dev/null +++ b/nixpkgs/nixos/tests/systemd-shutdown.nix @@ -0,0 +1,26 @@ +import ./make-test-python.nix ({ pkgs, systemdStage1 ? false, ...} : let + msg = "Shutting down NixOS"; +in { + name = "systemd-shutdown"; + meta = with pkgs.lib.maintainers; { + maintainers = [ das_j ]; + }; + + nodes.machine = { + imports = [ ../modules/profiles/minimal.nix ]; + systemd.shutdownRamfs.contents."/etc/systemd/system-shutdown/shutdown-message".source = pkgs.writeShellScript "shutdown-message" '' + echo "${msg}" + ''; + }; + + testScript = '' + machine.wait_for_unit("multi-user.target") + # .shutdown() would wait for the machine to power off + machine.succeed("systemctl poweroff") + # Message printed by systemd-shutdown + machine.wait_for_console_text("Unmounting '/oldroot'") + machine.wait_for_console_text("${msg}") + # Don't try to sync filesystems + machine.booted = False + ''; +}) diff --git a/nixpkgs/nixos/tests/systemd.nix b/nixpkgs/nixos/tests/systemd.nix index f86daa5eea97..3317823e03f7 100644 --- a/nixpkgs/nixos/tests/systemd.nix +++ b/nixpkgs/nixos/tests/systemd.nix @@ -1,7 +1,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { name = "systemd"; - machine = { lib, ... }: { + nodes.machine = { lib, ... }: { imports = [ common/user-account.nix common/x11.nix ]; virtualisation.emptyDiskImages = [ 512 512 ]; @@ -192,5 +192,9 @@ import ./make-test-python.nix ({ pkgs, ... }: { with subtest("systemd per-unit accounting works"): assert "IP traffic received: 84B" in output_ping assert "IP traffic sent: 84B" in output_ping + + with subtest("systemd environment is properly set"): + machine.systemctl("daemon-reexec") # Rewrites /proc/1/environ + machine.succeed("grep -q TZDIR=/etc/zoneinfo /proc/1/environ") ''; }) diff --git a/nixpkgs/nixos/tests/taskserver.nix b/nixpkgs/nixos/tests/taskserver.nix index f34782c7059a..b2bd421e231f 100644 --- a/nixpkgs/nixos/tests/taskserver.nix +++ b/nixpkgs/nixos/tests/taskserver.nix @@ -63,6 +63,7 @@ in { server = { services.taskserver.enable = true; services.taskserver.listenHost = "::"; + services.taskserver.openFirewall = true; services.taskserver.fqdn = "server"; services.taskserver.organisations = { testOrganisation.users = [ "alice" "foo" ]; diff --git a/nixpkgs/nixos/tests/telegraf.nix b/nixpkgs/nixos/tests/telegraf.nix index d99680ce2c3c..c3cdb1645213 100644 --- a/nixpkgs/nixos/tests/telegraf.nix +++ b/nixpkgs/nixos/tests/telegraf.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, ...} : { maintainers = [ mic92 ]; }; - machine = { ... }: { + nodes.machine = { ... }: { services.telegraf.enable = true; services.telegraf.environmentFiles = [(pkgs.writeText "secrets" '' SECRET=example diff --git a/nixpkgs/nixos/tests/teleport.nix b/nixpkgs/nixos/tests/teleport.nix index 15b16e44409d..34bf1bc0c70d 100644 --- a/nixpkgs/nixos/tests/teleport.nix +++ b/nixpkgs/nixos/tests/teleport.nix @@ -72,9 +72,9 @@ in nodes = { inherit minimal; }; testScript = '' - minimal.wait_for_open_port("3025") - minimal.wait_for_open_port("3080") - minimal.wait_for_open_port("3022") + minimal.wait_for_open_port(3025) + minimal.wait_for_open_port(3080) + minimal.wait_for_open_port(3022) ''; }; @@ -86,12 +86,12 @@ in testScript = '' with subtest("teleport ready"): - server.wait_for_open_port("3025") - client.wait_for_open_port("3022") + server.wait_for_open_port(3025) + client.wait_for_open_port(3022) with subtest("check applied configuration"): server.wait_until_succeeds("tctl get nodes --format=json | ${pkgs.jq}/bin/jq -e '.[] | select(.spec.hostname==\"client\") | .metadata.labels.role==\"client\"'") - server.wait_for_open_port("3000") + server.wait_for_open_port(3000) client.succeed("journalctl -u teleport.service --grep='DEBU'") server.succeed("journalctl -u teleport.service --grep='Starting teleport in insecure mode.'") ''; diff --git a/nixpkgs/nixos/tests/terminal-emulators.nix b/nixpkgs/nixos/tests/terminal-emulators.nix index 6ea0f1c18725..c724608b9155 100644 --- a/nixpkgs/nixos/tests/terminal-emulators.nix +++ b/nixpkgs/nixos/tests/terminal-emulators.nix @@ -197,6 +197,7 @@ in mapAttrs (name: { pkg, executable ? name, cmd ? "SHELL=$command ${executable} with subtest("have the terminal display a colour"): # We run this command in the background + assert machine.shell is not None machine.shell.send(b"(run-in-this-term display-colour |& systemd-cat -t terminal) &\n") with machine.nested("Waiting for the screen to have pink on it:"): diff --git a/nixpkgs/nixos/tests/tinywl.nix b/nixpkgs/nixos/tests/tinywl.nix index 8fb87b533306..411cdb1f6419 100644 --- a/nixpkgs/nixos/tests/tinywl.nix +++ b/nixpkgs/nixos/tests/tinywl.nix @@ -6,7 +6,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: maintainers = with lib.maintainers; [ primeos ]; }; - machine = { config, ... }: { + nodes.machine = { config, ... }: { # Automatically login on tty1 as a normal user: imports = [ ./common/user-account.nix ]; services.getty.autologinUser = "alice"; diff --git a/nixpkgs/nixos/tests/tomcat.nix b/nixpkgs/nixos/tests/tomcat.nix index e383f224e3d1..4cfb3cc5a7d8 100644 --- a/nixpkgs/nixos/tests/tomcat.nix +++ b/nixpkgs/nixos/tests/tomcat.nix @@ -3,7 +3,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { name = "tomcat"; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { services.tomcat.enable = true; }; diff --git a/nixpkgs/nixos/tests/traefik.nix b/nixpkgs/nixos/tests/traefik.nix index 1d6c0a479ef6..989ec390c060 100644 --- a/nixpkgs/nixos/tests/traefik.nix +++ b/nixpkgs/nixos/tests/traefik.nix @@ -11,14 +11,20 @@ import ./make-test-python.nix ({ pkgs, ... }: { environment.systemPackages = [ pkgs.curl ]; }; traefik = { config, pkgs, ... }: { - virtualisation.oci-containers.containers.nginx = { - extraOptions = [ - "-l" "traefik.enable=true" - "-l" "traefik.http.routers.nginx.entrypoints=web" - "-l" "traefik.http.routers.nginx.rule=Host(`nginx.traefik.test`)" - ]; - image = "nginx-container"; - imageFile = pkgs.dockerTools.examples.nginx; + virtualisation.oci-containers = { + backend = "docker"; + containers.nginx = { + extraOptions = [ + "-l" + "traefik.enable=true" + "-l" + "traefik.http.routers.nginx.entrypoints=web" + "-l" + "traefik.http.routers.nginx.rule=Host(`nginx.traefik.test`)" + ]; + image = "nginx-container"; + imageFile = pkgs.dockerTools.examples.nginx; + }; }; networking.firewall.allowedTCPPorts = [ 80 ]; diff --git a/nixpkgs/nixos/tests/transmission.nix b/nixpkgs/nixos/tests/transmission.nix index 7e2648804de2..b69ddd84d009 100644 --- a/nixpkgs/nixos/tests/transmission.nix +++ b/nixpkgs/nixos/tests/transmission.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, ...} : { maintainers = [ coconnor ]; }; - machine = { ... }: { + nodes.machine = { ... }: { imports = [ ../modules/profiles/minimal.nix ]; networking.firewall.allowedTCPPorts = [ 9091 ]; diff --git a/nixpkgs/nixos/tests/tsm-client-gui.nix b/nixpkgs/nixos/tests/tsm-client-gui.nix index e4bcd344a895..e11501da53d0 100644 --- a/nixpkgs/nixos/tests/tsm-client-gui.nix +++ b/nixpkgs/nixos/tests/tsm-client-gui.nix @@ -10,7 +10,7 @@ import ./make-test-python.nix ({ lib, pkgs, ... }: { enableOCR = true; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { imports = [ ./common/x11.nix ]; programs.tsmClient = { enable = true; diff --git a/nixpkgs/nixos/tests/tuptime.nix b/nixpkgs/nixos/tests/tuptime.nix index 6d37e3069839..93410de7bdf5 100644 --- a/nixpkgs/nixos/tests/tuptime.nix +++ b/nixpkgs/nixos/tests/tuptime.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, ...} : { maintainers = [ evils ]; }; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { imports = [ ../modules/profiles/minimal.nix ]; services.tuptime.enable = true; }; diff --git a/nixpkgs/nixos/tests/turbovnc-headless-server.nix b/nixpkgs/nixos/tests/turbovnc-headless-server.nix index 7d705c56ecf3..1dbf9297c813 100644 --- a/nixpkgs/nixos/tests/turbovnc-headless-server.nix +++ b/nixpkgs/nixos/tests/turbovnc-headless-server.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { maintainers = with lib.maintainers; [ nh2 ]; }; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { environment.systemPackages = with pkgs; [ glxinfo diff --git a/nixpkgs/nixos/tests/tuxguitar.nix b/nixpkgs/nixos/tests/tuxguitar.nix index 63a7b6c7dec9..037f489e5448 100644 --- a/nixpkgs/nixos/tests/tuxguitar.nix +++ b/nixpkgs/nixos/tests/tuxguitar.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { maintainers = [ asbachb ]; }; - machine = { config, pkgs, ... }: { + nodes.machine = { config, pkgs, ... }: { imports = [ ./common/x11.nix ]; diff --git a/nixpkgs/nixos/tests/udisks2.nix b/nixpkgs/nixos/tests/udisks2.nix index 6c4b71aaa2ed..6afb200f8566 100644 --- a/nixpkgs/nixos/tests/udisks2.nix +++ b/nixpkgs/nixos/tests/udisks2.nix @@ -15,7 +15,7 @@ in maintainers = [ eelco ]; }; - machine = + nodes.machine = { ... }: { services.udisks2.enable = true; imports = [ ./common/user-account.nix ]; diff --git a/nixpkgs/nixos/tests/uptermd.nix b/nixpkgs/nixos/tests/uptermd.nix new file mode 100644 index 000000000000..429e3c9dd5ff --- /dev/null +++ b/nixpkgs/nixos/tests/uptermd.nix @@ -0,0 +1,65 @@ +import ./make-test-python.nix ({ pkgs, ...}: + +let + client = {pkgs, ...}:{ + environment.systemPackages = [ pkgs.upterm ]; + }; +in +{ + name = "uptermd"; + meta = with pkgs.lib.maintainers; { + maintainers = [ fleaz ]; + }; + + nodes = { + server = {config, ...}: { + services.uptermd = { + enable = true; + openFirewall = true; + port = 1337; + }; + }; + client1 = client; + client2 = client; + }; + + + testScript = '' + start_all() + + server.wait_for_unit("uptermd.service") + server.wait_for_unit("network-online.target") + + # wait for upterm port to be reachable + client1.wait_until_succeeds("nc -z -v server 1337") + + # Add SSH hostkeys from the server to both clients + # uptermd needs an '@cert-authority entry so we need to modify the known_hosts file + client1.execute("mkdir -p ~/.ssh && ssh -o StrictHostKeyChecking=no -p 1337 server ls") + client1.execute("echo @cert-authority $(cat ~/.ssh/known_hosts) > ~/.ssh/known_hosts") + client2.execute("mkdir -p ~/.ssh && ssh -o StrictHostKeyChecking=no -p 1337 server ls") + client2.execute("echo @cert-authority $(cat ~/.ssh/known_hosts) > ~/.ssh/known_hosts") + + client1.wait_for_unit("multi-user.target") + client1.wait_until_succeeds("pgrep -f 'agetty.*tty1'") + client1.wait_until_tty_matches("1", "login: ") + client1.send_chars("root\n") + client1.wait_until_succeeds("pgrep -u root bash") + + client1.execute("ssh-keygen -t ed25519 -N \"\" -f /root/.ssh/id_ed25519") + client1.send_chars("TERM=xterm upterm host --server ssh://server:1337 --force-command hostname -- bash > /tmp/session-details\n") + client1.wait_for_file("/tmp/session-details") + client1.send_key("q") + + # uptermd can't connect if we don't have a keypair + client2.execute("ssh-keygen -t ed25519 -N \"\" -f /root/.ssh/id_ed25519") + + # Grep the ssh connect command from the output of 'upterm host' + ssh_command = client1.succeed("grep 'SSH Session' /tmp/session-details | cut -d':' -f2-").strip() + + # Connect with client2. Because we used '--force-command hostname' we should get "client1" as the output + output = client2.succeed(ssh_command) + + assert output.strip() == "client1" + ''; +}) diff --git a/nixpkgs/nixos/tests/usbguard.nix b/nixpkgs/nixos/tests/usbguard.nix index bb707bdbf702..d6d3a80c5d23 100644 --- a/nixpkgs/nixos/tests/usbguard.nix +++ b/nixpkgs/nixos/tests/usbguard.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { maintainers = [ tnias ]; }; - machine = + nodes.machine = { ... }: { services.usbguard = { diff --git a/nixpkgs/nixos/tests/user-activation-scripts.nix b/nixpkgs/nixos/tests/user-activation-scripts.nix index 0de8664c5ef0..5df072ce0508 100644 --- a/nixpkgs/nixos/tests/user-activation-scripts.nix +++ b/nixpkgs/nixos/tests/user-activation-scripts.nix @@ -2,7 +2,7 @@ import ./make-test-python.nix ({ lib, ... }: { name = "user-activation-scripts"; meta = with lib.maintainers; { maintainers = [ chkno ]; }; - machine = { + nodes.machine = { system.userActivationScripts.foo = "mktemp ~/user-activation-ran.XXXXXX"; users.users.alice = { initialPassword = "pass1"; @@ -19,9 +19,9 @@ import ./make-test-python.nix ({ lib, ... }: { machine.wait_for_unit("multi-user.target") machine.wait_for_unit("getty@tty1.service") - machine.wait_until_tty_matches(1, "login: ") + machine.wait_until_tty_matches("1", "login: ") machine.send_chars("alice\n") - machine.wait_until_tty_matches(1, "Password: ") + machine.wait_until_tty_matches("1", "Password: ") machine.send_chars("pass1\n") machine.send_chars("touch login-ok\n") machine.wait_for_file("/home/alice/login-ok") diff --git a/nixpkgs/nixos/tests/user-home-mode.nix b/nixpkgs/nixos/tests/user-home-mode.nix new file mode 100644 index 000000000000..070cb0b75cc9 --- /dev/null +++ b/nixpkgs/nixos/tests/user-home-mode.nix @@ -0,0 +1,27 @@ +import ./make-test-python.nix ({ lib, ... }: { + name = "user-home-mode"; + meta = with lib.maintainers; { maintainers = [ fbeffa ]; }; + + nodes.machine = { + users.users.alice = { + initialPassword = "pass1"; + isNormalUser = true; + }; + users.users.bob = { + initialPassword = "pass2"; + isNormalUser = true; + homeMode = "750"; + }; + }; + + testScript = '' + machine.wait_for_unit("multi-user.target") + machine.wait_for_unit("getty@tty1.service") + machine.wait_until_tty_matches("1", "login: ") + machine.send_chars("alice\n") + machine.wait_until_tty_matches("1", "Password: ") + machine.send_chars("pass1\n") + machine.succeed('[ "$(stat -c %a /home/alice)" == "700" ]') + machine.succeed('[ "$(stat -c %a /home/bob)" == "750" ]') + ''; +}) diff --git a/nixpkgs/nixos/tests/uwsgi.nix b/nixpkgs/nixos/tests/uwsgi.nix index 80dcde324aad..62da9e0a7168 100644 --- a/nixpkgs/nixos/tests/uwsgi.nix +++ b/nixpkgs/nixos/tests/uwsgi.nix @@ -5,7 +5,7 @@ import ./make-test-python.nix ({ pkgs, ... }: maintainers = [ lnl7 ]; }; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { users.users.hello = { isSystemUser = true; group = "hello"; diff --git a/nixpkgs/nixos/tests/v2ray.nix b/nixpkgs/nixos/tests/v2ray.nix index 4808e149d31e..fb36ea8557d5 100644 --- a/nixpkgs/nixos/tests/v2ray.nix +++ b/nixpkgs/nixos/tests/v2ray.nix @@ -57,7 +57,7 @@ in { meta = with lib.maintainers; { maintainers = [ servalcatty ]; }; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { environment.systemPackages = [ pkgs.curl ]; services.v2ray = { enable = true; diff --git a/nixpkgs/nixos/tests/vault-dev.nix b/nixpkgs/nixos/tests/vault-dev.nix new file mode 100644 index 000000000000..ba9a1015cc13 --- /dev/null +++ b/nixpkgs/nixos/tests/vault-dev.nix @@ -0,0 +1,35 @@ +import ./make-test-python.nix ({ pkgs, ... }: +{ + name = "vault-dev"; + meta = with pkgs.lib.maintainers; { + maintainers = [ lnl7 mic92 ]; + }; + nodes.machine = { pkgs, config, ... }: { + environment.systemPackages = [ pkgs.vault ]; + environment.variables.VAULT_ADDR = "http://127.0.0.1:8200"; + environment.variables.VAULT_TOKEN = "phony-secret"; + + services.vault = { + enable = true; + dev = true; + devRootTokenID = config.environment.variables.VAULT_TOKEN; + }; + }; + + testScript = '' + import json + start_all() + machine.wait_for_unit("multi-user.target") + machine.wait_for_unit("vault.service") + machine.wait_for_open_port(8200) + out = machine.succeed("vault status -format=json") + print(out) + status = json.loads(out) + assert status.get("initialized") == True + machine.succeed("vault kv put secret/foo bar=baz") + out = machine.succeed("vault kv get -format=json secret/foo") + print(out) + status = json.loads(out) + assert status.get("data", {}).get("data", {}).get("bar") == "baz" + ''; +}) diff --git a/nixpkgs/nixos/tests/vault-postgresql.nix b/nixpkgs/nixos/tests/vault-postgresql.nix index 2847af13cbf0..e0e5881c6da7 100644 --- a/nixpkgs/nixos/tests/vault-postgresql.nix +++ b/nixpkgs/nixos/tests/vault-postgresql.nix @@ -11,7 +11,7 @@ import ./make-test-python.nix ({ pkgs, ... }: meta = with pkgs.lib.maintainers; { maintainers = [ lnl7 roberth ]; }; - machine = { lib, pkgs, ... }: { + nodes.machine = { lib, pkgs, ... }: { environment.systemPackages = [ pkgs.vault ]; environment.variables.VAULT_ADDR = "http://127.0.0.1:8200"; services.vault.enable = true; diff --git a/nixpkgs/nixos/tests/vault.nix b/nixpkgs/nixos/tests/vault.nix index e86acd5b593f..1b0a26a4487f 100644 --- a/nixpkgs/nixos/tests/vault.nix +++ b/nixpkgs/nixos/tests/vault.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, ... }: meta = with pkgs.lib.maintainers; { maintainers = [ lnl7 ]; }; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { environment.systemPackages = [ pkgs.vault ]; environment.variables.VAULT_ADDR = "http://127.0.0.1:8200"; services.vault.enable = true; diff --git a/nixpkgs/nixos/tests/vaultwarden.nix b/nixpkgs/nixos/tests/vaultwarden.nix index 56f1d245d505..408019666da3 100644 --- a/nixpkgs/nixos/tests/vaultwarden.nix +++ b/nixpkgs/nixos/tests/vaultwarden.nix @@ -74,7 +74,10 @@ let services.vaultwarden = { enable = true; dbBackend = backend; - config.rocketPort = 80; + config = { + rocketAddress = "0.0.0.0"; + rocketPort = 80; + }; }; networking.firewall.allowedTCPPorts = [ 80 ]; @@ -85,6 +88,8 @@ let { libraries = [ pkgs.python3Packages.selenium ]; } '' + + from selenium.webdriver.common.by import By from selenium.webdriver import Firefox from selenium.webdriver.firefox.options import Options from selenium.webdriver.support.ui import WebDriverWait @@ -101,41 +106,40 @@ let wait.until(EC.title_contains("Create Account")) - driver.find_element_by_css_selector('input#email').send_keys( + driver.find_element(By.CSS_SELECTOR, 'input#email').send_keys( '${userEmail}' ) - driver.find_element_by_css_selector('input#name').send_keys( + driver.find_element(By.CSS_SELECTOR, 'input#name').send_keys( 'A Cat' ) - driver.find_element_by_css_selector('input#masterPassword').send_keys( + driver.find_element(By.CSS_SELECTOR, 'input#masterPassword').send_keys( '${userPassword}' ) - driver.find_element_by_css_selector('input#masterPasswordRetype').send_keys( + driver.find_element(By.CSS_SELECTOR, 'input#masterPasswordRetype').send_keys( '${userPassword}' ) - driver.find_element_by_css_selector('input#acceptPolicies').click() - driver.find_element_by_xpath("//button[contains(., 'Submit')]").click() + driver.find_element(By.XPATH, "//button[contains(., 'Submit')]").click() wait.until_not(EC.title_contains("Create Account")) - driver.find_element_by_css_selector('input#masterPassword').send_keys( + driver.find_element(By.CSS_SELECTOR, 'input#masterPassword').send_keys( '${userPassword}' ) - driver.find_element_by_xpath("//button[contains(., 'Log In')]").click() + driver.find_element(By.XPATH, "//button[contains(., 'Log In')]").click() - wait.until(EC.title_contains("My Vault")) + wait.until(EC.title_contains("Bitwarden Web Vault")) - driver.find_element_by_xpath("//button[contains(., 'Add Item')]").click() + driver.find_element(By.XPATH, "//button[contains(., 'Add Item')]").click() - driver.find_element_by_css_selector('input#name').send_keys( + driver.find_element(By.CSS_SELECTOR, 'input#name').send_keys( 'secrets' ) - driver.find_element_by_css_selector('input#loginPassword').send_keys( + driver.find_element(By.CSS_SELECTOR, 'input#loginPassword').send_keys( '${storedPassword}' ) - driver.find_element_by_xpath("//button[contains(., 'Save')]").click() + driver.find_element(By.XPATH, "//button[contains(., 'Save')]").click() ''; in [ pkgs.firefox-unwrapped pkgs.geckodriver testRunner ]; diff --git a/nixpkgs/nixos/tests/vector.nix b/nixpkgs/nixos/tests/vector.nix index 583e60ddc568..ecf94e33ff17 100644 --- a/nixpkgs/nixos/tests/vector.nix +++ b/nixpkgs/nixos/tests/vector.nix @@ -9,7 +9,7 @@ with pkgs.lib; name = "vector-test1"; meta.maintainers = [ pkgs.lib.maintainers.happysalada ]; - machine = { config, pkgs, ... }: { + nodes.machine = { config, pkgs, ... }: { services.vector = { enable = true; journaldAccess = true; diff --git a/nixpkgs/nixos/tests/vengi-tools.nix b/nixpkgs/nixos/tests/vengi-tools.nix index 6b90542887d5..5bc8d72c7723 100644 --- a/nixpkgs/nixos/tests/vengi-tools.nix +++ b/nixpkgs/nixos/tests/vengi-tools.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { maintainers = [ fgaz ]; }; - machine = { config, pkgs, ... }: { + nodes.machine = { config, pkgs, ... }: { imports = [ ./common/x11.nix ]; @@ -23,7 +23,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { # OCR on voxedit's window is very expensive, so we avoid wasting a try # by letting the window load fully first machine.sleep(15) - machine.wait_for_text("Palette") + machine.wait_for_text("Solid") machine.screenshot("screen") ''; }) diff --git a/nixpkgs/nixos/tests/vikunja.nix b/nixpkgs/nixos/tests/vikunja.nix index bd884b37f4f9..2f6c4c1f4661 100644 --- a/nixpkgs/nixos/tests/vikunja.nix +++ b/nixpkgs/nixos/tests/vikunja.nix @@ -1,9 +1,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { name = "vikunja"; - meta = with lib.maintainers; { - maintainers = [ em0lar ]; - }; + meta.maintainers = with lib.maintainers; [ leona ]; nodes = { vikunjaSqlite = { ... }: { diff --git a/nixpkgs/nixos/tests/virtualbox.nix b/nixpkgs/nixos/tests/virtualbox.nix index f15412d365fa..1c1b0dac7f37 100644 --- a/nixpkgs/nixos/tests/virtualbox.nix +++ b/nixpkgs/nixos/tests/virtualbox.nix @@ -3,18 +3,9 @@ pkgs ? import ../.. { inherit system config; }, debug ? false, enableUnfree ? false, - # Nested KVM virtualization (https://www.linux-kvm.org/page/Nested_Guests) - # requires a modprobe flag on the build machine: (kvm-amd for AMD CPUs) - # boot.extraModprobeConfig = "options kvm-intel nested=Y"; - # Without this VirtualBox will use SW virtualization and will only be able - # to run 32-bit guests. - useKvmNestedVirt ? false, - # Whether to run 64-bit guests instead of 32-bit. Requires nested KVM. - use64bitGuest ? false + use64bitGuest ? true }: -assert use64bitGuest -> useKvmNestedVirt; - with import ../lib/testing-python.nix { inherit system pkgs; }; with pkgs.lib; @@ -26,7 +17,8 @@ let #!${pkgs.runtimeShell} -xe export PATH="${lib.makeBinPath [ pkgs.coreutils pkgs.util-linux ]}" - mkdir -p /run/dbus + mkdir -p /run/dbus /var + ln -s /run /var cat > /etc/passwd <<EOF root:x:0:0::/root:/bin/false messagebus:x:1:1::/run/dbus:/bin/false @@ -200,6 +192,7 @@ let systemd.services."vboxtestlog-${name}@" = { description = "VirtualBox Test Machine Log For ${name}"; serviceConfig.StandardInput = "socket"; + serviceConfig.StandardOutput = "journal"; serviceConfig.SyslogIdentifier = "GUEST-${name}"; serviceConfig.ExecStart = "${pkgs.coreutils}/bin/cat"; }; @@ -222,10 +215,11 @@ let machine.execute(ru("VBoxManage controlvm ${name} poweroff")) machine.succeed("rm -rf ${sharePath}") machine.succeed("mkdir -p ${sharePath}") - machine.succeed("chown alice.users ${sharePath}") + machine.succeed("chown alice:users ${sharePath}") def create_vm_${name}(): + cleanup_${name}() vbm("createvm --name ${name} ${createFlags}") vbm("modifyvm ${name} ${vmFlags}") vbm("setextradata ${name} VBoxInternal/PDM/HaltOnReset 1") @@ -233,7 +227,6 @@ let vbm("storageattach ${name} ${diskFlags}") vbm("sharedfolder add ${name} ${sharedFlags}") vbm("sharedfolder add ${name} ${nixstoreFlags}") - cleanup_${name}() ${mkLog "$HOME/VirtualBox VMs/${name}/Logs/VBox.log" "HOST-${name}"} @@ -317,10 +310,7 @@ let ]; dhcpScript = pkgs: '' - ${pkgs.dhcp}/bin/dhclient \ - -lf /run/dhcp.leases \ - -pf /run/dhclient.pid \ - -v eth0 eth1 + ${pkgs.dhcpcd}/bin/dhcpcd eth0 eth1 otherIP="$(${pkgs.netcat}/bin/nc -l 1234 || :)" ${pkgs.iputils}/bin/ping -I eth1 -c1 "$otherIP" @@ -353,14 +343,13 @@ let mkVBoxTest = useExtensionPack: vms: name: testScript: makeTest { name = "virtualbox-${name}"; - machine = { lib, config, ... }: { + nodes.machine = { lib, config, ... }: { imports = let mkVMConf = name: val: val.machine // { key = "${name}-config"; }; vmConfigs = mapAttrsToList mkVMConf vms; in [ ./common/user-account.nix ./common/x11.nix ] ++ vmConfigs; virtualisation.memorySize = 2048; - virtualisation.qemu.options = - if useKvmNestedVirt then ["-cpu" "kvm64,vmx=on"] else []; + virtualisation.qemu.options = ["-cpu" "kvm64,svm=on,vmx=on"]; virtualisation.virtualbox.host.enable = true; test-support.displayManager.auto.user = "alice"; users.users.alice.extraGroups = let @@ -468,7 +457,7 @@ in mapAttrs (mkVBoxTest false vboxVMs) { headless = '' create_vm_headless() - machine.succeed(ru("VBoxHeadless --startvm headless & disown %1")) + machine.succeed(ru("VBoxHeadless --startvm headless >&2 & disown %1")) wait_for_startup_headless() wait_for_vm_boot_headless() shutdown_vm_headless() @@ -476,6 +465,8 @@ in mapAttrs (mkVBoxTest false vboxVMs) { ''; host-usb-permissions = '' + import sys + user_usb = remove_uuids(vbm("list usbhost")) print(user_usb, file=sys.stderr) root_usb = remove_uuids(machine.succeed("VBoxManage list usbhost")) diff --git a/nixpkgs/nixos/tests/vscodium.nix b/nixpkgs/nixos/tests/vscodium.nix index 688ddfe07e3e..3bdb99947a40 100644 --- a/nixpkgs/nixos/tests/vscodium.nix +++ b/nixpkgs/nixos/tests/vscodium.nix @@ -32,6 +32,14 @@ let maintainers = [ synthetica turion ]; }; enableOCR = true; + + # testScriptWithTypes:55: error: Item "function" of + # "Union[Callable[[Callable[..., Any]], ContextManager[Any]], ContextManager[Any]]" + # has no attribute "__enter__" + # with codium_running: + # ^ + skipTypeCheck = true; + testScript = '' @polling_condition def codium_running(): diff --git a/nixpkgs/nixos/tests/vsftpd.nix b/nixpkgs/nixos/tests/vsftpd.nix index 4bea27f0eb10..6eaf32b22583 100644 --- a/nixpkgs/nixos/tests/vsftpd.nix +++ b/nixpkgs/nixos/tests/vsftpd.nix @@ -29,7 +29,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { testScript = '' client.start() server.wait_for_unit("vsftpd") - server.wait_for_open_port("21") + server.wait_for_open_port(21) client.succeed("curl -u ftp-test-user:ftp-test-password ftp://server") client.succeed('echo "this is a test" > /tmp/test.file.up') diff --git a/nixpkgs/nixos/tests/web-apps/healthchecks.nix b/nixpkgs/nixos/tests/web-apps/healthchecks.nix new file mode 100644 index 000000000000..41374f5e314b --- /dev/null +++ b/nixpkgs/nixos/tests/web-apps/healthchecks.nix @@ -0,0 +1,42 @@ +import ../make-test-python.nix ({ lib, pkgs, ... }: { + name = "healthchecks"; + + meta = with lib.maintainers; { + maintainers = [ phaer ]; + }; + + nodes.machine = { ... }: { + services.healthchecks = { + enable = true; + settings = { + SITE_NAME = "MyUniqueInstance"; + COMPRESS_ENABLED = "True"; + SECRET_KEY_FILE = pkgs.writeText "secret" + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + }; + }; + }; + + testScript = '' + machine.start() + machine.wait_for_unit("healthchecks.target") + machine.wait_until_succeeds("journalctl --since -1m --unit healthchecks --grep Listening") + + with subtest("Home screen loads"): + machine.succeed( + "curl -sSfL http://localhost:8000 | grep '<title>Sign In'" + ) + + with subtest("Setting SITE_NAME via freeform option works"): + machine.succeed( + "curl -sSfL http://localhost:8000 | grep 'MyUniqueInstance</title>'" + ) + + with subtest("Manage script works"): + # Should fail if not called by healthchecks user + machine.fail("echo 'print(\"foo\")' | healthchecks-manage help") + + # "shell" sucommand should succeed, needs python in PATH. + assert "foo\n" == machine.succeed("echo 'print(\"foo\")' | sudo -u healthchecks healthchecks-manage shell") + ''; +}) diff --git a/nixpkgs/nixos/tests/web-apps/netbox.nix b/nixpkgs/nixos/tests/web-apps/netbox.nix new file mode 100644 index 000000000000..35decdd49e87 --- /dev/null +++ b/nixpkgs/nixos/tests/web-apps/netbox.nix @@ -0,0 +1,30 @@ +import ../make-test-python.nix ({ lib, pkgs, ... }: { + name = "netbox"; + + meta = with lib.maintainers; { + maintainers = [ n0emis ]; + }; + + nodes.machine = { ... }: { + services.netbox = { + enable = true; + secretKeyFile = pkgs.writeText "secret" '' + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 + ''; + }; + }; + + testScript = '' + machine.start() + machine.wait_for_unit("netbox.target") + machine.wait_until_succeeds("journalctl --since -1m --unit netbox --grep Listening") + + with subtest("Home screen loads"): + machine.succeed( + "curl -sSfL http://[::1]:8001 | grep '<title>Home | NetBox</title>'" + ) + + with subtest("Staticfiles are generated"): + machine.succeed("test -e /var/lib/netbox/static/netbox.js") + ''; +}) diff --git a/nixpkgs/nixos/tests/web-apps/nifi.nix b/nixpkgs/nixos/tests/web-apps/nifi.nix new file mode 100644 index 000000000000..92f7fa231df3 --- /dev/null +++ b/nixpkgs/nixos/tests/web-apps/nifi.nix @@ -0,0 +1,30 @@ +import ../make-test-python.nix ({pkgs, ...}: +{ + name = "nifi"; + meta.maintainers = with pkgs.lib.maintainers; [ izorkin ]; + + nodes = { + nifi = { pkgs, ... }: { + virtualisation = { + memorySize = 2048; + diskSize = 4096; + }; + services.nifi = { + enable = true; + enableHTTPS = false; + }; + }; + }; + + testScript = '' + nifi.start() + + nifi.wait_for_unit("nifi.service") + nifi.wait_for_open_port(8080) + + # Check if NiFi is running + nifi.succeed("curl --fail http://127.0.0.1:8080/nifi/login 2> /dev/null | grep 'NiFi Login'") + + nifi.shutdown() + ''; +}) diff --git a/nixpkgs/nixos/tests/web-apps/peertube.nix b/nixpkgs/nixos/tests/web-apps/peertube.nix index 706c598338e8..ecc45bff2e2c 100644 --- a/nixpkgs/nixos/tests/web-apps/peertube.nix +++ b/nixpkgs/nixos/tests/web-apps/peertube.nix @@ -11,7 +11,7 @@ import ../make-test-python.nix ({pkgs, ...}: { address = "192.168.2.10"; prefixLength = 24; } ]; }; - firewall.allowedTCPPorts = [ 5432 6379 ]; + firewall.allowedTCPPorts = [ 5432 31638 ]; }; services.postgresql = { @@ -30,10 +30,11 @@ import ../make-test-python.nix ({pkgs, ...}: ''; }; - services.redis = { + services.redis.servers.peertube = { enable = true; bind = "0.0.0.0"; requirePass = "turrQfaQwnanGbcsdhxy"; + port = 31638; }; }; @@ -75,6 +76,7 @@ import ../make-test-python.nix ({pkgs, ...}: redis = { host = "192.168.2.10"; + port = 31638; passwordFile = "/etc/peertube/password-redis-db"; }; @@ -109,10 +111,10 @@ import ../make-test-python.nix ({pkgs, ...}: start_all() database.wait_for_unit("postgresql.service") - database.wait_for_unit("redis.service") + database.wait_for_unit("redis-peertube.service") database.wait_for_open_port(5432) - database.wait_for_open_port(6379) + database.wait_for_open_port(31638) server.wait_for_unit("peertube.service") server.wait_for_open_port(9000) diff --git a/nixpkgs/nixos/tests/web-apps/phylactery.nix b/nixpkgs/nixos/tests/web-apps/phylactery.nix new file mode 100644 index 000000000000..cf2689d2300d --- /dev/null +++ b/nixpkgs/nixos/tests/web-apps/phylactery.nix @@ -0,0 +1,20 @@ +import ../make-test-python.nix ({ pkgs, lib, ... }: { + name = "phylactery"; + + nodes.machine = { ... }: { + services.phylactery = rec { + enable = true; + port = 8080; + library = "/tmp"; + }; + }; + + testScript = '' + start_all() + machine.wait_for_unit('phylactery') + machine.wait_for_open_port(8080) + machine.wait_until_succeeds('curl localhost:8080') + ''; + + meta.maintainers = with lib.maintainers; [ McSinyx ]; +}) diff --git a/nixpkgs/nixos/tests/web-servers/unit-php.nix b/nixpkgs/nixos/tests/web-servers/unit-php.nix index 00512b506cc2..f0df371945e5 100644 --- a/nixpkgs/nixos/tests/web-servers/unit-php.nix +++ b/nixpkgs/nixos/tests/web-servers/unit-php.nix @@ -6,19 +6,19 @@ in { name = "unit-php-test"; meta.maintainers = with pkgs.lib.maintainers; [ izorkin ]; - machine = { config, lib, pkgs, ... }: { + nodes.machine = { config, lib, pkgs, ... }: { services.unit = { enable = true; config = pkgs.lib.strings.toJSON { - listeners."*:9080".application = "php_80"; - applications.php_80 = { - type = "php 8.0"; + listeners."*:9081".application = "php_81"; + applications.php_81 = { + type = "php 8.1"; processes = 1; user = "testuser"; group = "testgroup"; root = "${testdir}/www"; index = "info.php"; - options.file = "${pkgs.unit.usedPhp80}/lib/php.ini"; + options.file = "${pkgs.unit.usedPhp81}/lib/php.ini"; }; }; }; @@ -34,14 +34,19 @@ in { }; }; testScript = '' + machine.start() + machine.wait_for_unit("unit.service") + machine.wait_for_open_port(9081) # Check so we get an evaluated PHP back - response = machine.succeed("curl -f -vvv -s http://127.0.0.1:9080/") - assert "PHP Version ${pkgs.unit.usedPhp80.version}" in response, "PHP version not detected" + response = machine.succeed("curl -f -vvv -s http://127.0.0.1:9081/") + assert "PHP Version ${pkgs.unit.usedPhp81.version}" in response, "PHP version not detected" # Check so we have database and some other extensions loaded for ext in ["json", "opcache", "pdo_mysql", "pdo_pgsql", "pdo_sqlite"]: assert ext in response, f"Missing {ext} extension" + + machine.shutdown() ''; }) diff --git a/nixpkgs/nixos/tests/wiki-js.nix b/nixpkgs/nixos/tests/wiki-js.nix index 783887d2dcaa..c3541be5d8b5 100644 --- a/nixpkgs/nixos/tests/wiki-js.nix +++ b/nixpkgs/nixos/tests/wiki-js.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, lib, ...} : { maintainers = [ ma27 ]; }; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { virtualisation.memorySize = 2048; services.wiki-js = { enable = true; diff --git a/nixpkgs/nixos/tests/wine.nix b/nixpkgs/nixos/tests/wine.nix index 8135cb90a591..8a64c3179c51 100644 --- a/nixpkgs/nixos/tests/wine.nix +++ b/nixpkgs/nixos/tests/wine.nix @@ -15,7 +15,7 @@ let inherit name; meta = with pkgs.lib.maintainers; { maintainers = [ chkno ]; }; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { environment.systemPackages = [ pkgs."${packageSet}"."${variant}" ]; virtualisation.diskSize = 800; }; diff --git a/nixpkgs/nixos/tests/wireguard/wg-quick.nix b/nixpkgs/nixos/tests/wireguard/wg-quick.nix index 961c2e15c30f..bc2cba911888 100644 --- a/nixpkgs/nixos/tests/wireguard/wg-quick.nix +++ b/nixpkgs/nixos/tests/wireguard/wg-quick.nix @@ -29,6 +29,8 @@ import ../make-test-python.nix ({ pkgs, lib, ... }: inherit (wg-snakeoil-keys.peer1) publicKey; }; + + dns = [ "10.23.42.2" "fc00::2" "wg0" ]; }; }; }; @@ -38,6 +40,7 @@ import ../make-test-python.nix ({ pkgs, lib, ... }: ip6 = "fd00::2"; extraConfig = { boot = lib.mkIf (kernelPackages != null) { inherit kernelPackages; }; + networking.useNetworkd = true; networking.wg-quick.interfaces.wg0 = { address = [ "10.23.42.2/32" "fc00::2/128" ]; inherit (wg-snakeoil-keys.peer1) privateKey; @@ -49,6 +52,8 @@ import ../make-test-python.nix ({ pkgs, lib, ... }: inherit (wg-snakeoil-keys.peer0) publicKey; }; + + dns = [ "10.23.42.1" "fc00::1" "wg0" ]; }; }; }; diff --git a/nixpkgs/nixos/tests/wmderland.nix b/nixpkgs/nixos/tests/wmderland.nix index 6de0cd9212ee..ebfd443763e1 100644 --- a/nixpkgs/nixos/tests/wmderland.nix +++ b/nixpkgs/nixos/tests/wmderland.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, ...} : { maintainers = [ takagiy ]; }; - machine = { lib, ... }: { + nodes.machine = { lib, ... }: { imports = [ ./common/x11.nix ./common/user-account.nix ]; test-support.displayManager.auto.user = "alice"; services.xserver.displayManager.defaultSession = lib.mkForce "none+wmderland"; diff --git a/nixpkgs/nixos/tests/wpa_supplicant.nix b/nixpkgs/nixos/tests/wpa_supplicant.nix index 40d934b8e1db..a05a79e8367d 100644 --- a/nixpkgs/nixos/tests/wpa_supplicant.nix +++ b/nixpkgs/nixos/tests/wpa_supplicant.nix @@ -5,7 +5,7 @@ import ./make-test-python.nix ({ pkgs, lib, ...}: maintainers = [ rnhmjoj ]; }; - machine = { ... }: { + nodes.machine = { ... }: { imports = [ ../modules/profiles/minimal.nix ]; # add a virtual wlan interface diff --git a/nixpkgs/nixos/tests/xfce.nix b/nixpkgs/nixos/tests/xfce.nix index 9051deebae76..31f00f77c40d 100644 --- a/nixpkgs/nixos/tests/xfce.nix +++ b/nixpkgs/nixos/tests/xfce.nix @@ -1,7 +1,7 @@ import ./make-test-python.nix ({ pkgs, ...} : { name = "xfce"; - machine = + nodes.machine = { pkgs, ... }: { diff --git a/nixpkgs/nixos/tests/xmonad-xdg-autostart.nix b/nixpkgs/nixos/tests/xmonad-xdg-autostart.nix new file mode 100644 index 000000000000..2577a9ce2ea1 --- /dev/null +++ b/nixpkgs/nixos/tests/xmonad-xdg-autostart.nix @@ -0,0 +1,35 @@ +import ./make-test-python.nix ({ lib, ... }: { + name = "xmonad-xdg-autostart"; + meta.maintainers = with lib.maintainers; [ oxalica ]; + + nodes.machine = { pkgs, config, ... }: { + imports = [ ./common/x11.nix ./common/user-account.nix ]; + test-support.displayManager.auto.user = "alice"; + services.xserver.displayManager.defaultSession = "none+xmonad"; + services.xserver.windowManager.xmonad.enable = true; + services.xserver.desktopManager.runXdgAutostartIfNone = true; + + environment.systemPackages = [ + (pkgs.writeTextFile { + name = "test-xdg-autostart"; + destination = "/etc/xdg/autostart/test-xdg-autostart.desktop"; + text = '' + [Desktop Entry] + Name=test-xdg-autoatart + Type=Application + Terminal=false + Exec=${pkgs.coreutils}/bin/touch ${config.users.users.alice.home}/xdg-autostart-executed + ''; + }) + ]; + }; + + testScript = { nodes, ... }: + let + user = nodes.machine.config.users.users.alice; + in + '' + machine.wait_for_x() + machine.wait_for_file("${user.home}/xdg-autostart-executed") + ''; +}) diff --git a/nixpkgs/nixos/tests/xmonad.nix b/nixpkgs/nixos/tests/xmonad.nix index a2fb38e53bd1..ec48c3e11275 100644 --- a/nixpkgs/nixos/tests/xmonad.nix +++ b/nixpkgs/nixos/tests/xmonad.nix @@ -13,7 +13,9 @@ let import System.Environment (getArgs) import System.FilePath ((</>)) - main = launch $ def { startupHook = startup } `additionalKeysP` myKeys + main = do + dirs <- getDirectories + launch (def { startupHook = startup } `additionalKeysP` myKeys) dirs startup = isSessionStart >>= \sessInit -> spawn "touch /tmp/${name}" @@ -23,14 +25,15 @@ let compiledConfig = printf "xmonad-%s-%s" arch os - compileRestart resume = - whenX (recompile True) $ + compileRestart resume = do + dirs <- asks directories + + whenX (recompile dirs True) $ when resume writeStateToFile *> catchIO ( do - dir <- getXMonadDataDir args <- getArgs - executeFile (dir </> compiledConfig) False args Nothing + executeFile (cacheDir dirs </> compiledConfig) False args Nothing ) ''; @@ -55,7 +58,7 @@ in { maintainers = [ nequissimus ivanbrennan ]; }; - machine = { pkgs, ... }: { + nodes.machine = { pkgs, ... }: { imports = [ ./common/x11.nix ./common/user-account.nix ]; test-support.displayManager.auto.user = "alice"; services.xserver.displayManager.defaultSession = "none+xmonad"; @@ -94,7 +97,7 @@ in { # set up the new config machine.succeed("mkdir -p ${user.home}/.xmonad") - machine.copy_from_host("${newConfig}", "${user.home}/.xmonad/xmonad.hs") + machine.copy_from_host("${newConfig}", "${user.home}/.config/xmonad/xmonad.hs") # recompile xmonad using the new config machine.send_key("alt-ctrl-q") diff --git a/nixpkgs/nixos/tests/xmpp/xmpp-sendmessage.nix b/nixpkgs/nixos/tests/xmpp/xmpp-sendmessage.nix index 47a77f524c6a..4c009464b704 100644 --- a/nixpkgs/nixos/tests/xmpp/xmpp-sendmessage.nix +++ b/nixpkgs/nixos/tests/xmpp/xmpp-sendmessage.nix @@ -6,7 +6,7 @@ let Please find this *really* important attachment. Yours truly, - John + Bob ''; in writeScriptBin "send-message" '' #!${(python3.withPackages (ps: [ ps.slixmpp ])).interpreter} @@ -51,11 +51,8 @@ class CthonTest(ClientXMPP): log.info('Message sent') # Test http upload (XEP_0363) - def timeout_callback(arg): - log.error("ERROR: Cannot upload file. XEP_0363 seems broken") - sys.exit(1) try: - url = await self['xep_0363'].upload_file("${dummyFile}",timeout=10, timeout_callback=timeout_callback) + url = await self['xep_0363'].upload_file("${dummyFile}",timeout=10) except: log.error("ERROR: Cannot run upload command. XEP_0363 seems broken") sys.exit(1) diff --git a/nixpkgs/nixos/tests/xrdp.nix b/nixpkgs/nixos/tests/xrdp.nix index 0e1d521c5ace..f277d4b79525 100644 --- a/nixpkgs/nixos/tests/xrdp.nix +++ b/nixpkgs/nixos/tests/xrdp.nix @@ -1,7 +1,7 @@ import ./make-test-python.nix ({ pkgs, ...} : { name = "xrdp"; meta = with pkgs.lib.maintainers; { - maintainers = [ volth ]; + maintainers = [ ]; }; nodes = { diff --git a/nixpkgs/nixos/tests/xterm.nix b/nixpkgs/nixos/tests/xterm.nix index 4ee31139ab52..745d33e8a0d5 100644 --- a/nixpkgs/nixos/tests/xterm.nix +++ b/nixpkgs/nixos/tests/xterm.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, ...} : { maintainers = [ nequissimus ]; }; - machine = { pkgs, ... }: + nodes.machine = { pkgs, ... }: { imports = [ ./common/x11.nix ]; services.xserver.desktopManager.xterm.enable = false; diff --git a/nixpkgs/nixos/tests/yabar.nix b/nixpkgs/nixos/tests/yabar.nix index c2431e556c37..ff7a47ae6370 100644 --- a/nixpkgs/nixos/tests/yabar.nix +++ b/nixpkgs/nixos/tests/yabar.nix @@ -8,7 +8,7 @@ with lib; maintainers = [ ]; }; - machine = { + nodes.machine = { imports = [ ./common/x11.nix ./common/user-account.nix ]; test-support.displayManager.auto.user = "bob"; diff --git a/nixpkgs/nixos/tests/yggdrasil.nix b/nixpkgs/nixos/tests/yggdrasil.nix index b409d9ed7853..b60a0e6b06cc 100644 --- a/nixpkgs/nixos/tests/yggdrasil.nix +++ b/nixpkgs/nixos/tests/yggdrasil.nix @@ -42,7 +42,7 @@ in import ./make-test-python.nix ({ pkgs, ...} : { services.yggdrasil = { enable = true; - config = { + settings = { Listen = ["tcp://0.0.0.0:12345"]; MulticastInterfaces = [ ]; }; @@ -112,7 +112,7 @@ in import ./make-test-python.nix ({ pkgs, ...} : { services.yggdrasil = { enable = true; denyDhcpcdInterfaces = [ "ygg0" ]; - config = { + settings = { IfTAPMode = true; IfName = "ygg0"; MulticastInterfaces = [ "eth1" ]; diff --git a/nixpkgs/nixos/tests/zeronet-conservancy.nix b/nixpkgs/nixos/tests/zeronet-conservancy.nix new file mode 100644 index 000000000000..8cb649cbdaab --- /dev/null +++ b/nixpkgs/nixos/tests/zeronet-conservancy.nix @@ -0,0 +1,25 @@ +let + port = 43110; +in +import ./make-test-python.nix ({ pkgs, ... }: { + name = "zeronet-conservancy"; + meta = with pkgs.lib.maintainers; { + maintainers = [ fgaz ]; + }; + + nodes.machine = { config, pkgs, ... }: { + services.zeronet = { + enable = true; + package = pkgs.zeronet-conservancy; + inherit port; + }; + }; + + testScript = '' + machine.wait_for_unit("zeronet.service") + + machine.wait_for_open_port(${toString port}) + + machine.succeed("curl --fail -H 'Accept: text/html, application/xml, */*' localhost:${toString port}/Stats") + ''; +}) diff --git a/nixpkgs/nixos/tests/zfs.nix b/nixpkgs/nixos/tests/zfs.nix index d25090403e5f..0b44961a3deb 100644 --- a/nixpkgs/nixos/tests/zfs.nix +++ b/nixpkgs/nixos/tests/zfs.nix @@ -18,7 +18,7 @@ let maintainers = [ adisbladis ]; }; - machine = { pkgs, lib, ... }: + nodes.machine = { pkgs, lib, ... }: let usersharePath = "/var/lib/samba/usershares"; in { @@ -127,4 +127,54 @@ in { }; installer = (import ./installer.nix { }).zfsroot; + + expand-partitions = makeTest { + name = "multi-disk-zfs"; + nodes = { + machine = { pkgs, ... }: { + environment.systemPackages = [ pkgs.parted ]; + boot.supportedFilesystems = [ "zfs" ]; + networking.hostId = "00000000"; + + virtualisation = { + emptyDiskImages = [ 20480 20480 20480 20480 20480 20480 ]; + }; + + specialisation.resize.configuration = { + services.zfs.expandOnBoot = [ "tank" ]; + }; + }; + }; + + testScript = { nodes, ... }: + '' + start_all() + machine.wait_for_unit("default.target") + print(machine.succeed('mount')) + + print(machine.succeed('parted --script /dev/vdb -- mklabel gpt')) + print(machine.succeed('parted --script /dev/vdb -- mkpart primary 1M 70M')) + + print(machine.succeed('parted --script /dev/vdc -- mklabel gpt')) + print(machine.succeed('parted --script /dev/vdc -- mkpart primary 1M 70M')) + + print(machine.succeed('zpool create tank mirror /dev/vdb1 /dev/vdc1 mirror /dev/vdd /dev/vde mirror /dev/vdf /dev/vdg')) + print(machine.succeed('zpool list -v')) + print(machine.succeed('mount')) + start_size = int(machine.succeed('df -k --output=size /tank | tail -n1').strip()) + + print(machine.succeed("/run/current-system/specialisation/resize/bin/switch-to-configuration test >&2")) + machine.wait_for_unit("zpool-expand-pools.service") + machine.wait_for_unit("zpool-expand@tank.service") + + print(machine.succeed('zpool list -v')) + new_size = int(machine.succeed('df -k --output=size /tank | tail -n1').strip()) + + if (new_size - start_size) > 20000000: + print("Disk grew appropriately.") + else: + print(f"Disk went from {start_size} to {new_size}, which doesn't seem right.") + exit(1) + ''; + }; } diff --git a/nixpkgs/nixos/tests/zigbee2mqtt.nix b/nixpkgs/nixos/tests/zigbee2mqtt.nix index 98aadbb699bd..1592202fb3a7 100644 --- a/nixpkgs/nixos/tests/zigbee2mqtt.nix +++ b/nixpkgs/nixos/tests/zigbee2mqtt.nix @@ -1,7 +1,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { - machine = { pkgs, ... }: + nodes.machine = { pkgs, ... }: { services.zigbee2mqtt = { enable = true; diff --git a/nixpkgs/nixos/tests/zoneminder.nix b/nixpkgs/nixos/tests/zoneminder.nix index a4e1a05ec0ee..3c97bc8282d2 100644 --- a/nixpkgs/nixos/tests/zoneminder.nix +++ b/nixpkgs/nixos/tests/zoneminder.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ lib, ...}: name = "zoneminder"; meta.maintainers = with lib.maintainers; [ danielfullmer ]; - machine = { ... }: + nodes.machine = { ... }: { services.zoneminder = { enable = true; diff --git a/nixpkgs/nixos/tests/zrepl.nix b/nixpkgs/nixos/tests/zrepl.nix new file mode 100644 index 000000000000..85dd834a6aaf --- /dev/null +++ b/nixpkgs/nixos/tests/zrepl.nix @@ -0,0 +1,66 @@ +import ./make-test-python.nix ( + { + nodes.host = {config, pkgs, ...}: { + config = { + # Prerequisites for ZFS and tests. + boot.supportedFilesystems = [ "zfs" ]; + environment.systemPackages = [ pkgs.zrepl ]; + networking.hostId = "deadbeef"; + services.zrepl = { + enable = true; + settings = { + # Enable Prometheus output for status assertions. + global.monitoring = [{ + type = "prometheus"; + listen = ":9811"; + }]; + # Create a periodic snapshot job for an ephemeral zpool. + jobs = [{ + name = "snap_test"; + type = "snap"; + + filesystems."test" = true; + snapshotting = { + type = "periodic"; + prefix = "zrepl_"; + interval = "1s"; + }; + + pruning.keep = [{ + type = "last_n"; + count = 8; + }]; + }]; + }; + }; + }; + }; + + testScript = '' + start_all() + + with subtest("Wait for zrepl and network ready"): + host.wait_for_unit("network-online.target") + host.wait_for_unit("zrepl.service") + + with subtest("Create test zpool"): + # ZFS requires 64MiB minimum pool size. + host.succeed("fallocate -l 64MiB /root/zpool.img") + host.succeed("zpool create test /root/zpool.img") + + with subtest("Check for completed zrepl snapshot"): + # zrepl periodic snapshot job creates a snapshot with this prefix. + host.wait_until_succeeds("zfs list -t snapshot | grep -q zrepl_") + + with subtest("Verify HTTP monitoring server is configured"): + out = host.succeed("curl -f localhost:9811/metrics") + + assert ( + "zrepl_version_daemon" in out + ), "zrepl version metric was not found in Prometheus output" + + assert ( + "zrepl_zfs_snapshot_duration_count{filesystem=\"test\"}" in out + ), "zrepl snapshot counter for test was not found in Prometheus output" + ''; + }) diff --git a/nixpkgs/nixos/tests/zsh-history.nix b/nixpkgs/nixos/tests/zsh-history.nix index 355687798406..64f32a07e215 100644 --- a/nixpkgs/nixos/tests/zsh-history.nix +++ b/nixpkgs/nixos/tests/zsh-history.nix @@ -21,13 +21,13 @@ import ./make-test-python.nix ({ pkgs, ...} : { default.wait_until_succeeds("pgrep -f 'agetty.*tty1'") # Login - default.wait_until_tty_matches(1, "login: ") + default.wait_until_tty_matches("1", "login: ") default.send_chars("root\n") - default.wait_until_tty_matches(1, r"\nroot@default\b") + default.wait_until_tty_matches("1", r"\nroot@default\b") # Generate some history default.send_chars("echo foobar\n") - default.wait_until_tty_matches(1, "foobar") + default.wait_until_tty_matches("1", "foobar") # Ensure that command was recorded in history default.succeed("/run/current-system/sw/bin/history list | grep -q foobar") |