at master 5.2 kB view raw
1import ./make-test-python.nix { 2 name = "opensmtpd"; 3 4 nodes = { 5 smtp1 = 6 { pkgs, ... }: 7 { 8 imports = [ common/user-account.nix ]; 9 networking = { 10 firewall.allowedTCPPorts = [ 25 ]; 11 useDHCP = false; 12 interfaces.eth1.ipv4.addresses = pkgs.lib.mkOverride 0 [ 13 { 14 address = "192.168.1.1"; 15 prefixLength = 24; 16 } 17 ]; 18 }; 19 environment.systemPackages = 20 let 21 testSendmail = pkgs.writeScriptBin "test-sendmail" '' 22 #!/bin/sh 23 set -euxo pipefail 24 echo "========= SENDING" >&2 25 ${pkgs.system-sendmail}/bin/sendmail -v -f alice@smtp1 bob@smtp2 >&2 <<EOF 26 From: alice@smtp1 27 To: bob@smtp2 28 Subject: Sendmail Test 29 30 Hello World 31 EOF 32 echo "=========== FINISHED SENDING" >&2 33 ''; 34 in 35 [ 36 pkgs.opensmtpd 37 testSendmail 38 ]; 39 services.opensmtpd = { 40 enable = true; 41 extraServerArgs = [ "-v" ]; 42 serverConfiguration = '' 43 listen on 0.0.0.0 44 action relay_smtp2 relay host "smtp://192.168.1.2" 45 match from any for any action relay_smtp2 46 ''; 47 }; 48 }; 49 50 smtp2 = 51 { pkgs, ... }: 52 { 53 imports = [ common/user-account.nix ]; 54 networking = { 55 firewall.allowedTCPPorts = [ 56 25 57 143 58 ]; 59 useDHCP = false; 60 interfaces.eth1.ipv4.addresses = pkgs.lib.mkOverride 0 [ 61 { 62 address = "192.168.1.2"; 63 prefixLength = 24; 64 } 65 ]; 66 }; 67 environment.systemPackages = [ pkgs.opensmtpd ]; 68 services.opensmtpd = { 69 enable = true; 70 extraServerArgs = [ "-v" ]; 71 serverConfiguration = '' 72 listen on 0.0.0.0 73 action dovecot_deliver mda \ 74 "${pkgs.dovecot}/libexec/dovecot/deliver -d %{user.username}" 75 match from any for local action dovecot_deliver 76 ''; 77 }; 78 services.dovecot2 = { 79 enable = true; 80 enableImap = true; 81 mailLocation = "maildir:~/mail"; 82 protocols = [ "imap" ]; 83 }; 84 }; 85 86 client = 87 { pkgs, ... }: 88 { 89 networking = { 90 useDHCP = false; 91 interfaces.eth1.ipv4.addresses = pkgs.lib.mkOverride 0 [ 92 { 93 address = "192.168.1.3"; 94 prefixLength = 24; 95 } 96 ]; 97 }; 98 environment.systemPackages = 99 let 100 sendTestMail = pkgs.writeScriptBin "send-a-test-mail" '' 101 #!${pkgs.python3.interpreter} 102 import smtplib, sys 103 104 with smtplib.SMTP('192.168.1.1') as smtp: 105 smtp.sendmail('alice@smtp1', 'bob@smtp2', """ 106 From: alice@smtp1 107 To: bob@smtp2 108 Subject: Test 109 110 Hello World 111 """) 112 ''; 113 114 checkMailLanded = pkgs.writeScriptBin "check-mail-landed" '' 115 #!${pkgs.python3.interpreter} 116 import imaplib 117 118 with imaplib.IMAP4('192.168.1.2', 143) as imap: 119 imap.login('bob', 'foobar') 120 imap.select() 121 status, refs = imap.search(None, 'ALL') 122 assert status == 'OK' 123 assert len(refs) == 1 and refs[0] != "" 124 status, msg = imap.fetch(refs[0], '(BODY[TEXT])') 125 assert status == 'OK' 126 content = msg[0][1] 127 print("===> content:", content) 128 split = content.split(b'\r\n') 129 print("===> split:", split) 130 split.reverse() 131 lastline = next(filter(lambda x: x != b"", map(bytes.strip, split))) 132 print("===> lastline:", lastline) 133 assert lastline.strip() == b'Hello World' 134 imap.store(refs[0], '+FLAGS', '\\Deleted') 135 imap.expunge() 136 ''; 137 in 138 [ 139 sendTestMail 140 checkMailLanded 141 ]; 142 }; 143 }; 144 145 testScript = '' 146 start_all() 147 148 client.systemctl("start network-online.target") 149 client.wait_for_unit("network-online.target") 150 smtp1.wait_for_unit("opensmtpd") 151 smtp2.wait_for_unit("opensmtpd") 152 smtp2.wait_for_unit("dovecot2") 153 154 # To prevent sporadic failures during daemon startup, make sure 155 # services are listening on their ports before sending requests 156 smtp1.wait_for_open_port(25) 157 smtp2.wait_for_open_port(25) 158 smtp2.wait_for_open_port(143) 159 160 client.succeed("send-a-test-mail") 161 smtp1.wait_until_fails("smtpctl show queue | egrep .") 162 smtp2.wait_until_fails("smtpctl show queue | egrep .") 163 client.succeed("check-mail-landed >&2") 164 165 smtp1.succeed("test-sendmail") 166 smtp1.wait_until_fails("smtpctl show queue | egrep .") 167 smtp2.wait_until_fails("smtpctl show queue | egrep .") 168 client.succeed("check-mail-landed >&2") 169 ''; 170 171 meta.timeout = 1800; 172}