summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2017-07-18 10:41:51 +0200
committerLudovic Courtès <ludo@gnu.org>2017-07-20 11:57:13 +0200
commit8b113790fa3bfd2300c737901ba161f079fedbdf (patch)
tree72b7aa4fa9be2a6c129b97b04a11cfbe0d298a79
parented419fa0c56e6ff3aa8bd8e8f100a81442c51e6d (diff)
tests: Use 'virtual-machine' records instead of monadic procedures.
* gnu/tests/base.scm (%test-basic-os): Use 'let*' instead of 'mlet*' and 'virtual-machine' instead of 'system-qemu-image/shared-store-script'. (run-mcron-test): Likewise. (run-nss-mdns-test): Likewise. * gnu/tests/dict.scm (run-dicod-test): Likewise. * gnu/tests/mail.scm (run-opensmtpd-test): Likewise. (run-exim-test): Likewise. * gnu/tests/messaging.scm (run-xmpp-test): Likewise. * gnu/tests/networking.scm (run-inetd-test): Likewise. * gnu/tests/nfs.scm (run-nfs-test): Likewise. * gnu/tests/ssh.scm (run-ssh-test): Likewise. * gnu/tests/web.scm (run-nginx-test): Likewise.
-rw-r--r--gnu/tests/base.scm310
-rw-r--r--gnu/tests/dict.scm165
-rw-r--r--gnu/tests/mail.scm388
-rw-r--r--gnu/tests/messaging.scm198
-rw-r--r--gnu/tests/networking.scm95
-rw-r--r--gnu/tests/nfs.scm140
-rw-r--r--gnu/tests/ssh.scm268
-rw-r--r--gnu/tests/web.scm125
8 files changed, 846 insertions, 843 deletions
diff --git a/gnu/tests/base.scm b/gnu/tests/base.scm
index 8389b67f68f..6132aa96ef7 100644
--- a/gnu/tests/base.scm
+++ b/gnu/tests/base.scm
@@ -34,7 +34,6 @@
34 #:use-module (gnu packages package-management) 34 #:use-module (gnu packages package-management)
35 #:use-module (guix gexp) 35 #:use-module (guix gexp)
36 #:use-module (guix store) 36 #:use-module (guix store)
37 #:use-module (guix monads)
38 #:use-module (guix packages) 37 #:use-module (guix packages)
39 #:use-module (srfi srfi-1) 38 #:use-module (srfi srfi-1)
40 #:export (run-basic-test 39 #:export (run-basic-test
@@ -393,17 +392,16 @@ info --version")
393 "Instrument %SIMPLE-OS, run it in a VM, and run a series of basic 392 "Instrument %SIMPLE-OS, run it in a VM, and run a series of basic
394functionality tests.") 393functionality tests.")
395 (value 394 (value
396 (mlet* %store-monad ((os -> (marionette-operating-system 395 (let* ((os (marionette-operating-system
397 %simple-os 396 %simple-os
398 #:imported-modules '((gnu services herd) 397 #:imported-modules '((gnu services herd)
399 (guix combinators)))) 398 (guix combinators))))
400 (run (system-qemu-image/shared-store-script 399 (vm (virtual-machine os)))
401 os #:graphic? #f)))
402 ;; XXX: Add call to 'virtualized-operating-system' to get the exact same 400 ;; XXX: Add call to 'virtualized-operating-system' to get the exact same
403 ;; set of services as the OS produced by 401 ;; set of services as the OS produced by
404 ;; 'system-qemu-image/shared-store-script'. 402 ;; 'system-qemu-image/shared-store-script'.
405 (run-basic-test (virtualized-operating-system os '()) 403 (run-basic-test (virtualized-operating-system os '())
406 #~(list #$run)))))) 404 #~(list #$vm))))))
407 405
408 406
409;;; 407;;;
@@ -430,60 +428,60 @@ functionality tests.")
430 (mcron-service (list job1 job2 job3))))) 428 (mcron-service (list job1 job2 job3)))))
431 429
432(define (run-mcron-test name) 430(define (run-mcron-test name)
433 (mlet* %store-monad ((os -> (marionette-operating-system 431 (define os
434 %mcron-os 432 (marionette-operating-system
435 #:imported-modules '((gnu services herd) 433 %mcron-os
436 (guix combinators)))) 434 #:imported-modules '((gnu services herd)
437 (command (system-qemu-image/shared-store-script 435 (guix combinators))))
438 os #:graphic? #f))) 436
439 (define test 437 (define test
440 (with-imported-modules '((gnu build marionette)) 438 (with-imported-modules '((gnu build marionette))
441 #~(begin 439 #~(begin
442 (use-modules (gnu build marionette) 440 (use-modules (gnu build marionette)
443 (srfi srfi-64) 441 (srfi srfi-64)
444 (ice-9 match)) 442 (ice-9 match))
445 443
446 (define marionette 444 (define marionette
447 (make-marionette (list #$command))) 445 (make-marionette (list #$(virtual-machine os))))
448 446
449 (mkdir #$output) 447 (mkdir #$output)
450 (chdir #$output) 448 (chdir #$output)
451 449
452 (test-begin "mcron") 450 (test-begin "mcron")
453 451
454 (test-eq "service running" 452 (test-eq "service running"
455 'running! 453 'running!
456 (marionette-eval 454 (marionette-eval
457 '(begin 455 '(begin
458 (use-modules (gnu services herd)) 456 (use-modules (gnu services herd))
459 (start-service 'mcron) 457 (start-service 'mcron)
460 'running!) 458 'running!)
461 marionette)) 459 marionette))
462 460
463 ;; Make sure root's mcron job runs, has its cwd set to "/root", and 461 ;; Make sure root's mcron job runs, has its cwd set to "/root", and
464 ;; runs with the right UID/GID. 462 ;; runs with the right UID/GID.
465 (test-equal "root's job" 463 (test-equal "root's job"
466 '(0 0) 464 '(0 0)
467 (wait-for-file "/root/witness" marionette)) 465 (wait-for-file "/root/witness" marionette))
468 466
469 ;; Likewise for Alice's job. We cannot know what its GID is since 467 ;; Likewise for Alice's job. We cannot know what its GID is since
470 ;; it's chosen by 'groupadd', but it's strictly positive. 468 ;; it's chosen by 'groupadd', but it's strictly positive.
471 (test-assert "alice's job" 469 (test-assert "alice's job"
472 (match (wait-for-file "/home/alice/witness" marionette) 470 (match (wait-for-file "/home/alice/witness" marionette)
473 ((1000 gid) 471 ((1000 gid)
474 (>= gid 100)))) 472 (>= gid 100))))
475 473
476 ;; Last, the job that uses a command; allows us to test whether 474 ;; Last, the job that uses a command; allows us to test whether
477 ;; $PATH is sane. (Note that 'marionette-eval' stringifies objects 475 ;; $PATH is sane. (Note that 'marionette-eval' stringifies objects
478 ;; that don't have a read syntax, hence the string.) 476 ;; that don't have a read syntax, hence the string.)
479 (test-equal "root's job with command" 477 (test-equal "root's job with command"
480 "#<eof>" 478 "#<eof>"
481 (wait-for-file "/root/witness-touch" marionette)) 479 (wait-for-file "/root/witness-touch" marionette))
482 480
483 (test-end) 481 (test-end)
484 (exit (= (test-runner-fail-count (test-runner-current)) 0))))) 482 (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
485 483
486 (gexp->derivation name test))) 484 (gexp->derivation name test))
487 485
488(define %test-mcron 486(define %test-mcron
489 (system-test 487 (system-test
@@ -526,102 +524,102 @@ functionality tests.")
526 ;; *after* nscd. Failing to do that, libc will try to connect to nscd, 524 ;; *after* nscd. Failing to do that, libc will try to connect to nscd,
527 ;; fail, then never try again (see '__nss_not_use_nscd_hosts' in libc), 525 ;; fail, then never try again (see '__nss_not_use_nscd_hosts' in libc),
528 ;; leading to '.local' resolution failures. 526 ;; leading to '.local' resolution failures.
529 (mlet* %store-monad ((os -> (marionette-operating-system 527 (define os
530 %avahi-os 528 (marionette-operating-system
531 #:requirements '(nscd) 529 %avahi-os
532 #:imported-modules '((gnu services herd) 530 #:requirements '(nscd)
533 (guix combinators)))) 531 #:imported-modules '((gnu services herd)
534 (run (system-qemu-image/shared-store-script 532 (guix combinators))))
535 os #:graphic? #f)))
536 (define mdns-host-name
537 (string-append (operating-system-host-name os)
538 ".local"))
539
540 (define test
541 (with-imported-modules '((gnu build marionette))
542 #~(begin
543 (use-modules (gnu build marionette)
544 (srfi srfi-1)
545 (srfi srfi-64)
546 (ice-9 match))
547
548 (define marionette
549 (make-marionette (list #$run)))
550
551 (mkdir #$output)
552 (chdir #$output)
553
554 (test-begin "avahi")
555
556 (test-assert "wait for services"
557 (marionette-eval
558 '(begin
559 (use-modules (gnu services herd))
560 533
561 (start-service 'nscd) 534 (define mdns-host-name
562 535 (string-append (operating-system-host-name os)
563 ;; XXX: Work around a race condition in nscd: nscd creates its 536 ".local"))
564 ;; PID file before it is listening on its socket.
565 (let ((sock (socket PF_UNIX SOCK_STREAM 0)))
566 (let try ()
567 (catch 'system-error
568 (lambda ()
569 (connect sock AF_UNIX "/var/run/nscd/socket")
570 (close-port sock)
571 (format #t "nscd is ready~%"))
572 (lambda args
573 (format #t "waiting for nscd...~%")
574 (usleep 500000)
575 (try)))))
576
577 ;; Wait for the other useful things.
578 (start-service 'avahi-daemon)
579 (start-service 'networking)
580
581 #t)
582 marionette))
583
584 (test-equal "avahi-resolve-host-name"
585 0
586 (marionette-eval
587 '(system*
588 "/run/current-system/profile/bin/avahi-resolve-host-name"
589 "-v" #$mdns-host-name)
590 marionette))
591 537
592 (test-equal "avahi-browse" 538 (define test
593 0 539 (with-imported-modules '((gnu build marionette))
594 (marionette-eval 540 #~(begin
595 '(system* "avahi-browse" "-avt") 541 (use-modules (gnu build marionette)
596 marionette)) 542 (srfi srfi-1)
597 543 (srfi srfi-64)
598 (test-assert "getaddrinfo .local" 544 (ice-9 match))
599 ;; Wait for the 'avahi-daemon' service and perform a resolution. 545
600 (match (marionette-eval 546 (define marionette
601 '(getaddrinfo #$mdns-host-name) 547 (make-marionette (list #$(virtual-machine os))))
602 marionette) 548
603 (((? vector? addrinfos) ..1) 549 (mkdir #$output)
604 (pk 'getaddrinfo addrinfos) 550 (chdir #$output)
605 (and (any (lambda (ai) 551
606 (= AF_INET (addrinfo:fam ai))) 552 (test-begin "avahi")
607 addrinfos) 553
608 (any (lambda (ai) 554 (test-assert "wait for services"
609 (= AF_INET6 (addrinfo:fam ai))) 555 (marionette-eval
610 addrinfos))))) 556 '(begin
611 557 (use-modules (gnu services herd))
612 (test-assert "gethostbyname .local" 558
613 (match (pk 'gethostbyname 559 (start-service 'nscd)
614 (marionette-eval '(gethostbyname #$mdns-host-name) 560
615 marionette)) 561 ;; XXX: Work around a race condition in nscd: nscd creates its
616 ((? vector? result) 562 ;; PID file before it is listening on its socket.
617 (and (string=? (hostent:name result) #$mdns-host-name) 563 (let ((sock (socket PF_UNIX SOCK_STREAM 0)))
618 (= (hostent:addrtype result) AF_INET))))) 564 (let try ()
619 565 (catch 'system-error
620 566 (lambda ()
621 (test-end) 567 (connect sock AF_UNIX "/var/run/nscd/socket")
622 (exit (= (test-runner-fail-count (test-runner-current)) 0))))) 568 (close-port sock)
623 569 (format #t "nscd is ready~%"))
624 (gexp->derivation "nss-mdns" test))) 570 (lambda args
571 (format #t "waiting for nscd...~%")
572 (usleep 500000)
573 (try)))))
574
575 ;; Wait for the other useful things.
576 (start-service 'avahi-daemon)
577 (start-service 'networking)
578
579 #t)
580 marionette))
581
582 (test-equal "avahi-resolve-host-name"
583 0
584 (marionette-eval
585 '(system*
586 "/run/current-system/profile/bin/avahi-resolve-host-name"
587 "-v" #$mdns-host-name)
588 marionette))
589
590 (test-equal "avahi-browse"
591 0
592 (marionette-eval
593 '(system* "avahi-browse" "-avt")
594 marionette))
595
596 (test-assert "getaddrinfo .local"
597 ;; Wait for the 'avahi-daemon' service and perform a resolution.
598 (match (marionette-eval
599 '(getaddrinfo #$mdns-host-name)
600 marionette)
601 (((? vector? addrinfos) ..1)
602 (pk 'getaddrinfo addrinfos)
603 (and (any (lambda (ai)
604 (= AF_INET (addrinfo:fam ai)))
605 addrinfos)
606 (any (lambda (ai)
607 (= AF_INET6 (addrinfo:fam ai)))
608 addrinfos)))))
609
610 (test-assert "gethostbyname .local"
611 (match (pk 'gethostbyname
612 (marionette-eval '(gethostbyname #$mdns-host-name)
613 marionette))
614 ((? vector? result)
615 (and (string=? (hostent:name result) #$mdns-host-name)
616 (= (hostent:addrtype result) AF_INET)))))
617
618
619 (test-end)
620 (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
621
622 (gexp->derivation "nss-mdns" test))
625 623
626(define %test-nss-mdns 624(define %test-nss-mdns
627 (system-test 625 (system-test
diff --git a/gnu/tests/dict.scm b/gnu/tests/dict.scm
index 16b6edbd9e9..b9c741e3e00 100644
--- a/gnu/tests/dict.scm
+++ b/gnu/tests/dict.scm
@@ -27,7 +27,6 @@
27 #:use-module (gnu packages wordnet) 27 #:use-module (gnu packages wordnet)
28 #:use-module (guix gexp) 28 #:use-module (guix gexp)
29 #:use-module (guix store) 29 #:use-module (guix store)
30 #:use-module (guix monads)
31 #:use-module (guix packages) 30 #:use-module (guix packages)
32 #:use-module (guix modules) 31 #:use-module (guix modules)
33 #:export (%test-dicod)) 32 #:export (%test-dicod))
@@ -54,86 +53,90 @@
54 53
55(define* (run-dicod-test) 54(define* (run-dicod-test)
56 "Run tests of 'dicod-service-type'." 55 "Run tests of 'dicod-service-type'."
57 (mlet* %store-monad ((os -> (marionette-operating-system 56 (define os
58 %dicod-os 57 (marionette-operating-system
59 #:imported-modules 58 %dicod-os
60 (source-module-closure '((gnu services herd))))) 59 #:imported-modules
61 (command (system-qemu-image/shared-store-script 60 (source-module-closure '((gnu services herd)))))
62 os #:graphic? #f))) 61
63 (define test 62 (define vm
64 (with-imported-modules '((gnu build marionette)) 63 (virtual-machine
65 #~(begin 64 (operating-system os)
66 (use-modules (ice-9 rdelim) 65 (port-forwardings '((8000 . 2628)))))
67 (ice-9 regex) 66
68 (srfi srfi-64) 67 (define test
69 (gnu build marionette)) 68 (with-imported-modules '((gnu build marionette))
70 (define marionette 69 #~(begin
71 ;; Forward the guest's DICT port to local port 8000. 70 (use-modules (ice-9 rdelim)
72 (make-marionette (list #$command "-net" 71 (ice-9 regex)
73 "user,hostfwd=tcp::8000-:2628"))) 72 (srfi srfi-64)
74 73 (gnu build marionette))
75 (define %dico-socket 74 (define marionette
76 (socket PF_INET SOCK_STREAM 0)) 75 ;; Forward the guest's DICT port to local port 8000.
77 76 (make-marionette (list #$vm)))
78 (mkdir #$output) 77
79 (chdir #$output) 78 (define %dico-socket
80 79 (socket PF_INET SOCK_STREAM 0))
81 (test-begin "dicod") 80
82 81 (mkdir #$output)
83 ;; Wait for the service to be started. 82 (chdir #$output)
84 (test-eq "service is running" 83
85 'running! 84 (test-begin "dicod")
86 (marionette-eval 85
87 '(begin 86 ;; Wait for the service to be started.
88 (use-modules (gnu services herd)) 87 (test-eq "service is running"
89 (start-service 'dicod) 88 'running!
90 'running!) 89 (marionette-eval
91 marionette)) 90 '(begin
92 91 (use-modules (gnu services herd))
93 ;; Wait until dicod is actually listening. 92 (start-service 'dicod)
94 ;; TODO: Use a PID file instead. 93 'running!)
95 (test-assert "connect inside" 94 marionette))
96 (marionette-eval 95
97 '(begin 96 ;; Wait until dicod is actually listening.
98 (use-modules (ice-9 rdelim)) 97 ;; TODO: Use a PID file instead.
99 (let ((sock (socket PF_INET SOCK_STREAM 0))) 98 (test-assert "connect inside"
100 (let loop ((i 0)) 99 (marionette-eval
101 (pk 'try i) 100 '(begin
102 (catch 'system-error 101 (use-modules (ice-9 rdelim))
103 (lambda () 102 (let ((sock (socket PF_INET SOCK_STREAM 0)))
104 (connect sock AF_INET INADDR_LOOPBACK 2628)) 103 (let loop ((i 0))
105 (lambda args 104 (pk 'try i)
106 (pk 'connection-error args) 105 (catch 'system-error
107 (when (< i 20) 106 (lambda ()
108 (sleep 1) 107 (connect sock AF_INET INADDR_LOOPBACK 2628))
109 (loop (+ 1 i)))))) 108 (lambda args
110 (read-line sock 'concat))) 109 (pk 'connection-error args)
111 marionette)) 110 (when (< i 20)
112 111 (sleep 1)
113 (test-assert "connect" 112 (loop (+ 1 i))))))
114 (let ((addr (make-socket-address AF_INET INADDR_LOOPBACK 8000))) 113 (read-line sock 'concat)))
115 (connect %dico-socket addr) 114 marionette))
116 (read-line %dico-socket 'concat))) 115
117 116 (test-assert "connect"
118 (test-equal "CLIENT" 117 (let ((addr (make-socket-address AF_INET INADDR_LOOPBACK 8000)))
119 "250 ok\r\n" 118 (connect %dico-socket addr)
120 (begin 119 (read-line %dico-socket 'concat)))
121 (display "CLIENT \"GNU Guile\"\r\n" %dico-socket) 120
122 (read-line %dico-socket 'concat))) 121 (test-equal "CLIENT"
123 122 "250 ok\r\n"
124 (test-assert "DEFINE" 123 (begin
125 (begin 124 (display "CLIENT \"GNU Guile\"\r\n" %dico-socket)
126 (display "DEFINE ! hello\r\n" %dico-socket) 125 (read-line %dico-socket 'concat)))
127 (display "QUIT\r\n" %dico-socket) 126
128 (let ((result (read-string %dico-socket))) 127 (test-assert "DEFINE"
129 (and (string-contains result "gcide") 128 (begin
130 (string-contains result "hello") 129 (display "DEFINE ! hello\r\n" %dico-socket)
131 result)))) 130 (display "QUIT\r\n" %dico-socket)
132 131 (let ((result (read-string %dico-socket)))
133 (test-end) 132 (and (string-contains result "gcide")
134 (exit (= (test-runner-fail-count (test-runner-current)) 0))))) 133 (string-contains result "hello")
135 134 result))))
136 (gexp->derivation "dicod" test))) 135
136 (test-end)
137 (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
138
139 (gexp->derivation "dicod" test))
137 140
138(define %test-dicod 141(define %test-dicod
139 (system-test 142 (system-test
diff --git a/gnu/tests/mail.scm b/gnu/tests/mail.scm
index 247f4f667f1..312df9b1cd3 100644
--- a/gnu/tests/mail.scm
+++ b/gnu/tests/mail.scm
@@ -1,6 +1,7 @@
1;;; GNU Guix --- Functional package management for GNU 1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2016 Sou Bunnbu <iyzsong@member.fsf.org> 2;;; Copyright © 2016 Sou Bunnbu <iyzsong@member.fsf.org>
3;;; Copyright © 2017 Carlo Zancanaro <carlo@zancanaro.id.au> 3;;; Copyright © 2017 Carlo Zancanaro <carlo@zancanaro.id.au>
4;;; Copyright © 2017 Ludovic Courtès <ludo@gnu.org>
4;;; 5;;;
5;;; This file is part of GNU Guix. 6;;; This file is part of GNU Guix.
6;;; 7;;;
@@ -25,7 +26,6 @@
25 #:use-module (gnu services mail) 26 #:use-module (gnu services mail)
26 #:use-module (gnu services networking) 27 #:use-module (gnu services networking)
27 #:use-module (guix gexp) 28 #:use-module (guix gexp)
28 #:use-module (guix monads)
29 #:use-module (guix store) 29 #:use-module (guix store)
30 #:use-module (ice-9 ftw) 30 #:use-module (ice-9 ftw)
31 #:export (%test-opensmtpd 31 #:export (%test-opensmtpd
@@ -44,105 +44,105 @@ accept from any for local deliver to mbox
44 44
45(define (run-opensmtpd-test) 45(define (run-opensmtpd-test)
46 "Return a test of an OS running OpenSMTPD service." 46 "Return a test of an OS running OpenSMTPD service."
47 (mlet* %store-monad ((command (system-qemu-image/shared-store-script 47 (define vm
48 (marionette-operating-system 48 (virtual-machine
49 %opensmtpd-os 49 (operating-system (marionette-operating-system
50 #:imported-modules '((gnu services herd))) 50 %opensmtpd-os
51 #:graphic? #f))) 51 #:imported-modules '((gnu services herd))))
52 (define test 52 (port-forwardings '((1025 . 25)))))
53 (with-imported-modules '((gnu build marionette)) 53
54 #~(begin 54 (define test
55 (use-modules (rnrs base) 55 (with-imported-modules '((gnu build marionette))
56 (srfi srfi-64) 56 #~(begin
57 (ice-9 rdelim) 57 (use-modules (rnrs base)
58 (ice-9 regex) 58 (srfi srfi-64)
59 (gnu build marionette)) 59 (ice-9 rdelim)
60 60 (ice-9 regex)
61 (define marionette 61 (gnu build marionette))
62 (make-marionette 62
63 ;; Enable TCP forwarding of the guest's port 25. 63 (define marionette
64 '(#$command "-net" "user,hostfwd=tcp::1025-:25"))) 64 (make-marionette '(#$vm)))
65 65
66 (define (read-reply-code port) 66 (define (read-reply-code port)
67 "Read a SMTP reply from PORT and return its reply code." 67 "Read a SMTP reply from PORT and return its reply code."
68 (let* ((line (read-line port)) 68 (let* ((line (read-line port))
69 (mo (string-match "([0-9]+)([ -]).*" line)) 69 (mo (string-match "([0-9]+)([ -]).*" line))
70 (code (string->number (match:substring mo 1))) 70 (code (string->number (match:substring mo 1)))
71 (finished? (string= " " (match:substring mo 2)))) 71 (finished? (string= " " (match:substring mo 2))))
72 (if finished? 72 (if finished?
73 code 73 code
74 (read-reply-code port)))) 74 (read-reply-code port))))
75 75
76 (mkdir #$output) 76 (mkdir #$output)
77 (chdir #$output) 77 (chdir #$output)
78 78
79 (test-begin "opensmptd") 79 (test-begin "opensmptd")
80 80
81 (test-assert "service is running" 81 (test-assert "service is running"
82 (marionette-eval 82 (marionette-eval
83 '(begin 83 '(begin
84 (use-modules (gnu services herd)) 84 (use-modules (gnu services herd))
85 (start-service 'smtpd) 85 (start-service 'smtpd)
86 #t) 86 #t)
87 marionette)) 87 marionette))
88 88
89 (test-assert "mbox is empty" 89 (test-assert "mbox is empty"
90 (marionette-eval 90 (marionette-eval
91 '(and (file-exists? "/var/mail") 91 '(and (file-exists? "/var/mail")
92 (not (file-exists? "/var/mail/root"))) 92 (not (file-exists? "/var/mail/root")))
93 marionette)) 93 marionette))
94 94
95 (test-eq "accept an email" 95 (test-eq "accept an email"
96 #t 96 #t
97 (let* ((smtp (socket AF_INET SOCK_STREAM 0)) 97 (let* ((smtp (socket AF_INET SOCK_STREAM 0))
98 (addr (make-socket-address AF_INET INADDR_LOOPBACK 1025))) 98 (addr (make-socket-address AF_INET INADDR_LOOPBACK 1025)))
99 (connect smtp addr) 99 (connect smtp addr)
100 ;; Be greeted. 100 ;; Be greeted.
101 (read-reply-code smtp) ;220 101 (read-reply-code smtp) ;220
102 ;; Greet the server. 102 ;; Greet the server.
103 (write-line "EHLO somehost" smtp) 103 (write-line "EHLO somehost" smtp)
104 (read-reply-code smtp) ;250 104 (read-reply-code smtp) ;250
105 ;; Set sender email. 105 ;; Set sender email.
106 (write-line "MAIL FROM: <someone>" smtp) 106 (write-line "MAIL FROM: <someone>" smtp)
107 (read-reply-code smtp) ;250 107 (read-reply-code smtp) ;250
108 ;; Set recipient email. 108 ;; Set recipient email.
109 (write-line "RCPT TO: <root>" smtp) 109 (write-line "RCPT TO: <root>" smtp)
110 (read-reply-code smtp) ;250 110 (read-reply-code smtp) ;250
111 ;; Send message. 111 ;; Send message.
112 (write-line "DATA" smtp) 112 (write-line "DATA" smtp)
113 (read-reply-code smtp) ;354 113 (read-reply-code smtp) ;354
114 (write-line "Subject: Hello" smtp) 114 (write-line "Subject: Hello" smtp)
115 (newline smtp) 115 (newline smtp)
116 (write-line "Nice to meet you!" smtp) 116 (write-line "Nice to meet you!" smtp)
117 (write-line "." smtp) 117 (write-line "." smtp)
118 (read-reply-code smtp) ;250 118 (read-reply-code smtp) ;250
119 ;; Say goodbye. 119 ;; Say goodbye.
120 (write-line "QUIT" smtp) 120 (write-line "QUIT" smtp)
121 (read-reply-code smtp) ;221 121 (read-reply-code smtp) ;221
122 (close smtp) 122 (close smtp)
123 #t)) 123 #t))
124 124
125 (test-assert "mail arrived" 125 (test-assert "mail arrived"
126 (marionette-eval 126 (marionette-eval
127 '(begin 127 '(begin
128 (use-modules (ice-9 popen) 128 (use-modules (ice-9 popen)
129 (ice-9 rdelim)) 129 (ice-9 rdelim))
130 130
131 (define (queue-empty?) 131 (define (queue-empty?)
132 (eof-object? 132 (eof-object?
133 (read-line 133 (read-line
134 (open-input-pipe "smtpctl show queue")))) 134 (open-input-pipe "smtpctl show queue"))))
135 135
136 (let wait () 136 (let wait ()
137 (if (queue-empty?) 137 (if (queue-empty?)
138 (file-exists? "/var/mail/root") 138 (file-exists? "/var/mail/root")
139 (begin (sleep 1) (wait))))) 139 (begin (sleep 1) (wait)))))
140 marionette)) 140 marionette))
141 141
142 (test-end) 142 (test-end)
143 (exit (= (test-runner-fail-count (test-runner-current)) 0))))) 143 (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
144 144
145 (gexp->derivation "opensmtpd-test" test))) 145 (gexp->derivation "opensmtpd-test" test))
146 146
147(define %test-opensmtpd 147(define %test-opensmtpd
148 (system-test 148 (system-test
@@ -179,100 +179,100 @@ acl_check_data:
179 179
180(define (run-exim-test) 180(define (run-exim-test)
181 "Return a test of an OS running an Exim service." 181 "Return a test of an OS running an Exim service."
182 (mlet* %store-monad ((command (system-qemu-image/shared-store-script 182 (define vm
183 (marionette-operating-system 183 (virtual-machine
184 %exim-os 184 (operating-system (marionette-operating-system
185 #:imported-modules '((gnu services herd))) 185 %exim-os
186 #:graphic? #f))) 186 #:imported-modules '((gnu services herd))))
187 (define test 187 (port-forwardings '((1025 . 25)))))
188 (with-imported-modules '((gnu build marionette) 188
189 (ice-9 ftw)) 189 (define test
190 #~(begin 190 (with-imported-modules '((gnu build marionette)
191 (use-modules (rnrs base) 191 (ice-9 ftw))
192 (srfi srfi-64) 192 #~(begin
193 (ice-9 ftw) 193 (use-modules (rnrs base)
194 (ice-9 rdelim) 194 (srfi srfi-64)
195 (ice-9 regex) 195 (ice-9 ftw)
196 (gnu build marionette)) 196 (ice-9 rdelim)
197 197 (ice-9 regex)
198 (define marionette 198 (gnu build marionette))
199 (make-marionette 199
200 ;; Enable TCP forwarding of the guest's port 25. 200 (define marionette
201 '(#$command "-net" "user,hostfwd=tcp::1025-:25"))) 201 (make-marionette '(#$vm)))
202 202
203 (define (read-reply-code port) 203 (define (read-reply-code port)
204 "Read a SMTP reply from PORT and return its reply code." 204 "Read a SMTP reply from PORT and return its reply code."
205 (let* ((line (read-line port)) 205 (let* ((line (read-line port))
206 (mo (string-match "([0-9]+)([ -]).*" line)) 206 (mo (string-match "([0-9]+)([ -]).*" line))
207 (code (string->number (match:substring mo 1))) 207 (code (string->number (match:substring mo 1)))
208 (finished? (string= " " (match:substring mo 2)))) 208 (finished? (string= " " (match:substring mo 2))))
209 (if finished? 209 (if finished?
210 code 210 code
211 (read-reply-code port)))) 211 (read-reply-code port))))
212 212
213 (define smtp (socket AF_INET SOCK_STREAM 0)) 213 (define smtp (socket AF_INET SOCK_STREAM 0))
214 (define addr (make-socket-address AF_INET INADDR_LOOPBACK 1025)) 214 (define addr (make-socket-address AF_INET INADDR_LOOPBACK 1025))
215 215
216 (mkdir #$output) 216 (mkdir #$output)
217 (chdir #$output) 217 (chdir #$output)
218 218
219 (test-begin "exim") 219 (test-begin "exim")
220 220
221 (test-assert "service is running" 221 (test-assert "service is running"
222 (marionette-eval 222 (marionette-eval
223 '(begin 223 '(begin
224 (use-modules (gnu services herd)) 224 (use-modules (gnu services herd))
225 (start-service 'exim) 225 (start-service 'exim)
226 #t) 226 #t)
227 marionette)) 227 marionette))
228 228
229 (sleep 1) ;; give the service time to start talking 229 (sleep 1) ;; give the service time to start talking
230 230
231 (connect smtp addr) 231 (connect smtp addr)
232 ;; Be greeted. 232 ;; Be greeted.
233 (test-eq "greeting received" 233 (test-eq "greeting received"
234 220 (read-reply-code smtp)) 234 220 (read-reply-code smtp))
235 ;; Greet the server. 235 ;; Greet the server.
236 (write-line "EHLO somehost" smtp) 236 (write-line "EHLO somehost" smtp)
237 (test-eq "greeting successful" 237 (test-eq "greeting successful"
238 250 (read-reply-code smtp)) 238 250 (read-reply-code smtp))
239 ;; Set sender email. 239 ;; Set sender email.
240 (write-line "MAIL FROM: test@example.com" smtp) 240 (write-line "MAIL FROM: test@example.com" smtp)
241 (test-eq "sender set" 241 (test-eq "sender set"
242 250 (read-reply-code smtp)) ;250 242 250 (read-reply-code smtp)) ;250
243 ;; Set recipient email. 243 ;; Set recipient email.
244 (write-line "RCPT TO: root@komputilo" smtp) 244 (write-line "RCPT TO: root@komputilo" smtp)
245 (test-eq "recipient set" 245 (test-eq "recipient set"
246 250 (read-reply-code smtp)) ;250 246 250 (read-reply-code smtp)) ;250
247 ;; Send message. 247 ;; Send message.
248 (write-line "DATA" smtp) 248 (write-line "DATA" smtp)
249 (test-eq "data begun" 249 (test-eq "data begun"
250 354 (read-reply-code smtp)) ;354 250 354 (read-reply-code smtp)) ;354
251 (write-line "Subject: Hello" smtp) 251 (write-line "Subject: Hello" smtp)
252 (newline smtp) 252 (newline smtp)
253 (write-line "Nice to meet you!" smtp) 253 (write-line "Nice to meet you!" smtp)
254 (write-line "." smtp) 254 (write-line "." smtp)
255 (test-eq "message sent" 255 (test-eq "message sent"
256 250 (read-reply-code smtp)) ;250 256 250 (read-reply-code smtp)) ;250
257 ;; Say goodbye. 257 ;; Say goodbye.
258 (write-line "QUIT" smtp) 258 (write-line "QUIT" smtp)
259 (test-eq "quit successful" 259 (test-eq "quit successful"
260 221 (read-reply-code smtp)) ;221 260 221 (read-reply-code smtp)) ;221
261 (close smtp) 261 (close smtp)
262 262
263 (test-eq "the email is received" 263 (test-eq "the email is received"
264 1 264 1
265 (marionette-eval 265 (marionette-eval
266 '(begin 266 '(begin
267 (use-modules (ice-9 ftw)) 267 (use-modules (ice-9 ftw))
268 (length (scandir "/var/spool/exim/msglog" 268 (length (scandir "/var/spool/exim/msglog"
269 (lambda (x) (not (string-prefix? "." x)))))) 269 (lambda (x) (not (string-prefix? "." x))))))
270 marionette)) 270 marionette))
271 271
272 (test-end) 272 (test-end)
273 (exit (= (test-runner-fail-count (test-runner-current)) 0))))) 273 (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
274 274
275 (gexp->derivation "exim-test" test))) 275 (gexp->derivation "exim-test" test))
276 276
277(define %test-exim 277(define %test-exim
278 (system-test 278 (system-test
diff --git a/gnu/tests/messaging.scm b/gnu/tests/messaging.scm
index b76b8e84341..0ba0c839de6 100644
--- a/gnu/tests/messaging.scm
+++ b/gnu/tests/messaging.scm
@@ -1,5 +1,6 @@
1;;; GNU Guix --- Functional package management for GNU 1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2017 Clément Lassieur <clement@lassieur.org> 2;;; Copyright © 2017 Clément Lassieur <clement@lassieur.org>
3;;; Copyright © 2017 Ludovic Courtès <ludo@gnu.org>
3;;; 4;;;
4;;; This file is part of GNU Guix. 5;;; This file is part of GNU Guix.
5;;; 6;;;
@@ -26,108 +27,109 @@
26 #:use-module (gnu packages messaging) 27 #:use-module (gnu packages messaging)
27 #:use-module (guix gexp) 28 #:use-module (guix gexp)
28 #:use-module (guix store) 29 #:use-module (guix store)
29 #:use-module (guix monads)
30 #:export (%test-prosody)) 30 #:export (%test-prosody))
31 31
32(define (run-xmpp-test name xmpp-service pid-file create-account) 32(define (run-xmpp-test name xmpp-service pid-file create-account)
33 "Run a test of an OS running XMPP-SERVICE, which writes its PID to PID-FILE." 33 "Run a test of an OS running XMPP-SERVICE, which writes its PID to PID-FILE."
34 (mlet* %store-monad ((os -> (marionette-operating-system 34 (define os
35 (simple-operating-system (dhcp-client-service) 35 (marionette-operating-system
36 xmpp-service) 36 (simple-operating-system (dhcp-client-service)
37 #:imported-modules '((gnu services herd)))) 37 xmpp-service)
38 (command (system-qemu-image/shared-store-script 38 #:imported-modules '((gnu services herd))))
39 os #:graphic? #f)) 39
40 (username -> "alice") 40 (define port 15222)
41 (server -> "localhost") 41
42 (jid -> (string-append username "@" server)) 42 (define vm
43 (password -> "correct horse battery staple") 43 (virtual-machine
44 (port -> 15222) 44 (operating-system os)
45 (message -> "hello world") 45 (port-forwardings `((,port . 5222)))))
46 (witness -> "/tmp/freetalk-witness")) 46
47 47 (define username "alice")
48 (define script.ft 48 (define server "localhost")
49 (scheme-file 49 (define jid (string-append username "@" server))
50 "script.ft" 50 (define password "correct horse battery staple")
51 #~(begin 51 (define message "hello world")
52 (define (handle-received-message time from nickname message) 52 (define witness "/tmp/freetalk-witness")
53 (define (touch file-name) 53
54 (call-with-output-file file-name (const #t))) 54 (define script.ft
55 (when (equal? message #$message) 55 (scheme-file
56 (touch #$witness))) 56 "script.ft"
57 (add-hook! ft-message-receive-hook handle-received-message) 57 #~(begin
58 58 (define (handle-received-message time from nickname message)
59 (ft-set-jid! #$jid) 59 (define (touch file-name)
60 (ft-set-password! #$password) 60 (call-with-output-file file-name (const #t)))
61 (ft-set-server! #$server) 61 (when (equal? message #$message)
62 (ft-set-port! #$port) 62 (touch #$witness)))
63 (ft-set-sslconn! #f) 63 (add-hook! ft-message-receive-hook handle-received-message)
64 (ft-connect-blocking) 64
65 (ft-send-message #$jid #$message) 65 (ft-set-jid! #$jid)
66 66 (ft-set-password! #$password)
67 (ft-set-daemon) 67 (ft-set-server! #$server)
68 (ft-main-loop)))) 68 (ft-set-port! #$port)
69 69 (ft-set-sslconn! #f)
70 (define test 70 (ft-connect-blocking)
71 (with-imported-modules '((gnu build marionette)) 71 (ft-send-message #$jid #$message)
72 #~(begin 72
73 (use-modules (gnu build marionette) 73 (ft-set-daemon)
74 (srfi srfi-64)) 74 (ft-main-loop))))
75 75
76 (define marionette 76 (define test
77 ;; Enable TCP forwarding of the guest's port 5222. 77 (with-imported-modules '((gnu build marionette))
78 (make-marionette (list #$command "-net" 78 #~(begin
79 (string-append "user,hostfwd=tcp::" 79 (use-modules (gnu build marionette)
80 (number->string #$port) 80 (srfi srfi-64))
81 "-:5222")))) 81
82 82 (define marionette
83 (define (host-wait-for-file file) 83 (make-marionette (list #$vm)))
84 ;; Wait until FILE exists in the host. 84
85 (let loop ((i 60)) 85 (define (host-wait-for-file file)
86 (cond ((file-exists? file) 86 ;; Wait until FILE exists in the host.
87 #t) 87 (let loop ((i 60))
88 ((> i 0) 88 (cond ((file-exists? file)
89 (begin 89 #t)
90 (sleep 1)) 90 ((> i 0)
91 (loop (- i 1))) 91 (begin
92 (else 92 (sleep 1))
93 (error "file didn't show up" file))))) 93 (loop (- i 1)))
94 94 (else
95 (mkdir #$output) 95 (error "file didn't show up" file)))))
96 (chdir #$output) 96
97 97 (mkdir #$output)
98 (test-begin "xmpp") 98 (chdir #$output)
99 99
100 ;; Wait for XMPP service to be up and running. 100 (test-begin "xmpp")
101 (test-eq "service running" 101
102 'running! 102 ;; Wait for XMPP service to be up and running.
103 (marionette-eval 103 (test-eq "service running"
104 '(begin 104 'running!
105 (use-modules (gnu services herd)) 105 (marionette-eval
106 (start-service 'xmpp-daemon) 106 '(begin
107 'running!) 107 (use-modules (gnu services herd))
108 marionette)) 108 (start-service 'xmpp-daemon)
109 109 'running!)
110 ;; Check XMPP service's PID. 110 marionette))
111 (test-assert "service process id" 111
112 (let ((pid (number->string (wait-for-file #$pid-file 112 ;; Check XMPP service's PID.
113 marionette)))) 113 (test-assert "service process id"
114 (marionette-eval `(file-exists? (string-append "/proc/" ,pid)) 114 (let ((pid (number->string (wait-for-file #$pid-file
115 marionette))) 115 marionette))))
116 116 (marionette-eval `(file-exists? (string-append "/proc/" ,pid))
117 ;; Alice sends an XMPP message to herself, with Freetalk. 117 marionette)))
118 (test-assert "client-to-server communication" 118
119 (let ((freetalk-bin (string-append #$freetalk "/bin/freetalk"))) 119 ;; Alice sends an XMPP message to herself, with Freetalk.
120 (marionette-eval '(system* #$create-account #$jid #$password) 120 (test-assert "client-to-server communication"
121 marionette) 121 (let ((freetalk-bin (string-append #$freetalk "/bin/freetalk")))
122 ;; Freetalk requires write access to $HOME. 122 (marionette-eval '(system* #$create-account #$jid #$password)
123 (setenv "HOME" "/tmp") 123 marionette)
124 (system* freetalk-bin "-s" #$script.ft) 124 ;; Freetalk requires write access to $HOME.
125 (host-wait-for-file #$witness))) 125 (setenv "HOME" "/tmp")
126 126 (system* freetalk-bin "-s" #$script.ft)
127 (test-end) 127 (host-wait-for-file #$witness)))
128 (exit (= (test-runner-fail-count (test-runner-current)) 0))))) 128
129 129 (test-end)
130 (gexp->derivation name test))) 130 (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
131
132 (gexp->derivation name test))
131 133
132(define %create-prosody-account 134(define %create-prosody-account
133 (program-file 135 (program-file
diff --git a/gnu/tests/networking.scm b/gnu/tests/networking.scm
index cfcb4908748..aeee105a1c7 100644
--- a/gnu/tests/networking.scm
+++ b/gnu/tests/networking.scm
@@ -74,60 +74,61 @@ done" ))))))))))
74(define* (run-inetd-test) 74(define* (run-inetd-test)
75 "Run tests in %INETD-OS, where the inetd service provides an echo service on 75 "Run tests in %INETD-OS, where the inetd service provides an echo service on
76port 7, and a dict service on port 2628." 76port 7, and a dict service on port 2628."
77 (mlet* %store-monad ((os -> (marionette-operating-system %inetd-os)) 77 (define os
78 (command (system-qemu-image/shared-store-script 78 (marionette-operating-system %inetd-os))
79 os #:graphic? #f)))
80 (define test
81 (with-imported-modules '((gnu build marionette))
82 #~(begin
83 (use-modules (ice-9 rdelim)
84 (srfi srfi-64)
85 (gnu build marionette))
86 (define marionette
87 ;; Forward guest ports 7 and 2628 to host ports 8007 and 8628.
88 (make-marionette (list #$command "-net"
89 (string-append
90 "user"
91 ",hostfwd=tcp::8007-:7"
92 ",hostfwd=tcp::8628-:2628"))))
93 79
94 (mkdir #$output) 80 (define vm
95 (chdir #$output) 81 (virtual-machine
82 (operating-system os)
83 (port-forwardings `((8007 . 7)
84 (8628 . 2628)))))
96 85
97 (test-begin "inetd") 86 (define test
87 (with-imported-modules '((gnu build marionette))
88 #~(begin
89 (use-modules (ice-9 rdelim)
90 (srfi srfi-64)
91 (gnu build marionette))
92 (define marionette
93 (make-marionette (list #$vm)))
98 94
99 ;; Make sure the PID file is created. 95 (mkdir #$output)
100 (test-assert "PID file" 96 (chdir #$output)
101 (marionette-eval
102 '(file-exists? "/var/run/inetd.pid")
103 marionette))
104 97
105 ;; Test the echo service. 98 (test-begin "inetd")
106 (test-equal "echo response"
107 "Hello, Guix!"
108 (let ((echo (socket PF_INET SOCK_STREAM 0))
109 (addr (make-socket-address AF_INET INADDR_LOOPBACK 8007)))
110 (connect echo addr)
111 (display "Hello, Guix!\n" echo)
112 (let ((response (read-line echo)))
113 (close echo)
114 response)))
115 99
116 ;; Test the dict service 100 ;; Make sure the PID file is created.
117 (test-equal "dict response" 101 (test-assert "PID file"
118 "GNU Guix is a package management tool for the GNU system." 102 (marionette-eval
119 (let ((dict (socket PF_INET SOCK_STREAM 0)) 103 '(file-exists? "/var/run/inetd.pid")
120 (addr (make-socket-address AF_INET INADDR_LOOPBACK 8628))) 104 marionette))
121 (connect dict addr)
122 (display "DEFINE Guix\n" dict)
123 (let ((response (read-line dict)))
124 (close dict)
125 response)))
126 105
127 (test-end) 106 ;; Test the echo service.
128 (exit (= (test-runner-fail-count (test-runner-current)) 0))))) 107 (test-equal "echo response"
108 "Hello, Guix!"
109 (let ((echo (socket PF_INET SOCK_STREAM 0))
110 (addr (make-socket-address AF_INET INADDR_LOOPBACK 8007)))
111 (connect echo addr)
112 (display "Hello, Guix!\n" echo)
113 (let ((response (read-line echo)))
114 (close echo)
115 response)))
129 116
130 (gexp->derivation "inetd-test" test))) 117 ;; Test the dict service
118 (test-equal "dict response"
119 "GNU Guix is a package management tool for the GNU system."
120 (let ((dict (socket PF_INET SOCK_STREAM 0))
121 (addr (make-socket-address AF_INET INADDR_LOOPBACK 8628)))
122 (connect dict addr)
123 (display "DEFINE Guix\n" dict)
124 (let ((response (read-line dict)))
125 (close dict)
126 response)))
127
128 (test-end)
129 (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
130
131 (gexp->derivation "inetd-test" test))
131 132
132(define %test-inetd 133(define %test-inetd
133 (system-test 134 (system-test
diff --git a/gnu/tests/nfs.scm b/gnu/tests/nfs.scm
index 9e1ac1d55ae..2e666b2c081 100644
--- a/gnu/tests/nfs.scm
+++ b/gnu/tests/nfs.scm
@@ -1,5 +1,5 @@
1;;; GNU Guix --- Functional package management for GNU 1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2016 Ludovic Courtès <ludo@gnu.org> 2;;; Copyright © 2016, 2017 Ludovic Courtès <ludo@gnu.org>
3;;; Copyright © 2016 John Darrington <jmd@gnu.org> 3;;; Copyright © 2016 John Darrington <jmd@gnu.org>
4;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com> 4;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com>
5;;; 5;;;
@@ -55,75 +55,75 @@
55 55
56(define (run-nfs-test name socket) 56(define (run-nfs-test name socket)
57 "Run a test of an OS running RPC-SERVICE, which should create SOCKET." 57 "Run a test of an OS running RPC-SERVICE, which should create SOCKET."
58 (mlet* %store-monad ((os -> (marionette-operating-system 58 (define os
59 %base-os 59 (marionette-operating-system
60 #:imported-modules '((gnu services herd) 60 %base-os
61 (guix combinators)))) 61 #:imported-modules '((gnu services herd)
62 (command (system-qemu-image/shared-store-script 62 (guix combinators))))
63 os #:graphic? #f))) 63
64 (define test 64 (define test
65 (with-imported-modules '((gnu build marionette)) 65 (with-imported-modules '((gnu build marionette))
66 #~(begin 66 #~(begin
67 (use-modules (gnu build marionette) 67 (use-modules (gnu build marionette)
68 (srfi srfi-64)) 68 (srfi srfi-64))
69 69
70 (define marionette 70 (define marionette
71 (make-marionette (list #$command))) 71 (make-marionette (list #$(virtual-machine os))))
72 72
73 (define (wait-for-socket file) 73 (define (wait-for-socket file)
74 ;; Wait until SOCKET exists in the guest 74 ;; Wait until SOCKET exists in the guest
75 (marionette-eval 75 (marionette-eval
76 `(let loop ((i 10)) 76 `(let loop ((i 10))
77 (cond ((and (file-exists? ,file) 77 (cond ((and (file-exists? ,file)
78 (eq? 'socket (stat:type (stat ,file)))) 78 (eq? 'socket (stat:type (stat ,file))))
79 #t) 79 #t)
80 ((> i 0) 80 ((> i 0)
81 (sleep 1) 81 (sleep 1)
82 (loop (- i 1))) 82 (loop (- i 1)))
83 (else 83 (else
84 (error "Socket didn't show up: " ,file)))) 84 (error "Socket didn't show up: " ,file))))
85 marionette)) 85 marionette))
86 86
87 (mkdir #$output) 87 (mkdir #$output)
88 (chdir #$output) 88 (chdir #$output)
89 89
90 (test-begin "rpc-daemon") 90 (test-begin "rpc-daemon")
91 91
92 ;; Wait for the rpcbind daemon to be up and running. 92 ;; Wait for the rpcbind daemon to be up and running.
93 (test-eq "RPC service running" 93 (test-eq "RPC service running"
94 'running! 94 'running!
95 (marionette-eval 95 (marionette-eval
96 '(begin 96 '(begin
97 (use-modules (gnu services herd)) 97 (use-modules (gnu services herd))
98 (start-service 'rpcbind-daemon) 98 (start-service 'rpcbind-daemon)
99 'running!) 99 'running!)
100 marionette)) 100 marionette))
101 101
102 ;; Check the socket file and that the service is still running. 102 ;; Check the socket file and that the service is still running.
103 (test-assert "RPC socket exists" 103 (test-assert "RPC socket exists"
104 (and 104 (and
105 (wait-for-socket #$socket) 105 (wait-for-socket #$socket)
106 (marionette-eval 106 (marionette-eval
107 '(begin 107 '(begin
108 (use-modules (gnu services herd) 108 (use-modules (gnu services herd)
109 (srfi srfi-1)) 109 (srfi srfi-1))
110 110
111 (live-service-running 111 (live-service-running
112 (find (lambda (live) 112 (find (lambda (live)
113 (memq 'rpcbind-daemon 113 (memq 'rpcbind-daemon
114 (live-service-provision live))) 114 (live-service-provision live)))
115 (current-services)))) 115 (current-services))))
116 marionette))) 116 marionette)))
117 117
118 (test-assert "Probe RPC daemon" 118 (test-assert "Probe RPC daemon"
119 (marionette-eval 119 (marionette-eval
120 '(zero? (system* "rpcinfo" "-p")) 120 '(zero? (system* "rpcinfo" "-p"))
121 marionette)) 121 marionette))
122 122
123 (test-end) 123 (test-end)
124 (exit (= (test-runner-fail-count (test-runner-current)) 0))))) 124 (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
125 125
126 (gexp->derivation name test))) 126 (gexp->derivation name test))
127 127
128(define %test-nfs 128(define %test-nfs
129 (system-test 129 (system-test
diff --git a/gnu/tests/ssh.scm b/gnu/tests/ssh.scm
index 9c83a9cd481..05a8d35476f 100644
--- a/gnu/tests/ssh.scm
+++ b/gnu/tests/ssh.scm
@@ -27,7 +27,6 @@
27 #:use-module (gnu packages ssh) 27 #:use-module (gnu packages ssh)
28 #:use-module (guix gexp) 28 #:use-module (guix gexp)
29 #:use-module (guix store) 29 #:use-module (guix store)
30 #:use-module (guix monads)
31 #:export (%test-openssh 30 #:export (%test-openssh
32 %test-dropbear)) 31 %test-dropbear))
33 32
@@ -37,142 +36,143 @@ SSH-SERVICE must be configured to listen on port 22 and to allow for root and
37empty-password logins. 36empty-password logins.
38 37
39When SFTP? is true, run an SFTP server test." 38When SFTP? is true, run an SFTP server test."
40 (mlet* %store-monad ((os -> (marionette-operating-system 39 (define os
41 (simple-operating-system 40 (marionette-operating-system
42 (dhcp-client-service) 41 (simple-operating-system (dhcp-client-service) ssh-service)
43 ssh-service) 42 #:imported-modules '((gnu services herd)
44 #:imported-modules '((gnu services herd) 43 (guix combinators))))
45 (guix combinators)))) 44 (define vm
46 (command (system-qemu-image/shared-store-script 45 (virtual-machine
47 os #:graphic? #f))) 46 (operating-system os)
48 (define test 47 (port-forwardings '((2222 . 22)))))
49 (with-imported-modules '((gnu build marionette)) 48
50 #~(begin 49 (define test
51 (eval-when (expand load eval) 50 (with-imported-modules '((gnu build marionette))
52 ;; Prepare to use Guile-SSH. 51 #~(begin
53 (set! %load-path 52 (eval-when (expand load eval)
54 (cons (string-append #+guile2.0-ssh "/share/guile/site/" 53 ;; Prepare to use Guile-SSH.
55 (effective-version)) 54 (set! %load-path
56 %load-path))) 55 (cons (string-append #+guile2.0-ssh "/share/guile/site/"
57 56 (effective-version))
58 (use-modules (gnu build marionette) 57 %load-path)))
59 (srfi srfi-26) 58
60 (srfi srfi-64) 59 (use-modules (gnu build marionette)
61 (ice-9 match) 60 (srfi srfi-26)
62 (ssh session) 61 (srfi srfi-64)
63 (ssh auth) 62 (ice-9 match)
64 (ssh channel) 63 (ssh session)
65 (ssh sftp)) 64 (ssh auth)
66 65 (ssh channel)
67 (define marionette 66 (ssh sftp))
68 ;; Enable TCP forwarding of the guest's port 22. 67
69 (make-marionette (list #$command "-net" 68 (define marionette
70 "user,hostfwd=tcp::2222-:22"))) 69 ;; Enable TCP forwarding of the guest's port 22.
71 70 (make-marionette (list #$vm)))
72 (define (make-session-for-test) 71
73 "Make a session with predefined parameters for a test." 72 (define (make-session-for-test)
74 (make-session #:user "root" 73 "Make a session with predefined parameters for a test."
75 #:port 2222 74 (make-session #:user "root"
76 #:host "localhost" 75 #:port 2222
77 #:log-verbosity 'protocol)) 76 #:host "localhost"
78 77 #:log-verbosity 'protocol))
79 (define (call-with-connected-session proc) 78
80 "Call the one-argument procedure PROC with a freshly created and 79 (define (call-with-connected-session proc)
80 "Call the one-argument procedure PROC with a freshly created and
81connected SSH session object, return the result of the procedure call. The 81connected SSH session object, return the result of the procedure call. The
82session is disconnected when the PROC is finished." 82session is disconnected when the PROC is finished."
83 (let ((session (make-session-for-test))) 83 (let ((session (make-session-for-test)))
84 (dynamic-wind 84 (dynamic-wind
85 (lambda () 85 (lambda ()
86 (let ((result (connect! session))) 86 (let ((result (connect! session)))
87 (unless (equal? result 'ok) 87 (unless (equal? result 'ok)
88 (error "Could not connect to a server" 88 (error "Could not connect to a server"
89 session result)))) 89 session result))))
90 (lambda () (proc session)) 90 (lambda () (proc session))
91 (lambda () (disconnect! session))))) 91 (lambda () (disconnect! session)))))
92 92
93 (define (call-with-connected-session/auth proc) 93 (define (call-with-connected-session/auth proc)
94 "Make an authenticated session. We should be able to connect as 94 "Make an authenticated session. We should be able to connect as
95root with an empty password." 95root with an empty password."
96 (call-with-connected-session 96 (call-with-connected-session
97 (lambda (session) 97 (lambda (session)
98 ;; Try the simple authentication methods. Dropbear requires 98 ;; Try the simple authentication methods. Dropbear requires
99 ;; 'none' when there are no passwords, whereas OpenSSH accepts 99 ;; 'none' when there are no passwords, whereas OpenSSH accepts
100 ;; 'password' with an empty password. 100 ;; 'password' with an empty password.
101 (let loop ((methods (list (cut userauth-password! <> "") 101 (let loop ((methods (list (cut userauth-password! <> "")
102 (cut userauth-none! <>)))) 102 (cut userauth-none! <>))))
103 (match methods 103 (match methods
104 (() 104 (()
105 (error "all the authentication methods failed")) 105 (error "all the authentication methods failed"))
106 ((auth rest ...) 106 ((auth rest ...)
107 (match (pk 'auth (auth session)) 107 (match (pk 'auth (auth session))
108 ('success 108 ('success
109 (proc session)) 109 (proc session))
110 ('denied 110 ('denied
111 (loop rest))))))))) 111 (loop rest)))))))))
112 112
113 (mkdir #$output) 113 (mkdir #$output)
114 (chdir #$output) 114 (chdir #$output)
115 115
116 (test-begin "ssh-daemon") 116 (test-begin "ssh-daemon")
117 117
118 ;; Wait for sshd to be up and running. 118 ;; Wait for sshd to be up and running.
119 (test-eq "service running" 119 (test-eq "service running"
120 'running! 120 'running!
121 (marionette-eval 121 (marionette-eval
122 '(begin 122 '(begin
123 (use-modules (gnu services herd)) 123 (use-modules (gnu services herd))
124 (start-service 'ssh-daemon) 124 (start-service 'ssh-daemon)
125 'running!) 125 'running!)
126 marionette)) 126 marionette))
127 127
128 ;; Check sshd's PID file. 128 ;; Check sshd's PID file.
129 (test-equal "sshd PID" 129 (test-equal "sshd PID"
130 (wait-for-file #$pid-file marionette) 130 (wait-for-file #$pid-file marionette)
131 (marionette-eval 131 (marionette-eval
132 '(begin 132 '(begin
133 (use-modules (gnu services herd) 133 (use-modules (gnu services herd)
134 (srfi srfi-1)) 134 (srfi srfi-1))
135 135
136 (live-service-running 136 (live-service-running
137 (find (lambda (live) 137 (find (lambda (live)
138 (memq 'ssh-daemon 138 (memq 'ssh-daemon
139 (live-service-provision live))) 139 (live-service-provision live)))
140 (current-services)))) 140 (current-services))))
141 marionette)) 141 marionette))
142 142
143 ;; Connect to the guest over SSH. Make sure we can run a shell 143 ;; Connect to the guest over SSH. Make sure we can run a shell
144 ;; command there. 144 ;; command there.
145 (test-equal "shell command" 145 (test-equal "shell command"
146 'hello 146 'hello
147 (call-with-connected-session/auth 147 (call-with-connected-session/auth
148 (lambda (session) 148 (lambda (session)
149 ;; FIXME: 'get-server-public-key' segfaults. 149 ;; FIXME: 'get-server-public-key' segfaults.
150 ;; (get-server-public-key session) 150 ;; (get-server-public-key session)
151 (let ((channel (make-channel session))) 151 (let ((channel (make-channel session)))
152 (channel-open-session channel) 152 (channel-open-session channel)
153 (channel-request-exec channel "echo hello > /root/witness") 153 (channel-request-exec channel "echo hello > /root/witness")
154 (and (zero? (channel-get-exit-status channel)) 154 (and (zero? (channel-get-exit-status channel))
155 (wait-for-file "/root/witness" marionette)))))) 155 (wait-for-file "/root/witness" marionette))))))
156 156
157 ;; Connect to the guest over SFTP. Make sure we can write and 157 ;; Connect to the guest over SFTP. Make sure we can write and
158 ;; read a file there. 158 ;; read a file there.
159 (unless #$sftp? 159 (unless #$sftp?
160 (test-skip 1)) 160 (test-skip 1))
161 (test-equal "SFTP file writing and reading" 161 (test-equal "SFTP file writing and reading"
162 'hello 162 'hello
163 (call-with-connected-session/auth 163 (call-with-connected-session/auth
164 (lambda (session) 164 (lambda (session)
165 (let ((sftp-session (make-sftp-session session)) 165 (let ((sftp-session (make-sftp-session session))
166 (witness "/root/sftp-witness")) 166 (witness "/root/sftp-witness"))
167 (call-with-remote-output-file sftp-session witness 167 (call-with-remote-output-file sftp-session witness
168 (cut display "hello" <>)) 168 (cut display "hello" <>))
169 (call-with-remote-input-file sftp-session witness 169 (call-with-remote-input-file sftp-session witness
170 read))))) 170 read)))))
171 171
172 (test-end) 172 (test-end)
173 (exit (= (test-runner-fail-count (test-runner-current)) 0))))) 173 (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
174 174
175 (gexp->derivation name test))) 175 (gexp->derivation name test))
176 176
177(define %test-openssh 177(define %test-openssh
178 (system-test 178 (system-test
diff --git a/gnu/tests/web.scm b/gnu/tests/web.scm
index bc7e3b89a94..3fa272c676d 100644
--- a/gnu/tests/web.scm
+++ b/gnu/tests/web.scm
@@ -27,7 +27,6 @@
27 #:use-module (gnu services networking) 27 #:use-module (gnu services networking)
28 #:use-module (guix gexp) 28 #:use-module (guix gexp)
29 #:use-module (guix store) 29 #:use-module (guix store)
30 #:use-module (guix monads)
31 #:export (%test-nginx)) 30 #:export (%test-nginx))
32 31
33(define %index.html-contents 32(define %index.html-contents
@@ -65,68 +64,68 @@
65(define* (run-nginx-test #:optional (http-port 8042)) 64(define* (run-nginx-test #:optional (http-port 8042))
66 "Run tests in %NGINX-OS, which has nginx running and listening on 65 "Run tests in %NGINX-OS, which has nginx running and listening on
67HTTP-PORT." 66HTTP-PORT."
68 (mlet* %store-monad ((os -> (marionette-operating-system 67 (define os
69 %nginx-os 68 (marionette-operating-system
70 #:imported-modules '((gnu services herd) 69 %nginx-os
71 (guix combinators)))) 70 #:imported-modules '((gnu services herd)
72 (command (system-qemu-image/shared-store-script 71 (guix combinators))))
73 os #:graphic? #f))) 72
74 (define test 73 (define vm
75 (with-imported-modules '((gnu build marionette)) 74 (virtual-machine
76 #~(begin 75 (operating-system os)
77 (use-modules (srfi srfi-11) (srfi srfi-64) 76 (port-forwardings `((8080 . ,http-port)))))
78 (gnu build marionette) 77
79 (web uri) 78 (define test
80 (web client) 79 (with-imported-modules '((gnu build marionette))
81 (web response)) 80 #~(begin
82 81 (use-modules (srfi srfi-11) (srfi srfi-64)
83 (define marionette 82 (gnu build marionette)
84 ;; Forward the guest's HTTP-PORT, where nginx is listening, to 83 (web uri)
85 ;; port 8080 in the host. 84 (web client)
86 (make-marionette (list #$command "-net" 85 (web response))
87 (string-append 86
88 "user,hostfwd=tcp::8080-:" 87 (define marionette
89 #$(number->string http-port))))) 88 (make-marionette (list #$vm)))
90 89
91 (mkdir #$output) 90 (mkdir #$output)
92 (chdir #$output) 91 (chdir #$output)
93 92
94 (test-begin "nginx") 93 (test-begin "nginx")
95 94
96 ;; Wait for nginx to be up and running. 95 ;; Wait for nginx to be up and running.
97 (test-eq "service running" 96 (test-eq "service running"
98 'running! 97 'running!
99 (marionette-eval 98 (marionette-eval
100 '(begin 99 '(begin
101 (use-modules (gnu services herd)) 100 (use-modules (gnu services herd))
102 (start-service 'nginx) 101 (start-service 'nginx)
103 'running!) 102 'running!)
104 marionette)) 103 marionette))
105 104
106 ;; Make sure the PID file is created. 105 ;; Make sure the PID file is created.
107 (test-assert "PID file" 106 (test-assert "PID file"
108 (marionette-eval 107 (marionette-eval
109 '(file-exists? "/var/run/nginx/pid") 108 '(file-exists? "/var/run/nginx/pid")
110 marionette)) 109 marionette))
111 110
112 ;; Retrieve the index.html file we put in /srv. 111 ;; Retrieve the index.html file we put in /srv.
113 (test-equal "http-get" 112 (test-equal "http-get"
114 '(200 #$%index.html-contents) 113 '(200 #$%index.html-contents)
115 (let-values (((response text) 114 (let-values (((response text)
116 (http-get "http://localhost:8080/index.html" 115 (http-get "http://localhost:8080/index.html"
117 #:decode-body? #t))) 116 #:decode-body? #t)))
118 (list (response-code response) text))) 117 (list (response-code response) text)))
119 118
120 ;; There should be a log file in here. 119 ;; There should be a log file in here.
121 (test-assert "log file" 120 (test-assert "log file"
122 (marionette-eval 121 (marionette-eval
123 '(file-exists? "/var/log/nginx/access.log") 122 '(file-exists? "/var/log/nginx/access.log")
124 marionette)) 123 marionette))
125 124
126 (test-end) 125 (test-end)
127 (exit (= (test-runner-fail-count (test-runner-current)) 0))))) 126 (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
128 127
129 (gexp->derivation "nginx-test" test))) 128 (gexp->derivation "nginx-test" test))
130 129
131(define %test-nginx 130(define %test-nginx
132 (system-test 131 (system-test