projects/guix·blob ruby-team · refs

789 lines · 27.8 KiB

1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2016 Sou Bunnbu <[email protected]>
3;;; Copyright © 2017 Carlo Zancanaro <[email protected]>
4;;; Copyright © 2017, 2020, 2021 Ludovic Courtès <[email protected]>
5;;; Copyright © 2018 Oleg Pykhalov <[email protected]>
6;;; Copyright © 2018 Clément Lassieur <[email protected]>
7;;; Copyright © 2019 Christopher Baines <[email protected]>
8;;; Copyright © 2019, 2020 Tobias Geerinckx-Rice <[email protected]>
9;;; Copyright © 2023 Thomas Ieong <[email protected]>
10;;;
11;;; This file is part of GNU Guix.
12;;;
13;;; GNU Guix is free software; you can redistribute it and/or modify it
14;;; under the terms of the GNU General Public License as published by
15;;; the Free Software Foundation; either version 3 of the License, or (at
16;;; your option) any later version.
17;;;
18;;; GNU Guix is distributed in the hope that it will be useful, but
19;;; WITHOUT ANY WARRANTY; without even the implied warranty of
20;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21;;; GNU General Public License for more details.
22;;;
23;;; You should have received a copy of the GNU General Public License
24;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
25
26(define-module (gnu tests mail)
27 #:use-module (gnu tests)
28 #:use-module (gnu packages mail)
29 #:use-module (gnu system)
30 #:use-module (gnu system accounts)
31 #:use-module (gnu system shadow)
32 #:use-module (gnu system vm)
33 #:use-module (gnu services)
34 #:use-module (gnu services base)
35 #:use-module (gnu services getmail)
36 #:use-module (gnu services mail)
37 #:use-module (gnu services networking)
38 #:use-module (guix gexp)
39 #:use-module (guix store)
40 #:use-module (ice-9 ftw)
41 #:export (%test-opensmtpd
42 %test-exim
43 %test-dovecot
44 %test-getmail
45 %test-rspamd
46 %test-radicale))
47
48(define %qemu-static-networking-no-nameserver
49 ;; Networking configuration for QEMU without nameserver.
50 (static-networking
51 (addresses (list (network-address
52 (device "eth0")
53 (value "10.0.2.15/24"))))
54 (routes (list (network-route
55 (destination "default")
56 (gateway "10.0.2.2"))))
57 (requirement '())
58 (provision '(networking))
59 (name-servers '())))
60
61(define %opensmtpd-os
62 (simple-operating-system
63 (service static-networking-service-type
64 (list %qemu-static-networking-no-nameserver))
65 (service opensmtpd-service-type
66 (opensmtpd-configuration
67 (config-file
68 (plain-file "smtpd.conf" "
69listen on 0.0.0.0
70action inbound mbox
71match from any for local action inbound
72"))))))
73
74(define (run-opensmtpd-test)
75 "Return a test of an OS running OpenSMTPD service."
76 (define vm
77 (virtual-machine
78 (operating-system (marionette-operating-system
79 %opensmtpd-os
80 #:imported-modules '((gnu services herd))))
81 (port-forwardings '((1025 . 25)))))
82
83 (define test
84 (with-imported-modules '((gnu build marionette))
85 #~(begin
86 (use-modules (rnrs base)
87 (srfi srfi-64)
88 (ice-9 rdelim)
89 (ice-9 regex)
90 (gnu build marionette))
91
92 (define marionette
93 (make-marionette '(#$vm)))
94
95 (define (read-reply-code port)
96 "Read a SMTP reply from PORT and return its reply code."
97 (let* ((line (read-line port))
98 (mo (string-match "([0-9]+)([ -]).*" line))
99 (code (string->number (match:substring mo 1)))
100 (finished? (string= " " (match:substring mo 2))))
101 (if finished?
102 code
103 (read-reply-code port))))
104
105 (test-runner-current (system-test-runner #$output))
106 (test-begin "opensmptd")
107
108 (test-assert "service is running"
109 (marionette-eval
110 '(begin
111 (use-modules (gnu services herd))
112 (start-service 'smtpd))
113 marionette))
114
115 (test-assert "mbox is empty"
116 (marionette-eval
117 '(and (file-exists? "/var/mail")
118 (not (file-exists? "/var/mail/root")))
119 marionette))
120
121 (test-eq "accept an email"
122 #t
123 (let* ((smtp (socket AF_INET SOCK_STREAM 0))
124 (addr (make-socket-address AF_INET INADDR_LOOPBACK 1025)))
125 (connect smtp addr)
126 ;; Be greeted.
127 (read-reply-code smtp) ;220
128 ;; Greet the server.
129 (write-line "EHLO somehost" smtp)
130 (read-reply-code smtp) ;250
131 ;; Set sender email.
132 (write-line "MAIL FROM: <someone>" smtp)
133 (read-reply-code smtp) ;250
134 ;; Set recipient email.
135 (write-line "RCPT TO: <root>" smtp)
136 (read-reply-code smtp) ;250
137 ;; Send message.
138 (write-line "DATA" smtp)
139 (read-reply-code smtp) ;354
140 (write-line "Subject: Hello" smtp)
141 (newline smtp)
142 (write-line "Nice to meet you!" smtp)
143 (write-line "." smtp)
144 (read-reply-code smtp) ;250
145 ;; Say goodbye.
146 (write-line "QUIT" smtp)
147 (read-reply-code smtp) ;221
148 (close smtp)
149 #t))
150
151 (test-assert "mail arrived"
152 (marionette-eval
153 '(begin
154 (use-modules (ice-9 popen)
155 (ice-9 rdelim))
156
157 (define (queue-empty?)
158 (let* ((pipe (open-pipe* OPEN_READ
159 #$(file-append opensmtpd
160 "/sbin/smtpctl")
161 "show" "queue"))
162 (line (read-line pipe)))
163 (close-pipe pipe)
164 (eof-object? line)))
165
166 (let wait ((n 20))
167 (cond ((queue-empty?)
168 (file-exists? "/var/mail/root"))
169 ((zero? n)
170 (error "root mailbox didn't show up"))
171 (else
172 (sleep 1) (wait (- n 1))))))
173 marionette))
174
175 (test-end))))
176
177 (gexp->derivation "opensmtpd-test" test))
178
179(define %test-opensmtpd
180 (system-test
181 (name "opensmtpd")
182 (description "Send an email to a running OpenSMTPD server.")
183 (value (run-opensmtpd-test))))
184
185
186(define %exim-os
187 (simple-operating-system
188 (service dhcpcd-service-type)
189 (service mail-aliases-service-type '())
190 (service exim-service-type
191 (exim-configuration
192 (config-file
193 (plain-file "exim.conf" "
194primary_hostname = komputilo
195domainlist local_domains = @
196domainlist relay_to_domains =
197hostlist relay_from_hosts = localhost
198
199never_users =
200
201acl_smtp_rcpt = acl_check_rcpt
202acl_smtp_data = acl_check_data
203
204begin acl
205
206acl_check_rcpt:
207 accept
208acl_check_data:
209 accept
210"))))))
211
212(define (run-exim-test)
213 "Return a test of an OS running an Exim service."
214 (define vm
215 (virtual-machine
216 (operating-system (marionette-operating-system
217 %exim-os
218 #:imported-modules '((gnu services herd))))
219 (port-forwardings '((1025 . 25)))))
220
221 (define test
222 (with-imported-modules '((gnu build marionette))
223 #~(begin
224 (use-modules (rnrs base)
225 (srfi srfi-64)
226 (ice-9 ftw)
227 (ice-9 rdelim)
228 (ice-9 regex)
229 (gnu build marionette))
230
231 (define marionette
232 (make-marionette '(#$vm)))
233
234 (define (read-reply-code port)
235 "Read a SMTP reply from PORT and return its reply code."
236 (let* ((line (read-line port))
237 (mo (string-match "([0-9]+)([ -]).*" line))
238 (code (string->number (match:substring mo 1)))
239 (finished? (string= " " (match:substring mo 2))))
240 (if finished?
241 code
242 (read-reply-code port))))
243
244 (define smtp (socket AF_INET SOCK_STREAM 0))
245 (define addr (make-socket-address AF_INET INADDR_LOOPBACK 1025))
246
247 (test-runner-current (system-test-runner #$output))
248 (test-begin "exim")
249
250 (test-assert "service is running"
251 (marionette-eval
252 '(begin
253 (use-modules (gnu services herd))
254 (start-service 'exim))
255 marionette))
256
257 (sleep 1) ;; give the service time to start talking
258
259 (connect smtp addr)
260 ;; Be greeted.
261 (test-eq "greeting received"
262 220 (read-reply-code smtp))
263 ;; Greet the server.
264 (write-line "EHLO somehost" smtp)
265 (test-eq "greeting successful"
266 250 (read-reply-code smtp))
267 ;; Set sender email.
268 (write-line "MAIL FROM: [email protected]" smtp)
269 (test-eq "sender set"
270 250 (read-reply-code smtp)) ;250
271 ;; Set recipient email.
272 (write-line "RCPT TO: root@komputilo" smtp)
273 (test-eq "recipient set"
274 250 (read-reply-code smtp)) ;250
275 ;; Send message.
276 (write-line "DATA" smtp)
277 (test-eq "data begun"
278 354 (read-reply-code smtp)) ;354
279 (write-line "Subject: Hello" smtp)
280 (newline smtp)
281 (write-line "Nice to meet you!" smtp)
282 (write-line "." smtp)
283 (test-eq "message sent"
284 250 (read-reply-code smtp)) ;250
285 ;; Say goodbye.
286 (write-line "QUIT" smtp)
287 (test-eq "quit successful"
288 221 (read-reply-code smtp)) ;221
289 (close smtp)
290
291 (test-eq "the email is received"
292 1
293 (marionette-eval
294 '(begin
295 (use-modules (ice-9 ftw))
296 (length (scandir "/var/spool/exim/msglog"
297 (lambda (x) (not (string-prefix? "." x))))))
298 marionette))
299
300 (test-end))))
301
302 (gexp->derivation "exim-test" test))
303
304(define %test-exim
305 (system-test
306 (name "exim")
307 (description "Send an email to a running an Exim server.")
308 (value (run-exim-test))))
309
310(define %dovecot-os
311 (simple-operating-system
312 (service dhcpcd-service-type)
313 (service dovecot-service-type
314 (dovecot-configuration
315 (extensions (list dovecot-pigeonhole))
316 (disable-plaintext-auth? #f)
317 ;; Required for sieve!
318 (postmaster-address "postmaster@komputilo")
319 (ssl? "no")
320 (auth-mechanisms '("anonymous"))
321 (auth-anonymous-username "alice")
322 (protocols
323 (list (protocol-configuration
324 (name "imap")
325 (mail-plugins '("$mail_plugins" "imap_sieve"))
326 (imap-metadata? #t))))
327
328 (plugin-configuration
329 (plugin-configuration
330 (entries (list
331 (cons 'sieve-global "/tmp")
332 (cons 'sieve-extensions "+editheader")
333
334 (cons 'imapsieve-mailbox1-name "*")
335 (cons 'imapsieve-mailbox1-causes "APPEND")
336 ;; Run the script *before* the user scripts
337 (cons 'imapsieve-mailbox1-before "file:/tmp/main.sieve")
338 ;; We want to automatically remove original email
339 (cons 'imapsieve-expunge-discarded "yes")
340
341 (cons 'sieve-trace-debug "yes")
342 (cons 'sieve-trace-dir "/tmp")
343 (cons 'sieve-trace-level "tests")
344 (cons 'sieve-plugins "sieve_imapsieve")
345 ;; You cannot run scripts anywhere you want
346 ;; Sieve allows you to only run scripts under
347 ;; sieve_pipe_bin_dir.
348 (cons 'sieve-pipe-bin-dir "/tmp")))))
349
350 (mail-location
351 (string-append "maildir:~/Maildir"
352 ":INBOX=~/Maildir/INBOX"
353 ":LAYOUT=fs"))))))
354
355(define (run-dovecot-test)
356 "Return a test of an OS running Dovecot service."
357 (define vm
358 (virtual-machine
359 (operating-system (marionette-operating-system
360 %dovecot-os
361 #:imported-modules '((gnu services herd))))
362 (port-forwardings '((8143 . 143)))))
363
364 (define test
365 (with-imported-modules '((gnu build marionette))
366 #~(begin
367 (use-modules (gnu build marionette)
368 (ice-9 iconv)
369 (ice-9 rdelim)
370 (rnrs base)
371 (rnrs bytevectors)
372 (srfi srfi-64))
373
374 (define marionette
375 (make-marionette '(#$vm)))
376
377 (define* (message-length message #:key (encoding "iso-8859-1"))
378 (bytevector-length (string->bytevector message encoding)))
379
380 (define message "From: [email protected]\n\
381Subject: Hello Nice to meet you!")
382
383 (define sieve-script
384 "require \"editheader\";\n
385addheader \"X-Sieve-Filtered\" \"Guix\";
386")
387 ;; Install our sieve script
388 (marionette-eval
389 `(begin
390 (with-output-to-file "/tmp/main.sieve"
391 (lambda ()
392 (display ,sieve-script))))
393 marionette)
394
395 (test-runner-current (system-test-runner #$output))
396 (test-begin "dovecot")
397
398 ;; Wait for dovecot to be up and running.
399 (test-assert "dovecot running"
400 (marionette-eval
401 '(begin
402 (use-modules (gnu services herd))
403 (start-service 'dovecot))
404 marionette))
405
406 ;; Check Dovecot service's PID.
407 (test-assert "service process id"
408 (let ((pid
409 (number->string (wait-for-file "/var/run/dovecot/master.pid"
410 marionette))))
411 (marionette-eval `(file-exists? (string-append "/proc/" ,pid))
412 marionette)))
413
414 (test-assert "accept an email"
415 (let ((imap (socket AF_INET SOCK_STREAM 0))
416 (addr (make-socket-address AF_INET INADDR_LOOPBACK 8143)))
417 (connect imap addr)
418 ;; Be greeted.
419 (read-line imap) ;OK
420 ;; Authenticate
421 (write-line "a AUTHENTICATE ANONYMOUS" imap)
422 (read-line imap) ;+
423 (write-line "c2lyaGM=" imap)
424 (read-line imap) ;OK
425 ;; Create a TESTBOX mailbox
426 (write-line "a CREATE TESTBOX" imap)
427 (read-line imap) ;OK
428 ;; Select mailbox. This is required so that dovecot did
429 ;; synchronization correctly.
430 (write-line "a SELECT TESTBOX" imap)
431 ;; ("* FLAGS (\\Answered \\Flagged \\Deleted \\Seen \\Draft)\r")
432 ;; ("* OK [PERMANENTFLAGS (\\Answered \\Flagged \\Deleted \\Seen \\Draft \\*)] Flags permitted.\r")
433 ;; ("* 1 EXISTS\r")
434 ;; ("* 1 RECENT\r")
435 ;; ("* OK [UNSEEN 1] First unseen.\r")
436 ;; ("* OK [UIDVALIDITY 1732177859] UIDs valid\r")
437 ;; ("* OK [UIDNEXT 3] Predicted next UID\r")
438 (for-each (lambda (n)
439 (read-line imap))
440 (iota 7))
441 ;; Append a message to a TESTBOX mailbox
442 (write-line (format #f "a APPEND TESTBOX {~a}"
443 (number->string (message-length message)))
444 imap)
445 (read-line imap) ;+
446 (write-line message imap)
447 (read-line imap) ;OK
448 ;; Logout
449 (write-line "a LOGOUT" imap)
450 (close imap)
451 #t))
452
453 (test-equal "mail arrived"
454 (string-join (list "X-Sieve-Filtered: Guix" message) "\n")
455 (marionette-eval
456 '(begin
457 (use-modules (ice-9 ftw)
458 (ice-9 match)
459 (rnrs io ports))
460 ;; XXX: We expect a new email in /cur directory
461 (let ((TESTBOX/cur "/home/alice/Maildir/TESTBOX/cur/"))
462 (match (scandir TESTBOX/cur)
463 (("." ".." message-file)
464 (call-with-input-file
465 (string-append TESTBOX/cur message-file)
466 get-string-all)))))
467 marionette))
468
469 (test-end))))
470
471 (gexp->derivation "dovecot-test" test))
472
473(define %test-dovecot
474 (system-test
475 (name "dovecot")
476 (description "Connect to a running Dovecot server.")
477 (value (run-dovecot-test))))
478
479(define %getmail-os
480 (operating-system
481 (inherit (simple-operating-system))
482
483 ;; Set a password for the user account; the test needs it.
484 (users (cons (user-account
485 (name "alice")
486 (password (crypt "testpass" "$6$abc"))
487 (comment "Bob's sister")
488 (group "users")
489 (supplementary-groups '("wheel" "audio" "video")))
490 %base-user-accounts))
491
492 (services (cons* (service dhcpcd-service-type)
493 (service dovecot-service-type
494 (dovecot-configuration
495 (disable-plaintext-auth? #f)
496 (ssl? "no")
497 (auth-mechanisms '("anonymous" "plain"))
498 (auth-anonymous-username "alice")
499 (mail-location
500 (string-append "maildir:~/Maildir"
501 ":INBOX=~/Maildir/INBOX"
502 ":LAYOUT=fs"))
503 (namespaces
504 (list
505 (namespace-configuration
506 (name "main")
507 (inbox? #t)
508 (mailboxes
509 (list
510 (mailbox-configuration
511 (name "TESTBOX")
512 (auto "create")))))))))
513 (service getmail-service-type
514 (list
515 (getmail-configuration
516 (name 'test)
517 (user "alice")
518 (directory "/var/lib/getmail/alice")
519 (idle '("TESTBOX"))
520 (rcfile
521 (getmail-configuration-file
522 (retriever
523 (getmail-retriever-configuration
524 (type "SimpleIMAPRetriever")
525 (server "localhost")
526 (username "alice")
527 (port 143)
528 (extra-parameters
529 '((password . "testpass")
530 (mailboxes . ("TESTBOX"))))))
531 (destination
532 (getmail-destination-configuration
533 (type "Maildir")
534 (path "/home/alice/TestMaildir/")))
535 (options
536 (getmail-options-configuration
537 (read-all #f))))))))
538 %base-services))))
539
540(define (run-getmail-test)
541 "Return a test of an OS running Getmail service."
542 (define vm
543 (virtual-machine
544 (operating-system (marionette-operating-system
545 %getmail-os
546 #:imported-modules '((gnu services herd))))
547 (port-forwardings '((8143 . 143)))))
548
549 (define test
550 (with-imported-modules '((gnu build marionette))
551 #~(begin
552 (use-modules (gnu build marionette)
553 (ice-9 iconv)
554 (ice-9 rdelim)
555 (rnrs base)
556 (rnrs bytevectors)
557 (srfi srfi-64))
558
559 (define marionette
560 (make-marionette '(#$vm)))
561
562 (define* (message-length message #:key (encoding "iso-8859-1"))
563 (bytevector-length (string->bytevector message encoding)))
564
565 (define message "From: [email protected]\n\
566Subject: Hello Nice to meet you!")
567
568 (test-runner-current (system-test-runner #$output))
569 (test-begin "getmail")
570
571 ;; Wait for dovecot to be up and running.
572 (test-assert "dovecot running"
573 (marionette-eval
574 '(begin
575 (use-modules (gnu services herd))
576 (start-service 'dovecot))
577 marionette))
578
579 ;; Wait for getmail to be up and running.
580 (test-assert "getmail-test running"
581 (marionette-eval
582 '(let* ((pw (getpw "alice"))
583 (uid (passwd:uid pw))
584 (gid (passwd:gid pw)))
585 (use-modules (gnu services herd))
586
587 (for-each
588 (lambda (dir)
589 (mkdir dir)
590 (chown dir uid gid))
591 '("/home/alice/TestMaildir"
592 "/home/alice/TestMaildir/cur"
593 "/home/alice/TestMaildir/new"
594 "/home/alice/TestMaildir/tmp"
595 "/home/alice/TestMaildir/TESTBOX"
596 "/home/alice/TestMaildir/TESTBOX/cur"
597 "/home/alice/TestMaildir/TESTBOX/new"
598 "/home/alice/TestMaildir/TESTBOX/tmp"))
599
600 (start-service 'getmail-test))
601 marionette))
602
603 ;; Check Dovecot service's PID.
604 (test-assert "service process id"
605 (let ((pid
606 (number->string (wait-for-file "/var/run/dovecot/master.pid"
607 marionette))))
608 (marionette-eval `(file-exists? (string-append "/proc/" ,pid))
609 marionette)))
610
611 (test-assert "accept an email"
612 (let ((imap (socket AF_INET SOCK_STREAM 0))
613 (addr (make-socket-address AF_INET INADDR_LOOPBACK 8143)))
614 (connect imap addr)
615 ;; Be greeted.
616 (read-line imap) ;OK
617 ;; Authenticate
618 (write-line "a AUTHENTICATE ANONYMOUS" imap)
619 (read-line imap) ;+
620 (write-line "c2lyaGM=" imap)
621 (read-line imap) ;OK
622 ;; Append a message to a TESTBOX mailbox
623 (write-line (format #f "a APPEND TESTBOX {~a}"
624 (number->string (message-length message)))
625 imap)
626 (read-line imap) ;+
627 (write-line message imap)
628 (read-line imap) ;OK
629 ;; Logout
630 (write-line "a LOGOUT" imap)
631 (close imap)
632 #t))
633
634 (sleep 1)
635
636 (test-assert "mail arrived"
637 (string-contains
638 (marionette-eval
639 '(begin
640 (use-modules (ice-9 ftw)
641 (ice-9 match)
642 (rnrs io ports))
643
644 (let ((TESTBOX/new "/home/alice/TestMaildir/new/"))
645 (match (scandir TESTBOX/new)
646 (("." ".." message-file)
647 (call-with-input-file
648 (string-append TESTBOX/new message-file)
649 get-string-all)))))
650 marionette)
651 message))
652
653 (test-end))))
654
655 (gexp->derivation "getmail-test" test))
656
657(define %test-getmail
658 (system-test
659 (name "getmail")
660 (description "Connect to a running Getmail server.")
661 (value (run-getmail-test))))
662
663(define %rspamd-os
664 (simple-operating-system
665 (service rspamd-service-type)))
666
667(define (run-rspamd-test)
668 "Return a test of an OS running Rspamd service."
669
670 (define vm
671 (virtual-machine
672 (marionette-operating-system
673 %rspamd-os
674 #:imported-modules '((gnu services herd)))))
675
676 (define test
677 (with-imported-modules '((gnu build marionette))
678 #~(begin
679 (use-modules (srfi srfi-64)
680 (gnu build marionette))
681
682 (define marionette
683 (make-marionette '(#$vm)))
684
685 (test-runner-current (system-test-runner #$output))
686 (test-begin "rspamd")
687
688 (test-assert "service is running"
689 (marionette-eval
690 '(begin
691 (use-modules (gnu services herd))
692 (start-service 'rspamd))
693 marionette))
694
695 (test-assert "rspamd socket ready"
696 (wait-for-unix-socket
697 "/var/lib/rspamd/rspamd.sock"
698 marionette))
699
700 (test-assert "rspamd log file"
701 (wait-for-file "/var/log/rspamd/rspamd.log" marionette))
702
703 ;; Check that we can access the web ui
704
705 (test-equal "http-get"
706 200
707 (marionette-eval
708 '(begin
709 (use-modules (web client)
710 (web response))
711 ;; HEAD returns 500 internal server error, so use GET even though
712 ;; only the headers are relevant
713 (response-code (http-get "http://localhost:11334")))
714 marionette))
715
716 (test-end))))
717
718 (gexp->derivation "rspamd-test" test))
719
720(define %test-rspamd
721 (system-test
722 (name "rspamd")
723 (description "Basic rspamd service test.")
724 (value (run-rspamd-test))))
725
726(define %radicale-os
727 (simple-operating-system
728 (service dhcpcd-service-type)
729 (service radicale-service-type)))
730
731(define (run-radicale-test)
732 "Return a test of an OS running Radicale service."
733
734 (define forwarded-port 5232)
735
736 (define vm
737 (virtual-machine
738 (operating-system
739 (marionette-operating-system
740 %radicale-os
741 #:imported-modules '((gnu services herd))))
742 (port-forwardings `((5232 . ,forwarded-port)))))
743
744 (define test
745 (with-imported-modules '((gnu build marionette))
746 #~(begin
747 (use-modules (srfi srfi-64)
748 (gnu build marionette))
749
750 (define marionette
751 (make-marionette '(#$vm)))
752
753 (test-runner-current (system-test-runner #$output))
754 (test-begin "Radicale")
755
756 (test-assert "Radicale service is running"
757 (marionette-eval
758 '(begin
759 (use-modules (gnu services herd))
760 (wait-for-service 'radicale))
761 marionette))
762
763 (test-assert "Radicale TCP port ready, IPv4"
764 (wait-for-tcp-port #$forwarded-port marionette))
765
766 (test-equal "Radicale internal web interface works"
767 200
768 (marionette-eval
769 '(begin
770 (use-modules (web client)
771 (web response))
772 (response-code (http-get "http://localhost:5232/.web/index.html")))
773 marionette))
774
775 (test-assert "Radicale configuration action"
776 (marionette-eval '(with-shepherd-action 'radicale ('configuration)
777 results
778 (file-exists? (car results)))
779 marionette))
780
781 (test-end))))
782
783 (gexp->derivation "radicale-test" test))
784
785(define %test-radicale
786 (system-test
787 (name "radicale")
788 (description "Basic radicale service test.")
789 (value (run-radicale-test))))