X-Git-Url: https://git.hcoop.net/jackhill/guix/guix.git/blobdiff_plain/01497dfe6c0a2ce69287d0fd0008747965a000df..a20e00ddaf343c8bebc608ebe59c4204deb065d1:/gnu/tests.scm diff --git a/gnu/tests.scm b/gnu/tests.scm index ea779ed6f0..2886a982f4 100644 --- a/gnu/tests.scm +++ b/gnu/tests.scm @@ -1,5 +1,6 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2016 Ludovic Courtès +;;; Copyright © 2016, 2017 Ludovic Courtès +;;; Copyright © 2017 Mathieu Othacehe ;;; ;;; This file is part of GNU Guix. ;;; @@ -20,17 +21,29 @@ #:use-module (guix gexp) #:use-module (guix utils) #:use-module (guix records) + #:use-module (gnu bootloader grub) #:use-module (gnu system) + #:use-module (gnu system file-systems) + #:use-module (gnu system shadow) #:use-module (gnu services) + #:use-module (gnu services base) #:use-module (gnu services shepherd) - #:use-module ((gnu packages) #:select (scheme-modules)) + #:use-module (guix discovery) #:use-module (srfi srfi-1) #:use-module (srfi srfi-9 gnu) #:use-module (ice-9 match) - #:export (marionette-service-type + #:export (marionette-configuration + marionette-configuration? + marionette-configuration-device + marionette-configuration-imported-modules + marionette-configuration-requirements + + marionette-service-type marionette-operating-system define-os-with-source + simple-operating-system + system-test system-test? system-test-name @@ -50,81 +63,93 @@ ;;; ;;; Code: -(define (marionette-shepherd-service imported-modules) +(define-record-type* + marionette-configuration make-marionette-configuration + marionette-configuration? + (device marionette-configuration-device ;string + (default "/dev/hvc0")) + (imported-modules marionette-configuration-imported-modules + (default '())) + (requirements marionette-configuration-requirements ;list of symbols + (default '()))) + +(define (marionette-shepherd-service config) "Return the Shepherd service for the marionette REPL" - (define device - "/dev/hvc0") - - (list (shepherd-service - (provision '(marionette)) - (requirement '(udev)) ;so that DEVICE is available - (modules '((ice-9 match) - (srfi srfi-9 gnu) - (guix build syscalls) - (rnrs bytevectors))) - (imported-modules `((guix build syscalls) - ,@imported-modules)) - (start - #~(lambda () - (define (clear-echo termios) - (set-field termios (termios-local-flags) - (logand (lognot (local-flags ECHO)) - (termios-local-flags termios)))) - - (define (self-quoting? x) - (letrec-syntax ((one-of (syntax-rules () - ((_) #f) - ((_ pred rest ...) - (or (pred x) - (one-of rest ...)))))) - (one-of symbol? string? pair? null? vector? - bytevector? number? boolean?))) - - (match (primitive-fork) - (0 - (dynamic-wind - (const #t) - (lambda () - (let* ((repl (open-file #$device "r+0")) - (termios (tcgetattr (fileno repl))) - (console (open-file "/dev/console" "r+0"))) - ;; Don't echo input back. - (tcsetattr (fileno repl) (tcsetattr-action TCSANOW) - (clear-echo termios)) - - ;; Redirect output to the console. - (close-fdes 1) - (close-fdes 2) - (dup2 (fileno console) 1) - (dup2 (fileno console) 2) - (close-port console) - - (display 'ready repl) - (let loop () - (newline repl) - - (match (read repl) - ((? eof-object?) - (primitive-exit 0)) - (expr - (catch #t - (lambda () - (let ((result (primitive-eval expr))) - (write (if (self-quoting? result) - result - (object->string result)) - repl))) - (lambda (key . args) - (print-exception (current-error-port) - (stack-ref (make-stack #t) 1) - key args) - (write #f repl))))) - (loop)))) - (lambda () - (primitive-exit 1)))) - (pid - pid)))) - (stop #~(make-kill-destructor))))) + (match config + (($ device imported-modules requirement) + (list (shepherd-service + (provision '(marionette)) + + ;; Always depend on UDEV so that DEVICE is available. + (requirement `(udev ,@requirement)) + + (modules '((ice-9 match) + (srfi srfi-9 gnu) + (guix build syscalls) + (rnrs bytevectors))) + (start + (with-imported-modules `((guix build syscalls) + ,@imported-modules) + #~(lambda () + (define (clear-echo termios) + (set-field termios (termios-local-flags) + (logand (lognot (local-flags ECHO)) + (termios-local-flags termios)))) + + (define (self-quoting? x) + (letrec-syntax ((one-of (syntax-rules () + ((_) #f) + ((_ pred rest ...) + (or (pred x) + (one-of rest ...)))))) + (one-of symbol? string? pair? null? vector? + bytevector? number? boolean?))) + + (match (primitive-fork) + (0 + (dynamic-wind + (const #t) + (lambda () + (let* ((repl (open-file #$device "r+0")) + (termios (tcgetattr (fileno repl))) + (console (open-file "/dev/console" "r+0"))) + ;; Don't echo input back. + (tcsetattr (fileno repl) (tcsetattr-action TCSANOW) + (clear-echo termios)) + + ;; Redirect output to the console. + (close-fdes 1) + (close-fdes 2) + (dup2 (fileno console) 1) + (dup2 (fileno console) 2) + (close-port console) + + (display 'ready repl) + (let loop () + (newline repl) + + (match (read repl) + ((? eof-object?) + (primitive-exit 0)) + (expr + (catch #t + (lambda () + (let ((result (primitive-eval expr))) + (write (if (self-quoting? result) + result + (object->string result)) + repl))) + (lambda (key . args) + (print-exception (current-error-port) + (stack-ref (make-stack #t) 1) + key args) + (write #f repl))))) + (loop)))) + (lambda () + (primitive-exit 1)))) + (pid + pid))))) + (stop #~(make-kill-destructor))))))) (define marionette-service-type ;; This is the type of the "marionette" service, allowing a guest system to @@ -136,12 +161,19 @@ marionette-shepherd-service))))) (define* (marionette-operating-system os - #:key (imported-modules '())) - "Return a marionetteed variant of OS such that OS can be used as a marionette -in a virtual machine--i.e., controlled from the host system." + #:key + (imported-modules '()) + (requirements '())) + "Return a marionetteed variant of OS such that OS can be used as a +marionette in a virtual machine--i.e., controlled from the host system. The +marionette service in the guest is started after the Shepherd services listed +in REQUIREMENTS." (operating-system (inherit os) - (services (cons (service marionette-service-type imported-modules) + (services (cons (service marionette-service-type + (marionette-configuration + (requirements requirements) + (imported-modules imported-modules))) (operating-system-user-services os))))) (define-syntax define-os-with-source @@ -164,6 +196,41 @@ the system under test." (operating-system fields ...))))))) +;;; +;;; Simple operating systems. +;;; + +(define %simple-os + (operating-system + (host-name "komputilo") + (timezone "Europe/Berlin") + (locale "en_US.UTF-8") + + (bootloader (grub-configuration (device "/dev/sdX"))) + (file-systems (cons (file-system + (device "my-root") + (title 'label) + (mount-point "/") + (type "ext4")) + %base-file-systems)) + (firmware '()) + + (users (cons (user-account + (name "alice") + (comment "Bob's sister") + (group "users") + (supplementary-groups '("wheel" "audio" "video")) + (home-directory "/home/alice")) + %base-user-accounts)))) + +(define-syntax-rule (simple-operating-system user-services ...) + "Return an operating system that includes USER-SERVICES in addition to +%BASE-SERVICES." + (operating-system (inherit %simple-os) + (services (cons* user-services ... %base-services)))) + + + ;;; ;;; Tests. ;;; @@ -197,17 +264,12 @@ the system under test." (define (fold-system-tests proc seed) "Invoke PROC on each system test, passing it the test and the previous result." - (fold (lambda (module result) - (fold (lambda (thing result) - (if (system-test? thing) - (proc thing result) - result)) - result - (module-map (lambda (sym var) - (false-if-exception (variable-ref var))) - module))) - '() - (test-modules))) + (fold-module-public-variables (lambda (obj result) + (if (system-test? obj) + (cons obj result) + result)) + '() + (test-modules))) (define (all-system-tests) "Return the list of system tests."