This fixes a regression introduced with commita09c7da("tests: Fork and exec a new Guile for the marionette REPL.") and only partially fixed with the follow-up commitf518882(" tests: Add missing module imports for marionette-evaluated code."). * gnu/tests/telephony.scm (run-jami-test): Remove extraneous module imports. Move the setting of the DBUS_SESSION_BUS_ADDRESS environment variable inside the first marionette-eval'd setup test. ["service can be stopped"]: Add missing (gnu build dbus-service) module.
		
			
				
	
	
		
			393 lines
		
	
	
	
		
			16 KiB
		
	
	
	
		
			Scheme
		
	
	
	
	
	
			
		
		
	
	
			393 lines
		
	
	
	
		
			16 KiB
		
	
	
	
		
			Scheme
		
	
	
	
	
	
;;; GNU Guix --- Functional package management for GNU
 | 
						|
;;; Copyright © 2021, 2022, 2023 Maxim Cournoyer <maxim.cournoyer@gmail.com>.
 | 
						|
;;;
 | 
						|
;;; This file is part of GNU Guix.
 | 
						|
;;;
 | 
						|
;;; GNU Guix is free software; you can redistribute it and/or modify it
 | 
						|
;;; under the terms of the GNU General Public License as published by
 | 
						|
;;; the Free Software Foundation; either version 3 of the License, or (at
 | 
						|
;;; your option) any later version.
 | 
						|
;;;
 | 
						|
;;; GNU Guix is distributed in the hope that it will be useful, but
 | 
						|
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
						|
;;; GNU General Public License for more details.
 | 
						|
;;;
 | 
						|
;;; You should have received a copy of the GNU General Public License
 | 
						|
;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
 | 
						|
 | 
						|
(define-module (gnu tests telephony)
 | 
						|
  #:use-module (gnu)
 | 
						|
  #:use-module (gnu packages)
 | 
						|
  #:use-module (gnu packages guile)
 | 
						|
  #:use-module (gnu packages guile-xyz)
 | 
						|
  #:use-module (gnu tests)
 | 
						|
  #:use-module (gnu system vm)
 | 
						|
  #:use-module (gnu services)
 | 
						|
  #:use-module (gnu services dbus)
 | 
						|
  #:use-module (gnu services networking)
 | 
						|
  #:use-module (gnu services ssh)
 | 
						|
  #:use-module (gnu services telephony)
 | 
						|
  #:use-module (guix gexp)
 | 
						|
  #:use-module (guix modules)
 | 
						|
  #:export (%test-jami
 | 
						|
            %test-jami-provisioning
 | 
						|
            %test-jami-provisioning-partial))
 | 
						|
 | 
						|
;;;
 | 
						|
;;; Jami daemon.
 | 
						|
;;;
 | 
						|
 | 
						|
(include "data/jami-dummy-account.dat") ;defines %jami-account-content-sexp
 | 
						|
 | 
						|
