Merge pull request #42326 from Ekleog/opensmtpd-test

opensmtpd package and module: add nixos test

authored by Matthew Bauer and committed by GitHub ba0cd50e ef7a63e2

+116
+1
nixos/release.nix
··· 364 tests.nsd = callTest tests/nsd.nix {}; 365 tests.openssh = callTest tests/openssh.nix {}; 366 tests.openldap = callTest tests/openldap.nix {}; 367 tests.owncloud = callTest tests/owncloud.nix {}; 368 tests.pam-oath-login = callTest tests/pam-oath-login.nix {}; 369 tests.peerflix = callTest tests/peerflix.nix {};
··· 364 tests.nsd = callTest tests/nsd.nix {}; 365 tests.openssh = callTest tests/openssh.nix {}; 366 tests.openldap = callTest tests/openldap.nix {}; 367 + tests.opensmtpd = callTest tests/opensmtpd.nix {}; 368 tests.owncloud = callTest tests/owncloud.nix {}; 369 tests.pam-oath-login = callTest tests/pam-oath-login.nix {}; 370 tests.peerflix = callTest tests/peerflix.nix {};
+115
nixos/tests/opensmtpd.nix
···
··· 1 + import ./make-test.nix { 2 + name = "opensmtpd"; 3 + 4 + nodes = { 5 + smtp1 = { pkgs, ... }: { 6 + imports = [ common/user-account.nix ]; 7 + networking = { 8 + firewall.allowedTCPPorts = [ 25 ]; 9 + useDHCP = false; 10 + interfaces.eth1.ipv4.addresses = pkgs.lib.mkOverride 0 [ 11 + { address = "192.168.1.1"; prefixLength = 24; } 12 + ]; 13 + }; 14 + environment.systemPackages = [ pkgs.opensmtpd ]; 15 + services.opensmtpd = { 16 + enable = true; 17 + extraServerArgs = [ "-v" ]; 18 + serverConfiguration = '' 19 + listen on 0.0.0.0 20 + # DO NOT DO THIS IN PRODUCTION! 21 + # Setting up authentication requires a certificate which is painful in 22 + # a test environment, but THIS WOULD BE DANGEROUS OUTSIDE OF A 23 + # WELL-CONTROLLED ENVIRONMENT! 24 + accept from any for any relay 25 + ''; 26 + }; 27 + }; 28 + 29 + smtp2 = { pkgs, ... }: { 30 + imports = [ common/user-account.nix ]; 31 + networking = { 32 + firewall.allowedTCPPorts = [ 25 143 ]; 33 + useDHCP = false; 34 + interfaces.eth1.ipv4.addresses = pkgs.lib.mkOverride 0 [ 35 + { address = "192.168.1.2"; prefixLength = 24; } 36 + ]; 37 + }; 38 + environment.systemPackages = [ pkgs.opensmtpd ]; 39 + services.opensmtpd = { 40 + enable = true; 41 + extraServerArgs = [ "-v" ]; 42 + serverConfiguration = '' 43 + listen on 0.0.0.0 44 + accept from any for local deliver to mda \ 45 + "${pkgs.dovecot}/libexec/dovecot/deliver -d %{user.username}" 46 + ''; 47 + }; 48 + services.dovecot2 = { 49 + enable = true; 50 + enableImap = true; 51 + mailLocation = "maildir:~/mail"; 52 + protocols = [ "imap" ]; 53 + }; 54 + }; 55 + 56 + client = { pkgs, ... }: { 57 + networking = { 58 + useDHCP = false; 59 + interfaces.eth1.ipv4.addresses = pkgs.lib.mkOverride 0 [ 60 + { address = "192.168.1.3"; prefixLength = 24; } 61 + ]; 62 + }; 63 + environment.systemPackages = let 64 + sendTestMail = pkgs.writeScriptBin "send-a-test-mail" '' 65 + #!${pkgs.python3.interpreter} 66 + import smtplib, sys 67 + 68 + with smtplib.SMTP('192.168.1.1') as smtp: 69 + smtp.sendmail('alice@[192.168.1.1]', 'bob@[192.168.1.2]', """ 70 + From: alice@smtp1 71 + To: bob@smtp2 72 + Subject: Test 73 + 74 + Hello World 75 + """) 76 + ''; 77 + 78 + checkMailLanded = pkgs.writeScriptBin "check-mail-landed" '' 79 + #!${pkgs.python3.interpreter} 80 + import imaplib 81 + 82 + with imaplib.IMAP4('192.168.1.2', 143) as imap: 83 + imap.login('bob', 'foobar') 84 + imap.select() 85 + status, refs = imap.search(None, 'ALL') 86 + assert status == 'OK' 87 + assert len(refs) == 1 88 + status, msg = imap.fetch(refs[0], 'BODY[TEXT]') 89 + assert status == 'OK' 90 + content = msg[0][1] 91 + print("===> content:", content) 92 + split = content.split(b'\r\n') 93 + print("===> split:", split) 94 + lastline = split[-3] 95 + print("===> lastline:", lastline) 96 + assert lastline.strip() == b'Hello World' 97 + ''; 98 + in [ sendTestMail checkMailLanded ]; 99 + }; 100 + }; 101 + 102 + testScript = '' 103 + startAll; 104 + 105 + $client->waitForUnit("network.target"); 106 + $smtp1->waitForUnit('opensmtpd'); 107 + $smtp2->waitForUnit('opensmtpd'); 108 + $smtp2->waitForUnit('dovecot2'); 109 + 110 + $client->succeed('send-a-test-mail'); 111 + $smtp1->waitUntilFails('smtpctl show queue | egrep .'); 112 + $smtp2->waitUntilFails('smtpctl show queue | egrep .'); 113 + $client->succeed('check-mail-landed >&2'); 114 + ''; 115 + }