* [bug#27751] [PATCH 0/2] Simplify VM handling in system tests
@ 2017-07-18 8:58 Ludovic Courtès
2017-07-18 9:02 ` [bug#27751] [PATCH 1/2] vm: Add a <virtual-machine> type and associated gexp compiler Ludovic Courtès
2017-07-20 9:57 ` bug#27751: [PATCH 0/2] Simplify VM handling in system tests Ludovic Courtès
0 siblings, 2 replies; 4+ messages in thread
From: Ludovic Courtès @ 2017-07-18 8:58 UTC (permalink / raw)
To: 27751
Hello,
The attached patches simplify VM handling in system tests by
defining a new <virtual-machine> type that can be used directly
in gexps, instead of using the monadic procedures from (gnu system
vm).
The second patch shows a lot of churn but that's mostly whitespace
changes due to things being rewritten from:
(mlet* %store-monad ((os -> ...)
(command (system-qemu-image/shared-store-script ...)))
...)
to
(define os
...)
(define vm
(virtual-machine ...))
...
The next step will be to handle VMs that do not use a shared store,
is the case for the tests in (gnu system install).
Let me know what you think!
Ludo'.
Ludovic Courtès (2):
vm: Add a <virtual-machine> type and associated gexp compiler.
tests: Use 'virtual-machine' records instead of monadic procedures.
gnu/system/vm.scm | 70 +++++++++-
gnu/tests/base.scm | 314 +++++++++++++++++++++----------------------
gnu/tests/dict.scm | 145 ++++++++++----------
gnu/tests/mail.scm | 342 +++++++++++++++++++++++------------------------
gnu/tests/messaging.scm | 198 +++++++++++++--------------
gnu/tests/networking.scm | 109 +++++++--------
gnu/tests/nfs.scm | 120 ++++++++---------
gnu/tests/ssh.scm | 240 ++++++++++++++++-----------------
gnu/tests/web.scm | 125 +++++++++--------
9 files changed, 865 insertions(+), 798 deletions(-)
--
2.13.2
^ permalink raw reply [flat|nested] 4+ messages in thread
* [bug#27751] [PATCH 1/2] vm: Add a <virtual-machine> type and associated gexp compiler.
2017-07-18 8:58 [bug#27751] [PATCH 0/2] Simplify VM handling in system tests Ludovic Courtès
@ 2017-07-18 9:02 ` Ludovic Courtès
2017-07-18 9:02 ` [bug#27751] [PATCH 2/2] tests: Use 'virtual-machine' records instead of monadic procedures Ludovic Courtès
2017-07-20 9:57 ` bug#27751: [PATCH 0/2] Simplify VM handling in system tests Ludovic Courtès
1 sibling, 1 reply; 4+ messages in thread
From: Ludovic Courtès @ 2017-07-18 9:02 UTC (permalink / raw)
To: 27751
* gnu/system/vm.scm (system-qemu-image/shared-store-script): Add
#:options parameter and honor it.
(<virtual-machine>): New record type.
(virtual-machine): New macro.
(port-forwardings->qemu-options, virtual-machine-compiler): New
procedures.
---
gnu/system/vm.scm | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 67 insertions(+), 3 deletions(-)
diff --git a/gnu/system/vm.scm b/gnu/system/vm.scm
index 028649f80..ec3fb031a 100644
--- a/gnu/system/vm.scm
+++ b/gnu/system/vm.scm
@@ -68,7 +68,10 @@
system-qemu-image/shared-store
system-qemu-image/shared-store-script
- system-disk-image))
+ system-disk-image
+
+ virtual-machine
+ virtual-machine?))
\f
;;; Commentary:
@@ -576,7 +579,8 @@ with '-virtfs' options for the host file systems listed in SHARED-FS."
full-boot?
(disk-image-size
(* (if full-boot? 500 70)
- (expt 2 20))))
+ (expt 2 20)))
+ (options '()))
"Return a derivation that builds a script to run a virtual machine image of
OS that shares its store with the host. The virtual machine runs with
MEMORY-SIZE MiB of memory.
@@ -609,7 +613,8 @@ it is mostly useful when FULL-BOOT? is true."
#$@(common-qemu-options image
(map file-system-mapping-source
(cons %store-mapping mappings)))
- "-m " (number->string #$memory-size)))
+ "-m " (number->string #$memory-size)
+ #$@options))
(define builder
#~(call-with-output-file #$output
@@ -621,4 +626,63 @@ it is mostly useful when FULL-BOOT? is true."
(gexp->derivation "run-vm.sh" builder)))
+\f
+;;;
+;;; High-level abstraction.
+;;;
+
+(define-record-type* <virtual-machine> %virtual-machine
+ make-virtual-machine
+ virtual-machine?
+ (operating-system virtual-machine-operating-system) ;<operating-system>
+ (qemu virtual-machine-qemu ;<package>
+ (default qemu))
+ (graphic? virtual-machine-graphic? ;Boolean
+ (default #f))
+ (memory-size virtual-machine-memory-size ;integer (MiB)
+ (default 256))
+ (port-forwardings virtual-machine-port-forwardings ;list of integer pairs
+ (default '())))
+
+(define-syntax virtual-machine
+ (syntax-rules ()
+ "Declare a virtual machine running the specified OS, with the given
+options."
+ ((_ os) ;shortcut
+ (%virtual-machine (operating-system os)))
+ ((_ fields ...)
+ (%virtual-machine fields ...))))
+
+(define (port-forwardings->qemu-options forwardings)
+ "Return the QEMU option for the given port FORWARDINGS as a string, where
+FORWARDINGS is a list of host-port/guest-port pairs."
+ (string-join
+ (map (match-lambda
+ ((host-port . guest-port)
+ (string-append "hostfwd=tcp::"
+ (number->string host-port)
+ "-:" (number->string guest-port))))
+ forwardings)
+ ","))
+
+(define-gexp-compiler (virtual-machine-compiler (vm <virtual-machine>)
+ system target)
+ ;; XXX: SYSTEM and TARGET are ignored.
+ (match vm
+ (($ <virtual-machine> os qemu graphic? memory-size ())
+ (system-qemu-image/shared-store-script os
+ #:qemu qemu
+ #:graphic? graphic?
+ #:memory-size memory-size))
+ (($ <virtual-machine> os qemu graphic? memory-size forwardings)
+ (let ((options
+ `("-net" ,(string-append
+ "user,"
+ (port-forwardings->qemu-options forwardings)))))
+ (system-qemu-image/shared-store-script os
+ #:qemu qemu
+ #:graphic? graphic?
+ #:memory-size memory-size
+ #:options options)))))
+
;;; vm.scm ends here
--
2.13.2
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [bug#27751] [PATCH 2/2] tests: Use 'virtual-machine' records instead of monadic procedures.
2017-07-18 9:02 ` [bug#27751] [PATCH 1/2] vm: Add a <virtual-machine> type and associated gexp compiler Ludovic Courtès
@ 2017-07-18 9:02 ` Ludovic Courtès
0 siblings, 0 replies; 4+ messages in thread
From: Ludovic Courtès @ 2017-07-18 9:02 UTC (permalink / raw)
To: 27751
* 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.
---
gnu/tests/base.scm | 314 +++++++++++++++++++++----------------------
gnu/tests/dict.scm | 145 ++++++++++----------
gnu/tests/mail.scm | 342 +++++++++++++++++++++++------------------------
gnu/tests/messaging.scm | 198 +++++++++++++--------------
gnu/tests/networking.scm | 109 +++++++--------
gnu/tests/nfs.scm | 120 ++++++++---------
gnu/tests/ssh.scm | 240 ++++++++++++++++-----------------
gnu/tests/web.scm | 125 +++++++++--------
8 files changed, 798 insertions(+), 795 deletions(-)
diff --git a/gnu/tests/base.scm b/gnu/tests/base.scm
index 8389b67f6..6132aa96e 100644
--- a/gnu/tests/base.scm
+++ b/gnu/tests/base.scm
@@ -34,7 +34,6 @@
#:use-module (gnu packages package-management)
#:use-module (guix gexp)
#:use-module (guix store)
- #:use-module (guix monads)
#:use-module (guix packages)
#:use-module (srfi srfi-1)
#:export (run-basic-test
@@ -393,17 +392,16 @@ info --version")
"Instrument %SIMPLE-OS, run it in a VM, and run a series of basic
functionality tests.")
(value
- (mlet* %store-monad ((os -> (marionette-operating-system
- %simple-os
- #:imported-modules '((gnu services herd)
- (guix combinators))))
- (run (system-qemu-image/shared-store-script
- os #:graphic? #f)))
+ (let* ((os (marionette-operating-system
+ %simple-os
+ #:imported-modules '((gnu services herd)
+ (guix combinators))))
+ (vm (virtual-machine os)))
;; XXX: Add call to 'virtualized-operating-system' to get the exact same
;; set of services as the OS produced by
;; 'system-qemu-image/shared-store-script'.
(run-basic-test (virtualized-operating-system os '())
- #~(list #$run))))))
+ #~(list #$vm))))))
\f
;;;
@@ -430,60 +428,60 @@ functionality tests.")
(mcron-service (list job1 job2 job3)))))
(define (run-mcron-test name)
- (mlet* %store-monad ((os -> (marionette-operating-system
- %mcron-os
- #:imported-modules '((gnu services herd)
- (guix combinators))))
- (command (system-qemu-image/shared-store-script
- os #:graphic? #f)))
- (define test
- (with-imported-modules '((gnu build marionette))
- #~(begin
- (use-modules (gnu build marionette)
- (srfi srfi-64)
- (ice-9 match))
-
- (define marionette
- (make-marionette (list #$command)))
-
- (mkdir #$output)
- (chdir #$output)
-
- (test-begin "mcron")
-
- (test-eq "service running"
- 'running!
- (marionette-eval
- '(begin
- (use-modules (gnu services herd))
- (start-service 'mcron)
- 'running!)
- marionette))
-
- ;; Make sure root's mcron job runs, has its cwd set to "/root", and
- ;; runs with the right UID/GID.
- (test-equal "root's job"
- '(0 0)
- (wait-for-file "/root/witness" marionette))
-
- ;; Likewise for Alice's job. We cannot know what its GID is since
- ;; it's chosen by 'groupadd', but it's strictly positive.
- (test-assert "alice's job"
- (match (wait-for-file "/home/alice/witness" marionette)
- ((1000 gid)
- (>= gid 100))))
-
- ;; Last, the job that uses a command; allows us to test whether
- ;; $PATH is sane. (Note that 'marionette-eval' stringifies objects
- ;; that don't have a read syntax, hence the string.)
- (test-equal "root's job with command"
- "#<eof>"
- (wait-for-file "/root/witness-touch" marionette))
-
- (test-end)
- (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
-
- (gexp->derivation name test)))
+ (define os
+ (marionette-operating-system
+ %mcron-os
+ #:imported-modules '((gnu services herd)
+ (guix combinators))))
+
+ (define test
+ (with-imported-modules '((gnu build marionette))
+ #~(begin
+ (use-modules (gnu build marionette)
+ (srfi srfi-64)
+ (ice-9 match))
+
+ (define marionette
+ (make-marionette (list #$(virtual-machine os))))
+
+ (mkdir #$output)
+ (chdir #$output)
+
+ (test-begin "mcron")
+
+ (test-eq "service running"
+ 'running!
+ (marionette-eval
+ '(begin
+ (use-modules (gnu services herd))
+ (start-service 'mcron)
+ 'running!)
+ marionette))
+
+ ;; Make sure root's mcron job runs, has its cwd set to "/root", and
+ ;; runs with the right UID/GID.
+ (test-equal "root's job"
+ '(0 0)
+ (wait-for-file "/root/witness" marionette))
+
+ ;; Likewise for Alice's job. We cannot know what its GID is since
+ ;; it's chosen by 'groupadd', but it's strictly positive.
+ (test-assert "alice's job"
+ (match (wait-for-file "/home/alice/witness" marionette)
+ ((1000 gid)
+ (>= gid 100))))
+
+ ;; Last, the job that uses a command; allows us to test whether
+ ;; $PATH is sane. (Note that 'marionette-eval' stringifies objects
+ ;; that don't have a read syntax, hence the string.)
+ (test-equal "root's job with command"
+ "#<eof>"
+ (wait-for-file "/root/witness-touch" marionette))
+
+ (test-end)
+ (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
+
+ (gexp->derivation name test))
(define %test-mcron
(system-test
@@ -526,102 +524,102 @@ functionality tests.")
;; *after* nscd. Failing to do that, libc will try to connect to nscd,
;; fail, then never try again (see '__nss_not_use_nscd_hosts' in libc),
;; leading to '.local' resolution failures.
- (mlet* %store-monad ((os -> (marionette-operating-system
- %avahi-os
- #:requirements '(nscd)
- #:imported-modules '((gnu services herd)
- (guix combinators))))
- (run (system-qemu-image/shared-store-script
- os #:graphic? #f)))
- (define mdns-host-name
- (string-append (operating-system-host-name os)
- ".local"))
-
- (define test
- (with-imported-modules '((gnu build marionette))
- #~(begin
- (use-modules (gnu build marionette)
- (srfi srfi-1)
- (srfi srfi-64)
- (ice-9 match))
-
- (define marionette
- (make-marionette (list #$run)))
-
- (mkdir #$output)
- (chdir #$output)
-
- (test-begin "avahi")
-
- (test-assert "wait for services"
- (marionette-eval
- '(begin
- (use-modules (gnu services herd))
-
- (start-service 'nscd)
-
- ;; XXX: Work around a race condition in nscd: nscd creates its
- ;; PID file before it is listening on its socket.
- (let ((sock (socket PF_UNIX SOCK_STREAM 0)))
- (let try ()
- (catch 'system-error
- (lambda ()
- (connect sock AF_UNIX "/var/run/nscd/socket")
- (close-port sock)
- (format #t "nscd is ready~%"))
- (lambda args
- (format #t "waiting for nscd...~%")
- (usleep 500000)
- (try)))))
-
- ;; Wait for the other useful things.
- (start-service 'avahi-daemon)
- (start-service 'networking)
-
- #t)
- marionette))
-
- (test-equal "avahi-resolve-host-name"
- 0
- (marionette-eval
- '(system*
- "/run/current-system/profile/bin/avahi-resolve-host-name"
- "-v" #$mdns-host-name)
- marionette))
-
- (test-equal "avahi-browse"
- 0
- (marionette-eval
- '(system* "avahi-browse" "-avt")
- marionette))
-
- (test-assert "getaddrinfo .local"
- ;; Wait for the 'avahi-daemon' service and perform a resolution.
- (match (marionette-eval
- '(getaddrinfo #$mdns-host-name)
- marionette)
- (((? vector? addrinfos) ..1)
- (pk 'getaddrinfo addrinfos)
- (and (any (lambda (ai)
- (= AF_INET (addrinfo:fam ai)))
- addrinfos)
- (any (lambda (ai)
- (= AF_INET6 (addrinfo:fam ai)))
- addrinfos)))))
-
- (test-assert "gethostbyname .local"
- (match (pk 'gethostbyname
- (marionette-eval '(gethostbyname #$mdns-host-name)
- marionette))
- ((? vector? result)
- (and (string=? (hostent:name result) #$mdns-host-name)
- (= (hostent:addrtype result) AF_INET)))))
-
-
- (test-end)
- (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
-
- (gexp->derivation "nss-mdns" test)))
+ (define os
+ (marionette-operating-system
+ %avahi-os
+ #:requirements '(nscd)
+ #:imported-modules '((gnu services herd)
+ (guix combinators))))
+
+ (define mdns-host-name
+ (string-append (operating-system-host-name os)
+ ".local"))
+
+ (define test
+ (with-imported-modules '((gnu build marionette))
+ #~(begin
+ (use-modules (gnu build marionette)
+ (srfi srfi-1)
+ (srfi srfi-64)
+ (ice-9 match))
+
+ (define marionette
+ (make-marionette (list #$(virtual-machine os))))
+
+ (mkdir #$output)
+ (chdir #$output)
+
+ (test-begin "avahi")
+
+ (test-assert "wait for services"
+ (marionette-eval
+ '(begin
+ (use-modules (gnu services herd))
+
+ (start-service 'nscd)
+
+ ;; XXX: Work around a race condition in nscd: nscd creates its
+ ;; PID file before it is listening on its socket.
+ (let ((sock (socket PF_UNIX SOCK_STREAM 0)))
+ (let try ()
+ (catch 'system-error
+ (lambda ()
+ (connect sock AF_UNIX "/var/run/nscd/socket")
+ (close-port sock)
+ (format #t "nscd is ready~%"))
+ (lambda args
+ (format #t "waiting for nscd...~%")
+ (usleep 500000)
+ (try)))))
+
+ ;; Wait for the other useful things.
+ (start-service 'avahi-daemon)
+ (start-service 'networking)
+
+ #t)
+ marionette))
+
+ (test-equal "avahi-resolve-host-name"
+ 0
+ (marionette-eval
+ '(system*
+ "/run/current-system/profile/bin/avahi-resolve-host-name"
+ "-v" #$mdns-host-name)
+ marionette))
+
+ (test-equal "avahi-browse"
+ 0
+ (marionette-eval
+ '(system* "avahi-browse" "-avt")
+ marionette))
+
+ (test-assert "getaddrinfo .local"
+ ;; Wait for the 'avahi-daemon' service and perform a resolution.
+ (match (marionette-eval
+ '(getaddrinfo #$mdns-host-name)
+ marionette)
+ (((? vector? addrinfos) ..1)
+ (pk 'getaddrinfo addrinfos)
+ (and (any (lambda (ai)
+ (= AF_INET (addrinfo:fam ai)))
+ addrinfos)
+ (any (lambda (ai)
+ (= AF_INET6 (addrinfo:fam ai)))
+ addrinfos)))))
+
+ (test-assert "gethostbyname .local"
+ (match (pk 'gethostbyname
+ (marionette-eval '(gethostbyname #$mdns-host-name)
+ marionette))
+ ((? vector? result)
+ (and (string=? (hostent:name result) #$mdns-host-name)
+ (= (hostent:addrtype result) AF_INET)))))
+
+
+ (test-end)
+ (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
+
+ (gexp->derivation "nss-mdns" test))
(define %test-nss-mdns
(system-test
diff --git a/gnu/tests/dict.scm b/gnu/tests/dict.scm
index 16b6edbd9..b9c741e3e 100644
--- a/gnu/tests/dict.scm
+++ b/gnu/tests/dict.scm
@@ -27,7 +27,6 @@
#:use-module (gnu packages wordnet)
#:use-module (guix gexp)
#:use-module (guix store)
- #:use-module (guix monads)
#:use-module (guix packages)
#:use-module (guix modules)
#:export (%test-dicod))
@@ -54,86 +53,90 @@
(define* (run-dicod-test)
"Run tests of 'dicod-service-type'."
- (mlet* %store-monad ((os -> (marionette-operating-system
- %dicod-os
- #:imported-modules
- (source-module-closure '((gnu services herd)))))
- (command (system-qemu-image/shared-store-script
- os #:graphic? #f)))
- (define test
- (with-imported-modules '((gnu build marionette))
- #~(begin
- (use-modules (ice-9 rdelim)
- (ice-9 regex)
- (srfi srfi-64)
- (gnu build marionette))
- (define marionette
- ;; Forward the guest's DICT port to local port 8000.
- (make-marionette (list #$command "-net"
- "user,hostfwd=tcp::8000-:2628")))
+ (define os
+ (marionette-operating-system
+ %dicod-os
+ #:imported-modules
+ (source-module-closure '((gnu services herd)))))
- (define %dico-socket
- (socket PF_INET SOCK_STREAM 0))
+ (define vm
+ (virtual-machine
+ (operating-system os)
+ (port-forwardings '((8000 . 2628)))))
- (mkdir #$output)
- (chdir #$output)
+ (define test
+ (with-imported-modules '((gnu build marionette))
+ #~(begin
+ (use-modules (ice-9 rdelim)
+ (ice-9 regex)
+ (srfi srfi-64)
+ (gnu build marionette))
+ (define marionette
+ ;; Forward the guest's DICT port to local port 8000.
+ (make-marionette (list #$vm)))
- (test-begin "dicod")
+ (define %dico-socket
+ (socket PF_INET SOCK_STREAM 0))
- ;; Wait for the service to be started.
- (test-eq "service is running"
- 'running!
- (marionette-eval
- '(begin
- (use-modules (gnu services herd))
- (start-service 'dicod)
- 'running!)
- marionette))
+ (mkdir #$output)
+ (chdir #$output)
- ;; Wait until dicod is actually listening.
- ;; TODO: Use a PID file instead.
- (test-assert "connect inside"
- (marionette-eval
- '(begin
- (use-modules (ice-9 rdelim))
- (let ((sock (socket PF_INET SOCK_STREAM 0)))
- (let loop ((i 0))
- (pk 'try i)
- (catch 'system-error
- (lambda ()
- (connect sock AF_INET INADDR_LOOPBACK 2628))
- (lambda args
- (pk 'connection-error args)
- (when (< i 20)
- (sleep 1)
- (loop (+ 1 i))))))
- (read-line sock 'concat)))
- marionette))
+ (test-begin "dicod")
- (test-assert "connect"
- (let ((addr (make-socket-address AF_INET INADDR_LOOPBACK 8000)))
- (connect %dico-socket addr)
- (read-line %dico-socket 'concat)))
+ ;; Wait for the service to be started.
+ (test-eq "service is running"
+ 'running!
+ (marionette-eval
+ '(begin
+ (use-modules (gnu services herd))
+ (start-service 'dicod)
+ 'running!)
+ marionette))
- (test-equal "CLIENT"
- "250 ok\r\n"
- (begin
- (display "CLIENT \"GNU Guile\"\r\n" %dico-socket)
- (read-line %dico-socket 'concat)))
+ ;; Wait until dicod is actually listening.
+ ;; TODO: Use a PID file instead.
+ (test-assert "connect inside"
+ (marionette-eval
+ '(begin
+ (use-modules (ice-9 rdelim))
+ (let ((sock (socket PF_INET SOCK_STREAM 0)))
+ (let loop ((i 0))
+ (pk 'try i)
+ (catch 'system-error
+ (lambda ()
+ (connect sock AF_INET INADDR_LOOPBACK 2628))
+ (lambda args
+ (pk 'connection-error args)
+ (when (< i 20)
+ (sleep 1)
+ (loop (+ 1 i))))))
+ (read-line sock 'concat)))
+ marionette))
- (test-assert "DEFINE"
- (begin
- (display "DEFINE ! hello\r\n" %dico-socket)
- (display "QUIT\r\n" %dico-socket)
- (let ((result (read-string %dico-socket)))
- (and (string-contains result "gcide")
- (string-contains result "hello")
- result))))
+ (test-assert "connect"
+ (let ((addr (make-socket-address AF_INET INADDR_LOOPBACK 8000)))
+ (connect %dico-socket addr)
+ (read-line %dico-socket 'concat)))
- (test-end)
- (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
+ (test-equal "CLIENT"
+ "250 ok\r\n"
+ (begin
+ (display "CLIENT \"GNU Guile\"\r\n" %dico-socket)
+ (read-line %dico-socket 'concat)))
- (gexp->derivation "dicod" test)))
+ (test-assert "DEFINE"
+ (begin
+ (display "DEFINE ! hello\r\n" %dico-socket)
+ (display "QUIT\r\n" %dico-socket)
+ (let ((result (read-string %dico-socket)))
+ (and (string-contains result "gcide")
+ (string-contains result "hello")
+ result))))
+
+ (test-end)
+ (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
+
+ (gexp->derivation "dicod" test))
(define %test-dicod
(system-test
diff --git a/gnu/tests/mail.scm b/gnu/tests/mail.scm
index 247f4f667..312df9b1c 100644
--- a/gnu/tests/mail.scm
+++ b/gnu/tests/mail.scm
@@ -1,6 +1,7 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2016 Sou Bunnbu <iyzsong@member.fsf.org>
;;; Copyright © 2017 Carlo Zancanaro <carlo@zancanaro.id.au>
+;;; Copyright © 2017 Ludovic Courtès <ludo@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -25,7 +26,6 @@
#:use-module (gnu services mail)
#:use-module (gnu services networking)
#:use-module (guix gexp)
- #:use-module (guix monads)
#:use-module (guix store)
#:use-module (ice-9 ftw)
#:export (%test-opensmtpd
@@ -44,105 +44,105 @@ accept from any for local deliver to mbox
(define (run-opensmtpd-test)
"Return a test of an OS running OpenSMTPD service."
- (mlet* %store-monad ((command (system-qemu-image/shared-store-script
- (marionette-operating-system
- %opensmtpd-os
- #:imported-modules '((gnu services herd)))
- #:graphic? #f)))
- (define test
- (with-imported-modules '((gnu build marionette))
- #~(begin
- (use-modules (rnrs base)
- (srfi srfi-64)
- (ice-9 rdelim)
- (ice-9 regex)
- (gnu build marionette))
+ (define vm
+ (virtual-machine
+ (operating-system (marionette-operating-system
+ %opensmtpd-os
+ #:imported-modules '((gnu services herd))))
+ (port-forwardings '((1025 . 25)))))
- (define marionette
- (make-marionette
- ;; Enable TCP forwarding of the guest's port 25.
- '(#$command "-net" "user,hostfwd=tcp::1025-:25")))
+ (define test
+ (with-imported-modules '((gnu build marionette))
+ #~(begin
+ (use-modules (rnrs base)
+ (srfi srfi-64)
+ (ice-9 rdelim)
+ (ice-9 regex)
+ (gnu build marionette))
- (define (read-reply-code port)
- "Read a SMTP reply from PORT and return its reply code."
- (let* ((line (read-line port))
- (mo (string-match "([0-9]+)([ -]).*" line))
- (code (string->number (match:substring mo 1)))
- (finished? (string= " " (match:substring mo 2))))
- (if finished?
- code
- (read-reply-code port))))
+ (define marionette
+ (make-marionette '(#$vm)))
- (mkdir #$output)
- (chdir #$output)
+ (define (read-reply-code port)
+ "Read a SMTP reply from PORT and return its reply code."
+ (let* ((line (read-line port))
+ (mo (string-match "([0-9]+)([ -]).*" line))
+ (code (string->number (match:substring mo 1)))
+ (finished? (string= " " (match:substring mo 2))))
+ (if finished?
+ code
+ (read-reply-code port))))
- (test-begin "opensmptd")
+ (mkdir #$output)
+ (chdir #$output)
- (test-assert "service is running"
- (marionette-eval
- '(begin
- (use-modules (gnu services herd))
- (start-service 'smtpd)
- #t)
- marionette))
+ (test-begin "opensmptd")
- (test-assert "mbox is empty"
- (marionette-eval
- '(and (file-exists? "/var/mail")
- (not (file-exists? "/var/mail/root")))
- marionette))
+ (test-assert "service is running"
+ (marionette-eval
+ '(begin
+ (use-modules (gnu services herd))
+ (start-service 'smtpd)
+ #t)
+ marionette))
- (test-eq "accept an email"
- #t
- (let* ((smtp (socket AF_INET SOCK_STREAM 0))
- (addr (make-socket-address AF_INET INADDR_LOOPBACK 1025)))
- (connect smtp addr)
- ;; Be greeted.
- (read-reply-code smtp) ;220
- ;; Greet the server.
- (write-line "EHLO somehost" smtp)
- (read-reply-code smtp) ;250
- ;; Set sender email.
- (write-line "MAIL FROM: <someone>" smtp)
- (read-reply-code smtp) ;250
- ;; Set recipient email.
- (write-line "RCPT TO: <root>" smtp)
- (read-reply-code smtp) ;250
- ;; Send message.
- (write-line "DATA" smtp)
- (read-reply-code smtp) ;354
- (write-line "Subject: Hello" smtp)
- (newline smtp)
- (write-line "Nice to meet you!" smtp)
- (write-line "." smtp)
- (read-reply-code smtp) ;250
- ;; Say goodbye.
- (write-line "QUIT" smtp)
- (read-reply-code smtp) ;221
- (close smtp)
- #t))
+ (test-assert "mbox is empty"
+ (marionette-eval
+ '(and (file-exists? "/var/mail")
+ (not (file-exists? "/var/mail/root")))
+ marionette))
- (test-assert "mail arrived"
- (marionette-eval
- '(begin
- (use-modules (ice-9 popen)
- (ice-9 rdelim))
+ (test-eq "accept an email"
+ #t
+ (let* ((smtp (socket AF_INET SOCK_STREAM 0))
+ (addr (make-socket-address AF_INET INADDR_LOOPBACK 1025)))
+ (connect smtp addr)
+ ;; Be greeted.
+ (read-reply-code smtp) ;220
+ ;; Greet the server.
+ (write-line "EHLO somehost" smtp)
+ (read-reply-code smtp) ;250
+ ;; Set sender email.
+ (write-line "MAIL FROM: <someone>" smtp)
+ (read-reply-code smtp) ;250
+ ;; Set recipient email.
+ (write-line "RCPT TO: <root>" smtp)
+ (read-reply-code smtp) ;250
+ ;; Send message.
+ (write-line "DATA" smtp)
+ (read-reply-code smtp) ;354
+ (write-line "Subject: Hello" smtp)
+ (newline smtp)
+ (write-line "Nice to meet you!" smtp)
+ (write-line "." smtp)
+ (read-reply-code smtp) ;250
+ ;; Say goodbye.
+ (write-line "QUIT" smtp)
+ (read-reply-code smtp) ;221
+ (close smtp)
+ #t))
- (define (queue-empty?)
- (eof-object?
- (read-line
- (open-input-pipe "smtpctl show queue"))))
+ (test-assert "mail arrived"
+ (marionette-eval
+ '(begin
+ (use-modules (ice-9 popen)
+ (ice-9 rdelim))
- (let wait ()
- (if (queue-empty?)
- (file-exists? "/var/mail/root")
- (begin (sleep 1) (wait)))))
- marionette))
+ (define (queue-empty?)
+ (eof-object?
+ (read-line
+ (open-input-pipe "smtpctl show queue"))))
- (test-end)
- (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
+ (let wait ()
+ (if (queue-empty?)
+ (file-exists? "/var/mail/root")
+ (begin (sleep 1) (wait)))))
+ marionette))
- (gexp->derivation "opensmtpd-test" test)))
+ (test-end)
+ (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
+
+ (gexp->derivation "opensmtpd-test" test))
(define %test-opensmtpd
(system-test
@@ -179,100 +179,100 @@ acl_check_data:
(define (run-exim-test)
"Return a test of an OS running an Exim service."
- (mlet* %store-monad ((command (system-qemu-image/shared-store-script
- (marionette-operating-system
- %exim-os
- #:imported-modules '((gnu services herd)))
- #:graphic? #f)))
- (define test
- (with-imported-modules '((gnu build marionette)
- (ice-9 ftw))
- #~(begin
- (use-modules (rnrs base)
- (srfi srfi-64)
- (ice-9 ftw)
- (ice-9 rdelim)
- (ice-9 regex)
- (gnu build marionette))
+ (define vm
+ (virtual-machine
+ (operating-system (marionette-operating-system
+ %exim-os
+ #:imported-modules '((gnu services herd))))
+ (port-forwardings '((1025 . 25)))))
- (define marionette
- (make-marionette
- ;; Enable TCP forwarding of the guest's port 25.
- '(#$command "-net" "user,hostfwd=tcp::1025-:25")))
+ (define test
+ (with-imported-modules '((gnu build marionette)
+ (ice-9 ftw))
+ #~(begin
+ (use-modules (rnrs base)
+ (srfi srfi-64)
+ (ice-9 ftw)
+ (ice-9 rdelim)
+ (ice-9 regex)
+ (gnu build marionette))
- (define (read-reply-code port)
- "Read a SMTP reply from PORT and return its reply code."
- (let* ((line (read-line port))
- (mo (string-match "([0-9]+)([ -]).*" line))
- (code (string->number (match:substring mo 1)))
- (finished? (string= " " (match:substring mo 2))))
- (if finished?
- code
- (read-reply-code port))))
+ (define marionette
+ (make-marionette '(#$vm)))
- (define smtp (socket AF_INET SOCK_STREAM 0))
- (define addr (make-socket-address AF_INET INADDR_LOOPBACK 1025))
+ (define (read-reply-code port)
+ "Read a SMTP reply from PORT and return its reply code."
+ (let* ((line (read-line port))
+ (mo (string-match "([0-9]+)([ -]).*" line))
+ (code (string->number (match:substring mo 1)))
+ (finished? (string= " " (match:substring mo 2))))
+ (if finished?
+ code
+ (read-reply-code port))))
- (mkdir #$output)
- (chdir #$output)
+ (define smtp (socket AF_INET SOCK_STREAM 0))
+ (define addr (make-socket-address AF_INET INADDR_LOOPBACK 1025))
- (test-begin "exim")
+ (mkdir #$output)
+ (chdir #$output)
- (test-assert "service is running"
- (marionette-eval
- '(begin
- (use-modules (gnu services herd))
- (start-service 'exim)
- #t)
- marionette))
+ (test-begin "exim")
- (sleep 1) ;; give the service time to start talking
+ (test-assert "service is running"
+ (marionette-eval
+ '(begin
+ (use-modules (gnu services herd))
+ (start-service 'exim)
+ #t)
+ marionette))
- (connect smtp addr)
- ;; Be greeted.
- (test-eq "greeting received"
- 220 (read-reply-code smtp))
- ;; Greet the server.
- (write-line "EHLO somehost" smtp)
- (test-eq "greeting successful"
- 250 (read-reply-code smtp))
- ;; Set sender email.
- (write-line "MAIL FROM: test@example.com" smtp)
- (test-eq "sender set"
- 250 (read-reply-code smtp)) ;250
- ;; Set recipient email.
- (write-line "RCPT TO: root@komputilo" smtp)
- (test-eq "recipient set"
- 250 (read-reply-code smtp)) ;250
- ;; Send message.
- (write-line "DATA" smtp)
- (test-eq "data begun"
- 354 (read-reply-code smtp)) ;354
- (write-line "Subject: Hello" smtp)
- (newline smtp)
- (write-line "Nice to meet you!" smtp)
- (write-line "." smtp)
- (test-eq "message sent"
- 250 (read-reply-code smtp)) ;250
- ;; Say goodbye.
- (write-line "QUIT" smtp)
- (test-eq "quit successful"
- 221 (read-reply-code smtp)) ;221
- (close smtp)
+ (sleep 1) ;; give the service time to start talking
- (test-eq "the email is received"
- 1
- (marionette-eval
- '(begin
- (use-modules (ice-9 ftw))
- (length (scandir "/var/spool/exim/msglog"
- (lambda (x) (not (string-prefix? "." x))))))
- marionette))
+ (connect smtp addr)
+ ;; Be greeted.
+ (test-eq "greeting received"
+ 220 (read-reply-code smtp))
+ ;; Greet the server.
+ (write-line "EHLO somehost" smtp)
+ (test-eq "greeting successful"
+ 250 (read-reply-code smtp))
+ ;; Set sender email.
+ (write-line "MAIL FROM: test@example.com" smtp)
+ (test-eq "sender set"
+ 250 (read-reply-code smtp)) ;250
+ ;; Set recipient email.
+ (write-line "RCPT TO: root@komputilo" smtp)
+ (test-eq "recipient set"
+ 250 (read-reply-code smtp)) ;250
+ ;; Send message.
+ (write-line "DATA" smtp)
+ (test-eq "data begun"
+ 354 (read-reply-code smtp)) ;354
+ (write-line "Subject: Hello" smtp)
+ (newline smtp)
+ (write-line "Nice to meet you!" smtp)
+ (write-line "." smtp)
+ (test-eq "message sent"
+ 250 (read-reply-code smtp)) ;250
+ ;; Say goodbye.
+ (write-line "QUIT" smtp)
+ (test-eq "quit successful"
+ 221 (read-reply-code smtp)) ;221
+ (close smtp)
- (test-end)
- (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
+ (test-eq "the email is received"
+ 1
+ (marionette-eval
+ '(begin
+ (use-modules (ice-9 ftw))
+ (length (scandir "/var/spool/exim/msglog"
+ (lambda (x) (not (string-prefix? "." x))))))
+ marionette))
- (gexp->derivation "exim-test" test)))
+ (test-end)
+ (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
+
+ (gexp->derivation "exim-test" test))
(define %test-exim
(system-test
diff --git a/gnu/tests/messaging.scm b/gnu/tests/messaging.scm
index b76b8e843..0ba0c839d 100644
--- a/gnu/tests/messaging.scm
+++ b/gnu/tests/messaging.scm
@@ -1,5 +1,6 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2017 Clément Lassieur <clement@lassieur.org>
+;;; Copyright © 2017 Ludovic Courtès <ludo@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -26,108 +27,109 @@
#:use-module (gnu packages messaging)
#:use-module (guix gexp)
#:use-module (guix store)
- #:use-module (guix monads)
#:export (%test-prosody))
(define (run-xmpp-test name xmpp-service pid-file create-account)
"Run a test of an OS running XMPP-SERVICE, which writes its PID to PID-FILE."
- (mlet* %store-monad ((os -> (marionette-operating-system
- (simple-operating-system (dhcp-client-service)
- xmpp-service)
- #:imported-modules '((gnu services herd))))
- (command (system-qemu-image/shared-store-script
- os #:graphic? #f))
- (username -> "alice")
- (server -> "localhost")
- (jid -> (string-append username "@" server))
- (password -> "correct horse battery staple")
- (port -> 15222)
- (message -> "hello world")
- (witness -> "/tmp/freetalk-witness"))
-
- (define script.ft
- (scheme-file
- "script.ft"
- #~(begin
- (define (handle-received-message time from nickname message)
- (define (touch file-name)
- (call-with-output-file file-name (const #t)))
- (when (equal? message #$message)
- (touch #$witness)))
- (add-hook! ft-message-receive-hook handle-received-message)
-
- (ft-set-jid! #$jid)
- (ft-set-password! #$password)
- (ft-set-server! #$server)
- (ft-set-port! #$port)
- (ft-set-sslconn! #f)
- (ft-connect-blocking)
- (ft-send-message #$jid #$message)
-
- (ft-set-daemon)
- (ft-main-loop))))
-
- (define test
- (with-imported-modules '((gnu build marionette))
- #~(begin
- (use-modules (gnu build marionette)
- (srfi srfi-64))
-
- (define marionette
- ;; Enable TCP forwarding of the guest's port 5222.
- (make-marionette (list #$command "-net"
- (string-append "user,hostfwd=tcp::"
- (number->string #$port)
- "-:5222"))))
-
- (define (host-wait-for-file file)
- ;; Wait until FILE exists in the host.
- (let loop ((i 60))
- (cond ((file-exists? file)
- #t)
- ((> i 0)
- (begin
- (sleep 1))
- (loop (- i 1)))
- (else
- (error "file didn't show up" file)))))
-
- (mkdir #$output)
- (chdir #$output)
-
- (test-begin "xmpp")
-
- ;; Wait for XMPP service to be up and running.
- (test-eq "service running"
- 'running!
- (marionette-eval
- '(begin
- (use-modules (gnu services herd))
- (start-service 'xmpp-daemon)
- 'running!)
- marionette))
-
- ;; Check XMPP service's PID.
- (test-assert "service process id"
- (let ((pid (number->string (wait-for-file #$pid-file
- marionette))))
- (marionette-eval `(file-exists? (string-append "/proc/" ,pid))
- marionette)))
-
- ;; Alice sends an XMPP message to herself, with Freetalk.
- (test-assert "client-to-server communication"
- (let ((freetalk-bin (string-append #$freetalk "/bin/freetalk")))
- (marionette-eval '(system* #$create-account #$jid #$password)
- marionette)
- ;; Freetalk requires write access to $HOME.
- (setenv "HOME" "/tmp")
- (system* freetalk-bin "-s" #$script.ft)
- (host-wait-for-file #$witness)))
-
- (test-end)
- (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
-
- (gexp->derivation name test)))
+ (define os
+ (marionette-operating-system
+ (simple-operating-system (dhcp-client-service)
+ xmpp-service)
+ #:imported-modules '((gnu services herd))))
+
+ (define port 15222)
+
+ (define vm
+ (virtual-machine
+ (operating-system os)
+ (port-forwardings `((,port . 5222)))))
+
+ (define username "alice")
+ (define server "localhost")
+ (define jid (string-append username "@" server))
+ (define password "correct horse battery staple")
+ (define message "hello world")
+ (define witness "/tmp/freetalk-witness")
+
+ (define script.ft
+ (scheme-file
+ "script.ft"
+ #~(begin
+ (define (handle-received-message time from nickname message)
+ (define (touch file-name)
+ (call-with-output-file file-name (const #t)))
+ (when (equal? message #$message)
+ (touch #$witness)))
+ (add-hook! ft-message-receive-hook handle-received-message)
+
+ (ft-set-jid! #$jid)
+ (ft-set-password! #$password)
+ (ft-set-server! #$server)
+ (ft-set-port! #$port)
+ (ft-set-sslconn! #f)
+ (ft-connect-blocking)
+ (ft-send-message #$jid #$message)
+
+ (ft-set-daemon)
+ (ft-main-loop))))
+
+ (define test
+ (with-imported-modules '((gnu build marionette))
+ #~(begin
+ (use-modules (gnu build marionette)
+ (srfi srfi-64))
+
+ (define marionette
+ (make-marionette (list #$vm)))
+
+ (define (host-wait-for-file file)
+ ;; Wait until FILE exists in the host.
+ (let loop ((i 60))
+ (cond ((file-exists? file)
+ #t)
+ ((> i 0)
+ (begin
+ (sleep 1))
+ (loop (- i 1)))
+ (else
+ (error "file didn't show up" file)))))
+
+ (mkdir #$output)
+ (chdir #$output)
+
+ (test-begin "xmpp")
+
+ ;; Wait for XMPP service to be up and running.
+ (test-eq "service running"
+ 'running!
+ (marionette-eval
+ '(begin
+ (use-modules (gnu services herd))
+ (start-service 'xmpp-daemon)
+ 'running!)
+ marionette))
+
+ ;; Check XMPP service's PID.
+ (test-assert "service process id"
+ (let ((pid (number->string (wait-for-file #$pid-file
+ marionette))))
+ (marionette-eval `(file-exists? (string-append "/proc/" ,pid))
+ marionette)))
+
+ ;; Alice sends an XMPP message to herself, with Freetalk.
+ (test-assert "client-to-server communication"
+ (let ((freetalk-bin (string-append #$freetalk "/bin/freetalk")))
+ (marionette-eval '(system* #$create-account #$jid #$password)
+ marionette)
+ ;; Freetalk requires write access to $HOME.
+ (setenv "HOME" "/tmp")
+ (system* freetalk-bin "-s" #$script.ft)
+ (host-wait-for-file #$witness)))
+
+ (test-end)
+ (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
+
+ (gexp->derivation name test))
(define %create-prosody-account
(program-file
diff --git a/gnu/tests/networking.scm b/gnu/tests/networking.scm
index cfcb49087..aeee105a1 100644
--- a/gnu/tests/networking.scm
+++ b/gnu/tests/networking.scm
@@ -74,60 +74,61 @@ done" ))))))))))
(define* (run-inetd-test)
"Run tests in %INETD-OS, where the inetd service provides an echo service on
port 7, and a dict service on port 2628."
- (mlet* %store-monad ((os -> (marionette-operating-system %inetd-os))
- (command (system-qemu-image/shared-store-script
- os #:graphic? #f)))
- (define test
- (with-imported-modules '((gnu build marionette))
- #~(begin
- (use-modules (ice-9 rdelim)
- (srfi srfi-64)
- (gnu build marionette))
- (define marionette
- ;; Forward guest ports 7 and 2628 to host ports 8007 and 8628.
- (make-marionette (list #$command "-net"
- (string-append
- "user"
- ",hostfwd=tcp::8007-:7"
- ",hostfwd=tcp::8628-:2628"))))
-
- (mkdir #$output)
- (chdir #$output)
-
- (test-begin "inetd")
-
- ;; Make sure the PID file is created.
- (test-assert "PID file"
- (marionette-eval
- '(file-exists? "/var/run/inetd.pid")
- marionette))
-
- ;; Test the echo service.
- (test-equal "echo response"
- "Hello, Guix!"
- (let ((echo (socket PF_INET SOCK_STREAM 0))
- (addr (make-socket-address AF_INET INADDR_LOOPBACK 8007)))
- (connect echo addr)
- (display "Hello, Guix!\n" echo)
- (let ((response (read-line echo)))
- (close echo)
- response)))
-
- ;; Test the dict service
- (test-equal "dict response"
- "GNU Guix is a package management tool for the GNU system."
- (let ((dict (socket PF_INET SOCK_STREAM 0))
- (addr (make-socket-address AF_INET INADDR_LOOPBACK 8628)))
- (connect dict addr)
- (display "DEFINE Guix\n" dict)
- (let ((response (read-line dict)))
- (close dict)
- response)))
-
- (test-end)
- (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
-
- (gexp->derivation "inetd-test" test)))
+ (define os
+ (marionette-operating-system %inetd-os))
+
+ (define vm
+ (virtual-machine
+ (operating-system os)
+ (port-forwardings `((8007 . 7)
+ (8628 . 2628)))))
+
+ (define test
+ (with-imported-modules '((gnu build marionette))
+ #~(begin
+ (use-modules (ice-9 rdelim)
+ (srfi srfi-64)
+ (gnu build marionette))
+ (define marionette
+ (make-marionette (list #$vm)))
+
+ (mkdir #$output)
+ (chdir #$output)
+
+ (test-begin "inetd")
+
+ ;; Make sure the PID file is created.
+ (test-assert "PID file"
+ (marionette-eval
+ '(file-exists? "/var/run/inetd.pid")
+ marionette))
+
+ ;; Test the echo service.
+ (test-equal "echo response"
+ "Hello, Guix!"
+ (let ((echo (socket PF_INET SOCK_STREAM 0))
+ (addr (make-socket-address AF_INET INADDR_LOOPBACK 8007)))
+ (connect echo addr)
+ (display "Hello, Guix!\n" echo)
+ (let ((response (read-line echo)))
+ (close echo)
+ response)))
+
+ ;; Test the dict service
+ (test-equal "dict response"
+ "GNU Guix is a package management tool for the GNU system."
+ (let ((dict (socket PF_INET SOCK_STREAM 0))
+ (addr (make-socket-address AF_INET INADDR_LOOPBACK 8628)))
+ (connect dict addr)
+ (display "DEFINE Guix\n" dict)
+ (let ((response (read-line dict)))
+ (close dict)
+ response)))
+
+ (test-end)
+ (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
+
+ (gexp->derivation "inetd-test" test))
(define %test-inetd
(system-test
diff --git a/gnu/tests/nfs.scm b/gnu/tests/nfs.scm
index 9e1ac1d55..2e666b2c0 100644
--- a/gnu/tests/nfs.scm
+++ b/gnu/tests/nfs.scm
@@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2016 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2016, 2017 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2016 John Darrington <jmd@gnu.org>
;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com>
;;;
@@ -55,75 +55,75 @@
(define (run-nfs-test name socket)
"Run a test of an OS running RPC-SERVICE, which should create SOCKET."
- (mlet* %store-monad ((os -> (marionette-operating-system
- %base-os
- #:imported-modules '((gnu services herd)
- (guix combinators))))
- (command (system-qemu-image/shared-store-script
- os #:graphic? #f)))
- (define test
- (with-imported-modules '((gnu build marionette))
- #~(begin
- (use-modules (gnu build marionette)
- (srfi srfi-64))
+ (define os
+ (marionette-operating-system
+ %base-os
+ #:imported-modules '((gnu services herd)
+ (guix combinators))))
- (define marionette
- (make-marionette (list #$command)))
+ (define test
+ (with-imported-modules '((gnu build marionette))
+ #~(begin
+ (use-modules (gnu build marionette)
+ (srfi srfi-64))
- (define (wait-for-socket file)
- ;; Wait until SOCKET exists in the guest
- (marionette-eval
- `(let loop ((i 10))
- (cond ((and (file-exists? ,file)
- (eq? 'socket (stat:type (stat ,file))))
- #t)
- ((> i 0)
- (sleep 1)
- (loop (- i 1)))
- (else
- (error "Socket didn't show up: " ,file))))
- marionette))
+ (define marionette
+ (make-marionette (list #$(virtual-machine os))))
- (mkdir #$output)
- (chdir #$output)
+ (define (wait-for-socket file)
+ ;; Wait until SOCKET exists in the guest
+ (marionette-eval
+ `(let loop ((i 10))
+ (cond ((and (file-exists? ,file)
+ (eq? 'socket (stat:type (stat ,file))))
+ #t)
+ ((> i 0)
+ (sleep 1)
+ (loop (- i 1)))
+ (else
+ (error "Socket didn't show up: " ,file))))
+ marionette))
- (test-begin "rpc-daemon")
+ (mkdir #$output)
+ (chdir #$output)
- ;; Wait for the rpcbind daemon to be up and running.
- (test-eq "RPC service running"
- 'running!
- (marionette-eval
- '(begin
- (use-modules (gnu services herd))
- (start-service 'rpcbind-daemon)
- 'running!)
- marionette))
+ (test-begin "rpc-daemon")
- ;; Check the socket file and that the service is still running.
- (test-assert "RPC socket exists"
- (and
- (wait-for-socket #$socket)
- (marionette-eval
- '(begin
- (use-modules (gnu services herd)
- (srfi srfi-1))
+ ;; Wait for the rpcbind daemon to be up and running.
+ (test-eq "RPC service running"
+ 'running!
+ (marionette-eval
+ '(begin
+ (use-modules (gnu services herd))
+ (start-service 'rpcbind-daemon)
+ 'running!)
+ marionette))
- (live-service-running
- (find (lambda (live)
- (memq 'rpcbind-daemon
- (live-service-provision live)))
- (current-services))))
- marionette)))
+ ;; Check the socket file and that the service is still running.
+ (test-assert "RPC socket exists"
+ (and
+ (wait-for-socket #$socket)
+ (marionette-eval
+ '(begin
+ (use-modules (gnu services herd)
+ (srfi srfi-1))
- (test-assert "Probe RPC daemon"
- (marionette-eval
- '(zero? (system* "rpcinfo" "-p"))
- marionette))
+ (live-service-running
+ (find (lambda (live)
+ (memq 'rpcbind-daemon
+ (live-service-provision live)))
+ (current-services))))
+ marionette)))
- (test-end)
- (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
+ (test-assert "Probe RPC daemon"
+ (marionette-eval
+ '(zero? (system* "rpcinfo" "-p"))
+ marionette))
- (gexp->derivation name test)))
+ (test-end)
+ (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
+
+ (gexp->derivation name test))
(define %test-nfs
(system-test
diff --git a/gnu/tests/ssh.scm b/gnu/tests/ssh.scm
index 9c83a9cd4..05a8d3547 100644
--- a/gnu/tests/ssh.scm
+++ b/gnu/tests/ssh.scm
@@ -27,7 +27,6 @@
#:use-module (gnu packages ssh)
#:use-module (guix gexp)
#:use-module (guix store)
- #:use-module (guix monads)
#:export (%test-openssh
%test-dropbear))
@@ -37,142 +36,143 @@ SSH-SERVICE must be configured to listen on port 22 and to allow for root and
empty-password logins.
When SFTP? is true, run an SFTP server test."
- (mlet* %store-monad ((os -> (marionette-operating-system
- (simple-operating-system
- (dhcp-client-service)
- ssh-service)
- #:imported-modules '((gnu services herd)
- (guix combinators))))
- (command (system-qemu-image/shared-store-script
- os #:graphic? #f)))
- (define test
- (with-imported-modules '((gnu build marionette))
- #~(begin
- (eval-when (expand load eval)
- ;; Prepare to use Guile-SSH.
- (set! %load-path
- (cons (string-append #+guile2.0-ssh "/share/guile/site/"
- (effective-version))
- %load-path)))
+ (define os
+ (marionette-operating-system
+ (simple-operating-system (dhcp-client-service) ssh-service)
+ #:imported-modules '((gnu services herd)
+ (guix combinators))))
+ (define vm
+ (virtual-machine
+ (operating-system os)
+ (port-forwardings '((2222 . 22)))))
- (use-modules (gnu build marionette)
- (srfi srfi-26)
- (srfi srfi-64)
- (ice-9 match)
- (ssh session)
- (ssh auth)
- (ssh channel)
- (ssh sftp))
+ (define test
+ (with-imported-modules '((gnu build marionette))
+ #~(begin
+ (eval-when (expand load eval)
+ ;; Prepare to use Guile-SSH.
+ (set! %load-path
+ (cons (string-append #+guile2.0-ssh "/share/guile/site/"
+ (effective-version))
+ %load-path)))
- (define marionette
- ;; Enable TCP forwarding of the guest's port 22.
- (make-marionette (list #$command "-net"
- "user,hostfwd=tcp::2222-:22")))
+ (use-modules (gnu build marionette)
+ (srfi srfi-26)
+ (srfi srfi-64)
+ (ice-9 match)
+ (ssh session)
+ (ssh auth)
+ (ssh channel)
+ (ssh sftp))
- (define (make-session-for-test)
- "Make a session with predefined parameters for a test."
- (make-session #:user "root"
- #:port 2222
- #:host "localhost"
- #:log-verbosity 'protocol))
+ (define marionette
+ ;; Enable TCP forwarding of the guest's port 22.
+ (make-marionette (list #$vm)))
- (define (call-with-connected-session proc)
- "Call the one-argument procedure PROC with a freshly created and
+ (define (make-session-for-test)
+ "Make a session with predefined parameters for a test."
+ (make-session #:user "root"
+ #:port 2222
+ #:host "localhost"
+ #:log-verbosity 'protocol))
+
+ (define (call-with-connected-session proc)
+ "Call the one-argument procedure PROC with a freshly created and
connected SSH session object, return the result of the procedure call. The
session is disconnected when the PROC is finished."
- (let ((session (make-session-for-test)))
- (dynamic-wind
- (lambda ()
- (let ((result (connect! session)))
- (unless (equal? result 'ok)
- (error "Could not connect to a server"
- session result))))
- (lambda () (proc session))
- (lambda () (disconnect! session)))))
+ (let ((session (make-session-for-test)))
+ (dynamic-wind
+ (lambda ()
+ (let ((result (connect! session)))
+ (unless (equal? result 'ok)
+ (error "Could not connect to a server"
+ session result))))
+ (lambda () (proc session))
+ (lambda () (disconnect! session)))))
- (define (call-with-connected-session/auth proc)
- "Make an authenticated session. We should be able to connect as
+ (define (call-with-connected-session/auth proc)
+ "Make an authenticated session. We should be able to connect as
root with an empty password."
- (call-with-connected-session
- (lambda (session)
- ;; Try the simple authentication methods. Dropbear requires
- ;; 'none' when there are no passwords, whereas OpenSSH accepts
- ;; 'password' with an empty password.
- (let loop ((methods (list (cut userauth-password! <> "")
- (cut userauth-none! <>))))
- (match methods
- (()
- (error "all the authentication methods failed"))
- ((auth rest ...)
- (match (pk 'auth (auth session))
- ('success
- (proc session))
- ('denied
- (loop rest)))))))))
+ (call-with-connected-session
+ (lambda (session)
+ ;; Try the simple authentication methods. Dropbear requires
+ ;; 'none' when there are no passwords, whereas OpenSSH accepts
+ ;; 'password' with an empty password.
+ (let loop ((methods (list (cut userauth-password! <> "")
+ (cut userauth-none! <>))))
+ (match methods
+ (()
+ (error "all the authentication methods failed"))
+ ((auth rest ...)
+ (match (pk 'auth (auth session))
+ ('success
+ (proc session))
+ ('denied
+ (loop rest)))))))))
- (mkdir #$output)
- (chdir #$output)
+ (mkdir #$output)
+ (chdir #$output)
- (test-begin "ssh-daemon")
+ (test-begin "ssh-daemon")
- ;; Wait for sshd to be up and running.
- (test-eq "service running"
- 'running!
- (marionette-eval
- '(begin
- (use-modules (gnu services herd))
- (start-service 'ssh-daemon)
- 'running!)
- marionette))
+ ;; Wait for sshd to be up and running.
+ (test-eq "service running"
+ 'running!
+ (marionette-eval
+ '(begin
+ (use-modules (gnu services herd))
+ (start-service 'ssh-daemon)
+ 'running!)
+ marionette))
- ;; Check sshd's PID file.
- (test-equal "sshd PID"
- (wait-for-file #$pid-file marionette)
- (marionette-eval
- '(begin
- (use-modules (gnu services herd)
- (srfi srfi-1))
+ ;; Check sshd's PID file.
+ (test-equal "sshd PID"
+ (wait-for-file #$pid-file marionette)
+ (marionette-eval
+ '(begin
+ (use-modules (gnu services herd)
+ (srfi srfi-1))
- (live-service-running
- (find (lambda (live)
- (memq 'ssh-daemon
- (live-service-provision live)))
- (current-services))))
- marionette))
+ (live-service-running
+ (find (lambda (live)
+ (memq 'ssh-daemon
+ (live-service-provision live)))
+ (current-services))))
+ marionette))
- ;; Connect to the guest over SSH. Make sure we can run a shell
- ;; command there.
- (test-equal "shell command"
- 'hello
- (call-with-connected-session/auth
- (lambda (session)
- ;; FIXME: 'get-server-public-key' segfaults.
- ;; (get-server-public-key session)
- (let ((channel (make-channel session)))
- (channel-open-session channel)
- (channel-request-exec channel "echo hello > /root/witness")
- (and (zero? (channel-get-exit-status channel))
- (wait-for-file "/root/witness" marionette))))))
+ ;; Connect to the guest over SSH. Make sure we can run a shell
+ ;; command there.
+ (test-equal "shell command"
+ 'hello
+ (call-with-connected-session/auth
+ (lambda (session)
+ ;; FIXME: 'get-server-public-key' segfaults.
+ ;; (get-server-public-key session)
+ (let ((channel (make-channel session)))
+ (channel-open-session channel)
+ (channel-request-exec channel "echo hello > /root/witness")
+ (and (zero? (channel-get-exit-status channel))
+ (wait-for-file "/root/witness" marionette))))))
- ;; Connect to the guest over SFTP. Make sure we can write and
- ;; read a file there.
- (unless #$sftp?
- (test-skip 1))
- (test-equal "SFTP file writing and reading"
- 'hello
- (call-with-connected-session/auth
- (lambda (session)
- (let ((sftp-session (make-sftp-session session))
- (witness "/root/sftp-witness"))
- (call-with-remote-output-file sftp-session witness
- (cut display "hello" <>))
- (call-with-remote-input-file sftp-session witness
- read)))))
+ ;; Connect to the guest over SFTP. Make sure we can write and
+ ;; read a file there.
+ (unless #$sftp?
+ (test-skip 1))
+ (test-equal "SFTP file writing and reading"
+ 'hello
+ (call-with-connected-session/auth
+ (lambda (session)
+ (let ((sftp-session (make-sftp-session session))
+ (witness "/root/sftp-witness"))
+ (call-with-remote-output-file sftp-session witness
+ (cut display "hello" <>))
+ (call-with-remote-input-file sftp-session witness
+ read)))))
- (test-end)
- (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
+ (test-end)
+ (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
- (gexp->derivation name test)))
+ (gexp->derivation name test))
(define %test-openssh
(system-test
diff --git a/gnu/tests/web.scm b/gnu/tests/web.scm
index bc7e3b89a..3fa272c67 100644
--- a/gnu/tests/web.scm
+++ b/gnu/tests/web.scm
@@ -27,7 +27,6 @@
#:use-module (gnu services networking)
#:use-module (guix gexp)
#:use-module (guix store)
- #:use-module (guix monads)
#:export (%test-nginx))
(define %index.html-contents
@@ -65,68 +64,68 @@
(define* (run-nginx-test #:optional (http-port 8042))
"Run tests in %NGINX-OS, which has nginx running and listening on
HTTP-PORT."
- (mlet* %store-monad ((os -> (marionette-operating-system
- %nginx-os
- #:imported-modules '((gnu services herd)
- (guix combinators))))
- (command (system-qemu-image/shared-store-script
- os #:graphic? #f)))
- (define test
- (with-imported-modules '((gnu build marionette))
- #~(begin
- (use-modules (srfi srfi-11) (srfi srfi-64)
- (gnu build marionette)
- (web uri)
- (web client)
- (web response))
-
- (define marionette
- ;; Forward the guest's HTTP-PORT, where nginx is listening, to
- ;; port 8080 in the host.
- (make-marionette (list #$command "-net"
- (string-append
- "user,hostfwd=tcp::8080-:"
- #$(number->string http-port)))))
-
- (mkdir #$output)
- (chdir #$output)
-
- (test-begin "nginx")
-
- ;; Wait for nginx to be up and running.
- (test-eq "service running"
- 'running!
- (marionette-eval
- '(begin
- (use-modules (gnu services herd))
- (start-service 'nginx)
- 'running!)
- marionette))
-
- ;; Make sure the PID file is created.
- (test-assert "PID file"
- (marionette-eval
- '(file-exists? "/var/run/nginx/pid")
- marionette))
-
- ;; Retrieve the index.html file we put in /srv.
- (test-equal "http-get"
- '(200 #$%index.html-contents)
- (let-values (((response text)
- (http-get "http://localhost:8080/index.html"
- #:decode-body? #t)))
- (list (response-code response) text)))
-
- ;; There should be a log file in here.
- (test-assert "log file"
- (marionette-eval
- '(file-exists? "/var/log/nginx/access.log")
- marionette))
-
- (test-end)
- (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
-
- (gexp->derivation "nginx-test" test)))
+ (define os
+ (marionette-operating-system
+ %nginx-os
+ #:imported-modules '((gnu services herd)
+ (guix combinators))))
+
+ (define vm
+ (virtual-machine
+ (operating-system os)
+ (port-forwardings `((8080 . ,http-port)))))
+
+ (define test
+ (with-imported-modules '((gnu build marionette))
+ #~(begin
+ (use-modules (srfi srfi-11) (srfi srfi-64)
+ (gnu build marionette)
+ (web uri)
+ (web client)
+ (web response))
+
+ (define marionette
+ (make-marionette (list #$vm)))
+
+ (mkdir #$output)
+ (chdir #$output)
+
+ (test-begin "nginx")
+
+ ;; Wait for nginx to be up and running.
+ (test-eq "service running"
+ 'running!
+ (marionette-eval
+ '(begin
+ (use-modules (gnu services herd))
+ (start-service 'nginx)
+ 'running!)
+ marionette))
+
+ ;; Make sure the PID file is created.
+ (test-assert "PID file"
+ (marionette-eval
+ '(file-exists? "/var/run/nginx/pid")
+ marionette))
+
+ ;; Retrieve the index.html file we put in /srv.
+ (test-equal "http-get"
+ '(200 #$%index.html-contents)
+ (let-values (((response text)
+ (http-get "http://localhost:8080/index.html"
+ #:decode-body? #t)))
+ (list (response-code response) text)))
+
+ ;; There should be a log file in here.
+ (test-assert "log file"
+ (marionette-eval
+ '(file-exists? "/var/log/nginx/access.log")
+ marionette))
+
+ (test-end)
+ (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
+
+ (gexp->derivation "nginx-test" test))
(define %test-nginx
(system-test
--
2.13.2
^ permalink raw reply related [flat|nested] 4+ messages in thread
* bug#27751: [PATCH 0/2] Simplify VM handling in system tests
2017-07-18 8:58 [bug#27751] [PATCH 0/2] Simplify VM handling in system tests Ludovic Courtès
2017-07-18 9:02 ` [bug#27751] [PATCH 1/2] vm: Add a <virtual-machine> type and associated gexp compiler Ludovic Courtès
@ 2017-07-20 9:57 ` Ludovic Courtès
1 sibling, 0 replies; 4+ messages in thread
From: Ludovic Courtès @ 2017-07-20 9:57 UTC (permalink / raw)
To: 27751-done
Ludovic Courtès <ludo@gnu.org> skribis:
> The attached patches simplify VM handling in system tests by
> defining a new <virtual-machine> type that can be used directly
> in gexps, instead of using the monadic procedures from (gnu system
> vm).
>
> The second patch shows a lot of churn but that's mostly whitespace
> changes due to things being rewritten from:
>
> (mlet* %store-monad ((os -> ...)
> (command (system-qemu-image/shared-store-script ...)))
> ...)
>
> to
>
> (define os
> ...)
>
> (define vm
> (virtual-machine ...))
>
> ...
Pushed!
Ludo’.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2017-07-20 9:59 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-07-18 8:58 [bug#27751] [PATCH 0/2] Simplify VM handling in system tests Ludovic Courtès
2017-07-18 9:02 ` [bug#27751] [PATCH 1/2] vm: Add a <virtual-machine> type and associated gexp compiler Ludovic Courtès
2017-07-18 9:02 ` [bug#27751] [PATCH 2/2] tests: Use 'virtual-machine' records instead of monadic procedures Ludovic Courtès
2017-07-20 9:57 ` bug#27751: [PATCH 0/2] Simplify VM handling in system tests Ludovic Courtès
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/guix.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.