(define %dummy-jami-account-archive
 | 
						|
  ;; A Jami account archive is a gzipped JSON file.
 | 
						|
  (computed-file
 | 
						|
   "dummy-jami-account.gz"
 | 
						|
   (with-extensions (list guile-json-4 guile-zlib)
 | 
						|
     #~(begin
 | 
						|
         (use-modules (json) (zlib))
 | 
						|
         (let ((port (open-output-file #$output)))
 | 
						|
           (call-with-gzip-output-port port
 | 
						|
             (lambda (port)
 | 
						|
               (scm->json '#$%jami-account-content-sexp port))))))))
 | 
						|
 | 
						|
(define %allowed-contacts '("1dbcb0f5f37324228235564b79f2b9737e9a008f"
 | 
						|
                            "2dbcb0f5f37324228235564b79f2b9737e9a008f"))
 | 
						|
 | 
						|
(define %moderators '("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
 | 
						|
                      "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"))
 | 
						|
 | 
						|
(define %dummy-jami-account (jami-account
 | 
						|
                             (archive %dummy-jami-account-archive)
 | 
						|
                             (allowed-contacts %allowed-contacts)
 | 
						|
                             (moderators %moderators)
 | 
						|
                             (rendezvous-point? #t)
 | 
						|
                             (peer-discovery? #f)
 | 
						|
                             (bootstrap-hostnames '("bootstrap.me"
 | 
						|
                                                    "fallback.another.host"))
 | 
						|
                             (name-server-uri "https://my.name.server")))
 | 
						|
 | 
						|
;;; Like %dummy-jami-account, but with allowed-contacts and moderators left
 | 
						|
;;; unset (thus taking the value *unspecified*).
 | 
						|
(define %dummy-jami-account-partial
 | 
						|
  (jami-account
 | 
						|
   (archive %dummy-jami-account-archive)
 | 
						|
   (rendezvous-point? #t)
 | 
						|
   (peer-discovery? #f)
 | 
						|
   (bootstrap-hostnames '("bootstrap.me"
 | 
						|
                          "fallback.another.host"))
 | 
						|
   (name-server-uri "https://my.name.server")))
 | 
						|
 | 
						|
(define* (make-jami-os #:key provisioning? partial?)
 | 
						|
  (operating-system
 | 
						|
    (host-name "jami")
 | 
						|
    (timezone "America/Montreal")
 | 
						|
    (locale "en_US.UTF-8")
 | 
						|
 | 
						|
    (bootloader (bootloader-configuration
 | 
						|
                 (bootloader grub-bootloader)
 | 
						|
                 (targets '("/dev/sdX"))))
 | 
						|
    (file-systems (cons (file-system
 | 
						|
                          (device (file-system-label "my-root"))
 | 
						|
                          (mount-point "/")
 | 
						|
                          (type "ext4"))
 | 
						|
                        %base-file-systems))
 | 
						|
    (firmware '())
 | 
						|
 | 
						|
    (services (cons* (service jami-service-type
 | 
						|
                              (if provisioning?
 | 
						|
                                  (jami-configuration
 | 
						|
                                   (debug? #t)
 | 
						|
                                   (accounts
 | 
						|
                                    (list (if partial?
 | 
						|
                                              %dummy-jami-account-partial
 | 
						|
                                              %dummy-jami-account))))
 | 
						|
                                  (jami-configuration
 | 
						|
                                   (debug? #t))))
 | 
						|
                     (service dbus-root-service-type)
 | 
						|
                     ;; The following services/packages are added for
 | 
						|
                     ;; debugging purposes.
 | 
						|
                     (service dhcp-client-service-type)
 | 
						|
                     (service openssh-service-type
 | 
						|
                              (openssh-configuration
 | 
						|
                               (permit-root-login #t)
 | 
						|
                               (allow-empty-passwords? #t)))
 | 
						|
                     %base-services))
 | 
						|
    (packages (cons* (specification->package "recutils")
 | 
						|
                     (specification->package "strace")
 | 
						|
                     %base-packages))))
 | 
						|
 | 
						|
(define %jami-os
 | 
						|
  (make-jami-os))
 | 
						|
 | 
						|
(define %jami-os-provisioning
 | 
						|
  (make-jami-os #:provisioning? #t))
 | 
						|
 | 
						|
(define %jami-os-provisioning-partial
 | 
						|
  (make-jami-os #:provisioning? #t #:partial? #t))
 | 
						|
 | 
						|
(define* (run-jami-test #:key provisioning? partial?)
 | 
						|
  "Run tests in %JAMI-OS.  When PROVISIONING? is true, test the accounts
 | 
						|
provisioning feature of the service.  When PARTIAL? is #t, some fields of the
 | 
						|
jami account used as part of the jami configuration are left *unspecified*."
 | 
						|
  (define os (marionette-operating-system
 | 
						|
              (if provisioning?
 | 
						|
                  (if partial?
 | 
						|
                      %jami-os-provisioning-partial
 | 
						|
                      %jami-os-provisioning)
 | 
						|
                  %jami-os)
 | 
						|
              #:imported-modules '((gnu services herd)
 | 
						|
                                   (guix combinators)
 | 
						|
                                   (gnu build jami-service)
 | 
						|
                                   (gnu build dbus-service))))
 | 
						|
  (define vm (virtual-machine
 | 
						|
              (operating-system os)
 | 
						|
              (memory-size 512)))
 | 
						|
 | 
						|
  (define username (assoc-ref %jami-account-content-sexp
 | 
						|
                              "Account.username"))
 | 
						|
 | 
						|
  (define test
 | 
						|
    (with-imported-modules (source-module-closure
 | 
						|
                            '((gnu build marionette)))
 | 
						|
      #~(begin
 | 
						|
          (use-modules (srfi srfi-64)
 | 
						|
                       (gnu build marionette))
 | 
						|
 | 
						|
          (define marionette
 | 
						|
            (make-marionette (list #$vm)))
 | 
						|
 | 
						|
          (test-runner-current (system-test-runner #$output))
 | 
						|
          (test-begin "jami")
 | 
						|
 | 
						|
          (test-assert "d-bus tooling loaded"
 | 
						|
            ;; Add Guile-AC-D-Bus and related libraries to the marionette's
 | 
						|
            ;; search path.
 | 
						|
            (marionette-eval
 | 
						|
             '(let ((libraries '(#$guile-ac-d-bus
 | 
						|
                                 #$guile-packrat))) ;used by ac-d-bus
 | 
						|
                (setenv "DBUS_SESSION_BUS_ADDRESS" "unix:path=/var/run/jami/bus")
 | 
						|
                (set! %load-path
 | 
						|
                      (append %load-path
 | 
						|
                              (map (lambda (directory)
 | 
						|
                                     (string-append directory
 | 
						|
                                                    "/share/guile/site/"
 | 
						|
                                                    (effective-version)))
 | 
						|
                                   libraries)))
 | 
						|
                (set! %load-compiled-path
 | 
						|
                      (append %load-compiled-path
 | 
						|
                              (map (lambda (directory)
 | 
						|
                                     (string-append directory
 | 
						|
                                                    "/lib/guile/3.0/site-ccache"))
 | 
						|
                                   libraries)))
 | 
						|
                %load-path)
 | 
						|
             marionette))
 | 
						|
 | 
						|
          (test-assert "service is running"
 | 
						|
            (marionette-eval
 | 
						|
             '(begin
 | 
						|
                (use-modules (gnu build jami-service)
 | 
						|
                             (gnu services herd))
 | 
						|
 | 
						|
                (wait-for-service 'jami)
 | 
						|
                (jami-service-available?))
 | 
						|
             marionette))
 | 
						|
 | 
						|
          (test-assert "service can be stopped"
 | 
						|
            (marionette-eval
 | 
						|
             '(begin
 | 
						|
                (use-modules (gnu build dbus-service)
 | 
						|
                             (gnu build jami-service)
 | 
						|
                             (gnu services herd)
 | 
						|
                             (rnrs base))
 | 
						|
                (assert (jami-service-available?))
 | 
						|
 | 
						|
                (stop-service 'jami)
 | 
						|
 | 
						|
                (with-retries 20 1 (not (jami-service-available?))))
 | 
						|
             marionette))
 | 
						|
 | 
						|
          (test-assert "service can be restarted"
 | 
						|
            (marionette-eval
 | 
						|
             '(begin
 | 
						|
                (use-modules (gnu build dbus-service)
 | 
						|
                             (gnu build jami-service)
 | 
						|
                             (gnu services herd)
 | 
						|
                             (rnrs base)                               )
 | 
						|
                ;; Start the service.
 | 
						|
                (start-service 'jami)
 | 
						|
                (with-retries 20 1 (jami-service-available?))
 | 
						|
                ;; Restart the service.
 | 
						|
                (restart-service 'jami)
 | 
						|
                (with-retries 20 1 (jami-service-available?)))
 | 
						|
             marionette))
 | 
						|
 | 
						|
          (unless #$provisioning? (test-skip 1))
 | 
						|
          (test-assert "jami accounts provisioning, account present"
 | 
						|
            (marionette-eval
 | 
						|
             '(begin
 | 
						|
                (use-modules (gnu build dbus-service)
 | 
						|
                             (gnu services herd)
 | 
						|
                             (rnrs base))
 | 
						|
                ;; Accounts take some time to appear after being added.
 | 
						|
                (with-retries 20 1
 | 
						|
                              (with-shepherd-action 'jami ('list-accounts) results
 | 
						|
                                (let ((account (assoc-ref (car results) #$username)))
 | 
						|
                                  (assert (string=? #$username
 | 
						|
                                                    (assoc-ref account
 | 
						|
                                                               "Account.username")))))))
 | 
						|
             marionette))
 | 
						|
 | 
						|
          (unless #$(and provisioning? (not partial?)) (test-skip 1))
 | 
						|
          (test-assert "jami accounts provisioning, allowed-contacts"
 | 
						|
            (marionette-eval
 | 
						|
             '(begin
 | 
						|
                (use-modules (gnu services herd)
 | 
						|
                             (rnrs base)
 | 
						|
                             (srfi srfi-1))
 | 
						|
 | 
						|
                ;; Public mode is disabled.
 | 
						|
                (with-shepherd-action 'jami ('list-account-details)
 | 
						|
                                      results
 | 
						|
                  (let ((account (assoc-ref (car results) #$username)))
 | 
						|
                    (assert (string=? "false"
 | 
						|
                                      (assoc-ref account
 | 
						|
                                                 "DHT.PublicInCalls")))))
 | 
						|
 | 
						|
                ;; Allowed contacts match those declared in the configuration.
 | 
						|
                (with-shepherd-action 'jami ('list-contacts) results
 | 
						|
                  (let ((contacts (assoc-ref (car results) #$username)))
 | 
						|
                    (assert (lset= string-ci=? contacts '#$%allowed-contacts)))))
 | 
						|
             marionette))
 | 
						|
 | 
						|
          (unless #$(and provisioning? (not partial?)) (test-skip 1))
 | 
						|
          (test-assert "jami accounts provisioning, moderators"
 | 
						|
            (marionette-eval
 | 
						|
             '(begin
 | 
						|
                (use-modules (gnu services herd)
 | 
						|
                             (rnrs base)
 | 
						|
                             (srfi srfi-1))
 | 
						|
 | 
						|
                ;; Moderators match those declared in the configuration.
 | 
						|
                (with-shepherd-action 'jami ('list-moderators) results
 | 
						|
                  (let ((moderators (assoc-ref (car results) #$username)))
 | 
						|
                    (assert (lset= string-ci=? moderators '#$%moderators))))
 | 
						|
 | 
						|
                ;; Moderators can be added via the Shepherd action.
 | 
						|
                (with-shepherd-action 'jami
 | 
						|
                    ('add-moderator "cccccccccccccccccccccccccccccccccccccccc"
 | 
						|
                                    #$username) results
 | 
						|
                  (let ((moderators (car results)))
 | 
						|
                    (assert (lset= string-ci=? moderators
 | 
						|
                                   (cons "cccccccccccccccccccccccccccccccccccccccc"
 | 
						|
                                         '#$%moderators))))))
 | 
						|
             marionette))
 | 
						|
 | 
						|
          (unless #$provisioning? (test-skip 1))
 | 
						|
          (test-assert "jami service actions, ban/unban contacts"
 | 
						|
            (marionette-eval
 | 
						|
             '(begin
 | 
						|
                (use-modules (gnu services herd)
 | 
						|
                             (ice-9 match)
 | 
						|
                             (rnrs base)
 | 
						|
                             (srfi srfi-1))
 | 
						|
 | 
						|
                ;; Globally ban a contact.
 | 
						|
                (with-shepherd-action 'jami
 | 
						|
                    ('ban-contact "1dbcb0f5f37324228235564b79f2b9737e9a008f") _
 | 
						|
                  (with-shepherd-action 'jami ('list-banned-contacts) results
 | 
						|
                    (every (match-lambda
 | 
						|
                             ((username . banned-contacts)
 | 
						|
                              (member "1dbcb0f5f37324228235564b79f2b9737e9a008f"
 | 
						|
                                      banned-contacts)))
 | 
						|
                           (car results))))
 | 
						|
 | 
						|
                ;; Ban a contact for a single account.
 | 
						|
                (with-shepherd-action 'jami
 | 
						|
                    ('ban-contact "dddddddddddddddddddddddddddddddddddddddd"
 | 
						|
                                  #$username) _
 | 
						|
                  (with-shepherd-action 'jami ('list-banned-contacts) results
 | 
						|
                    (every (match-lambda
 | 
						|
                             ((username . banned-contacts)
 | 
						|
                              (let ((found? (member "dddddddddddddddddddddddddddddddddddddddd"
 | 
						|
                                                    banned-contacts)))
 | 
						|
                                (if (string=? #$username username)
 | 
						|
                                    found?
 | 
						|
                                    (not found?)))))
 | 
						|
                           (car results)))))
 | 
						|
             marionette))
 | 
						|
 | 
						|
          (unless #$provisioning? (test-skip 1))
 | 
						|
          (test-assert "jami service actions, enable/disable accounts"
 | 
						|
            (marionette-eval
 | 
						|
             '(begin
 | 
						|
                (use-modules (gnu services herd)
 | 
						|
                             (rnrs base))
 | 
						|
 | 
						|
                (with-shepherd-action 'jami
 | 
						|
                    ('disable-account #$username) _
 | 
						|
                  (with-shepherd-action 'jami ('list-accounts) results
 | 
						|
                    (let ((account (assoc-ref (car results) #$username)))
 | 
						|
                      (assert (string= "false"
 | 
						|
                                       (assoc-ref account "Account.enable"))))))
 | 
						|
 | 
						|
                (with-shepherd-action 'jami
 | 
						|
                    ('enable-account #$username) _
 | 
						|
                  (with-shepherd-action 'jami ('list-accounts) results
 | 
						|
                    (let ((account (assoc-ref (car results) #$username)))
 | 
						|
                      (assert (string= "true"
 | 
						|
                                       (assoc-ref account "Account.enable")))))))
 | 
						|
             marionette))
 | 
						|
 | 
						|
          (unless #$provisioning? (test-skip 1))
 | 
						|
          (test-assert "jami account parameters"
 | 
						|
            (marionette-eval
 | 
						|
             '(begin
 | 
						|
                (use-modules (gnu services herd)
 | 
						|
                             (rnrs base)
 | 
						|
                             (srfi srfi-1))
 | 
						|
 | 
						|
                (with-shepherd-action 'jami ('list-account-details) results
 | 
						|
                  (let ((account-details (assoc-ref (car results)
 | 
						|
                                                    #$username)))
 | 
						|
                    (assert (lset<=
 | 
						|
                             equal?
 | 
						|
                             '(("Account.hostname" .
 | 
						|
                                "bootstrap.me;fallback.another.host")
 | 
						|
                               ("Account.peerDiscovery" . "false")
 | 
						|
                               ("Account.rendezVous" . "true")
 | 
						|
                               ("RingNS.uri" . "https://my.name.server"))
 | 
						|
                             account-details)))))
 | 
						|
             marionette))
 | 
						|
 | 
						|
          (test-end))))
 | 
						|
 | 
						|
  (gexp->derivation (if provisioning?
 | 
						|
                        (if partial?
 | 
						|
                            "jami-provisioning-partial-test"
 | 
						|
                            "jami-provisioning-test")
 | 
						|
                        "jami-test")
 | 
						|
                    test))
 | 
						|
 | 
						|
(define %test-jami
 | 
						|
  (system-test
 | 
						|
   (name "jami")
 | 
						|
   (description "Basic tests for the jami service.")
 | 
						|
   (value (run-jami-test))))
 | 
						|
 | 
						|
(define %test-jami-provisioning
 | 
						|
  (system-test
 | 
						|
   (name "jami-provisioning")
 | 
						|
   (description "Provisioning test for the jami service.")
 | 
						|
   (value (run-jami-test #:provisioning? #t))))
 | 
						|
 | 
						|
;;; Thi test verifies that <jami-account> values can be left unspecified
 | 
						|
;;; without causing any issue (see: https://issues.guix.gnu.org/56799).
 | 
						|
(define %test-jami-provisioning-partial
 | 
						|
  (system-test
 | 
						|
   (name "jami-provisioning-partial")
 | 
						|
   (description "Provisioning test for the jami service, when some of the
 | 
						|
'maybe' fields aren't provided (such that their value end up being
 | 
						|
*unspecified*.")
 | 
						|
   (value (run-jami-test #:provisioning? #t #:partial? #t))))
 |