diff options
author | João Figueira <jmc.figueira@campus.fct.unl.pt> | 2022-01-24 01:33:13 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-24 01:33:13 +0000 |
commit | ae10fad86b2d7a357825c19a563dd5dac60a67da (patch) | |
tree | a2bde77769ba6055989c27aaf1ac7287ad56d640 /nixos/tests | |
parent | 0ac894e7d1d91e32fdcdc901229f16f27f321374 (diff) | |
parent | 8dbc4efd40169a8e3e57375b08d78205e5f83ff0 (diff) | |
download | nixpkgs-ae10fad86b2d7a357825c19a563dd5dac60a67da.tar nixpkgs-ae10fad86b2d7a357825c19a563dd5dac60a67da.tar.gz nixpkgs-ae10fad86b2d7a357825c19a563dd5dac60a67da.tar.bz2 nixpkgs-ae10fad86b2d7a357825c19a563dd5dac60a67da.tar.lz nixpkgs-ae10fad86b2d7a357825c19a563dd5dac60a67da.tar.xz nixpkgs-ae10fad86b2d7a357825c19a563dd5dac60a67da.tar.zst nixpkgs-ae10fad86b2d7a357825c19a563dd5dac60a67da.zip |
Merge branch 'master' into wine-wayland
Diffstat (limited to 'nixos/tests')
44 files changed, 1865 insertions, 1118 deletions
diff --git a/nixos/tests/acme.nix b/nixos/tests/acme.nix index 0dd7743c52b..2dd06a50f40 100644 --- a/nixos/tests/acme.nix +++ b/nixos/tests/acme.nix @@ -54,15 +54,15 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: let baseConfig = { nodes, config, specialConfig ? {} }: lib.mkMerge [ { security.acme = { - defaults = (dnsConfig nodes) // { - inherit group; - }; + defaults = (dnsConfig nodes); # One manual wildcard cert certs."example.test" = { domain = "*.example.test"; }; }; + users.users."${config.services."${server}".user}".extraGroups = ["acme"]; + services."${server}" = { enable = true; virtualHosts = { @@ -252,15 +252,15 @@ in { } // (let baseCaddyConfig = { nodes, config, ... }: { security.acme = { - defaults = (dnsConfig nodes) // { - group = config.services.caddy.group; - }; + defaults = (dnsConfig nodes); # One manual wildcard cert certs."example.test" = { domain = "*.example.test"; }; }; + users.users."${config.services.caddy.user}".extraGroups = ["acme"]; + services.caddy = { enable = true; virtualHosts."a.exmaple.test" = { diff --git a/nixos/tests/adguardhome.nix b/nixos/tests/adguardhome.nix new file mode 100644 index 00000000000..ddbe8ff9c11 --- /dev/null +++ b/nixos/tests/adguardhome.nix @@ -0,0 +1,57 @@ +import ./make-test-python.nix { + name = "adguardhome"; + + nodes = { + minimalConf = { ... }: { + services.adguardhome = { enable = true; }; + }; + + declarativeConf = { ... }: { + services.adguardhome = { + enable = true; + + mutableSettings = false; + settings = { + dns = { + bind_host = "0.0.0.0"; + bootstrap_dns = "127.0.0.1"; + }; + }; + }; + }; + + mixedConf = { ... }: { + services.adguardhome = { + enable = true; + + mutableSettings = true; + settings = { + dns = { + bind_host = "0.0.0.0"; + bootstrap_dns = "127.0.0.1"; + }; + }; + }; + }; + }; + + testScript = '' + with subtest("Minimal config test"): + minimalConf.wait_for_unit("adguardhome.service") + minimalConf.wait_for_open_port(3000) + + with subtest("Declarative config test, DNS will be reachable"): + declarativeConf.wait_for_unit("adguardhome.service") + declarativeConf.wait_for_open_port(53) + declarativeConf.wait_for_open_port(3000) + + with subtest("Mixed config test, check whether merging works"): + mixedConf.wait_for_unit("adguardhome.service") + mixedConf.wait_for_open_port(53) + mixedConf.wait_for_open_port(3000) + # Test whether merging works properly, even if nothing is changed + mixedConf.systemctl("restart adguardhome.service") + mixedConf.wait_for_unit("adguardhome.service") + mixedConf.wait_for_open_port(3000) + ''; +} diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 4f62980e8e9..7959fe5bb18 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -19,10 +19,18 @@ let handleTestOn = systems: path: args: if elem system systems then handleTest path args else {}; + + nixosLib = import ../lib { + # Experimental features need testing too, but there's no point in warning + # about it, so we enable the feature flag. + featureFlags.minimalModules = {}; + }; + evalMinimalConfig = module: nixosLib.evalModules { modules = [ module ]; }; in { _3proxy = handleTest ./3proxy.nix {}; acme = handleTest ./acme.nix {}; + adguardhome = handleTest ./adguardhome.nix {}; aesmd = handleTest ./aesmd.nix {}; agda = handleTest ./agda.nix {}; airsonic = handleTest ./airsonic.nix {}; @@ -103,6 +111,7 @@ in discourse = handleTest ./discourse.nix {}; dnscrypt-proxy2 = handleTestOn ["x86_64-linux"] ./dnscrypt-proxy2.nix {}; dnscrypt-wrapper = handleTestOn ["x86_64-linux"] ./dnscrypt-wrapper {}; + dnsdist = handleTest ./dnsdist.nix {}; doas = handleTest ./doas.nix {}; docker = handleTestOn ["x86_64-linux"] ./docker.nix {}; docker-rootless = handleTestOn ["x86_64-linux"] ./docker-rootless.nix {}; @@ -125,6 +134,7 @@ in enlightenment = handleTest ./enlightenment.nix {}; env = handleTest ./env.nix {}; ergo = handleTest ./ergo.nix {}; + ergochat = handleTest ./ergochat.nix {}; etcd = handleTestOn ["x86_64-linux"] ./etcd.nix {}; etcd-cluster = handleTestOn ["x86_64-linux"] ./etcd-cluster.nix {}; etebase-server = handleTest ./etebase-server.nix {}; @@ -143,6 +153,7 @@ in fluidd = handleTest ./fluidd.nix {}; fontconfig-default-fonts = handleTest ./fontconfig-default-fonts.nix {}; freeswitch = handleTest ./freeswitch.nix {}; + frr = handleTest ./frr.nix {}; fsck = handleTest ./fsck.nix {}; ft2-clone = handleTest ./ft2-clone.nix {}; gerrit = handleTest ./gerrit.nix {}; @@ -170,7 +181,6 @@ in hadoop.all = handleTestOn [ "x86_64-linux" ] ./hadoop/hadoop.nix {}; hadoop.hdfs = handleTestOn [ "x86_64-linux" ] ./hadoop/hdfs.nix {}; hadoop.yarn = handleTestOn [ "x86_64-linux" ] ./hadoop/yarn.nix {}; - handbrake = handleTestOn ["x86_64-linux"] ./handbrake.nix {}; haproxy = handleTest ./haproxy.nix {}; hardened = handleTest ./hardened.nix {}; hedgedoc = handleTest ./hedgedoc.nix {}; @@ -204,6 +214,7 @@ in initrd-secrets = handleTest ./initrd-secrets.nix {}; inspircd = handleTest ./inspircd.nix {}; installer = handleTest ./installer.nix {}; + invoiceplane = handleTest ./invoiceplane.nix {}; iodine = handleTest ./iodine.nix {}; ipfs = handleTest ./ipfs.nix {}; ipv6 = handleTest ./ipv6.nix {}; @@ -256,8 +267,7 @@ in mailcatcher = handleTest ./mailcatcher.nix {}; mailhog = handleTest ./mailhog.nix {}; man = handleTest ./man.nix {}; - mariadb-galera-mariabackup = handleTest ./mysql/mariadb-galera-mariabackup.nix {}; - mariadb-galera-rsync = handleTest ./mysql/mariadb-galera-rsync.nix {}; + mariadb-galera = handleTest ./mysql/mariadb-galera.nix {}; matomo = handleTest ./matomo.nix {}; matrix-appservice-irc = handleTest ./matrix-appservice-irc.nix {}; matrix-conduit = handleTest ./matrix-conduit.nix {}; @@ -327,6 +337,7 @@ in nix-serve-ssh = handleTest ./nix-serve-ssh.nix {}; nixops = handleTest ./nixops/default.nix {}; nixos-generate-config = handleTest ./nixos-generate-config.nix {}; + nixpkgs = pkgs.callPackage ../modules/misc/nixpkgs/test.nix { inherit evalMinimalConfig; }; node-red = handleTest ./node-red.nix {}; nomad = handleTest ./nomad.nix {}; novacomd = handleTestOn ["x86_64-linux"] ./novacomd.nix {}; @@ -396,7 +407,6 @@ in prometheus = handleTest ./prometheus.nix {}; prometheus-exporters = handleTest ./prometheus-exporters.nix {}; prosody = handleTest ./xmpp/prosody.nix {}; - prosodyMysql = handleTest ./xmpp/prosody-mysql.nix {}; proxy = handleTest ./proxy.nix {}; prowlarr = handleTest ./prowlarr.nix {}; pt2-clone = handleTest ./pt2-clone.nix {}; @@ -445,6 +455,7 @@ in sslh = handleTest ./sslh.nix {}; sssd = handleTestOn ["x86_64-linux"] ./sssd.nix {}; sssd-ldap = handleTestOn ["x86_64-linux"] ./sssd-ldap.nix {}; + starship = handleTest ./starship.nix {}; step-ca = handleTestOn ["x86_64-linux"] ./step-ca.nix {}; strongswan-swanctl = handleTest ./strongswan-swanctl.nix {}; sudo = handleTest ./sudo.nix {}; @@ -471,11 +482,14 @@ in systemd-unit-path = handleTest ./systemd-unit-path.nix {}; taskserver = handleTest ./taskserver.nix {}; telegraf = handleTest ./telegraf.nix {}; + teleport = handleTest ./teleport.nix {}; + thelounge = handleTest ./thelounge.nix {}; tiddlywiki = handleTest ./tiddlywiki.nix {}; tigervnc = handleTest ./tigervnc.nix {}; timezone = handleTest ./timezone.nix {}; tinc = handleTest ./tinc {}; tinydns = handleTest ./tinydns.nix {}; + tinywl = handleTest ./tinywl.nix {}; tor = handleTest ./tor.nix {}; # traefik test relies on docker-containers traefik = handleTestOn ["x86_64-linux"] ./traefik.nix {}; @@ -484,6 +498,7 @@ in trezord = handleTest ./trezord.nix {}; trickster = handleTest ./trickster.nix {}; trilium-server = handleTestOn ["x86_64-linux"] ./trilium-server.nix {}; + tsm-client-gui = handleTest ./tsm-client-gui.nix {}; txredisapi = handleTest ./txredisapi.nix {}; tuptime = handleTest ./tuptime.nix {}; turbovnc-headless-server = handleTest ./turbovnc-headless-server.nix {}; diff --git a/nixos/tests/boot-stage1.nix b/nixos/tests/boot-stage1.nix index ce86fc5f494..756decd2039 100644 --- a/nixos/tests/boot-stage1.nix +++ b/nixos/tests/boot-stage1.nix @@ -33,6 +33,8 @@ import ./make-test-python.nix ({ pkgs, ... }: { #include <linux/sched/signal.h> #endif + MODULE_LICENSE("GPL"); + struct task_struct *canaryTask; static int kcanary(void *nothing) diff --git a/nixos/tests/borgbackup.nix b/nixos/tests/borgbackup.nix index cbb28689209..d3cd6c66bfe 100644 --- a/nixos/tests/borgbackup.nix +++ b/nixos/tests/borgbackup.nix @@ -106,7 +106,7 @@ in { services.openssh = { enable = true; passwordAuthentication = false; - challengeResponseAuthentication = false; + kbdInteractiveAuthentication = false; }; services.borgbackup.repos.repo1 = { diff --git a/nixos/tests/btrbk.nix b/nixos/tests/btrbk.nix index 2689bb66c63..9f34f7dfbe3 100644 --- a/nixos/tests/btrbk.nix +++ b/nixos/tests/btrbk.nix @@ -53,7 +53,7 @@ import ./make-test-python.nix ({ pkgs, ... }: services.openssh = { enable = true; passwordAuthentication = false; - challengeResponseAuthentication = false; + kbdInteractiveAuthentication = false; }; services.btrbk = { extraPackages = [ pkgs.lz4 ]; diff --git a/nixos/tests/dnsdist.nix b/nixos/tests/dnsdist.nix new file mode 100644 index 00000000000..cfc41c13864 --- /dev/null +++ b/nixos/tests/dnsdist.nix @@ -0,0 +1,48 @@ +import ./make-test-python.nix ( + { pkgs, ... }: { + name = "dnsdist"; + meta = with pkgs.lib; { + maintainers = with maintainers; [ jojosch ]; + }; + + machine = { pkgs, lib, ... }: { + services.bind = { + enable = true; + extraOptions = "empty-zones-enable no;"; + zones = lib.singleton { + name = "."; + master = true; + file = pkgs.writeText "root.zone" '' + $TTL 3600 + . IN SOA ns.example.org. admin.example.org. ( 1 3h 1h 1w 1d ) + . IN NS ns.example.org. + + ns.example.org. IN A 192.168.0.1 + ns.example.org. IN AAAA abcd::1 + + 1.0.168.192.in-addr.arpa IN PTR ns.example.org. + ''; + }; + }; + services.dnsdist = { + enable = true; + listenPort = 5353; + extraConfig = '' + newServer({address="127.0.0.1:53", name="local-bind"}) + ''; + }; + + environment.systemPackages = with pkgs; [ dig ]; + }; + + testScript = '' + machine.wait_for_unit("bind.service") + machine.wait_for_open_port(53) + machine.succeed("dig @127.0.0.1 +short -x 192.168.0.1 | grep -qF ns.example.org") + + machine.wait_for_unit("dnsdist.service") + machine.wait_for_open_port(5353) + machine.succeed("dig @127.0.0.1 -p 5353 +short -x 192.168.0.1 | grep -qF ns.example.org") + ''; + } +) diff --git a/nixos/tests/ergochat.nix b/nixos/tests/ergochat.nix new file mode 100644 index 00000000000..2e9dc55e648 --- /dev/null +++ b/nixos/tests/ergochat.nix @@ -0,0 +1,97 @@ +let + clients = [ + "ircclient1" + "ircclient2" + ]; + server = "ergochat"; + ircPort = 6667; + channel = "nixos-cat"; + iiDir = "/tmp/irc"; +in + +import ./make-test-python.nix ({ pkgs, lib, ... }: { + name = "ergochat"; + nodes = { + "${server}" = { + networking.firewall.allowedTCPPorts = [ ircPort ]; + services.ergochat = { + enable = true; + settings.server.motd = pkgs.writeText "ergo.motd" '' + The default MOTD doesn't contain the word "nixos" in it. + This one does. + ''; + }; + }; + } // lib.listToAttrs (builtins.map (client: lib.nameValuePair client { + imports = [ + ./common/user-account.nix + ]; + + systemd.services.ii = { + requires = [ "network.target" ]; + wantedBy = [ "default.target" ]; + + serviceConfig = { + Type = "simple"; + ExecPreStartPre = "mkdir -p ${iiDir}"; + ExecStart = '' + ${lib.getBin pkgs.ii}/bin/ii -n ${client} -s ${server} -i ${iiDir} + ''; + User = "alice"; + }; + }; + }) clients); + + testScript = + let + msg = client: "Hello, my name is ${client}"; + clientScript = client: [ + '' + ${client}.wait_for_unit("network.target") + ${client}.systemctl("start ii") + ${client}.wait_for_unit("ii") + ${client}.wait_for_file("${iiDir}/${server}/out") + '' + # look for the custom text in the MOTD. + '' + ${client}.wait_until_succeeds("grep 'nixos' ${iiDir}/${server}/out") + '' + # wait until first PING from server arrives before joining, + # so we don't try it too early + '' + ${client}.wait_until_succeeds("grep 'PING' ${iiDir}/${server}/out") + '' + # join ${channel} + '' + ${client}.succeed("echo '/j #${channel}' > ${iiDir}/${server}/in") + ${client}.wait_for_file("${iiDir}/${server}/#${channel}/in") + '' + # send a greeting + '' + ${client}.succeed( + "echo '${msg client}' > ${iiDir}/${server}/#${channel}/in" + ) + '' + # check that all greetings arrived on all clients + ] ++ builtins.map (other: '' + ${client}.succeed( + "grep '${msg other}$' ${iiDir}/${server}/#${channel}/out" + ) + '') clients; + + # foldl', but requires a non-empty list instead of a start value + reduce = f: list: + builtins.foldl' f (builtins.head list) (builtins.tail list); + in '' + start_all() + ${server}.systemctl("status ergochat") + ${server}.wait_for_open_port(${toString ircPort}) + + # run clientScript for all clients so that every list + # entry is executed by every client before advancing + # to the next one. + '' + lib.concatStrings + (reduce + (lib.zipListsWith (cs: c: cs + c)) + (builtins.map clientScript clients)); +}) diff --git a/nixos/tests/frr.nix b/nixos/tests/frr.nix new file mode 100644 index 00000000000..598d7a7d286 --- /dev/null +++ b/nixos/tests/frr.nix @@ -0,0 +1,104 @@ +# This test runs FRR and checks if OSPF routing works. +# +# Network topology: +# [ client ]--net1--[ router1 ]--net2--[ router2 ]--net3--[ server ] +# +# All interfaces are in OSPF Area 0. + +import ./make-test-python.nix ({ pkgs, ... }: + let + + ifAddr = node: iface: (pkgs.lib.head node.config.networking.interfaces.${iface}.ipv4.addresses).address; + + ospfConf1 = '' + router ospf + network 192.168.0.0/16 area 0 + ''; + + ospfConf2 = '' + interface eth2 + ip ospf hello-interval 1 + ip ospf dead-interval 5 + ! + router ospf + network 192.168.0.0/16 area 0 + ''; + + in + { + name = "frr"; + + meta = with pkgs.lib.maintainers; { + maintainers = [ hexa ]; + }; + + nodes = { + + client = + { nodes, ... }: + { + virtualisation.vlans = [ 1 ]; + networking.defaultGateway = ifAddr nodes.router1 "eth1"; + }; + + router1 = + { ... }: + { + virtualisation.vlans = [ 1 2 ]; + boot.kernel.sysctl."net.ipv4.ip_forward" = "1"; + networking.firewall.extraCommands = "iptables -A nixos-fw -i eth2 -p ospfigp -j ACCEPT"; + services.frr.ospf = { + enable = true; + config = ospfConf1; + }; + + specialisation.ospf.configuration = { + services.frr.ospf.config = ospfConf2; + }; + }; + + router2 = + { ... }: + { + virtualisation.vlans = [ 3 2 ]; + boot.kernel.sysctl."net.ipv4.ip_forward" = "1"; + networking.firewall.extraCommands = "iptables -A nixos-fw -i eth2 -p ospfigp -j ACCEPT"; + services.frr.ospf = { + enable = true; + config = ospfConf2; + }; + }; + + server = + { nodes, ... }: + { + virtualisation.vlans = [ 3 ]; + networking.defaultGateway = ifAddr nodes.router2 "eth1"; + }; + }; + + testScript = + { nodes, ... }: + '' + start_all() + + # Wait for the networking to start on all machines + for machine in client, router1, router2, server: + machine.wait_for_unit("network.target") + + with subtest("Wait for Zebra and OSPFD"): + for gw in router1, router2: + gw.wait_for_unit("zebra") + gw.wait_for_unit("ospfd") + + router1.succeed("${nodes.router1.config.system.build.toplevel}/specialisation/ospf/bin/switch-to-configuration test >&2") + + with subtest("Wait for OSPF to form adjacencies"): + for gw in router1, router2: + gw.wait_until_succeeds("vtysh -c 'show ip ospf neighbor' | grep Full") + gw.wait_until_succeeds("vtysh -c 'show ip route' | grep '^O>'") + + with subtest("Test ICMP"): + client.wait_until_succeeds("ping -c 3 server >&2") + ''; + }) diff --git a/nixos/tests/google-oslogin/server.nix b/nixos/tests/google-oslogin/server.nix index fdb7141da31..a0a3144ae69 100644 --- a/nixos/tests/google-oslogin/server.nix +++ b/nixos/tests/google-oslogin/server.nix @@ -17,7 +17,7 @@ in { }; services.openssh.enable = true; - services.openssh.challengeResponseAuthentication = false; + services.openssh.kbdInteractiveAuthentication = false; services.openssh.passwordAuthentication = false; security.googleOsLogin.enable = true; diff --git a/nixos/tests/handbrake.nix b/nixos/tests/handbrake.nix deleted file mode 100644 index d2d41b372be..00000000000 --- a/nixos/tests/handbrake.nix +++ /dev/null @@ -1,33 +0,0 @@ -import ./make-test-python.nix ({ pkgs, ... }: - -let - # Download Big Buck Bunny example, licensed under CC Attribution 3.0. - testMkv = pkgs.fetchurl { - url = "https://github.com/Matroska-Org/matroska-test-files/blob/cf0792be144ac470c4b8052cfe19bb691993e3a2/test_files/test1.mkv?raw=true"; - sha256 = "1hfxbbgxwfkzv85pvpvx55a72qsd0hxjbm9hkl5r3590zw4s75h9"; - name = "test1.mkv"; - }; - -in -{ - name = "handbrake"; - - meta = { - maintainers = with pkgs.lib.maintainers; [ ]; - }; - - machine = { pkgs, ... }: { - environment.systemPackages = with pkgs; [ handbrake ]; - }; - - testScript = '' - # Test MP4 and MKV transcoding. Since this is a short clip, transcoding typically - # only takes a few seconds. - start_all() - - machine.succeed("HandBrakeCLI -i ${testMkv} -o test.mp4 -e x264 -q 20 -B 160") - machine.succeed("test -e test.mp4") - machine.succeed("HandBrakeCLI -i ${testMkv} -o test.mkv -e x264 -q 20 -B 160") - machine.succeed("test -e test.mkv") - ''; -}) diff --git a/nixos/tests/installer.nix b/nixos/tests/installer.nix index bc41b6efc2e..cf00bcafe4f 100644 --- a/nixos/tests/installer.nix +++ b/nixos/tests/installer.nix @@ -561,26 +561,16 @@ in { + " mkpart primary 2048M -1s" # PV2 + " set 2 lvm on", "udevadm settle", - "sleep 1", "pvcreate /dev/vda1 /dev/vda2", - "sleep 1", "vgcreate MyVolGroup /dev/vda1 /dev/vda2", - "sleep 1", "lvcreate --size 1G --name swap MyVolGroup", - "sleep 1", "lvcreate --size 3G --name nixos MyVolGroup", - "sleep 1", "mkswap -f /dev/MyVolGroup/swap -L swap", "swapon -L swap", "mkfs.xfs -L nixos /dev/MyVolGroup/nixos", "mount LABEL=nixos /mnt", ) ''; - postBootCommands = '' - assert "loaded active" in machine.succeed( - "systemctl list-units 'lvm2-pvscan@*' -ql --no-legend | tee /dev/stderr" - ) - ''; }; # Boot off an encrypted root partition with the default LUKS header format diff --git a/nixos/tests/invoiceplane.nix b/nixos/tests/invoiceplane.nix new file mode 100644 index 00000000000..4e63f8ac21c --- /dev/null +++ b/nixos/tests/invoiceplane.nix @@ -0,0 +1,82 @@ +import ./make-test-python.nix ({ pkgs, ... }: + +{ + name = "invoiceplane"; + meta = with pkgs.lib.maintainers; { + maintainers = [ + onny + ]; + }; + + nodes = { + invoiceplane_caddy = { ... }: { + services.invoiceplane.webserver = "caddy"; + services.invoiceplane.sites = { + "site1.local" = { + #database.name = "invoiceplane1"; + database.createLocally = true; + enable = true; + }; + "site2.local" = { + #database.name = "invoiceplane2"; + database.createLocally = true; + enable = true; + }; + }; + + networking.firewall.allowedTCPPorts = [ 80 ]; + networking.hosts."127.0.0.1" = [ "site1.local" "site2.local" ]; + }; + }; + + testScript = '' + start_all() + + invoiceplane_caddy.wait_for_unit("caddy") + invoiceplane_caddy.wait_for_open_port(80) + invoiceplane_caddy.wait_for_open_port(3306) + + site_names = ["site1.local", "site2.local"] + + for site_name in site_names: + machine.wait_for_unit(f"phpfpm-invoiceplane-{site_name}") + + with subtest("Website returns welcome screen"): + assert "Please install InvoicePlane" in machine.succeed(f"curl -L {site_name}") + + with subtest("Finish InvoicePlane setup"): + machine.succeed( + f"curl -sSfL --cookie-jar cjar {site_name}/index.php/setup/language" + ) + csrf_token = machine.succeed( + "grep ip_csrf_cookie cjar | cut -f 7 | tr -d '\n'" + ) + machine.succeed( + f"curl -sSfL --cookie cjar --cookie-jar cjar -d '_ip_csrf={csrf_token}&ip_lang=english&btn_continue=Continue' {site_name}/index.php/setup/language" + ) + csrf_token = machine.succeed( + "grep ip_csrf_cookie cjar | cut -f 7 | tr -d '\n'" + ) + machine.succeed( + f"curl -sSfL --cookie cjar --cookie-jar cjar -d '_ip_csrf={csrf_token}&btn_continue=Continue' {site_name}/index.php/setup/prerequisites" + ) + csrf_token = machine.succeed( + "grep ip_csrf_cookie cjar | cut -f 7 | tr -d '\n'" + ) + machine.succeed( + f"curl -sSfL --cookie cjar --cookie-jar cjar -d '_ip_csrf={csrf_token}&btn_continue=Continue' {site_name}/index.php/setup/configure_database" + ) + csrf_token = machine.succeed( + "grep ip_csrf_cookie cjar | cut -f 7 | tr -d '\n'" + ) + machine.succeed( + f"curl -sSfl --cookie cjar --cookie-jar cjar -d '_ip_csrf={csrf_token}&btn_continue=Continue' {site_name}/index.php/setup/install_tables" + ) + csrf_token = machine.succeed( + "grep ip_csrf_cookie cjar | cut -f 7 | tr -d '\n'" + ) + machine.succeed( + f"curl -sSfl --cookie cjar --cookie-jar cjar -d '_ip_csrf={csrf_token}&btn_continue=Continue' {site_name}/index.php/setup/upgrade_tables" + ) + ''; +}) diff --git a/nixos/tests/jibri.nix b/nixos/tests/jibri.nix index 3dd28e6aac1..af20e639d30 100644 --- a/nixos/tests/jibri.nix +++ b/nixos/tests/jibri.nix @@ -63,7 +63,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { """sleep 15 && curl -H "Content-Type: application/json" -X POST http://localhost:2222/jibri/api/v1.0/stopService -d '{"sessionId": "RecordTest","callParams":{"callUrlInfo":{"baseUrl": "https://machine","callName": "TestCall"}},"callLoginParams":{"domain": "recorder.machine", "username": "recorder", "password": "'"$(cat /var/lib/jitsi-meet/jibri-recorder-secret)"'" },"sinkType": "file"}'""" ) machine.wait_until_succeeds( - "cat /var/log/jitsi/jibri/log.0.txt | grep -q 'Recording finalize script finished with exit value 0'", timeout=36 + "cat /var/log/jitsi/jibri/log.0.txt | grep -q 'Finalize script finished with exit value 0'", timeout=36 ) ''; }) diff --git a/nixos/tests/k3s-single-node-docker.nix b/nixos/tests/k3s-single-node-docker.nix new file mode 100644 index 00000000000..7f3d15788b0 --- /dev/null +++ b/nixos/tests/k3s-single-node-docker.nix @@ -0,0 +1,84 @@ +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/nixos/tests/k3s-single-node.nix b/nixos/tests/k3s-single-node.nix new file mode 100644 index 00000000000..d98f20d468c --- /dev/null +++ b/nixos/tests/k3s-single-node.nix @@ -0,0 +1,82 @@ +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; + services.k3s.role = "server"; + services.k3s.package = pkgs.k3s; + # Slightly reduce resource usage + services.k3s.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} | k3s ctr image import -" + ) + + 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/nixos/tests/k3s.nix b/nixos/tests/k3s.nix deleted file mode 100644 index 494a3b68b59..00000000000 --- a/nixos/tests/k3s.nix +++ /dev/null @@ -1,78 +0,0 @@ -import ./make-test-python.nix ({ pkgs, ... }: - -let - # A suitable k3s pause image, also used for the test pod - pauseImage = pkgs.dockerTools.buildImage { - name = "test.local/pause"; - tag = "local"; - contents = with pkgs; [ tini coreutils busybox ]; - config.Entrypoint = [ "/bin/tini" "--" "/bin/sleep" "inf" ]; - }; - testPodYaml = pkgs.writeText "test.yml" '' - # Don't use the default service account because there's a race where it may - # not be created yet; make our own instead. - 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 ]; - }; - - nodes = { - k3s = - { pkgs, ... }: { - environment.systemPackages = [ pkgs.k3s pkgs.gzip ]; - - # k3s uses enough resources the default vm fails. - virtualisation.memorySize = pkgs.lib.mkDefault 1536; - virtualisation.diskSize = pkgs.lib.mkDefault 4096; - - services.k3s.enable = true; - services.k3s.role = "server"; - services.k3s.package = pkgs.k3s; - # Slightly reduce resource usage - services.k3s.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() - - k3s.wait_for_unit("k3s") - k3s.succeed("k3s kubectl cluster-info") - k3s.fail("sudo -u noprivs k3s kubectl cluster-info") - # k3s.succeed("k3s check-config") # fails with the current nixos kernel config, uncomment once this passes - - k3s.succeed( - "zcat ${pauseImage} | k3s ctr image import -" - ) - - k3s.succeed("k3s kubectl apply -f ${testPodYaml}") - k3s.succeed("k3s kubectl wait --for 'condition=Ready' pod/test") - ''; -}) diff --git a/nixos/tests/kubernetes/base.nix b/nixos/tests/kubernetes/base.nix index e1736f6fe17..f0c72084be5 100644 --- a/nixos/tests/kubernetes/base.nix +++ b/nixos/tests/kubernetes/base.nix @@ -60,13 +60,6 @@ let advertiseAddress = master.ip; }; masterAddress = "${masterName}.${config.networking.domain}"; - # workaround for: - # https://github.com/kubernetes/kubernetes/issues/102676 - # (workaround from) https://github.com/kubernetes/kubernetes/issues/95488 - kubelet.extraOpts = ''\ - --cgroups-per-qos=false \ - --enforce-node-allocatable="" \ - ''; }; } (optionalAttrs (any (role: role == "master") machine.roles) { diff --git a/nixos/tests/libreswan.nix b/nixos/tests/libreswan.nix index 56ab908aed9..ff3d2344a67 100644 --- a/nixos/tests/libreswan.nix +++ b/nixos/tests/libreswan.nix @@ -89,7 +89,7 @@ in """ Sends a message as Alice to Bob """ - bob.execute("nc -lu ::0 1234 >/tmp/msg >&2 &") + bob.execute("nc -lu ::0 1234 >/tmp/msg &") alice.sleep(1) alice.succeed(f"echo '{msg}' | nc -uw 0 bob 1234") bob.succeed(f"grep '{msg}' /tmp/msg") @@ -100,7 +100,7 @@ in Starts eavesdropping on Alice and Bob """ match = "src host alice and dst host bob" - eve.execute(f"tcpdump -i br0 -c 1 -Avv {match} >/tmp/log >&2 &") + eve.execute(f"tcpdump -i br0 -c 1 -Avv {match} >/tmp/log &") start_all() diff --git a/nixos/tests/lorri/default.nix b/nixos/tests/lorri/default.nix index 147ae999fdb..c33c7503993 100644 --- a/nixos/tests/lorri/default.nix +++ b/nixos/tests/lorri/default.nix @@ -14,7 +14,7 @@ import ../make-test-python.nix { ) # Start the daemon and wait until it is ready - machine.execute("lorri daemon > lorri.stdout 2> lorri.stderr >&2 &") + machine.execute("lorri daemon > lorri.stdout 2> lorri.stderr &") machine.wait_until_succeeds("grep --fixed-strings 'ready' lorri.stdout") # Ping the daemon diff --git a/nixos/tests/mysql/common.nix b/nixos/tests/mysql/common.nix new file mode 100644 index 00000000000..968253d109c --- /dev/null +++ b/nixos/tests/mysql/common.nix @@ -0,0 +1,10 @@ +{ lib, pkgs }: { + mariadbPackages = lib.filterAttrs (n: _: lib.hasPrefix "mariadb" n) (pkgs.callPackage ../../../pkgs/servers/sql/mariadb { + inherit (pkgs.darwin) cctools; + inherit (pkgs.darwin.apple_sdk.frameworks) CoreServices; + }); + mysqlPackage = { + inherit (pkgs) mysql57 mysql80; + }; + mkTestName = pkg: "mariadb_${builtins.replaceStrings ["."] [""] (lib.versions.majorMinor pkg.version)}"; +} diff --git a/nixos/tests/mysql/mariadb-galera-mariabackup.nix b/nixos/tests/mysql/mariadb-galera-mariabackup.nix deleted file mode 100644 index 10682c361d1..00000000000 --- a/nixos/tests/mysql/mariadb-galera-mariabackup.nix +++ /dev/null @@ -1,233 +0,0 @@ -import ./../make-test-python.nix ({ pkgs, ...} : - -let - mysqlenv-common = pkgs.buildEnv { name = "mysql-path-env-common"; pathsToLink = [ "/bin" ]; paths = with pkgs; [ bash gawk gnutar inetutils which ]; }; - mysqlenv-mariabackup = pkgs.buildEnv { name = "mysql-path-env-mariabackup"; pathsToLink = [ "/bin" ]; paths = with pkgs; [ gzip iproute2 netcat procps pv socat ]; }; - - # Common user configuration - users = { ... }: - { - users.users.testuser = { - isSystemUser = true; - group = "testusers"; - }; - users.groups.testusers = { }; - }; - -in { - name = "mariadb-galera-mariabackup"; - meta = with pkgs.lib.maintainers; { - maintainers = [ izorkin ]; - }; - - # The test creates a Galera cluster with 3 nodes and is checking if mariabackup-based SST works. The cluster is tested by creating a DB and an empty table on one node, - # and checking the table's presence on the other node. - - nodes = { - galera_01 = - { pkgs, ... }: - { - imports = [ users ]; - networking = { - interfaces.eth1 = { - ipv4.addresses = [ - { address = "192.168.1.1"; prefixLength = 24; } - ]; - }; - extraHosts = '' - 192.168.1.1 galera_01 - 192.168.1.2 galera_02 - 192.168.1.3 galera_03 - ''; - firewall.allowedTCPPorts = [ 3306 4444 4567 4568 ]; - firewall.allowedUDPPorts = [ 4567 ]; - }; - systemd.services.mysql = with pkgs; { - path = [ mysqlenv-common mysqlenv-mariabackup ]; - }; - services.mysql = { - enable = true; - package = pkgs.mariadb; - ensureDatabases = [ "testdb" ]; - ensureUsers = [{ - name = "testuser"; - ensurePermissions = { - "testdb.*" = "ALL PRIVILEGES"; - }; - }]; - initialScript = pkgs.writeText "mariadb-init.sql" '' - GRANT ALL PRIVILEGES ON *.* TO 'check_repl'@'localhost' IDENTIFIED BY 'check_pass' WITH GRANT OPTION; - FLUSH PRIVILEGES; - ''; - settings = { - mysqld = { - bind_address = "0.0.0.0"; - }; - galera = { - wsrep_on = "ON"; - wsrep_debug = "NONE"; - wsrep_retry_autocommit = "3"; - wsrep_provider = "${pkgs.mariadb-galera}/lib/galera/libgalera_smm.so"; - wsrep_cluster_address = "gcomm://"; - wsrep_cluster_name = "galera"; - wsrep_node_address = "192.168.1.1"; - wsrep_node_name = "galera_01"; - wsrep_sst_method = "mariabackup"; - wsrep_sst_auth = "check_repl:check_pass"; - binlog_format = "ROW"; - enforce_storage_engine = "InnoDB"; - innodb_autoinc_lock_mode = "2"; - }; - }; - }; - }; - - galera_02 = - { pkgs, ... }: - { - imports = [ users ]; - networking = { - interfaces.eth1 = { - ipv4.addresses = [ - { address = "192.168.1.2"; prefixLength = 24; } - ]; - }; - extraHosts = '' - 192.168.1.1 galera_01 - 192.168.1.2 galera_02 - 192.168.1.3 galera_03 - ''; - firewall.allowedTCPPorts = [ 3306 4444 4567 4568 ]; - firewall.allowedUDPPorts = [ 4567 ]; - }; - systemd.services.mysql = with pkgs; { - path = [ mysqlenv-common mysqlenv-mariabackup ]; - }; - services.mysql = { - enable = true; - package = pkgs.mariadb; - settings = { - mysqld = { - bind_address = "0.0.0.0"; - }; - galera = { - wsrep_on = "ON"; - wsrep_debug = "NONE"; - wsrep_retry_autocommit = "3"; - wsrep_provider = "${pkgs.mariadb-galera}/lib/galera/libgalera_smm.so"; - wsrep_cluster_address = "gcomm://galera_01,galera_02,galera_03"; - wsrep_cluster_name = "galera"; - wsrep_node_address = "192.168.1.2"; - wsrep_node_name = "galera_02"; - wsrep_sst_method = "mariabackup"; - wsrep_sst_auth = "check_repl:check_pass"; - binlog_format = "ROW"; - enforce_storage_engine = "InnoDB"; - innodb_autoinc_lock_mode = "2"; - }; - }; - }; - }; - - galera_03 = - { pkgs, ... }: - { - imports = [ users ]; - networking = { - interfaces.eth1 = { - ipv4.addresses = [ - { address = "192.168.1.3"; prefixLength = 24; } - ]; - }; - extraHosts = '' - 192.168.1.1 galera_01 - 192.168.1.2 galera_02 - 192.168.1.3 galera_03 - ''; - firewall.allowedTCPPorts = [ 3306 4444 4567 4568 ]; - firewall.allowedUDPPorts = [ 4567 ]; - }; - systemd.services.mysql = with pkgs; { - path = [ mysqlenv-common mysqlenv-mariabackup ]; - }; - services.mysql = { - enable = true; - package = pkgs.mariadb; - settings = { - mysqld = { - bind_address = "0.0.0.0"; - }; - galera = { - wsrep_on = "ON"; - wsrep_debug = "NONE"; - wsrep_retry_autocommit = "3"; - wsrep_provider = "${pkgs.mariadb-galera}/lib/galera/libgalera_smm.so"; - wsrep_cluster_address = "gcomm://galera_01,galera_02,galera_03"; - wsrep_cluster_name = "galera"; - wsrep_node_address = "192.168.1.3"; - wsrep_node_name = "galera_03"; - wsrep_sst_method = "mariabackup"; - wsrep_sst_auth = "check_repl:check_pass"; - binlog_format = "ROW"; - enforce_storage_engine = "InnoDB"; - innodb_autoinc_lock_mode = "2"; - }; - }; - }; - }; - }; - - testScript = '' - galera_01.start() - galera_01.wait_for_unit("mysql") - galera_01.wait_for_open_port(3306) - galera_01.succeed( - "sudo -u testuser mysql -u testuser -e 'use testdb; create table db1 (test_id INT, PRIMARY KEY (test_id)) ENGINE = InnoDB;'" - ) - galera_01.succeed( - "sudo -u testuser mysql -u testuser -e 'use testdb; insert into db1 values (37);'" - ) - galera_02.start() - galera_02.wait_for_unit("mysql") - galera_02.wait_for_open_port(3306) - galera_03.start() - galera_03.wait_for_unit("mysql") - galera_03.wait_for_open_port(3306) - galera_02.succeed( - "sudo -u testuser mysql -u testuser -e 'use testdb; select test_id from db1;' -N | grep 37" - ) - galera_02.succeed( - "sudo -u testuser mysql -u testuser -e 'use testdb; create table db2 (test_id INT, PRIMARY KEY (test_id)) ENGINE = InnoDB;'" - ) - galera_02.succeed("systemctl stop mysql") - galera_01.succeed( - "sudo -u testuser mysql -u testuser -e 'use testdb; insert into db2 values (38);'" - ) - galera_03.succeed( - "sudo -u testuser mysql -u testuser -e 'use testdb; create table db3 (test_id INT, PRIMARY KEY (test_id)) ENGINE = InnoDB;'" - ) - galera_01.succeed( - "sudo -u testuser mysql -u testuser -e 'use testdb; insert into db3 values (39);'" - ) - galera_02.succeed("systemctl start mysql") - galera_02.wait_for_open_port(3306) - galera_02.succeed( - "sudo -u testuser mysql -u testuser -e 'show status' -N | grep 'wsrep_cluster_size.*3'" - ) - galera_03.succeed( - "sudo -u testuser mysql -u testuser -e 'show status' -N | grep 'wsrep_local_state_comment.*Synced'" - ) - galera_01.succeed( - "sudo -u testuser mysql -u testuser -e 'use testdb; select test_id from db3;' -N | grep 39" - ) - galera_02.succeed( - "sudo -u testuser mysql -u testuser -e 'use testdb; select test_id from db2;' -N | grep 38" - ) - galera_03.succeed( - "sudo -u testuser mysql -u testuser -e 'use testdb; select test_id from db1;' -N | grep 37" - ) - galera_01.succeed("sudo -u testuser mysql -u testuser -e 'use testdb; drop table db3;'") - galera_02.succeed("sudo -u testuser mysql -u testuser -e 'use testdb; drop table db2;'") - galera_03.succeed("sudo -u testuser mysql -u testuser -e 'use testdb; drop table db1;'") - ''; -}) diff --git a/nixos/tests/mysql/mariadb-galera-rsync.nix b/nixos/tests/mysql/mariadb-galera-rsync.nix deleted file mode 100644 index 701e01e8871..00000000000 --- a/nixos/tests/mysql/mariadb-galera-rsync.nix +++ /dev/null @@ -1,226 +0,0 @@ -import ./../make-test-python.nix ({ pkgs, ...} : - -let - mysqlenv-common = pkgs.buildEnv { name = "mysql-path-env-common"; pathsToLink = [ "/bin" ]; paths = with pkgs; [ bash gawk gnutar inetutils which ]; }; - mysqlenv-rsync = pkgs.buildEnv { name = "mysql-path-env-rsync"; pathsToLink = [ "/bin" ]; paths = with pkgs; [ lsof procps rsync stunnel ]; }; - - # Common user configuration - users = { ... }: - { - users.users.testuser = { - isSystemUser = true; - group = "testusers"; - }; - users.groups.testusers = { }; - }; - -in { - name = "mariadb-galera-rsync"; - meta = with pkgs.lib.maintainers; { - maintainers = [ izorkin ]; - }; - - # The test creates a Galera cluster with 3 nodes and is checking if rsync-based SST works. The cluster is tested by creating a DB and an empty table on one node, - # and checking the table's presence on the other node. - - nodes = { - galera_04 = - { pkgs, ... }: - { - imports = [ users ]; - networking = { - interfaces.eth1 = { - ipv4.addresses = [ - { address = "192.168.2.1"; prefixLength = 24; } - ]; - }; - extraHosts = '' - 192.168.2.1 galera_04 - 192.168.2.2 galera_05 - 192.168.2.3 galera_06 - ''; - firewall.allowedTCPPorts = [ 3306 4444 4567 4568 ]; - firewall.allowedUDPPorts = [ 4567 ]; - }; - systemd.services.mysql = with pkgs; { - path = [ mysqlenv-common mysqlenv-rsync ]; - }; - services.mysql = { - enable = true; - package = pkgs.mariadb; - ensureDatabases = [ "testdb" ]; - ensureUsers = [{ - name = "testuser"; - ensurePermissions = { - "testdb.*" = "ALL PRIVILEGES"; - }; - }]; - settings = { - mysqld = { - bind_address = "0.0.0.0"; - }; - galera = { - wsrep_on = "ON"; - wsrep_debug = "NONE"; - wsrep_retry_autocommit = "3"; - wsrep_provider = "${pkgs.mariadb-galera}/lib/galera/libgalera_smm.so"; - wsrep_cluster_address = "gcomm://"; - wsrep_cluster_name = "galera-rsync"; - wsrep_node_address = "192.168.2.1"; - wsrep_node_name = "galera_04"; - wsrep_sst_method = "rsync"; - binlog_format = "ROW"; - enforce_storage_engine = "InnoDB"; - innodb_autoinc_lock_mode = "2"; - }; - }; - }; - }; - - galera_05 = - { pkgs, ... }: - { - imports = [ users ]; - networking = { - interfaces.eth1 = { - ipv4.addresses = [ - { address = "192.168.2.2"; prefixLength = 24; } - ]; - }; - extraHosts = '' - 192.168.2.1 galera_04 - 192.168.2.2 galera_05 - 192.168.2.3 galera_06 - ''; - firewall.allowedTCPPorts = [ 3306 4444 4567 4568 ]; - firewall.allowedUDPPorts = [ 4567 ]; - }; - systemd.services.mysql = with pkgs; { - path = [ mysqlenv-common mysqlenv-rsync ]; - }; - services.mysql = { - enable = true; - package = pkgs.mariadb; - settings = { - mysqld = { - bind_address = "0.0.0.0"; - }; - galera = { - wsrep_on = "ON"; - wsrep_debug = "NONE"; - wsrep_retry_autocommit = "3"; - wsrep_provider = "${pkgs.mariadb-galera}/lib/galera/libgalera_smm.so"; - wsrep_cluster_address = "gcomm://galera_04,galera_05,galera_06"; - wsrep_cluster_name = "galera-rsync"; - wsrep_node_address = "192.168.2.2"; - wsrep_node_name = "galera_05"; - wsrep_sst_method = "rsync"; - binlog_format = "ROW"; - enforce_storage_engine = "InnoDB"; - innodb_autoinc_lock_mode = "2"; - }; - }; - }; - }; - - galera_06 = - { pkgs, ... }: - { - imports = [ users ]; - networking = { - interfaces.eth1 = { - ipv4.addresses = [ - { address = "192.168.2.3"; prefixLength = 24; } - ]; - }; - extraHosts = '' - 192.168.2.1 galera_04 - 192.168.2.2 galera_05 - 192.168.2.3 galera_06 - ''; - firewall.allowedTCPPorts = [ 3306 4444 4567 4568 ]; - firewall.allowedUDPPorts = [ 4567 ]; - }; - systemd.services.mysql = with pkgs; { - path = [ mysqlenv-common mysqlenv-rsync ]; - }; - services.mysql = { - enable = true; - package = pkgs.mariadb; - settings = { - mysqld = { - bind_address = "0.0.0.0"; - }; - galera = { - wsrep_on = "ON"; - wsrep_debug = "NONE"; - wsrep_retry_autocommit = "3"; - wsrep_provider = "${pkgs.mariadb-galera}/lib/galera/libgalera_smm.so"; - wsrep_cluster_address = "gcomm://galera_04,galera_05,galera_06"; - wsrep_cluster_name = "galera-rsync"; - wsrep_node_address = "192.168.2.3"; - wsrep_node_name = "galera_06"; - wsrep_sst_method = "rsync"; - binlog_format = "ROW"; - enforce_storage_engine = "InnoDB"; - innodb_autoinc_lock_mode = "2"; - }; - }; - }; - }; - }; - - testScript = '' - galera_04.start() - galera_04.wait_for_unit("mysql") - galera_04.wait_for_open_port(3306) - galera_04.succeed( - "sudo -u testuser mysql -u testuser -e 'use testdb; create table db1 (test_id INT, PRIMARY KEY (test_id)) ENGINE = InnoDB;'" - ) - galera_04.succeed( - "sudo -u testuser mysql -u testuser -e 'use testdb; insert into db1 values (41);'" - ) - galera_05.start() - galera_05.wait_for_unit("mysql") - galera_05.wait_for_open_port(3306) - galera_06.start() - galera_06.wait_for_unit("mysql") - galera_06.wait_for_open_port(3306) - galera_05.succeed( - "sudo -u testuser mysql -u testuser -e 'use testdb; select test_id from db1;' -N | grep 41" - ) - galera_05.succeed( - "sudo -u testuser mysql -u testuser -e 'use testdb; create table db2 (test_id INT, PRIMARY KEY (test_id)) ENGINE = InnoDB;'" - ) - galera_05.succeed("systemctl stop mysql") - galera_04.succeed( - "sudo -u testuser mysql -u testuser -e 'use testdb; insert into db2 values (42);'" - ) - galera_06.succeed( - "sudo -u testuser mysql -u testuser -e 'use testdb; create table db3 (test_id INT, PRIMARY KEY (test_id)) ENGINE = InnoDB;'" - ) - galera_04.succeed( - "sudo -u testuser mysql -u testuser -e 'use testdb; insert into db3 values (43);'" - ) - galera_05.succeed("systemctl start mysql") - galera_05.wait_for_open_port(3306) - galera_05.succeed( - "sudo -u testuser mysql -u testuser -e 'show status' -N | grep 'wsrep_cluster_size.*3'" - ) - galera_06.succeed( - "sudo -u testuser mysql -u testuser -e 'show status' -N | grep 'wsrep_local_state_comment.*Synced'" - ) - galera_04.succeed( - "sudo -u testuser mysql -u testuser -e 'use testdb; select test_id from db3;' -N | grep 43" - ) - galera_05.succeed( - "sudo -u testuser mysql -u testuser -e 'use testdb; select test_id from db2;' -N | grep 42" - ) - galera_06.succeed( - "sudo -u testuser mysql -u testuser -e 'use testdb; select test_id from db1;' -N | grep 41" - ) - galera_04.succeed("sudo -u testuser mysql -u testuser -e 'use testdb; drop table db3;'") - galera_05.succeed("sudo -u testuser mysql -u testuser -e 'use testdb; drop table db2;'") - galera_06.succeed("sudo -u testuser mysql -u testuser -e 'use testdb; drop table db1;'") - ''; -}) diff --git a/nixos/tests/mysql/mariadb-galera.nix b/nixos/tests/mysql/mariadb-galera.nix new file mode 100644 index 00000000000..c9962f49c02 --- /dev/null +++ b/nixos/tests/mysql/mariadb-galera.nix @@ -0,0 +1,250 @@ +{ + system ? builtins.currentSystem, + config ? {}, + pkgs ? import ../../.. { inherit system config; }, + lib ? pkgs.lib +}: + +let + inherit (import ./common.nix { inherit pkgs lib; }) mkTestName mariadbPackages; + + makeTest = import ./../make-test-python.nix; + + # Common user configuration + makeGaleraTest = { + mariadbPackage, + name ? mkTestName mariadbPackage, + galeraPackage ? pkgs.mariadb-galera + }: makeTest { + name = "${name}-galera-mariabackup"; + meta = with pkgs.lib.maintainers; { + maintainers = [ izorkin ajs124 das_j ]; + }; + + # The test creates a Galera cluster with 3 nodes and is checking if mariabackup-based SST works. The cluster is tested by creating a DB and an empty table on one node, + # and checking the table's presence on the other node. + nodes = let + mkGaleraNode = { + id, + method + }: let + address = "192.168.1.${toString id}"; + isFirstClusterNode = id == 1 || id == 4; + in { + users = { + users.testuser = { + isSystemUser = true; + group = "testusers"; + }; + groups.testusers = { }; + }; + + networking = { + interfaces.eth1 = { + ipv4.addresses = [ + { inherit address; prefixLength = 24; } + ]; + }; + extraHosts = lib.concatMapStringsSep "\n" (i: "192.168.1.${toString i} galera_0${toString i}") (lib.range 1 6); + firewall.allowedTCPPorts = [ 3306 4444 4567 4568 ]; + firewall.allowedUDPPorts = [ 4567 ]; + }; + systemd.services.mysql = with pkgs; { + path = with pkgs; [ + bash + gawk + gnutar + gzip + inetutils + iproute2 + netcat + procps + pv + rsync + socat + stunnel + which + ]; + }; + services.mysql = { + enable = true; + package = mariadbPackage; + ensureDatabases = lib.mkIf isFirstClusterNode [ "testdb" ]; + ensureUsers = lib.mkIf isFirstClusterNode [{ + name = "testuser"; + ensurePermissions = { + "testdb.*" = "ALL PRIVILEGES"; + }; + }]; + initialScript = lib.mkIf isFirstClusterNode (pkgs.writeText "mariadb-init.sql" '' + GRANT ALL PRIVILEGES ON *.* TO 'check_repl'@'localhost' IDENTIFIED BY 'check_pass' WITH GRANT OPTION; + FLUSH PRIVILEGES; + ''); + settings = { + mysqld = { + bind_address = "0.0.0.0"; + }; + galera = { + wsrep_on = "ON"; + wsrep_debug = "NONE"; + wsrep_retry_autocommit = "3"; + wsrep_provider = "${galeraPackage}/lib/galera/libgalera_smm.so"; + wsrep_cluster_address = "gcomm://" + + lib.optionalString (id == 2 || id == 3) "galera_01,galera_02,galera_03" + + lib.optionalString (id == 5 || id == 6) "galera_04,galera_05,galera_06"; + wsrep_cluster_name = "galera"; + wsrep_node_address = address; + wsrep_node_name = "galera_0${toString id}"; + wsrep_sst_method = method; + wsrep_sst_auth = "check_repl:check_pass"; + binlog_format = "ROW"; + enforce_storage_engine = "InnoDB"; + innodb_autoinc_lock_mode = "2"; + }; + }; + }; + }; + in { + galera_01 = mkGaleraNode { + id = 1; + method = "mariabackup"; + }; + + galera_02 = mkGaleraNode { + id = 2; + method = "mariabackup"; + }; + + galera_03 = mkGaleraNode { + id = 3; + method = "mariabackup"; + }; + + galera_04 = mkGaleraNode { + id = 4; + method = "rsync"; + }; + + galera_05 = mkGaleraNode { + id = 5; + method = "rsync"; + }; + + galera_06 = mkGaleraNode { + id = 6; + method = "rsync"; + }; + + }; + + testScript = '' + galera_01.start() + galera_01.wait_for_unit("mysql") + galera_01.wait_for_open_port(3306) + galera_01.succeed( + "sudo -u testuser mysql -u testuser -e 'use testdb; create table db1 (test_id INT, PRIMARY KEY (test_id)) ENGINE = InnoDB;'" + ) + galera_01.succeed( + "sudo -u testuser mysql -u testuser -e 'use testdb; insert into db1 values (37);'" + ) + galera_02.start() + galera_02.wait_for_unit("mysql") + galera_02.wait_for_open_port(3306) + galera_03.start() + galera_03.wait_for_unit("mysql") + galera_03.wait_for_open_port(3306) + galera_02.succeed( + "sudo -u testuser mysql -u testuser -e 'use testdb; select test_id from db1;' -N | grep 37" + ) + galera_02.succeed( + "sudo -u testuser mysql -u testuser -e 'use testdb; create table db2 (test_id INT, PRIMARY KEY (test_id)) ENGINE = InnoDB;'" + ) + galera_02.succeed("systemctl stop mysql") + galera_01.succeed( + "sudo -u testuser mysql -u testuser -e 'use testdb; insert into db2 values (38);'" + ) + galera_03.succeed( + "sudo -u testuser mysql -u testuser -e 'use testdb; create table db3 (test_id INT, PRIMARY KEY (test_id)) ENGINE = InnoDB;'" + ) + galera_01.succeed( + "sudo -u testuser mysql -u testuser -e 'use testdb; insert into db3 values (39);'" + ) + galera_02.succeed("systemctl start mysql") + galera_02.wait_for_open_port(3306) + galera_02.succeed( + "sudo -u testuser mysql -u testuser -e 'show status' -N | grep 'wsrep_cluster_size.*3'" + ) + galera_03.succeed( + "sudo -u testuser mysql -u testuser -e 'show status' -N | grep 'wsrep_local_state_comment.*Synced'" + ) + galera_01.succeed( + "sudo -u testuser mysql -u testuser -e 'use testdb; select test_id from db3;' -N | grep 39" + ) + galera_02.succeed( + "sudo -u testuser mysql -u testuser -e 'use testdb; select test_id from db2;' -N | grep 38" + ) + galera_03.succeed( + "sudo -u testuser mysql -u testuser -e 'use testdb; select test_id from db1;' -N | grep 37" + ) + galera_01.succeed("sudo -u testuser mysql -u testuser -e 'use testdb; drop table db3;'") + galera_02.succeed("sudo -u testuser mysql -u testuser -e 'use testdb; drop table db2;'") + galera_03.succeed("sudo -u testuser mysql -u testuser -e 'use testdb; drop table db1;'") + galera_01.crash() + galera_02.crash() + galera_03.crash() + + galera_04.start() + galera_04.wait_for_unit("mysql") + galera_04.wait_for_open_port(3306) + galera_04.succeed( + "sudo -u testuser mysql -u testuser -e 'use testdb; create table db1 (test_id INT, PRIMARY KEY (test_id)) ENGINE = InnoDB;'" + ) + galera_04.succeed( + "sudo -u testuser mysql -u testuser -e 'use testdb; insert into db1 values (41);'" + ) + galera_05.start() + galera_05.wait_for_unit("mysql") + galera_05.wait_for_open_port(3306) + galera_06.start() + galera_06.wait_for_unit("mysql") + galera_06.wait_for_open_port(3306) + galera_05.succeed( + "sudo -u testuser mysql -u testuser -e 'use testdb; select test_id from db1;' -N | grep 41" + ) + galera_05.succeed( + "sudo -u testuser mysql -u testuser -e 'use testdb; create table db2 (test_id INT, PRIMARY KEY (test_id)) ENGINE = InnoDB;'" + ) + galera_05.succeed("systemctl stop mysql") + galera_04.succeed( + "sudo -u testuser mysql -u testuser -e 'use testdb; insert into db2 values (42);'" + ) + galera_06.succeed( + "sudo -u testuser mysql -u testuser -e 'use testdb; create table db3 (test_id INT, PRIMARY KEY (test_id)) ENGINE = InnoDB;'" + ) + galera_04.succeed( + "sudo -u testuser mysql -u testuser -e 'use testdb; insert into db3 values (43);'" + ) + galera_05.succeed("systemctl start mysql") + galera_05.wait_for_open_port(3306) + galera_05.succeed( + "sudo -u testuser mysql -u testuser -e 'show status' -N | grep 'wsrep_cluster_size.*3'" + ) + galera_06.succeed( + "sudo -u testuser mysql -u testuser -e 'show status' -N | grep 'wsrep_local_state_comment.*Synced'" + ) + galera_04.succeed( + "sudo -u testuser mysql -u testuser -e 'use testdb; select test_id from db3;' -N | grep 43" + ) + galera_05.succeed( + "sudo -u testuser mysql -u testuser -e 'use testdb; select test_id from db2;' -N | grep 42" + ) + galera_06.succeed( + "sudo -u testuser mysql -u testuser -e 'use testdb; select test_id from db1;' -N | grep 41" + ) + galera_04.succeed("sudo -u testuser mysql -u testuser -e 'use testdb; drop table db3;'") + galera_05.succeed("sudo -u testuser mysql -u testuser -e 'use testdb; drop table db2;'") + galera_06.succeed("sudo -u testuser mysql -u testuser -e 'use testdb; drop table db1;'") + ''; + }; +in + lib.mapAttrs (_: mariadbPackage: makeGaleraTest { inherit mariadbPackage; }) mariadbPackages diff --git a/nixos/tests/mysql/mysql-autobackup.nix b/nixos/tests/mysql/mysql-autobackup.nix index b0ec7daaf05..101122f7bde 100644 --- a/nixos/tests/mysql/mysql-autobackup.nix +++ b/nixos/tests/mysql/mysql-autobackup.nix @@ -1,38 +1,53 @@ -import ./../make-test-python.nix ({ pkgs, lib, ... }: - { - name = "automysqlbackup"; - meta.maintainers = [ lib.maintainers.aanderse ]; - - machine = - { pkgs, ... }: - { - services.mysql.enable = true; - services.mysql.package = pkgs.mariadb; - services.mysql.initialDatabases = [ { name = "testdb"; schema = ./testdb.sql; } ]; + system ? builtins.currentSystem, + config ? {}, + pkgs ? import ../../.. { inherit system config; }, + lib ? pkgs.lib +}: + +let + inherit (import ./common.nix { inherit pkgs lib; }) mkTestName mariadbPackages; + + makeTest = import ./../make-test-python.nix; + + makeAutobackupTest = { + package, + name ? mkTestName package, + }: makeTest { + name = "${name}-automysqlbackup"; + meta.maintainers = [ lib.maintainers.aanderse ]; + + machine = { + services.mysql = { + inherit package; + enable = true; + initialDatabases = [ { name = "testdb"; schema = ./testdb.sql; } ]; + }; services.automysqlbackup.enable = true; }; - testScript = '' - start_all() - - # Need to have mysql started so that it can be populated with data. - machine.wait_for_unit("mysql.service") - - with subtest("Wait for testdb to be fully populated (5 rows)."): - machine.wait_until_succeeds( - "mysql -u root -D testdb -N -B -e 'select count(id) from tests' | grep -q 5" - ) - - with subtest("Do a backup and wait for it to start"): - machine.start_job("automysqlbackup.service") - machine.wait_for_job("automysqlbackup.service") - - with subtest("wait for backup file and check that data appears in backup"): - machine.wait_for_file("/var/backup/mysql/daily/testdb") - machine.succeed( - "${pkgs.gzip}/bin/zcat /var/backup/mysql/daily/testdb/daily_testdb_*.sql.gz | grep hello" - ) - ''; -}) + testScript = '' + start_all() + + # Need to have mysql started so that it can be populated with data. + machine.wait_for_unit("mysql.service") + + with subtest("Wait for testdb to be fully populated (5 rows)."): + machine.wait_until_succeeds( + "mysql -u root -D testdb -N -B -e 'select count(id) from tests' | grep -q 5" + ) + + with subtest("Do a backup and wait for it to start"): + machine.start_job("automysqlbackup.service") + machine.wait_for_job("automysqlbackup.service") + + with subtest("wait for backup file and check that data appears in backup"): + machine.wait_for_file("/var/backup/mysql/daily/testdb") + machine.succeed( + "${pkgs.gzip}/bin/zcat /var/backup/mysql/daily/testdb/daily_testdb_*.sql.gz | grep hello" + ) + ''; + }; +in + lib.mapAttrs (_: package: makeAutobackupTest { inherit package; }) mariadbPackages diff --git a/nixos/tests/mysql/mysql-backup.nix b/nixos/tests/mysql/mysql-backup.nix index 269fddc66e1..9335b233327 100644 --- a/nixos/tests/mysql/mysql-backup.nix +++ b/nixos/tests/mysql/mysql-backup.nix @@ -1,56 +1,72 @@ -# Test whether mysqlBackup option works -import ./../make-test-python.nix ({ pkgs, ... } : { - name = "mysql-backup"; - meta = with pkgs.lib.maintainers; { - maintainers = [ rvl ]; - }; +{ + system ? builtins.currentSystem, + config ? {}, + pkgs ? import ../../.. { inherit system config; }, + lib ? pkgs.lib +}: - nodes = { - master = { pkgs, ... }: { - services.mysql = { - enable = true; - initialDatabases = [ { name = "testdb"; schema = ./testdb.sql; } ]; - package = pkgs.mariadb; - }; +let + inherit (import ./common.nix { inherit pkgs lib; }) mkTestName mariadbPackages; + + makeTest = import ./../make-test-python.nix; + + makeBackupTest = { + package, + name ? mkTestName package + }: makeTest { + name = "${name}-backup"; + meta = with pkgs.lib.maintainers; { + maintainers = [ rvl ]; + }; + + nodes = { + master = { pkgs, ... }: { + services.mysql = { + inherit package; + enable = true; + initialDatabases = [ { name = "testdb"; schema = ./testdb.sql; } ]; + }; - services.mysqlBackup = { - enable = true; - databases = [ "doesnotexist" "testdb" ]; + services.mysqlBackup = { + enable = true; + databases = [ "doesnotexist" "testdb" ]; + }; }; }; - }; - testScript = '' - start_all() + testScript = '' + start_all() - # Delete backup file that may be left over from a previous test run. - # This is not needed on Hydra but useful for repeated local test runs. - master.execute("rm -f /var/backup/mysql/testdb.gz") + # Delete backup file that may be left over from a previous test run. + # This is not needed on Hydra but useful for repeated local test runs. + master.execute("rm -f /var/backup/mysql/testdb.gz") - # Need to have mysql started so that it can be populated with data. - master.wait_for_unit("mysql.service") + # Need to have mysql started so that it can be populated with data. + master.wait_for_unit("mysql.service") - # Wait for testdb to be fully populated (5 rows). - master.wait_until_succeeds( - "mysql -u root -D testdb -N -B -e 'select count(id) from tests' | grep -q 5" - ) + # Wait for testdb to be fully populated (5 rows). + master.wait_until_succeeds( + "mysql -u root -D testdb -N -B -e 'select count(id) from tests' | grep -q 5" + ) - # Do a backup and wait for it to start - master.start_job("mysql-backup.service") - master.wait_for_unit("mysql-backup.service") + # 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") + # wait for backup to fail, because of database 'doesnotexist' + master.wait_until_fails("systemctl is-active -q mysql-backup.service") - # wait for backup file and check that data appears in backup - master.wait_for_file("/var/backup/mysql/testdb.gz") - master.succeed( - "${pkgs.gzip}/bin/zcat /var/backup/mysql/testdb.gz | grep hello" - ) + # wait for backup file and check that data appears in backup + master.wait_for_file("/var/backup/mysql/testdb.gz") + master.succeed( + "${pkgs.gzip}/bin/zcat /var/backup/mysql/testdb.gz | grep hello" + ) - # Check that a failed backup is logged - master.succeed( - "journalctl -u mysql-backup.service | grep 'fail.*doesnotexist' > /dev/null" - ) - ''; -}) + # Check that a failed backup is logged + master.succeed( + "journalctl -u mysql-backup.service | grep 'fail.*doesnotexist' > /dev/null" + ) + ''; + }; +in + lib.mapAttrs (_: package: makeBackupTest { inherit package; }) mariadbPackages diff --git a/nixos/tests/mysql/mysql-replication.nix b/nixos/tests/mysql/mysql-replication.nix index a52372ca47c..f6014019bd5 100644 --- a/nixos/tests/mysql/mysql-replication.nix +++ b/nixos/tests/mysql/mysql-replication.nix @@ -1,91 +1,101 @@ -import ./../make-test-python.nix ({ pkgs, ...} : +{ + system ? builtins.currentSystem, + config ? {}, + pkgs ? import ../../.. { inherit system config; }, + lib ? pkgs.lib +}: let + inherit (import ./common.nix { inherit pkgs lib; }) mkTestName mariadbPackages; + replicateUser = "replicate"; replicatePassword = "secret"; -in -{ - name = "mysql-replication"; - meta = with pkgs.lib.maintainers; { - maintainers = [ eelco shlevy ]; - }; + makeTest = import ./../make-test-python.nix; - nodes = { - master = - { pkgs, ... }: + makeReplicationTest = { + package, + name ? mkTestName package, + }: makeTest { + name = "${name}-replication"; + meta = with pkgs.lib.maintainers; { + maintainers = [ ajs124 das_j ]; + }; - { - services.mysql.enable = true; - services.mysql.package = pkgs.mariadb; - services.mysql.replication.role = "master"; - services.mysql.replication.slaveHost = "%"; - services.mysql.replication.masterUser = replicateUser; - services.mysql.replication.masterPassword = replicatePassword; - services.mysql.initialDatabases = [ { name = "testdb"; schema = ./testdb.sql; } ]; + nodes = { + primary = { + services.mysql = { + inherit package; + enable = true; + replication.role = "master"; + replication.slaveHost = "%"; + replication.masterUser = replicateUser; + replication.masterPassword = replicatePassword; + initialDatabases = [ { name = "testdb"; schema = ./testdb.sql; } ]; + }; networking.firewall.allowedTCPPorts = [ 3306 ]; }; - slave1 = - { pkgs, nodes, ... }: - - { - services.mysql.enable = true; - services.mysql.package = pkgs.mariadb; - services.mysql.replication.role = "slave"; - services.mysql.replication.serverId = 2; - services.mysql.replication.masterHost = nodes.master.config.networking.hostName; - services.mysql.replication.masterUser = replicateUser; - services.mysql.replication.masterPassword = replicatePassword; + secondary1 = { nodes, ... }: { + services.mysql = { + inherit package; + enable = true; + replication.role = "slave"; + replication.serverId = 2; + replication.masterHost = nodes.primary.config.networking.hostName; + replication.masterUser = replicateUser; + replication.masterPassword = replicatePassword; + }; }; - slave2 = - { pkgs, nodes, ... }: - - { - services.mysql.enable = true; - services.mysql.package = pkgs.mariadb; - services.mysql.replication.role = "slave"; - services.mysql.replication.serverId = 3; - services.mysql.replication.masterHost = nodes.master.config.networking.hostName; - services.mysql.replication.masterUser = replicateUser; - services.mysql.replication.masterPassword = replicatePassword; + secondary2 = { nodes, ... }: { + services.mysql = { + inherit package; + enable = true; + replication.role = "slave"; + replication.serverId = 3; + replication.masterHost = nodes.primary.config.networking.hostName; + replication.masterUser = replicateUser; + replication.masterPassword = replicatePassword; + }; }; - }; + }; - testScript = '' - master.start() - master.wait_for_unit("mysql") - master.wait_for_open_port(3306) - # Wait for testdb to be fully populated (5 rows). - master.wait_until_succeeds( - "sudo -u mysql mysql -u mysql -D testdb -N -B -e 'select count(id) from tests' | grep -q 5" - ) + testScript = '' + primary.start() + primary.wait_for_unit("mysql") + primary.wait_for_open_port(3306) + # Wait for testdb to be fully populated (5 rows). + primary.wait_until_succeeds( + "sudo -u mysql mysql -u mysql -D testdb -N -B -e 'select count(id) from tests' | grep -q 5" + ) - slave1.start() - slave2.start() - slave1.wait_for_unit("mysql") - slave1.wait_for_open_port(3306) - slave2.wait_for_unit("mysql") - slave2.wait_for_open_port(3306) + secondary1.start() + secondary2.start() + secondary1.wait_for_unit("mysql") + secondary1.wait_for_open_port(3306) + secondary2.wait_for_unit("mysql") + secondary2.wait_for_open_port(3306) - # wait for replications to finish - slave1.wait_until_succeeds( - "sudo -u mysql mysql -u mysql -D testdb -N -B -e 'select count(id) from tests' | grep -q 5" - ) - slave2.wait_until_succeeds( - "sudo -u mysql mysql -u mysql -D testdb -N -B -e 'select count(id) from tests' | grep -q 5" - ) + # wait for replications to finish + secondary1.wait_until_succeeds( + "sudo -u mysql mysql -u mysql -D testdb -N -B -e 'select count(id) from tests' | grep -q 5" + ) + secondary2.wait_until_succeeds( + "sudo -u mysql mysql -u mysql -D testdb -N -B -e 'select count(id) from tests' | grep -q 5" + ) - slave2.succeed("systemctl stop mysql") - master.succeed( - "echo 'insert into testdb.tests values (123, 456);' | sudo -u mysql mysql -u mysql -N" - ) - slave2.succeed("systemctl start mysql") - slave2.wait_for_unit("mysql") - slave2.wait_for_open_port(3306) - slave2.wait_until_succeeds( - "echo 'select * from testdb.tests where Id = 123;' | sudo -u mysql mysql -u mysql -N | grep 456" - ) - ''; -}) + secondary2.succeed("systemctl stop mysql") + primary.succeed( + "echo 'insert into testdb.tests values (123, 456);' | sudo -u mysql mysql -u mysql -N" + ) + secondary2.succeed("systemctl start mysql") + secondary2.wait_for_unit("mysql") + secondary2.wait_for_open_port(3306) + secondary2.wait_until_succeeds( + "echo 'select * from testdb.tests where Id = 123;' | sudo -u mysql mysql -u mysql -N | grep 456" + ) + ''; + }; +in + lib.mapAttrs (_: package: makeReplicationTest { inherit package; }) mariadbPackages diff --git a/nixos/tests/mysql/mysql.nix b/nixos/tests/mysql/mysql.nix index 2ac2b34a18e..a5e42f85a7f 100644 --- a/nixos/tests/mysql/mysql.nix +++ b/nixos/tests/mysql/mysql.nix @@ -1,221 +1,149 @@ -import ./../make-test-python.nix ({ pkgs, ...}: - +{ + system ? builtins.currentSystem, + config ? {}, + pkgs ? import ../../.. { inherit system config; }, + lib ? pkgs.lib +}: let - # Setup common users - users = { ... }: - { - users.groups.testusers = { }; + inherit (import ./common.nix { inherit pkgs lib; }) mkTestName mariadbPackages mysqlPackages; - users.users.testuser = { - isSystemUser = true; - group = "testusers"; + makeTest = import ./../make-test-python.nix; + # Setup common users + makeMySQLTest = { + package, + name ? mkTestName package, + useSocketAuth ? true, + hasMroonga ? true, + hasRocksDB ? true + }: makeTest { + inherit name; + meta = with lib.maintainers; { + maintainers = [ ajs124 das_j ]; }; - users.users.testuser2 = { - isSystemUser = true; - group = "testusers"; - }; - }; + nodes = { + ${name} = + { pkgs, ... }: { -in + users = { + groups.testusers = { }; -{ - name = "mysql"; - meta = with pkgs.lib.maintainers; { - maintainers = [ eelco shlevy ]; - }; - - nodes = { - mysql57 = - { pkgs, ... }: + users.testuser = { + isSystemUser = true; + group = "testusers"; + }; - { - imports = [ users ]; - - services.mysql.enable = true; - services.mysql.initialDatabases = [ - { name = "testdb3"; schema = ./testdb.sql; } - ]; - # note that using pkgs.writeText here is generally not a good idea, - # as it will store the password in world-readable /nix/store ;) - services.mysql.initialScript = pkgs.writeText "mysql-init.sql" '' - CREATE USER 'testuser3'@'localhost' IDENTIFIED BY 'secure'; - GRANT ALL PRIVILEGES ON testdb3.* TO 'testuser3'@'localhost'; - ''; - services.mysql.ensureDatabases = [ "testdb" "testdb2" ]; - services.mysql.ensureUsers = [{ - name = "testuser"; - ensurePermissions = { - "testdb.*" = "ALL PRIVILEGES"; - }; - } { - name = "testuser2"; - ensurePermissions = { - "testdb2.*" = "ALL PRIVILEGES"; + users.testuser2 = { + isSystemUser = true; + group = "testusers"; + }; }; - }]; - services.mysql.package = pkgs.mysql57; - }; - mysql80 = - { pkgs, ... }: - - { - imports = [ users ]; - - services.mysql.enable = true; - services.mysql.initialDatabases = [ - { name = "testdb3"; schema = ./testdb.sql; } - ]; - # note that using pkgs.writeText here is generally not a good idea, - # as it will store the password in world-readable /nix/store ;) - services.mysql.initialScript = pkgs.writeText "mysql-init.sql" '' - CREATE USER 'testuser3'@'localhost' IDENTIFIED BY 'secure'; - GRANT ALL PRIVILEGES ON testdb3.* TO 'testuser3'@'localhost'; - ''; - services.mysql.ensureDatabases = [ "testdb" "testdb2" ]; - services.mysql.ensureUsers = [{ - name = "testuser"; - ensurePermissions = { - "testdb.*" = "ALL PRIVILEGES"; - }; - } { - name = "testuser2"; - ensurePermissions = { - "testdb2.*" = "ALL PRIVILEGES"; + services.mysql = { + enable = true; + initialDatabases = [ + { name = "testdb3"; schema = ./testdb.sql; } + ]; + # note that using pkgs.writeText here is generally not a good idea, + # as it will store the password in world-readable /nix/store ;) + initialScript = pkgs.writeText "mysql-init.sql" (if (!useSocketAuth) then '' + CREATE USER 'testuser3'@'localhost' IDENTIFIED BY 'secure'; + GRANT ALL PRIVILEGES ON testdb3.* TO 'testuser3'@'localhost'; + '' else '' + ALTER USER root@localhost IDENTIFIED WITH unix_socket; + DELETE FROM mysql.user WHERE password = ''' AND plugin = '''; + DELETE FROM mysql.user WHERE user = '''; + FLUSH PRIVILEGES; + ''); + + ensureDatabases = [ "testdb" "testdb2" ]; + ensureUsers = [{ + name = "testuser"; + ensurePermissions = { + "testdb.*" = "ALL PRIVILEGES"; + }; + } { + name = "testuser2"; + ensurePermissions = { + "testdb2.*" = "ALL PRIVILEGES"; + }; + }]; + package = package; + settings = { + mysqld = { + plugin-load-add = lib.optional hasMroonga "ha_mroonga.so" + ++ lib.optional hasRocksDB "ha_rocksdb.so"; + }; + }; }; - }]; - services.mysql.package = pkgs.mysql80; - }; - - mariadb = - { pkgs, ... }: - - { - imports = [ users ]; + }; - services.mysql.enable = true; - services.mysql.initialScript = pkgs.writeText "mariadb-init.sql" '' - ALTER USER root@localhost IDENTIFIED WITH unix_socket; - DELETE FROM mysql.user WHERE password = ''' AND plugin = '''; - DELETE FROM mysql.user WHERE user = '''; - FLUSH PRIVILEGES; - ''; - services.mysql.ensureDatabases = [ "testdb" "testdb2" ]; - services.mysql.ensureUsers = [{ - name = "testuser"; - ensurePermissions = { - "testdb.*" = "ALL PRIVILEGES"; - }; - } { - name = "testuser2"; - ensurePermissions = { - "testdb2.*" = "ALL PRIVILEGES"; - }; - }]; - services.mysql.settings = { - mysqld = { - plugin-load-add = [ "ha_mroonga.so" "ha_rocksdb.so" ]; - }; + mariadb = { }; - services.mysql.package = pkgs.mariadb; - }; + }; + testScript = '' + start_all() + + machine = ${name} + machine.wait_for_unit("mysql") + machine.succeed( + "echo 'use testdb; create table tests (test_id INT, PRIMARY KEY (test_id));' | sudo -u testuser mysql -u testuser" + ) + machine.succeed( + "echo 'use testdb; insert into tests values (42);' | sudo -u testuser mysql -u testuser" + ) + # Ensure testuser2 is not able to insert into testdb as mysql testuser2 + machine.fail( + "echo 'use testdb; insert into tests values (23);' | sudo -u testuser2 mysql -u testuser2" + ) + # Ensure testuser2 is not able to authenticate as mysql testuser + machine.fail( + "echo 'use testdb; insert into tests values (23);' | sudo -u testuser2 mysql -u testuser" + ) + machine.succeed( + "echo 'use testdb; select test_id from tests;' | sudo -u testuser mysql -u testuser -N | grep 42" + ) + + ${lib.optionalString hasMroonga '' + # Check if Mroonga plugin works + machine.succeed( + "echo 'use testdb; create table mroongadb (test_id INT, PRIMARY KEY (test_id)) ENGINE = Mroonga;' | sudo -u testuser mysql -u testuser" + ) + machine.succeed( + "echo 'use testdb; insert into mroongadb values (25);' | sudo -u testuser mysql -u testuser" + ) + machine.succeed( + "echo 'use testdb; select test_id from mroongadb;' | sudo -u testuser mysql -u testuser -N | grep 25" + ) + machine.succeed( + "echo 'use testdb; drop table mroongadb;' | sudo -u testuser mysql -u testuser" + ) + ''} + + ${lib.optionalString hasRocksDB '' + # Check if RocksDB plugin works + machine.succeed( + "echo 'use testdb; create table rocksdb (test_id INT, PRIMARY KEY (test_id)) ENGINE = RocksDB;' | sudo -u testuser mysql -u testuser" + ) + machine.succeed( + "echo 'use testdb; insert into rocksdb values (28);' | sudo -u testuser mysql -u testuser" + ) + machine.succeed( + "echo 'use testdb; select test_id from rocksdb;' | sudo -u testuser mysql -u testuser -N | grep 28" + ) + machine.succeed( + "echo 'use testdb; drop table rocksdb;' | sudo -u testuser mysql -u testuser" + ) + ''} + ''; }; - - testScript = '' - start_all() - - mysql57.wait_for_unit("mysql") - mysql57.succeed( - "echo 'use testdb; create table tests (test_id INT, PRIMARY KEY (test_id));' | sudo -u testuser mysql -u testuser" - ) - mysql57.succeed( - "echo 'use testdb; insert into tests values (41);' | sudo -u testuser mysql -u testuser" - ) - # Ensure testuser2 is not able to insert into testdb as mysql testuser2 - mysql57.fail( - "echo 'use testdb; insert into tests values (22);' | sudo -u testuser2 mysql -u testuser2" - ) - # Ensure testuser2 is not able to authenticate as mysql testuser - mysql57.fail( - "echo 'use testdb; insert into tests values (22);' | sudo -u testuser2 mysql -u testuser" - ) - mysql57.succeed( - "echo 'use testdb; select test_id from tests;' | sudo -u testuser mysql -u testuser -N | grep 41" - ) - mysql57.succeed( - "echo 'use testdb3; select * from tests;' | mysql -u testuser3 --password=secure -N | grep 4" - ) - - mysql80.wait_for_unit("mysql") - mysql80.succeed( - "echo 'use testdb; create table tests (test_id INT, PRIMARY KEY (test_id));' | sudo -u testuser mysql -u testuser" - ) - mysql80.succeed( - "echo 'use testdb; insert into tests values (41);' | sudo -u testuser mysql -u testuser" - ) - # Ensure testuser2 is not able to insert into testdb as mysql testuser2 - mysql80.fail( - "echo 'use testdb; insert into tests values (22);' | sudo -u testuser2 mysql -u testuser2" - ) - # Ensure testuser2 is not able to authenticate as mysql testuser - mysql80.fail( - "echo 'use testdb; insert into tests values (22);' | sudo -u testuser2 mysql -u testuser" - ) - mysql80.succeed( - "echo 'use testdb; select test_id from tests;' | sudo -u testuser mysql -u testuser -N | grep 41" - ) - mysql80.succeed( - "echo 'use testdb3; select * from tests;' | mysql -u testuser3 --password=secure -N | grep 4" - ) - - mariadb.wait_for_unit("mysql") - mariadb.succeed( - "echo 'use testdb; create table tests (test_id INT, PRIMARY KEY (test_id));' | sudo -u testuser mysql -u testuser" - ) - mariadb.succeed( - "echo 'use testdb; insert into tests values (42);' | sudo -u testuser mysql -u testuser" - ) - # Ensure testuser2 is not able to insert into testdb as mysql testuser2 - mariadb.fail( - "echo 'use testdb; insert into tests values (23);' | sudo -u testuser2 mysql -u testuser2" - ) - # Ensure testuser2 is not able to authenticate as mysql testuser - mariadb.fail( - "echo 'use testdb; insert into tests values (23);' | sudo -u testuser2 mysql -u testuser" - ) - mariadb.succeed( - "echo 'use testdb; select test_id from tests;' | sudo -u testuser mysql -u testuser -N | grep 42" - ) - - # Check if Mroonga plugin works - mariadb.succeed( - "echo 'use testdb; create table mroongadb (test_id INT, PRIMARY KEY (test_id)) ENGINE = Mroonga;' | sudo -u testuser mysql -u testuser" - ) - mariadb.succeed( - "echo 'use testdb; insert into mroongadb values (25);' | sudo -u testuser mysql -u testuser" - ) - mariadb.succeed( - "echo 'use testdb; select test_id from mroongadb;' | sudo -u testuser mysql -u testuser -N | grep 25" - ) - mariadb.succeed( - "echo 'use testdb; drop table mroongadb;' | sudo -u testuser mysql -u testuser" - ) - - # Check if RocksDB plugin works - mariadb.succeed( - "echo 'use testdb; create table rocksdb (test_id INT, PRIMARY KEY (test_id)) ENGINE = RocksDB;' | sudo -u testuser mysql -u testuser" - ) - mariadb.succeed( - "echo 'use testdb; insert into rocksdb values (28);' | sudo -u testuser mysql -u testuser" - ) - mariadb.succeed( - "echo 'use testdb; select test_id from rocksdb;' | sudo -u testuser mysql -u testuser -N | grep 28" - ) - mariadb.succeed( - "echo 'use testdb; drop table rocksdb;' | sudo -u testuser mysql -u testuser" - ) - ''; -}) +in + lib.mapAttrs (_: package: makeMySQLTest { + inherit package; + hasRocksDB = false; hasMroonga = false; + }) mysqlPackages + // (lib.mapAttrs (_: package: makeMySQLTest { + inherit package; + }) mariadbPackages) diff --git a/nixos/tests/networking.nix b/nixos/tests/networking.nix index f46a115a07d..2510937b5dc 100644 --- a/nixos/tests/networking.nix +++ b/nixos/tests/networking.nix @@ -740,6 +740,7 @@ let routes = { name = "routes"; machine = { + networking.useNetworkd = networkd; networking.useDHCP = false; networking.interfaces.eth0 = { ipv4.addresses = [ { address = "192.168.1.2"; prefixLength = 24; } ]; @@ -749,7 +750,13 @@ let { address = "2001:1470:fffd:2098::"; prefixLength = 64; via = "fdfd:b3f0::1"; } ]; ipv4.routes = [ - { address = "10.0.0.0"; prefixLength = 16; options = { mtu = "1500"; }; } + { address = "10.0.0.0"; prefixLength = 16; options = { + mtu = "1500"; + # Explicitly set scope because iproute and systemd-networkd + # disagree on what the scope should be + # if the type is the default "unicast" + scope = "link"; + }; } { address = "192.168.2.0"; prefixLength = 24; via = "192.168.1.1"; } ]; }; @@ -798,6 +805,7 @@ let ipv6Table, targetIPv6Table ) + '' + optionalString (!networkd) '' with subtest("test clean-up of the tables"): machine.succeed("systemctl stop network-addresses-eth0") ipv4Residue = machine.succeed("ip -4 route list dev eth0 | head -n-3").strip() diff --git a/nixos/tests/nextcloud/with-mysql-and-memcached.nix b/nixos/tests/nextcloud/with-mysql-and-memcached.nix index 80cb63df5db..891001e30b2 100644 --- a/nixos/tests/nextcloud/with-mysql-and-memcached.nix +++ b/nixos/tests/nextcloud/with-mysql-and-memcached.nix @@ -40,15 +40,16 @@ in { services.mysql = { enable = true; - bind = "127.0.0.1"; + 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; - # 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 - extraOptions = '' - innodb_read_only_compressed=0 - ''; initialScript = pkgs.writeText "mysql-init" '' CREATE USER 'nextcloud'@'localhost' IDENTIFIED BY 'hunter2'; CREATE DATABASE IF NOT EXISTS nextcloud; diff --git a/nixos/tests/rstudio-server.nix b/nixos/tests/rstudio-server.nix new file mode 100644 index 00000000000..c7ac7670fbd --- /dev/null +++ b/nixos/tests/rstudio-server.nix @@ -0,0 +1,30 @@ +import ./make-test-python.nix ({ pkgs, ... }: + { + name = "rstudio-server-test"; + meta.maintainers = with pkgs.lib.maintainers; [ jbedo cfhammill ]; + + nodes.machine = { config, lib, pkgs, ... }: { + services.rstudio-server.enable = true; + }; + + nodes.customPackageMachine = { config, lib, pkgs, ... }: { + services.rstudio-server = { + enable = true; + package = pkgs.rstudioServerWrapper.override { packages = [ pkgs.rPackages.ggplot2 ]; }; + }; + }; + + users.testuser = { + uid = 1000; + group = "testgroup"; + }; + groups.testgroup.gid = 1000; + + testScript = '' + machine.wait_for_unit("rstudio-server.service") + machine.succeed("curl -f -vvv -s http://127.0.0.1:8787") + + customPackageMachine.wait_for_unit("rstudio-server.service") + customPackageMachine.succeed("curl -f -vvv -s http://127.0.0.1:8787") + ''; + }) diff --git a/nixos/tests/starship.nix b/nixos/tests/starship.nix new file mode 100644 index 00000000000..33e9a72f700 --- /dev/null +++ b/nixos/tests/starship.nix @@ -0,0 +1,42 @@ +import ./make-test-python.nix ({ pkgs, ... }: { + name = "starship"; + meta.maintainers = pkgs.starship.meta.maintainers; + + machine = { + programs = { + fish.enable = true; + zsh.enable = true; + + starship = { + enable = true; + settings.format = "<starship>"; + }; + }; + + environment.systemPackages = map + (shell: pkgs.writeScriptBin "expect-${shell}" '' + #!${pkgs.expect}/bin/expect -f + + spawn env TERM=xterm ${shell} -i + + expect "<starship>" { + send "exit\n" + } timeout { + send_user "\n${shell} failed to display Starship\n" + exit 1 + } + + expect eof + '') + [ "bash" "fish" "zsh" ]; + }; + + testScript = '' + start_all() + machine.wait_for_unit("default.target") + + machine.succeed("expect-bash") + machine.succeed("expect-fish") + machine.succeed("expect-zsh") + ''; +}) diff --git a/nixos/tests/sway.nix b/nixos/tests/sway.nix index 3476ebab3e2..43b8c847304 100644 --- a/nixos/tests/sway.nix +++ b/nixos/tests/sway.nix @@ -1,4 +1,4 @@ -import ./make-test-python.nix ({ pkgs, lib, ...} : +import ./make-test-python.nix ({ pkgs, lib, ... }: { name = "sway"; @@ -13,19 +13,38 @@ import ./make-test-python.nix ({ pkgs, lib, ...} : environment = { # For glinfo and wayland-info: - systemPackages = with pkgs; [ mesa-demos wayland-utils ]; + systemPackages = with pkgs; [ mesa-demos wayland-utils alacritty ]; # Use a fixed SWAYSOCK path (for swaymsg): variables = { "SWAYSOCK" = "/tmp/sway-ipc.sock"; - "WLR_RENDERER_ALLOW_SOFTWARE" = "1"; + # TODO: Investigate if we can get hardware acceleration to work (via + # virtio-gpu and Virgil). We currently have to use the Pixman software + # renderer since the GLES2 renderer doesn't work inside the VM (even + # with WLR_RENDERER_ALLOW_SOFTWARE): + # "WLR_RENDERER_ALLOW_SOFTWARE" = "1"; + "WLR_RENDERER" = "pixman"; }; # For convenience: shellAliases = { - test-x11 = "glinfo | head -n 3 | tee /tmp/test-x11.out && touch /tmp/test-x11-exit-ok"; + test-x11 = "glinfo | tee /tmp/test-x11.out && touch /tmp/test-x11-exit-ok"; test-wayland = "wayland-info | tee /tmp/test-wayland.out && touch /tmp/test-wayland-exit-ok"; }; + + # To help with OCR: + etc."xdg/foot/foot.ini".text = lib.generators.toINI { } { + main = { + font = "inconsolata:size=14"; + }; + colors = rec { + foreground = "000000"; + background = "ffffff"; + regular2 = foreground; + }; + }; }; + fonts.fonts = [ pkgs.inconsolata ]; + # Automatically configure and start Sway when logging in on tty1: programs.bash.loginShellInit = '' if [ "$(tty)" = "/dev/tty1" ]; then @@ -61,7 +80,7 @@ import ./make-test-python.nix ({ pkgs, lib, ...} : machine.wait_for_file("/run/user/1000/wayland-1") machine.wait_for_file("/tmp/sway-ipc.sock") - # Test XWayland: + # Test XWayland (foot does not support X): machine.succeed( "su - alice -c 'swaymsg exec WINIT_UNIX_BACKEND=x11 WAYLAND_DISPLAY=invalid alacritty'" ) @@ -69,21 +88,22 @@ import ./make-test-python.nix ({ pkgs, lib, ...} : machine.send_chars("test-x11\n") machine.wait_for_file("/tmp/test-x11-exit-ok") print(machine.succeed("cat /tmp/test-x11.out")) + machine.copy_from_vm("/tmp/test-x11.out") machine.screenshot("alacritty_glinfo") machine.succeed("pkill alacritty") - # Start a terminal (Alacritty) on workspace 3: + # Start a terminal (foot) on workspace 3: machine.send_key("alt-3") - machine.succeed( - "su - alice -c 'swaymsg exec WINIT_UNIX_BACKEND=wayland DISPLAY=invalid alacritty'" - ) + machine.sleep(3) + machine.send_key("alt-ret") machine.wait_for_text("alice@machine") machine.send_chars("test-wayland\n") machine.wait_for_file("/tmp/test-wayland-exit-ok") print(machine.succeed("cat /tmp/test-wayland.out")) - machine.screenshot("alacritty_wayland_info") + machine.copy_from_vm("/tmp/test-wayland.out") + machine.screenshot("foot_wayland_info") machine.send_key("alt-shift-q") - machine.wait_until_fails("pgrep alacritty") + machine.wait_until_fails("pgrep foot") # Test gpg-agent starting pinentry-gnome3 via D-Bus (tests if # $WAYLAND_DISPLAY is correctly imported into the D-Bus user env): @@ -104,9 +124,6 @@ import ./make-test-python.nix ({ pkgs, lib, ...} : # Exit Sway and verify process exit status 0: machine.succeed("su - alice -c 'swaymsg exit || true'") machine.wait_until_fails("pgrep -x sway") - - # TODO: Sway currently segfaults after "swaymsg exit" but only in this VM test: - # machine # [ 104.090032] sway[921]: segfault at 3f800008 ip 00007f7dbdc25f10 sp 00007ffe282182f8 error 4 in libwayland-server.so.0.1.0[7f7dbdc1f000+8000] - # machine.wait_for_file("/tmp/sway-exit-ok") + machine.wait_for_file("/tmp/sway-exit-ok") ''; }) diff --git a/nixos/tests/switch-test.nix b/nixos/tests/switch-test.nix index daad9134885..1c32bf6beb9 100644 --- a/nixos/tests/switch-test.nix +++ b/nixos/tests/switch-test.nix @@ -45,6 +45,50 @@ import ./make-test-python.nix ({ pkgs, ...} : { systemd.services.test.restartIfChanged = false; }; + restart-and-reload-by-activation-script.configuration = { + systemd.services = rec { + simple-service = { + # No wantedBy so we can check if the activation script restart triggers them + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + ExecStart = "${pkgs.coreutils}/bin/true"; + ExecReload = "${pkgs.coreutils}/bin/true"; + }; + }; + + simple-restart-service = simple-service // { + stopIfChanged = false; + }; + + simple-reload-service = simple-service // { + reloadIfChanged = true; + }; + + no-restart-service = simple-service // { + restartIfChanged = false; + }; + }; + + system.activationScripts.restart-and-reload-test = { + supportsDryActivation = true; + deps = []; + text = '' + if [ "$NIXOS_ACTION" = dry-activate ]; then + f=/run/nixos/dry-activation-restart-list + else + f=/run/nixos/activation-restart-list + fi + cat <<EOF >> "$f" + simple-service.service + simple-restart-service.service + simple-reload-service.service + no-restart-service.service + EOF + ''; + }; + }; + mount.configuration = { systemd.mounts = [ { @@ -261,6 +305,32 @@ import ./make-test-python.nix ({ pkgs, ...} : { assert_lacks(out, "as well:") assert_contains(out, "would start the following units: test.service\n") + with subtest("restart and reload by activation script"): + out = switch_to_specialisation("${machine}", "restart-and-reload-by-activation-script") + assert_contains(out, "stopping the following units: test.service\n") + assert_lacks(out, "NOT restarting the following changed units:") + assert_lacks(out, "reloading the following units:") + assert_lacks(out, "restarting the following units:") + assert_contains(out, "\nstarting the following units: no-restart-service.service, simple-reload-service.service, simple-restart-service.service, simple-service.service\n") + assert_lacks(out, "as well:") + # Switch to the same system where the example services get restarted + # by the activation script + out = switch_to_specialisation("${machine}", "restart-and-reload-by-activation-script") + assert_lacks(out, "stopping the following units:") + assert_lacks(out, "NOT restarting the following changed units:") + assert_contains(out, "reloading the following units: simple-reload-service.service\n") + assert_contains(out, "restarting the following units: simple-restart-service.service, simple-service.service\n") + assert_lacks(out, "\nstarting the following units:") + assert_lacks(out, "as well:") + # The same, but in dry mode + out = switch_to_specialisation("${machine}", "restart-and-reload-by-activation-script", action="dry-activate") + assert_lacks(out, "would stop the following units:") + assert_lacks(out, "would NOT stop the following changed units:") + assert_contains(out, "would reload the following units: simple-reload-service.service\n") + assert_contains(out, "would restart the following units: simple-restart-service.service, simple-service.service\n") + assert_lacks(out, "\nwould start the following units:") + assert_lacks(out, "as well:") + with subtest("mounts"): switch_to_specialisation("${machine}", "mount") out = machine.succeed("mount | grep 'on /testmount'") diff --git a/nixos/tests/systemd-boot.nix b/nixos/tests/systemd-boot.nix index c3899b58d6b..51cfd82e6c4 100644 --- a/nixos/tests/systemd-boot.nix +++ b/nixos/tests/systemd-boot.nix @@ -110,4 +110,145 @@ in assert "updating systemd-boot from (000.0-1-notnixos) to " in output ''; }; + + memtest86 = makeTest { + name = "systemd-boot-memtest86"; + meta.maintainers = with pkgs.lib.maintainers; [ Enzime ]; + + machine = { pkgs, lib, ... }: { + imports = [ common ]; + boot.loader.systemd-boot.memtest86.enable = true; + nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [ + "memtest86-efi" + ]; + }; + + testScript = '' + machine.succeed("test -e /boot/loader/entries/memtest86.conf") + machine.succeed("test -e /boot/efi/memtest86/BOOTX64.efi") + ''; + }; + + netbootxyz = makeTest { + name = "systemd-boot-netbootxyz"; + meta.maintainers = with pkgs.lib.maintainers; [ Enzime ]; + + machine = { pkgs, lib, ... }: { + imports = [ common ]; + boot.loader.systemd-boot.netbootxyz.enable = true; + }; + + testScript = '' + machine.succeed("test -e /boot/loader/entries/o_netbootxyz.conf") + machine.succeed("test -e /boot/efi/netbootxyz/netboot.xyz.efi") + ''; + }; + + entryFilename = makeTest { + name = "systemd-boot-entry-filename"; + meta.maintainers = with pkgs.lib.maintainers; [ Enzime ]; + + machine = { pkgs, lib, ... }: { + imports = [ common ]; + boot.loader.systemd-boot.memtest86.enable = true; + boot.loader.systemd-boot.memtest86.entryFilename = "apple.conf"; + nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [ + "memtest86-efi" + ]; + }; + + testScript = '' + machine.fail("test -e /boot/loader/entries/memtest86.conf") + machine.succeed("test -e /boot/loader/entries/apple.conf") + machine.succeed("test -e /boot/efi/memtest86/BOOTX64.efi") + ''; + }; + + extraEntries = makeTest { + name = "systemd-boot-extra-entries"; + meta.maintainers = with pkgs.lib.maintainers; [ Enzime ]; + + machine = { pkgs, lib, ... }: { + imports = [ common ]; + boot.loader.systemd-boot.extraEntries = { + "banana.conf" = '' + title banana + ''; + }; + }; + + testScript = '' + machine.succeed("test -e /boot/loader/entries/banana.conf") + machine.succeed("test -e /boot/efi/nixos/.extra-files/loader/entries/banana.conf") + ''; + }; + + extraFiles = makeTest { + name = "systemd-boot-extra-files"; + meta.maintainers = with pkgs.lib.maintainers; [ Enzime ]; + + machine = { pkgs, lib, ... }: { + imports = [ common ]; + boot.loader.systemd-boot.extraFiles = { + "efi/fruits/tomato.efi" = pkgs.netbootxyz-efi; + }; + }; + + testScript = '' + machine.succeed("test -e /boot/efi/fruits/tomato.efi") + machine.succeed("test -e /boot/efi/nixos/.extra-files/efi/fruits/tomato.efi") + ''; + }; + + switch-test = makeTest { + name = "systemd-boot-switch-test"; + meta.maintainers = with pkgs.lib.maintainers; [ Enzime ]; + + nodes = { + inherit common; + + machine = { pkgs, ... }: { + imports = [ common ]; + boot.loader.systemd-boot.extraFiles = { + "efi/fruits/tomato.efi" = pkgs.netbootxyz-efi; + }; + }; + + with_netbootxyz = { pkgs, ... }: { + imports = [ common ]; + boot.loader.systemd-boot.netbootxyz.enable = true; + }; + }; + + testScript = { nodes, ... }: let + originalSystem = nodes.machine.config.system.build.toplevel; + baseSystem = nodes.common.config.system.build.toplevel; + finalSystem = nodes.with_netbootxyz.config.system.build.toplevel; + in '' + machine.succeed("test -e /boot/efi/fruits/tomato.efi") + machine.succeed("test -e /boot/efi/nixos/.extra-files/efi/fruits/tomato.efi") + + with subtest("remove files when no longer needed"): + machine.succeed("${baseSystem}/bin/switch-to-configuration boot") + machine.fail("test -e /boot/efi/fruits/tomato.efi") + machine.fail("test -d /boot/efi/fruits") + machine.succeed("test -d /boot/efi/nixos/.extra-files") + machine.fail("test -e /boot/efi/nixos/.extra-files/efi/fruits/tomato.efi") + machine.fail("test -d /boot/efi/nixos/.extra-files/efi/fruits") + + with subtest("files are added back when needed again"): + machine.succeed("${originalSystem}/bin/switch-to-configuration boot") + machine.succeed("test -e /boot/efi/fruits/tomato.efi") + machine.succeed("test -e /boot/efi/nixos/.extra-files/efi/fruits/tomato.efi") + + with subtest("simultaneously removing and adding files works"): + machine.succeed("${finalSystem}/bin/switch-to-configuration boot") + machine.fail("test -e /boot/efi/fruits/tomato.efi") + machine.fail("test -e /boot/efi/nixos/.extra-files/efi/fruits/tomato.efi") + machine.succeed("test -e /boot/loader/entries/o_netbootxyz.conf") + machine.succeed("test -e /boot/efi/netbootxyz/netboot.xyz.efi") + machine.succeed("test -e /boot/efi/nixos/.extra-files/loader/entries/o_netbootxyz.conf") + machine.succeed("test -e /boot/efi/nixos/.extra-files/efi/netbootxyz/netboot.xyz.efi") + ''; + }; } diff --git a/nixos/tests/systemd-networkd-vrf.nix b/nixos/tests/systemd-networkd-vrf.nix index 9f09d801f77..8a1580fc2ad 100644 --- a/nixos/tests/systemd-networkd-vrf.nix +++ b/nixos/tests/systemd-networkd-vrf.nix @@ -161,6 +161,7 @@ in { # 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.2.3 dev vrf2 proto static metric 100 @@ -177,6 +178,7 @@ in { local 192.168.2.1 dev eth2 proto kernel scope host src 192.168.2.1 broadcast 192.168.2.255 dev eth2 proto kernel scope link src 192.168.2.1 """.strip() + # editorconfig-checker-enable # Check that networkd properly configures the main routing table # and the routing tables for the VRF. diff --git a/nixos/tests/teleport.nix b/nixos/tests/teleport.nix new file mode 100644 index 00000000000..15b16e44409 --- /dev/null +++ b/nixos/tests/teleport.nix @@ -0,0 +1,99 @@ +{ system ? builtins.currentSystem +, config ? { } +, pkgs ? import ../.. { inherit system config; } +}: + +with import ../lib/testing-python.nix { inherit system pkgs; }; + +let + minimal = { config, ... }: { + services.teleport.enable = true; + }; + + client = { config, ... }: { + services.teleport = { + enable = true; + settings = { + teleport = { + nodename = "client"; + advertise_ip = "192.168.1.20"; + auth_token = "8d1957b2-2ded-40e6-8297-d48156a898a9"; + auth_servers = [ "192.168.1.10:3025" ]; + log.severity = "DEBUG"; + }; + ssh_service = { + enabled = true; + labels = { + role = "client"; + }; + }; + proxy_service.enabled = false; + auth_service.enabled = false; + }; + }; + networking.interfaces.eth1.ipv4.addresses = [{ + address = "192.168.1.20"; + prefixLength = 24; + }]; + }; + + server = { config, ... }: { + services.teleport = { + enable = true; + settings = { + teleport = { + nodename = "server"; + advertise_ip = "192.168.1.10"; + }; + ssh_service.enabled = true; + proxy_service.enabled = true; + auth_service = { + enabled = true; + tokens = [ "node:8d1957b2-2ded-40e6-8297-d48156a898a9" ]; + }; + }; + diag.enable = true; + insecure.enable = true; + }; + networking = { + firewall.allowedTCPPorts = [ 3025 ]; + interfaces.eth1.ipv4.addresses = [{ + address = "192.168.1.10"; + prefixLength = 24; + }]; + }; + }; +in +{ + minimal = makeTest { + # minimal setup should always work + name = "teleport-minimal-setup"; + meta.maintainers = with pkgs.lib.maintainers; [ ymatsiuk ]; + nodes = { inherit minimal; }; + + testScript = '' + minimal.wait_for_open_port("3025") + minimal.wait_for_open_port("3080") + minimal.wait_for_open_port("3022") + ''; + }; + + basic = makeTest { + # basic server and client test + name = "teleport-server-client"; + meta.maintainers = with pkgs.lib.maintainers; [ ymatsiuk ]; + nodes = { inherit server client; }; + + testScript = '' + with subtest("teleport ready"): + 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") + client.succeed("journalctl -u teleport.service --grep='DEBU'") + server.succeed("journalctl -u teleport.service --grep='Starting teleport in insecure mode.'") + ''; + }; +} diff --git a/nixos/tests/thelounge.nix b/nixos/tests/thelounge.nix new file mode 100644 index 00000000000..e9b85685bf2 --- /dev/null +++ b/nixos/tests/thelounge.nix @@ -0,0 +1,29 @@ +import ./make-test-python.nix { + nodes = { + private = { config, pkgs, ... }: { + services.thelounge = { + enable = true; + plugins = [ pkgs.theLoungePlugins.themes.solarized ]; + }; + }; + + public = { config, pkgs, ... }: { + services.thelounge = { + enable = true; + public = true; + }; + }; + }; + + testScript = '' + start_all() + + for machine in machines: + machine.wait_for_unit("thelounge.service") + machine.wait_for_open_port(9000) + + private.wait_until_succeeds("journalctl -u thelounge.service | grep thelounge-theme-solarized") + private.wait_until_succeeds("journalctl -u thelounge.service | grep 'in private mode'") + public.wait_until_succeeds("journalctl -u thelounge.service | grep 'in public mode'") + ''; +} diff --git a/nixos/tests/tinywl.nix b/nixos/tests/tinywl.nix new file mode 100644 index 00000000000..b286cab7794 --- /dev/null +++ b/nixos/tests/tinywl.nix @@ -0,0 +1,56 @@ +import ./make-test-python.nix ({ pkgs, lib, ... }: + + { + name = "tinywl"; + meta = { + maintainers = with lib.maintainers; [ primeos ]; + }; + + machine = { config, ... }: { + # Automatically login on tty1 as a normal user: + imports = [ ./common/user-account.nix ]; + services.getty.autologinUser = "alice"; + + environment = { + systemPackages = with pkgs; [ tinywl foot wayland-utils ]; + }; + + # Automatically start TinyWL when logging in on tty1: + programs.bash.loginShellInit = '' + if [ "$(tty)" = "/dev/tty1" ]; then + set -e + test ! -e /tmp/tinywl.log # Only start tinywl once + readonly TEST_CMD="wayland-info |& tee /tmp/test-wayland.out && touch /tmp/test-wayland-exit-ok; read" + readonly FOOT_CMD="foot sh -c '$TEST_CMD'" + tinywl -s "$FOOT_CMD" |& tee /tmp/tinywl.log + touch /tmp/tinywl-exit-ok + fi + ''; + + # Switch to a different GPU driver (default: -vga std), otherwise TinyWL segfaults: + virtualisation.qemu.options = [ "-vga none -device virtio-gpu-pci" ]; + }; + + testScript = { nodes, ... }: '' + start_all() + machine.wait_for_unit("multi-user.target") + + # Wait for complete startup: + machine.wait_until_succeeds("pgrep tinywl") + machine.wait_for_file("/run/user/1000/wayland-0") + machine.wait_until_succeeds("pgrep foot") + machine.wait_for_file("/tmp/test-wayland-exit-ok") + + # Make a screenshot and save the result: + machine.screenshot("tinywl_foot") + print(machine.succeed("cat /tmp/test-wayland.out")) + machine.copy_from_vm("/tmp/test-wayland.out") + + # Terminate cleanly: + machine.send_key("alt-esc") + machine.wait_until_fails("pgrep foot") + machine.wait_until_fails("pgrep tinywl") + machine.wait_for_file("/tmp/tinywl-exit-ok") + machine.copy_from_vm("/tmp/tinywl.log") + ''; + }) diff --git a/nixos/tests/tsm-client-gui.nix b/nixos/tests/tsm-client-gui.nix new file mode 100644 index 00000000000..e4bcd344a89 --- /dev/null +++ b/nixos/tests/tsm-client-gui.nix @@ -0,0 +1,57 @@ +# The tsm-client GUI first tries to connect to a server. +# We can't simulate a server, so we just check if +# it reports the correct connection failure error. +# After that the test persuades the GUI +# to show its main application window +# and verifies some configuration information. + +import ./make-test-python.nix ({ lib, pkgs, ... }: { + name = "tsm-client"; + + enableOCR = true; + + machine = { pkgs, ... }: { + imports = [ ./common/x11.nix ]; + programs.tsmClient = { + enable = true; + package = pkgs.tsm-client-withGui; + defaultServername = "testserver"; + servers.testserver = { + # 192.0.0.8 is a "dummy address" according to RFC 7600 + server = "192.0.0.8"; + node = "SOME-NODE"; + passwdDir = "/tmp"; + }; + }; + }; + + testScript = '' + machine.succeed("which dsmj") # fail early if this is missing + machine.wait_for_x() + machine.execute("DSM_LOG=/tmp dsmj -optfile=/dev/null >&2 &") + + # does it report the "TCP/IP connection failure" error code? + machine.wait_for_window("IBM Spectrum Protect") + machine.wait_for_text("ANS2610S") + machine.send_key("esc") + + # it asks to continue to restore a local backupset now; + # "yes" (return) leads to the main application window + machine.wait_for_text("backupset") + machine.send_key("ret") + + # main window: navigate to "Connection Information" + machine.wait_for_text("Welcome") + machine.send_key("alt-f") # "File" menu + machine.send_key("c") # "Connection Information" + + # "Connection Information" dialog box + machine.wait_for_window("Connection Information") + machine.wait_for_text("SOME-NODE") + machine.wait_for_text("${pkgs.tsm-client.passthru.unwrapped.version}") + + machine.shutdown() + ''; + + meta.maintainers = [ lib.maintainers.yarny ]; +}) diff --git a/nixos/tests/vscodium.nix b/nixos/tests/vscodium.nix index 43a0d61c856..66baea73ec6 100644 --- a/nixos/tests/vscodium.nix +++ b/nixos/tests/vscodium.nix @@ -34,36 +34,46 @@ let }; enableOCR = true; testScript = '' + @polling_condition + def codium_running(): + machine.succeed('pgrep -x codium') + + start_all() machine.wait_for_unit('graphical.target') machine.wait_until_succeeds('pgrep -x codium') - # Wait until vscodium is visible. "File" is in the menu bar. - machine.wait_for_text('File') - machine.screenshot('start_screen') + with codium_running: + # Wait until vscodium is visible. "File" is in the menu bar. + machine.wait_for_text('Get Started') + machine.screenshot('start_screen') + + test_string = 'testfile' - test_string = 'testfile' + # Create a new file + machine.send_key('ctrl-n') + machine.wait_for_text('Untitled') + machine.screenshot('empty_editor') - # Create a new file - machine.send_key('ctrl-n') - machine.wait_for_text('Untitled') - machine.screenshot('empty_editor') + # Type a string + machine.send_chars(test_string) + machine.wait_for_text(test_string) + machine.screenshot('editor') - # Type a string - machine.send_chars(test_string) - machine.wait_for_text(test_string) - machine.screenshot('editor') + # Save the file + machine.send_key('ctrl-s') + machine.wait_for_text('Save') + machine.screenshot('save_window') + machine.send_key('ret') - # Save the file - machine.send_key('ctrl-s') - machine.wait_for_text('Save') - machine.screenshot('save_window') - machine.send_key('ret') + # (the default filename is the first line of the file) + machine.wait_for_file(f'/home/alice/{test_string}') - # (the default filename is the first line of the file) - machine.wait_for_file(f'/home/alice/{test_string}') + machine.send_key('ctrl-q') + machine.wait_until_fails('pgrep -x codium') ''; }); -in builtins.mapAttrs (k: v: mkTest k v { }) tests +in +builtins.mapAttrs (k: v: mkTest k v { }) tests diff --git a/nixos/tests/wordpress.nix b/nixos/tests/wordpress.nix index f7f39668c86..416a20aa7fe 100644 --- a/nixos/tests/wordpress.nix +++ b/nixos/tests/wordpress.nix @@ -15,15 +15,12 @@ import ./make-test-python.nix ({ pkgs, ... }: services.httpd.adminAddr = "webmaster@site.local"; services.httpd.logPerVirtualHost = true; - services.wordpress = { - # Test support for old interface + services.wordpress.sites = { "site1.local" = { database.tablePrefix = "site1_"; }; - sites = { - "site2.local" = { - database.tablePrefix = "site2_"; - }; + "site2.local" = { + database.tablePrefix = "site2_"; }; }; diff --git a/nixos/tests/xmonad.nix b/nixos/tests/xmonad.nix index 078cd211810..a2fb38e53bd 100644 --- a/nixos/tests/xmonad.nix +++ b/nixos/tests/xmonad.nix @@ -1,7 +1,58 @@ -import ./make-test-python.nix ({ pkgs, ...} : { +import ./make-test-python.nix ({ pkgs, ...}: + +let + mkConfig = name: keys: '' + import XMonad + import XMonad.Operations (restart) + import XMonad.Util.EZConfig + import XMonad.Util.SessionStart + import Control.Monad (when) + import Text.Printf (printf) + import System.Posix.Process (executeFile) + import System.Info (arch,os) + import System.Environment (getArgs) + import System.FilePath ((</>)) + + main = launch $ def { startupHook = startup } `additionalKeysP` myKeys + + startup = isSessionStart >>= \sessInit -> + spawn "touch /tmp/${name}" + >> if sessInit then setSessionStarted else spawn "xterm" + + myKeys = [${builtins.concatStringsSep ", " keys}] + + compiledConfig = printf "xmonad-%s-%s" arch os + + compileRestart resume = + whenX (recompile True) $ + when resume writeStateToFile + *> catchIO + ( do + dir <- getXMonadDataDir + args <- getArgs + executeFile (dir </> compiledConfig) False args Nothing + ) + ''; + + oldKeys = + [ ''("M-C-x", spawn "xterm")'' + ''("M-q", restart "xmonad" True)'' + ''("M-C-q", compileRestart True)'' + ''("M-C-t", spawn "touch /tmp/somefile")'' # create somefile + ]; + + newKeys = + [ ''("M-C-x", spawn "xterm")'' + ''("M-q", restart "xmonad" True)'' + ''("M-C-q", compileRestart True)'' + ''("M-C-r", spawn "rm /tmp/somefile")'' # delete somefile + ]; + + newConfig = pkgs.writeText "xmonad.hs" (mkConfig "newXMonad" newKeys); +in { name = "xmonad"; meta = with pkgs.lib.maintainers; { - maintainers = [ nequissimus ]; + maintainers = [ nequissimus ivanbrennan ]; }; machine = { pkgs, ... }: { @@ -10,21 +61,10 @@ import ./make-test-python.nix ({ pkgs, ...} : { services.xserver.displayManager.defaultSession = "none+xmonad"; services.xserver.windowManager.xmonad = { enable = true; + enableConfiguredRecompile = true; enableContribAndExtras = true; extraPackages = with pkgs.haskellPackages; haskellPackages: [ xmobar ]; - config = '' - import XMonad - import XMonad.Operations (restart) - import XMonad.Util.EZConfig - import XMonad.Util.SessionStart - - main = launch $ def { startupHook = startup } `additionalKeysP` myKeys - - startup = isSessionStart >>= \sessInit -> - if sessInit then setSessionStarted else spawn "xterm" - - myKeys = [ ("M-C-x", spawn "xterm"), ("M-q", restart "xmonad" True) ] - ''; + config = mkConfig "oldXMonad" oldKeys; }; }; @@ -38,10 +78,37 @@ import ./make-test-python.nix ({ pkgs, ...} : { machine.wait_for_window("${user.name}.*machine") machine.sleep(1) machine.screenshot("terminal1") + machine.succeed("rm /tmp/oldXMonad") machine.send_key("alt-q") - machine.sleep(3) + machine.wait_for_file("/tmp/oldXMonad") machine.wait_for_window("${user.name}.*machine") machine.sleep(1) machine.screenshot("terminal2") + + # /tmp/somefile should not exist yet + machine.fail("stat /tmp/somefile") + + # original config has a keybinding that creates somefile + machine.send_key("alt-ctrl-t") + machine.wait_for_file("/tmp/somefile") + + # set up the new config + machine.succeed("mkdir -p ${user.home}/.xmonad") + machine.copy_from_host("${newConfig}", "${user.home}/.xmonad/xmonad.hs") + + # recompile xmonad using the new config + machine.send_key("alt-ctrl-q") + machine.wait_for_file("/tmp/newXMonad") + + # new config has a keybinding that deletes somefile + machine.send_key("alt-ctrl-r") + machine.wait_until_fails("stat /tmp/somefile", timeout=30) + + # restart with the old config, and confirm the old keybinding is back + machine.succeed("rm /tmp/oldXMonad") + machine.send_key("alt-q") + machine.wait_for_file("/tmp/oldXMonad") + machine.send_key("alt-ctrl-t") + machine.wait_for_file("/tmp/somefile") ''; }) diff --git a/nixos/tests/xmpp/prosody-mysql.nix b/nixos/tests/xmpp/prosody-mysql.nix deleted file mode 100644 index 9a00bcabf38..00000000000 --- a/nixos/tests/xmpp/prosody-mysql.nix +++ /dev/null @@ -1,92 +0,0 @@ -import ../make-test-python.nix { - name = "prosody-mysql"; - - nodes = { - client = { nodes, pkgs, ... }: { - environment.systemPackages = [ - (pkgs.callPackage ./xmpp-sendmessage.nix { connectTo = nodes.server.config.networking.primaryIPAddress; }) - ]; - networking.extraHosts = '' - ${nodes.server.config.networking.primaryIPAddress} example.com - ${nodes.server.config.networking.primaryIPAddress} conference.example.com - ${nodes.server.config.networking.primaryIPAddress} uploads.example.com - ''; - }; - server = { config, pkgs, ... }: { - nixpkgs.overlays = [ - (self: super: { - prosody = super.prosody.override { - withDBI = true; - withExtraLibs = [ pkgs.luaPackages.luadbi-mysql ]; - }; - }) - ]; - networking.extraHosts = '' - ${config.networking.primaryIPAddress} example.com - ${config.networking.primaryIPAddress} conference.example.com - ${config.networking.primaryIPAddress} uploads.example.com - ''; - networking.firewall.enable = false; - services.prosody = { - enable = true; - # TODO: use a self-signed certificate - c2sRequireEncryption = false; - extraConfig = '' - storage = "sql" - sql = { - driver = "MySQL"; - database = "prosody"; - host = "mysql"; - port = 3306; - username = "prosody"; - password = "password123"; - }; - ''; - virtualHosts.test = { - domain = "example.com"; - enabled = true; - }; - muc = [ - { - domain = "conference.example.com"; - } - ]; - uploadHttp = { - domain = "uploads.example.com"; - }; - }; - }; - mysql = { config, pkgs, ... }: { - networking.firewall.enable = false; - services.mysql = { - enable = true; - initialScript = pkgs.writeText "mysql_init.sql" '' - CREATE DATABASE prosody; - CREATE USER 'prosody'@'server' IDENTIFIED BY 'password123'; - GRANT ALL PRIVILEGES ON prosody.* TO 'prosody'@'server'; - FLUSH PRIVILEGES; - ''; - package = pkgs.mariadb; - }; - }; - }; - - testScript = { nodes, ... }: '' - mysql.wait_for_unit("mysql.service") - server.wait_for_unit("prosody.service") - server.succeed('prosodyctl status | grep "Prosody is running"') - - # set password to 'nothunter2' (it's asked twice) - server.succeed("yes nothunter2 | prosodyctl adduser cthon98@example.com") - # set password to 'y' - server.succeed("yes | prosodyctl adduser azurediamond@example.com") - # correct password to 'hunter2' - server.succeed("yes hunter2 | prosodyctl passwd azurediamond@example.com") - - client.succeed("send-message") - - server.succeed("prosodyctl deluser cthon98@example.com") - server.succeed("prosodyctl deluser azurediamond@example.com") - ''; -} - |