From 8264bfe3a064d704c57df91e34b795b6ac7bad9e Mon Sep 17 00:00:00 2001 From: VojtechStep Date: Tue, 17 Dec 2024 17:28:24 +0100 Subject: [PATCH] mu: add integration tests --- modules/programs/mu.nix | 5 +- tests/integration/default.nix | 1 + .../mu/config-account-without-mu.nix | 5 + .../standalone/mu/config-no-accounts.nix | 9 ++ .../standalone/mu/config-one-account.nix | 9 ++ .../standalone/mu/config-one-alias.nix | 5 + .../standalone/mu/config-two-accounts.nix | 8 ++ tests/integration/standalone/mu/default.nix | 117 ++++++++++++++++++ 8 files changed, 156 insertions(+), 3 deletions(-) create mode 100644 tests/integration/standalone/mu/config-account-without-mu.nix create mode 100644 tests/integration/standalone/mu/config-no-accounts.nix create mode 100644 tests/integration/standalone/mu/config-one-account.nix create mode 100644 tests/integration/standalone/mu/config-one-alias.nix create mode 100644 tests/integration/standalone/mu/config-two-accounts.nix create mode 100644 tests/integration/standalone/mu/default.nix diff --git a/modules/programs/mu.nix b/modules/programs/mu.nix index 935fd100a..d1543f000 100644 --- a/modules/programs/mu.nix +++ b/modules/programs/mu.nix @@ -55,14 +55,13 @@ in { maildirOption = genCmdMaildir config.accounts.email.maildirBasePath; dbLocation = config.xdg.cacheHome + "/mu"; muExe = getExe cfg.package; + gawkExe = getExe pkgs.gawk; in hm.dag.entryAfter [ "writeBoundary" ] '' # If the database directory exists and registered personal addresses remain the same, # then `mu init` should NOT be run. # In theory, mu is the only thing that creates that directory, and it is # only created during the initial index. - MU_SORTED_ADDRS=$((${muExe} info store | ${ - getExe pkgs.gawk - } '/personal-address/{print $4}' | LC_ALL=C sort | paste -sd ' ') || exit 0) + MU_SORTED_ADDRS=$((${muExe} info store | ${gawkExe} '/personal-address/{print $4}' | LC_ALL=C sort | paste -sd ' ') || exit 0) if [[ ! -d "${dbLocation}" || ! "$MU_SORTED_ADDRS" = "${ concatStringsSep " " sortedAddresses }" ]]; then diff --git a/tests/integration/default.nix b/tests/integration/default.nix index 1ddd8bd4d..697a28432 100644 --- a/tests/integration/default.nix +++ b/tests/integration/default.nix @@ -12,6 +12,7 @@ let tests = { home-with-symbols = runTest ./standalone/home-with-symbols.nix; kitty = runTest ./standalone/kitty.nix; + mu = runTest ./standalone/mu; nixos-basics = runTest ./nixos/basics.nix; standalone-flake-basics = runTest ./standalone/flake-basics.nix; standalone-standard-basics = runTest ./standalone/standard-basics.nix; diff --git a/tests/integration/standalone/mu/config-account-without-mu.nix b/tests/integration/standalone/mu/config-account-without-mu.nix new file mode 100644 index 000000000..024bd7b99 --- /dev/null +++ b/tests/integration/standalone/mu/config-account-without-mu.nix @@ -0,0 +1,5 @@ +{ lib, ... }: { + imports = [ ./config-two-accounts.nix ]; + + accounts.email.accounts.example2.mu.enable = lib.mkForce false; +} diff --git a/tests/integration/standalone/mu/config-no-accounts.nix b/tests/integration/standalone/mu/config-no-accounts.nix new file mode 100644 index 000000000..7f7b092eb --- /dev/null +++ b/tests/integration/standalone/mu/config-no-accounts.nix @@ -0,0 +1,9 @@ +{ + home.username = "alice"; + home.homeDirectory = "/home/alice"; + home.stateVersion = "24.11"; + + programs.mu.enable = true; + + programs.home-manager.enable = true; +} diff --git a/tests/integration/standalone/mu/config-one-account.nix b/tests/integration/standalone/mu/config-one-account.nix new file mode 100644 index 000000000..bd8f95025 --- /dev/null +++ b/tests/integration/standalone/mu/config-one-account.nix @@ -0,0 +1,9 @@ +{ + imports = [ ./config-no-accounts.nix ]; + + accounts.email.accounts.example = { + primary = true; + address = "alice@example.com"; + mu.enable = true; + }; +} diff --git a/tests/integration/standalone/mu/config-one-alias.nix b/tests/integration/standalone/mu/config-one-alias.nix new file mode 100644 index 000000000..7c46268d9 --- /dev/null +++ b/tests/integration/standalone/mu/config-one-alias.nix @@ -0,0 +1,5 @@ +{ + imports = [ ./config-one-account.nix ]; + + accounts.email.accounts.example.aliases = [ "alias@example.com" ]; +} diff --git a/tests/integration/standalone/mu/config-two-accounts.nix b/tests/integration/standalone/mu/config-two-accounts.nix new file mode 100644 index 000000000..b4491fc08 --- /dev/null +++ b/tests/integration/standalone/mu/config-two-accounts.nix @@ -0,0 +1,8 @@ +{ + imports = [ ./config-one-account.nix ]; + + accounts.email.accounts.example2 = { + address = "alice@example2.com"; + mu.enable = true; + }; +} diff --git a/tests/integration/standalone/mu/default.nix b/tests/integration/standalone/mu/default.nix new file mode 100644 index 000000000..1a375d0eb --- /dev/null +++ b/tests/integration/standalone/mu/default.nix @@ -0,0 +1,117 @@ +{ pkgs, ... }: { + name = "mu-store-init"; + + nodes.machine = { ... }: { + imports = [ "${pkgs.path}/nixos/modules/installer/cd-dvd/channel.nix" ]; + virtualisation.memorySize = 2048; + users.users.alice = { + isNormalUser = true; + description = "Alice Foobar"; + password = "foobar"; + uid = 1000; + }; + }; + + testScript = '' + start_all() + machine.wait_for_unit("network.target") + machine.wait_for_unit("multi-user.target") + + home_manager = "${../../../..}" + home_config = "/home/alice/.config/home-manager" + + def login_as_alice(): + machine.wait_until_tty_matches("1", "login: ") + machine.send_chars("alice\n") + machine.wait_until_tty_matches("1", "Password: ") + machine.send_chars("foobar\n") + machine.wait_until_tty_matches("1", "alice\\@machine") + + def logout_alice(): + machine.send_chars("exit\n") + + def alice_cmd(cmd): + return f"su -l alice --shell /bin/sh -c $'export XDG_RUNTIME_DIR=/run/user/$UID ; {cmd}'" + + def succeed_as_alice(cmd): + return machine.succeed(alice_cmd(cmd)) + + def fail_as_alice(cmd): + return machine.fail(alice_cmd(cmd)) + + def switch_to(config): + succeed_as_alice(f"cp {home_config}/{config}.nix {home_config}/home.nix") + return succeed_as_alice("home-manager switch") + # succeed_as_alice(". /home/alice/.nix-profile/etc/profile.d/hm-session-vars.sh") + + # Create a persistent login so that Alice has a systemd session. + login_as_alice() + + # Set up a home-manager channel. + succeed_as_alice(" ; ".join([ + "mkdir -p /home/alice/.nix-defexpr/channels", + f"ln -s {home_manager} /home/alice/.nix-defexpr/channels/home-manager" + ])) + + succeed_as_alice("nix-shell \"\" -A install") + + succeed_as_alice(f"cp -t {home_config} ${./.}/config-*") + + with subtest("Switch to empty profile"): + switch_to("config-no-accounts") + actual = succeed_as_alice("mu info store") + expected = "/home/alice/Maildir" + assert expected in actual, \ + f"expected mu info store to contain {expected}, but got {actual}" + unexpected = "personal-address" + assert not unexpected in actual, \ + f"expected mu info store not to contain {unexpected}, but got {actual}" + + with subtest("Switch to profile with an account"): + switch_to("config-one-account") + actual = succeed_as_alice("mu info store") + expected = "alice@example.com" + assert expected in actual, \ + f"expected mu info store to contain {expected}, but got {actual}" + + with subtest("Switch to profile with two accounts"): + switch_to("config-two-accounts") + actual = succeed_as_alice("mu info store") + expected = "alice@example.com" + assert expected in actual, \ + f"expected mu info store to contain {expected}, but got {actual}" + expected = "alice@example2.com" + assert expected in actual, \ + f"expected mu info store to contain {expected}, but got {actual}" + + with subtest("Switch back to profile with one account"): + switch_to("config-one-account") + actual = succeed_as_alice("mu info store") + expected = "alice@example.com" + assert expected in actual, \ + f"expected mu info store to contain {expected}, but got {actual}" + unexpected = "alice@example2.com" + assert not unexpected in actual, \ + f"expected mu info store not to contain {unexpected}, but got {actual}" + + with subtest("Switch to profile with an alias"): + switch_to("config-one-alias") + actual = succeed_as_alice("mu info store") + expected = "alice@example.com" + assert expected in actual, \ + f"expected mu info store to contain {expected}, but got {actual}" + expected = "alias@example.com" + assert expected in actual, \ + f"expected mu info store to contain {expected}, but got {actual}" + + with subtest("Switch to a profile with mu disabled for one account"): + switch_to("config-account-without-mu") + actual = succeed_as_alice("mu info store") + expected = "alice@example.com" + assert expected in actual, \ + f"expected mu info store to contain {expected}, but got {actual}" + unexpected = "alice@example2.com" + assert not unexpected in actual, \ + f"expected mu info store not to contain {unexpected}, but got {actual}" + ''; +}