1 ;;; GNU Guix --- Functional package management for GNU
2 ;;; Copyright © 2016 Sou Bunnbu <iyzsong@member.fsf.org>
4 ;;; This file is part of GNU Guix.
6 ;;; GNU Guix is free software; you can redistribute it and/or modify it
7 ;;; under the terms of the GNU General Public License as published by
8 ;;; the Free Software Foundation; either version 3 of the License, or (at
9 ;;; your option) any later version.
11 ;;; GNU Guix is distributed in the hope that it will be useful, but
12 ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ;;; GNU General Public License for more details.
16 ;;; You should have received a copy of the GNU General Public License
17 ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
19 (define-module (gnu tests mail)
20 #:use-module (gnu tests)
21 #:use-module (gnu system)
22 #:use-module (gnu system file-systems)
23 #:use-module (gnu system grub)
24 #:use-module (gnu system vm)
25 #:use-module (gnu services)
26 #:use-module (gnu services base)
27 #:use-module (gnu services mail)
28 #:use-module (gnu services networking)
29 #:use-module (guix gexp)
30 #:use-module (guix monads)
31 #:use-module (guix store)
32 #:export (%test-opensmtpd))
36 (host-name "komputilo")
37 (timezone "Europe/Berlin")
38 (locale "en_US.UTF-8")
39 (bootloader (grub-configuration (device #f)))
40 (file-systems %base-file-systems)
44 (service opensmtpd-service-type
45 (opensmtpd-configuration
47 (plain-file "smtpd.conf" "
49 accept from any for local deliver to mbox
53 (define (run-opensmtpd-test)
54 "Return a test of an OS running OpenSMTPD service."
55 (mlet* %store-monad ((command (system-qemu-image/shared-store-script
56 (marionette-operating-system
58 #:imported-modules '((gnu services herd)))
61 (with-imported-modules '((gnu build marionette))
63 (use-modules (rnrs base)
67 (gnu build marionette))
71 ;; Enable TCP forwarding of the guest's port 25.
72 '(#$command "-net" "user,hostfwd=tcp::1025-:25")))
74 (define (read-reply-code port)
75 "Read a SMTP reply from PORT and return its reply code."
76 (let* ((line (read-line port))
77 (mo (string-match "([0-9]+)([ -]).*" line))
78 (code (string->number (match:substring mo 1)))
79 (finished? (string= " " (match:substring mo 2))))
82 (read-reply-code port))))
87 (test-begin "opensmptd")
89 (test-assert "service is running"
92 (use-modules (gnu services herd))
93 (start-service 'smtpd)
97 (test-assert "mbox is empty"
99 '(and (file-exists? "/var/mail")
100 (not (file-exists? "/var/mail/root")))
103 (test-eq "accept an email"
105 (let* ((smtp (socket AF_INET SOCK_STREAM 0))
106 (addr (make-socket-address AF_INET INADDR_LOOPBACK 1025)))
109 (read-reply-code smtp) ;220
111 (write-line "EHLO somehost" smtp)
112 (read-reply-code smtp) ;250
114 (write-line "MAIL FROM: <someone>" smtp)
115 (read-reply-code smtp) ;250
116 ;; Set recipient email.
117 (write-line "RCPT TO: <root>" smtp)
118 (read-reply-code smtp) ;250
120 (write-line "DATA" smtp)
121 (read-reply-code smtp) ;354
122 (write-line "Subject: Hello" smtp)
124 (write-line "Nice to meet you!" smtp)
125 (write-line "." smtp)
126 (read-reply-code smtp) ;250
128 (write-line "QUIT" smtp)
129 (read-reply-code smtp) ;221
133 (test-assert "mail arrived"
136 (use-modules (ice-9 popen)
139 (define (queue-empty?)
142 (open-input-pipe "smtpctl show queue"))))
146 (file-exists? "/var/mail/root")
147 (begin (sleep 1) (wait)))))
151 (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
153 (gexp->derivation "opensmtpd-test" test)))
155 (define %test-opensmtpd
158 (description "Send an email to a running OpenSMTPD server.")
159 (value (run-opensmtpd-test))))