aboutsummaryrefslogtreecommitdiff
path: root/gnu/tests/telephony.scm
diff options
context:
space:
mode:
authorMaxim Cournoyer <maxim.cournoyer@gmail.com>2021-04-15 01:18:24 -0400
committerMaxim Cournoyer <maxim.cournoyer@gmail.com>2021-08-02 15:15:02 -0400
commit69dcc24c9f0cdfea674eb690e7755d26a25ced2b (patch)
tree657e1068cea480e45c8fe7ea4c15b0f982bae52a /gnu/tests/telephony.scm
parent8e1f94421873777c6bb0b83daa4f81cbacc8b3ff (diff)
downloadguix-69dcc24c9f0cdfea674eb690e7755d26a25ced2b.tar
guix-69dcc24c9f0cdfea674eb690e7755d26a25ced2b.tar.gz
services: Add a service for Jami.
* gnu/services/telephony.scm (string-or-computed-file?) (string-list?, account-fingerprint-list?): New procedures. (maybe-string-list, maybe-account-fingerprint-list) (maybe-boolean, maybe-string, jami-account-list): New configuration field types. (serialize-string-list, serialize-boolean, serialize-string) (jami-account, jami-account->alist, jami-configuration) (jami-account-list?, jami-account-list-maybe): New procedures. (%jami-accounts): New variable. (jami-configuration->command-line-arguments): New procedure. (jami-dbus-session-activation, jami-shepherd-services): New procedures. (jami-service-type): New variable. * gnu/build/jami-service.scm: New file. * gnu/tests/data/jami-dummy-account.dat: Likewise. * gnu/tests/telephony.scm: Likewise. * gnu/local.mk (GNU_SYSTEM_MODULES): Register them. * Makefile.am (SCM_TESTS): Register the test file. (dist_patch_DATA): Register the new data file. * doc/guix.texi (Telephony Services): Document it.
Diffstat (limited to 'gnu/tests/telephony.scm')
-rw-r--r--gnu/tests/telephony.scm366
1 files changed, 366 insertions, 0 deletions
diff --git a/gnu/tests/telephony.scm b/gnu/tests/telephony.scm
new file mode 100644
index 0000000000..1155a9dbc2
--- /dev/null
+++ b/gnu/tests/telephony.scm
@@ -0,0 +1,366 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2021 Maxim Cournoyer <maxim.cournoyer@gnu.org>.
+;;;
+;;; 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 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))
+
+;;;
+;;; 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")))
+
+(define* (make-jami-os #:key provisioning?)
+ (operating-system
+ (host-name "jami")
+ (timezone "America/Montreal")
+ (locale "en_US.UTF-8")
+
+ (bootloader (bootloader-configuration
+ (bootloader grub-bootloader)
+ (target "/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 %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* (run-jami-test #:key provisioning?)
+ "Run tests in %JAMI-OS. When PROVISIONING? is true, test the
+accounts provisioning feature of the service."
+ (define os (marionette-operating-system
+ (if provisioning?
+ %jami-os-provisioning
+ %jami-os)
+ #:imported-modules '((gnu services herd)
+ (guix combinators))))
+ (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)
+ (gnu build jami-service)))
+ #~(begin
+ (use-modules (rnrs base)
+ (srfi srfi-11)
+ (srfi srfi-64)
+ (gnu build marionette)
+ (gnu build jami-service))
+
+ (define marionette
+ (make-marionette (list #$vm)))
+
+ (mkdir #$output)
+ (chdir #$output)
+
+ (test-begin "jami")
+
+ (test-assert "service is running"
+ (marionette-eval
+ '(begin
+ (use-modules (gnu services herd))
+ (match (start-service 'jami)
+ (#f #f)
+ (('service response-parts ...)
+ (match (assq-ref response-parts 'running)
+ ((pid) (number? pid))))))
+ marionette))
+
+ (test-assert "service can be stopped"
+ (marionette-eval
+ '(begin
+ (use-modules (gnu services herd)
+ (rnrs base))
+ (setenv "PATH" "/run/current-system/profile/bin")
+ (let ((pid (match (start-service 'jami)
+ (#f #f)
+ (('service response-parts ...)
+ (match (assq-ref response-parts 'running)
+ ((pid) pid))))))
+
+ (assert (number? pid))
+
+ (match (stop-service 'jami)
+ (services ;a list of service symbols
+ (member 'jami services)))
+ ;; Sometimes, the process still appear in pgrep, even
+ ;; though we are using waitpid after sending it SIGTERM
+ ;; in the service; use retries.
+ (with-retries 20 1
+ (not (zero? (status:exit-val
+ (system* "pgrep" "dring")))))))
+ marionette))
+
+ (test-assert "service can be restarted"
+ (marionette-eval
+ '(begin
+ (use-modules (gnu services herd)
+ (rnrs base))
+ ;; Start and retrieve the current PID.
+ (define pid (match (start-service 'jami)
+ (#f #f)
+ (('service response-parts ...)
+ (match (assq-ref response-parts 'running)
+ ((pid) pid)))))
+ (assert (number? pid))
+
+ ;; Restart the service.
+ (restart-service 'jami)
+
+ (define new-pid (match (start-service 'jami)
+ (#f #f)
+ (('service response-parts ...)
+ (match (assq-ref response-parts 'running)
+ ((pid) pid)))))
+ (assert (number? new-pid))
+
+ (not (eq? pid new-pid)))
+ marionette))
+
+ (unless #$provisioning? (test-skip 1))
+ (test-assert "jami accounts provisioning, account present"
+ (marionette-eval
+ '(begin
+ (use-modules (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 #$provisioning? (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 #$provisioning? (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)
+ (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)
+ (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
+
+ (gexp->derivation (if provisioning?
+ "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))))
+
+;; Local Variables:
+;; eval: (put 'with-retries 'scheme-indent-function 2)
+;; End: