aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenedikt Peetz <benedikt.peetz@b-peetz.de>2025-02-09 16:25:52 +0100
committerBenedikt Peetz <benedikt.peetz@b-peetz.de>2025-03-09 13:44:15 +0100
commit158d97b9dd08a0e378152224681294916c825fef (patch)
tree47359adb98ccd903b1fa8b45a57f2af5ac9948db
parentmodule/stalwart-mail: Init initial version (diff)
downloadnixos-server-158d97b9dd08a0e378152224681294916c825fef.zip
tests/email: Test the mvp
-rw-r--r--tests/by-name/em/email/test.nix173
1 files changed, 173 insertions, 0 deletions
diff --git a/tests/by-name/em/email/test.nix b/tests/by-name/em/email/test.nix
new file mode 100644
index 0000000..590136e
--- /dev/null
+++ b/tests/by-name/em/email/test.nix
@@ -0,0 +1,173 @@
+{
+ nixos-lib,
+ pkgsUnstable,
+ nixpkgs-unstable,
+ vhackPackages,
+ pkgs,
+ extraModules,
+ nixLib,
+ ...
+}: let
+ domain = "mail.server.test";
+
+ scripts = {
+ checkEmailEmpty = pkgs.writeShellScript "assert-empty-emails" ''
+ set -xe
+
+ # fetchmail returns EXIT_CODE 1 when no new mail
+ fetchmail --nosslcertck --verbose >&2 || [ "$?" -eq 1 ] || {
+ echo "Expected exit code 1, but got '$exit_code'"
+ exit 1
+ }
+ '';
+ };
+
+ mkUser = user: {nodes, ...}: let
+ domainIp = nodes.server.networking.primaryIPAddress;
+ in {
+ environment.systemPackages = with pkgs; [
+ fetchmail
+ msmtp
+ procmail
+ ];
+
+ users.users."${user}" = {isNormalUser = true;};
+
+ systemd.tmpfiles.rules = [
+ "d /home/${user}/mail 0700 ${user} users - -"
+ "L /home/${user}/.fetchmailrc - - - - /etc/homeSetup/.fetchmailrc"
+ "L /home/${user}/.procmailrc - - - - /etc/homeSetup/.procmailrc"
+ "L /home/${user}/.msmtprc - - - - /etc/homeSetup/.msmtprc"
+ ];
+
+ environment.etc = {
+ "homeSetup/.fetchmailrc" = {
+ text = ''
+ poll "${domainIp}" protocol IMAP
+ username "${user}"
+ password "${user}-password"
+ ssl
+ mda procmail;
+ '';
+ mode = "0600";
+ inherit user;
+ };
+ "homeSetup/.procmailrc" = {
+ text = ''
+ DEFAULT=$HOME/mail
+ '';
+ mode = "0600";
+ inherit user;
+ };
+ "homeSetup/.msmtprc" = {
+ text = ''
+ account ${user}
+ host ${domainIp}
+ port 465
+ from ${user}@${domain}
+ user ${user}
+ password ${user}-password
+ auth on
+ tls on
+ tls_starttls off
+ '';
+ mode = "0600";
+ inherit user;
+ };
+ };
+ };
+in
+ nixos-lib.runTest {
+ hostPkgs = pkgs; # the Nixpkgs package set used outside the VMs
+
+ name = "email";
+
+ node = {
+ specialArgs = {inherit pkgsUnstable vhackPackages nixpkgs-unstable nixLib;};
+
+ # Use the nixpkgs as constructed by the `nixpkgs.*` options
+ pkgs = null;
+ };
+
+ nodes = {
+ server = {config, ...}: {
+ imports =
+ extraModules
+ ++ [
+ ../../../../modules
+ ];
+
+ vhack = {
+ nginx = {
+ enable = true;
+ selfsign = true;
+ };
+
+ stalwart-mail = {
+ enable = true;
+ fqdn = domain;
+ security = null;
+ openFirewall = true;
+ principals = [
+ {
+ class = "individual";
+ name = "alice";
+ secret = "alice-password";
+ email = ["alice@${domain}"];
+ }
+ {
+ class = "individual";
+ name = "bob";
+ secret = "bob-password";
+ email = ["bob@${domain}"];
+ }
+ ];
+ };
+ };
+ };
+
+ alice = mkUser "alice";
+ bob = mkUser "bob";
+ };
+
+ testScript = {...}:
+ /*
+ python
+ */
+ ''
+ start_all()
+
+ server.wait_for_unit("stalwart-mail.service")
+ server.wait_for_open_port(993) # imap
+ server.wait_for_open_port(465) # smtp
+
+ with subtest("Both start without mail"):
+ alice.succeed("sudo -u alice ${scripts.checkEmailEmpty}")
+ bob.succeed("sudo -u bob ${scripts.checkEmailEmpty}")
+
+ with subtest("Alice can send an email to bob"):
+ alice.succeed("sudo -u alice ${pkgs.writeShellScript "alice-send" ''
+ set -xe
+
+ cat << EOF | msmtp --debug --account alice --tls-certcheck=off bob@${domain} >&2
+ Hi Bob!
+
+ This is an email.
+ It contains a subject and a body.
+
+ ALICE
+ EOF
+ ''}")
+ bob.succeed("sudo -u bob ${pkgs.writeShellScript "bob-receive" ''
+ set -xe
+
+ fetchmail --nosslcertck --verbose >&2 || {
+ echo New Mail did not arrive
+ exit 1
+ }
+ ''}")
+
+ server.copy_from_vm("/var/lib/", "server")
+ bob.copy_from_vm("/home/bob/mail", "bob")
+ '';
+ }