Subject: Re: [bug#30744] [PATCH] tests: mail: Add test for dovecot.

From: Clément Lassieur <[email-masked]>
Date: Thu, 08 Mar 2018 00:34:13 +0100

Hi Oleg,

Oleg Pykhalov <[email-masked]> writes:

> * gnu/tests/mail.scm (%dovecot-os, %test-dovecot): New variables.
> (run-dovecot-test): New procedure.
> ---
>  gnu/tests/mail.scm | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 112 insertions(+), 1 deletion(-)

Thank you for these patches!

> diff --git a/gnu/tests/mail.scm b/gnu/tests/mail.scm
> index 312df9b1c..69fe016e7 100644
> --- a/gnu/tests/mail.scm
> +++ b/gnu/tests/mail.scm
> @@ -29,7 +29,8 @@
>    #:use-module (guix store)
>    #:use-module (ice-9 ftw)
>    #:export (%test-opensmtpd
> -            %test-exim))
> +            %test-exim
> +            %test-dovecot))
>  
>  (define %opensmtpd-os
>    (simple-operating-system
> @@ -279,3 +280,113 @@ acl_check_data:
>     (name "exim")
>     (description "Send an email to a running an Exim server.")
>     (value (run-exim-test))))
> +
> +(define %dovecot-os
> +  (simple-operating-system
> +   (dhcp-client-service)
> +   (dovecot-service #:config
> +                    (dovecot-configuration
> +                     (disable-plaintext-auth? #f)
> +                     (ssl? "no")
> +                     (auth-mechanisms '("anonymous"))
> +                     (auth-anonymous-username "alice")
> +                     (mail-location
> +                      (string-append "maildir:~/Maildir"
> +                                     ":INBOX=~/Maildir/INBOX"
> +                                     ":LAYOUT=fs"))))))
> +
> +(define (run-dovecot-test)
> +  "Return a test of an OS running Dovecot service."
> +  (define vm
> +    (virtual-machine
> +     (operating-system (marionette-operating-system
> +                        %dovecot-os
> +                        #:imported-modules '((gnu services herd))))
> +     (port-forwardings '((8143 . 143)))))
> +
> +  (define test
> +    (with-imported-modules '((gnu build marionette))
> +      #~(begin
> +          (use-modules (gnu build marionette)
> +                       (ice-9 iconv)
> +                       (ice-9 rdelim)
> +                       (ice-9 regex)
> +                       (rnrs base)
> +                       (rnrs bytevectors)
> +                       (srfi srfi-64))
> +
> +          (define marionette
> +            (make-marionette '(#$vm)))
> +
> +          (define* (message-length message #:key (encoding "iso-8859-1"))
> +            (bytevector-length (string->bytevector message encoding)))
> +
> +          (mkdir #$output)
> +          (chdir #$output)
> +
> +          (test-begin "dovecot")
> +
> +          ;; Wait for dovecot to be up and running.
> +          (test-eq "dovecot running"
> +            'running!
> +            (marionette-eval
> +             '(begin
> +                (use-modules (gnu services herd))
> +                (start-service 'dovecot)
> +                'running!)
> +             marionette))
> +
> +          (sleep 1) ; give the service time to start talking

Here, it would probably be safer to wait for the PID file to arrive.
You could use 'wait-for-file' for this, there are examples in other
tests.  Dovecot's PID file is /var/run/dovecot/master.pid.

> +          (test-eq "accept an email"
> +            #t

Could you use 'test-assert' here?

> +            (let ((imap (socket AF_INET SOCK_STREAM 0))
> +                  (addr (make-socket-address AF_INET INADDR_LOOPBACK 8143))
> +                  (message "From: [email-masked]\n\
> +Subject: Hello Nice to meet you!"))
> +              (connect imap addr)
> +              ;; Be greeted.
> +              (read-line imap) ;OK
> +              ;; Authenticate
> +              (write-line "a AUTHENTICATE ANONYMOUS" imap)
> +              (read-line imap) ;+
> +              (write-line "c2lyaGM=" imap)
> +              (read-line imap) ;OK
> +              ;; Create a TESTBOX mailbox
> +              (write-line "a CREATE TESTBOX" imap)
> +              (read-line imap) ;OK
> +              ;; Append a message to a TESTBOX mailbox
> +              (write-line (format #f "a APPEND TESTBOX {~a}"
> +                                  (number->string (message-length message)))
> +                          imap)
> +              (read-line imap) ;+
> +              (write-line message imap)
> +              (read-line imap) ;OK
> +              ;; Logout
> +              (write-line "a LOGOUT" imap)
> +              (close imap)
> +              #t))
> +
> +          (test-assert "mail arrived"
> +            (marionette-eval
> +             '(begin
> +                (use-modules (ice-9 ftw)
> +                             (ice-9 match))
> +                ;; Get a message ID
> +                (string->number
> +                 (match (scandir "/home/alice/Maildir/TESTBOX/new/")
> +                   ((_ _ message)

Could you write "." ".." here instead of _ _?  It makes it easier to
understand the code.

> +                    (match (string-split message #\.)
> +                      ((message-id _ _) message-id))))))

Here I think it would be great to compare the arrived message and the
sent message to check that they are the same.  If they are the same,
then the test succeeds.  WDYT?

> +             marionette))
> +
> +          (test-end)
> +          (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
> +
> +  (gexp->derivation "dovecot-test" test))
> +
> +(define %test-dovecot
> +  (system-test
> +   (name "dovecot")
> +   (description "Connect to a running Dovecot server.")
> +   (value (run-dovecot-test))))