aboutsummaryrefslogtreecommitdiff
;;; 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.
;;;

(define %jami-account-content-sexp
  (call-with-input-file
      (search-path %load-path "gnu/tests/data/jami-dummy-account.dat")
    read))

(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 "dbus session is up"
            (and (marionette-eval
                  '(begin
                     (use-modules (gnu services herd))
                     (wait-for-service 'jami-dbus-session #:timeout 40))
                  marionette)
                 (wait-for-unix-socket "/var/run/jami/bus"
                                       marionette)))

          (test-assert "service is running"
            (marionette-eval
             '(begin
                (use-modules (gnu build jami-service)
                             (gnu services herd))

                (wait-for-service 'jami #:timeout 40)
                (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 40 1 (jami-service-available?))
                ;; Restart the service.
                (restart-service 'jami)
                (with-retries 40 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 40 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))))

;;; This 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))))
changed. * gnu/packages/base.scm (grep, sed, tar, patch, diffutils, glibc/hurd-headers) (coreutils, gnu-make, make-glibc-utf8-locales): Change input fields to plain package lists and use 'modify-inputs'. * gnu/packages/guile.scm (guile-1.8, guile-json-1, guile-json-3) (guile-gdbm-ffi, guile-sqlite3, guile-bytestructures) (guile-git, guile-zlib, guile-lzlib, guile-zstd, guile-next): Likewise. * gnu/packages/mes.scm (nyacc-0.86, nyacc-0.99) (nyacc, nyacc-1.00.2, mes-0.19, mes, m2-planet): Likewise. Ludovic Courtès 2021-07-10gnu: coreutils: Patch broken Gnulib tests....Fixes <https://bugs.gnu.org/49459>. * gnu/packages/patches/coreutils-gnulib-tests.patch: New file. * gnu/local.mk (dist_patch_DATA): Add it. * gnu/packages/base.scm (coreutils)[source]: Use it. Ludovic Courtès 2021-07-08gnu: glibc: Fix cross-compilation to powerpc64le-linux-gnu....Fixes <https://bugs.gnu.org/49417>. Reported by Maxime Devos <maximedevos@telenet.be>. * gnu/packages/patches/glibc-cross-objcopy.patch: New file. * gnu/local.mk (dist_patch_DATA): Add it. * gnu/packages/base.scm (glibc)[source]: Use it. Ludovic Courtès 2021-07-04gnu: glibc: Fix cross-compilation to aarch64-linux-gnu....Fixes <https://bugs.gnu.org/49113>. Reported by Maxime Devos <maximedevos@telenet.be>. Previously, the cross-compiled libc.so linker script would read: OUTPUT_FORMAT(elf64-little) instead of: OUTPUT_FORMAT(elf64-littleaarch64) This is because glibc 2.33 runs "objdump -f" instead of "aarch64-linux-gnu-objdump -f" to determine the output format. * gnu/packages/patches/glibc-cross-objdump.patch: New file. * gnu/local.mk (dist_patch_DATA): Add it. * gnu/packages/base.scm (glibc)[source]: Use it. Ludovic Courtès 2021-06-11gnu: coreutils: Disable inotify-dir-recreate test...This test fails on filesystems where tail detects that it cannot use inotify safely. See https://issues.guix.gnu.org/47935 for more details. * gnu/packages/base.scm (coreutils)[phases]: Disable inotify-dir-recreate tests, quote Hurd substitute* call to reduce rebuilds. Carl Dong 2021-05-23gnu: binutils: Fix bug in test suite in libiberty....* gnu/packages/base.scm (binutils)[source]: Add patch. * gnu/packages/patches/binutils-libiberty-endianness-bug.patch: New file. * gnu/local.mk (dist_patch_DATA): Register it. Efraim Flashner 2021-05-09gnu: libcap: Update to 2.49....* gnu/packages/linux.scm (libcap-2.31): Rename to ... (libcap): ... this: Update to 2.49. [arguments]: Adjust substitution. (libcap/next): Remove variable. * gnu/packages/avahi.scm (avahi)[inputs]: Change from LIBCAP/NEXT to LIBCAP. * gnu/packages/base.scm (coreutils)[inputs]: Likewise. Marius Bakke 2021-04-16Merge remote-tracking branch 'origin/master' into core-updates... Conflicts: gnu/local.mk gnu/packages/boost.scm gnu/packages/chez.scm gnu/packages/compression.scm gnu/packages/crates-io.scm gnu/packages/docbook.scm gnu/packages/engineering.scm gnu/packages/gcc.scm gnu/packages/gl.scm gnu/packages/gtk.scm gnu/packages/nettle.scm gnu/packages/python-check.scm gnu/packages/python-xyz.scm gnu/packages/radio.scm gnu/packages/rust.scm gnu/packages/sqlite.scm guix/build-system/node.scm Efraim Flashner 2021-04-09gnu: glibc: Update to 2.33....* gnu/packages/base.scm (glibc): Update to 2.33. [source]: Remove "glibc-hurd-signal-sa-siginfo.patch", now upstream. * gnu/packages/patches/glibc-hurd-clock_gettime_monotonic.patch: Update. * gnu/packages/patches/glibc-hurd-signal-sa-siginfo.patch: Remove. * gnu/local.mk (dist_patch_DATA): Adjust accordingly. Ludovic Courtès 2021-03-26gnu: tzdata: Update to 2021a....* gnu/packages/base.scm (tzdata): Update to 2021a. [inputs]: Update tzcode. Signed-off-by: Leo Famulari <leo@famulari.name> Vincent Legoll 2021-03-24gnu: glibc: Absorb powerpc patch....* gnu/packages/base.scm (glibc)[source]: Add patch. [arguments]: Remove 'apply-patch phase. [native-inputs]: Remove patch file. * gnu/packages/commencement.scm (glibc-final-with-bootstrap-bash, glibc-final)[native-inputs]: Remove patch file. Efraim Flashner 2021-03-24Merge remote-tracking branch 'origin/master' into core-updatesEfraim Flashner 2021-03-23gnu: sed: Make it build on SELinux-enabled kernels....Fixes: <https://bugs.gnu.org/41498>. * gnu/packages/base.scm (sed)[arguments]: New field. This adds a snippet, equivalent to the patch submitted upstream, which fixes an issue that prevents sed from building on SELinux-enabled kernels. Adjusted by Efraim Flashner to apply to master. Chris Marusich 2021-03-23gnu: glibc: Fix ldd path on powerpc*....This should avoid some problems, such as "not a dynamic executable" errors. * gnu/packages/patches/glibc-ldd-powerpc.patch: New patch. * gnu/local.mk (dist_patch_DATA): Register it. * gnu/packages/base.scm: (glibc)[native-inputs]: Add it. [arguments]: When building for powerpc* apply it. * gnu/packages/commencement.scm (glibc-final-with-bootstrap-bash, glibc-final)[native-inputs]: Add patch conditionally. This patch has been adjusted to apply to master. Signed-off-by: Chris Marusich <cmmarusich@gmail.com> Signed-off-by: Efraim Flashner <efraim@flashner.co.il> Leo Le Bouter 2021-02-18gnu: binutils: Update to 2.36.1....* gnu/packages/base.scm (binutils): Update to 2.36.1. Signed-off-by: Efraim Flashner <efraim@flashner.co.il> Vincent Legoll 2021-02-18gnu: tar: Update to 1.34....* gnu/packages/base.scm (tar): Update to 1.34. Efraim Flashner 2021-01-26gnu: binutils: Update to 2.36....* gnu/packages/base.scm (binutils): Update to 2.36. Efraim Flashner