telephony.scm 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. ;;; GNU Guix --- Functional package management for GNU
  2. ;;; Copyright © 2021, 2022, 2023 Maxim Cournoyer <maxim.cournoyer@gmail.com>.
  3. ;;;
  4. ;;; This file is part of GNU Guix.
  5. ;;;
  6. ;;; GNU Guix is free software; you can redistribute it and/or modify it
  7. ;;; under the terms of the GNU General Public License as published by
  8. ;;; the Free Software Foundation; either version 3 of the License, or (at
  9. ;;; your option) any later version.
  10. ;;;
  11. ;;; GNU Guix is distributed in the hope that it will be useful, but
  12. ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. ;;; GNU General Public License for more details.
  15. ;;;
  16. ;;; You should have received a copy of the GNU General Public License
  17. ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
  18. (define-module (gnu tests telephony)
  19. #:use-module (gnu)
  20. #:use-module (gnu packages)
  21. #:use-module (gnu packages guile)
  22. #:use-module (gnu packages guile-xyz)
  23. #:use-module (gnu tests)
  24. #:use-module (gnu system vm)
  25. #:use-module (gnu services)
  26. #:use-module (gnu services dbus)
  27. #:use-module (gnu services networking)
  28. #:use-module (gnu services ssh)
  29. #:use-module (gnu services telephony)
  30. #:use-module (guix gexp)
  31. #:use-module (guix modules)
  32. #:export (%test-jami
  33. %test-jami-provisioning
  34. %test-jami-provisioning-partial))
  35. ;;;
  36. ;;; Jami daemon.
  37. ;;;
  38. (include "data/jami-dummy-account.dat") ;defines %jami-account-content-sexp
  39. (define %dummy-jami-account-archive
  40. ;; A Jami account archive is a gzipped JSON file.
  41. (computed-file
  42. "dummy-jami-account.gz"
  43. (with-extensions (list guile-json-4 guile-zlib)
  44. #~(begin
  45. (use-modules (json) (zlib))
  46. (let ((port (open-output-file #$output)))
  47. (call-with-gzip-output-port port
  48. (lambda (port)
  49. (scm->json '#$%jami-account-content-sexp port))))))))
  50. (define %allowed-contacts '("1dbcb0f5f37324228235564b79f2b9737e9a008f"
  51. "2dbcb0f5f37324228235564b79f2b9737e9a008f"))
  52. (define %moderators '("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
  53. "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"))
  54. (define %dummy-jami-account (jami-account
  55. (archive %dummy-jami-account-archive)
  56. (allowed-contacts %allowed-contacts)
  57. (moderators %moderators)
  58. (rendezvous-point? #t)
  59. (peer-discovery? #f)
  60. (bootstrap-hostnames '("bootstrap.me"
  61. "fallback.another.host"))
  62. (name-server-uri "https://my.name.server")))
  63. ;;; Like %dummy-jami-account, but with allowed-contacts and moderators left
  64. ;;; unset (thus taking the value *unspecified*).
  65. (define %dummy-jami-account-partial
  66. (jami-account
  67. (archive %dummy-jami-account-archive)
  68. (rendezvous-point? #t)
  69. (peer-discovery? #f)
  70. (bootstrap-hostnames '("bootstrap.me"
  71. "fallback.another.host"))
  72. (name-server-uri "https://my.name.server")))
  73. (define* (make-jami-os #:key provisioning? partial?)
  74. (operating-system
  75. (host-name "jami")
  76. (timezone "America/Montreal")
  77. (locale "en_US.UTF-8")
  78. (bootloader (bootloader-configuration
  79. (bootloader grub-bootloader)
  80. (targets '("/dev/sdX"))))
  81. (file-systems (cons (file-system
  82. (device (file-system-label "my-root"))
  83. (mount-point "/")
  84. (type "ext4"))
  85. %base-file-systems))
  86. (firmware '())
  87. (services (cons* (service jami-service-type
  88. (if provisioning?
  89. (jami-configuration
  90. (debug? #t)
  91. (accounts
  92. (list (if partial?
  93. %dummy-jami-account-partial
  94. %dummy-jami-account))))
  95. (jami-configuration
  96. (debug? #t))))
  97. (service dbus-root-service-type)
  98. ;; The following services/packages are added for
  99. ;; debugging purposes.
  100. (service dhcp-client-service-type)
  101. (service openssh-service-type
  102. (openssh-configuration
  103. (permit-root-login #t)
  104. (allow-empty-passwords? #t)))
  105. %base-services))
  106. (packages (cons* (specification->package "recutils")
  107. (specification->package "strace")
  108. %base-packages))))
  109. (define %jami-os
  110. (make-jami-os))
  111. (define %jami-os-provisioning
  112. (make-jami-os #:provisioning? #t))
  113. (define %jami-os-provisioning-partial
  114. (make-jami-os #:provisioning? #t #:partial? #t))
  115. (define* (run-jami-test #:key provisioning? partial?)
  116. "Run tests in %JAMI-OS. When PROVISIONING? is true, test the accounts
  117. provisioning feature of the service. When PARTIAL? is #t, some fields of the
  118. jami account used as part of the jami configuration are left *unspecified*."
  119. (define os (marionette-operating-system
  120. (if provisioning?
  121. (if partial?
  122. %jami-os-provisioning-partial
  123. %jami-os-provisioning)
  124. %jami-os)
  125. #:imported-modules '((gnu services herd)
  126. (guix combinators)
  127. (gnu build jami-service)
  128. (gnu build dbus-service))))
  129. (define vm (virtual-machine
  130. (operating-system os)
  131. (memory-size 512)))
  132. (define username (assoc-ref %jami-account-content-sexp
  133. "Account.username"))
  134. (define test
  135. (with-imported-modules (source-module-closure
  136. '((gnu build marionette)))
  137. #~(begin
  138. (use-modules (srfi srfi-64)
  139. (gnu build marionette))
  140. (define marionette
  141. (make-marionette (list #$vm)))
  142. (test-runner-current (system-test-runner #$output))
  143. (test-begin "jami")
  144. (test-assert "d-bus tooling loaded"
  145. ;; Add Guile-AC-D-Bus and related libraries to the marionette's
  146. ;; search path.
  147. (marionette-eval
  148. '(let ((libraries '(#$guile-ac-d-bus
  149. #$guile-packrat))) ;used by ac-d-bus
  150. (setenv "DBUS_SESSION_BUS_ADDRESS" "unix:path=/var/run/jami/bus")
  151. (set! %load-path
  152. (append %load-path
  153. (map (lambda (directory)
  154. (string-append directory
  155. "/share/guile/site/"
  156. (effective-version)))
  157. libraries)))
  158. (set! %load-compiled-path
  159. (append %load-compiled-path
  160. (map (lambda (directory)
  161. (string-append directory
  162. "/lib/guile/3.0/site-ccache"))
  163. libraries)))
  164. %load-path)
  165. marionette))
  166. (test-assert "service is running"
  167. (marionette-eval
  168. '(begin
  169. (use-modules (gnu build jami-service)
  170. (gnu services herd))
  171. (wait-for-service 'jami)
  172. (jami-service-available?))
  173. marionette))
  174. (test-assert "service can be stopped"
  175. (marionette-eval
  176. '(begin
  177. (use-modules (gnu build dbus-service)
  178. (gnu build jami-service)
  179. (gnu services herd)
  180. (rnrs base))
  181. (assert (jami-service-available?))
  182. (stop-service 'jami)
  183. (with-retries 20 1 (not (jami-service-available?))))
  184. marionette))
  185. (test-assert "service can be restarted"
  186. (marionette-eval
  187. '(begin
  188. (use-modules (gnu build dbus-service)
  189. (gnu build jami-service)
  190. (gnu services herd)
  191. (rnrs base) )
  192. ;; Start the service.
  193. (start-service 'jami)
  194. (with-retries 20 1 (jami-service-available?))
  195. ;; Restart the service.
  196. (restart-service 'jami)
  197. (with-retries 20 1 (jami-service-available?)))
  198. marionette))
  199. (unless #$provisioning? (test-skip 1))
  200. (test-assert "jami accounts provisioning, account present"
  201. (marionette-eval
  202. '(begin
  203. (use-modules (gnu build dbus-service)
  204. (gnu services herd)
  205. (rnrs base))
  206. ;; Accounts take some time to appear after being added.
  207. (with-retries 20 1
  208. (with-shepherd-action 'jami ('list-accounts) results
  209. (let ((account (assoc-ref (car results) #$username)))
  210. (assert (string=? #$username
  211. (assoc-ref account
  212. "Account.username")))))))
  213. marionette))
  214. (unless #$(and provisioning? (not partial?)) (test-skip 1))
  215. (test-assert "jami accounts provisioning, allowed-contacts"
  216. (marionette-eval
  217. '(begin
  218. (use-modules (gnu services herd)
  219. (rnrs base)
  220. (srfi srfi-1))
  221. ;; Public mode is disabled.
  222. (with-shepherd-action 'jami ('list-account-details)
  223. results
  224. (let ((account (assoc-ref (car results) #$username)))
  225. (assert (string=? "false"
  226. (assoc-ref account
  227. "DHT.PublicInCalls")))))
  228. ;; Allowed contacts match those declared in the configuration.
  229. (with-shepherd-action 'jami ('list-contacts) results
  230. (let ((contacts (assoc-ref (car results) #$username)))
  231. (assert (lset= string-ci=? contacts '#$%allowed-contacts)))))
  232. marionette))
  233. (unless #$(and provisioning? (not partial?)) (test-skip 1))
  234. (test-assert "jami accounts provisioning, moderators"
  235. (marionette-eval
  236. '(begin
  237. (use-modules (gnu services herd)
  238. (rnrs base)
  239. (srfi srfi-1))
  240. ;; Moderators match those declared in the configuration.
  241. (with-shepherd-action 'jami ('list-moderators) results
  242. (let ((moderators (assoc-ref (car results) #$username)))
  243. (assert (lset= string-ci=? moderators '#$%moderators))))
  244. ;; Moderators can be added via the Shepherd action.
  245. (with-shepherd-action 'jami
  246. ('add-moderator "cccccccccccccccccccccccccccccccccccccccc"
  247. #$username) results
  248. (let ((moderators (car results)))
  249. (assert (lset= string-ci=? moderators
  250. (cons "cccccccccccccccccccccccccccccccccccccccc"
  251. '#$%moderators))))))
  252. marionette))
  253. (unless #$provisioning? (test-skip 1))
  254. (test-assert "jami service actions, ban/unban contacts"
  255. (marionette-eval
  256. '(begin
  257. (use-modules (gnu services herd)
  258. (ice-9 match)
  259. (rnrs base)
  260. (srfi srfi-1))
  261. ;; Globally ban a contact.
  262. (with-shepherd-action 'jami
  263. ('ban-contact "1dbcb0f5f37324228235564b79f2b9737e9a008f") _
  264. (with-shepherd-action 'jami ('list-banned-contacts) results
  265. (every (match-lambda
  266. ((username . banned-contacts)
  267. (member "1dbcb0f5f37324228235564b79f2b9737e9a008f"
  268. banned-contacts)))
  269. (car results))))
  270. ;; Ban a contact for a single account.
  271. (with-shepherd-action 'jami
  272. ('ban-contact "dddddddddddddddddddddddddddddddddddddddd"
  273. #$username) _
  274. (with-shepherd-action 'jami ('list-banned-contacts) results
  275. (every (match-lambda
  276. ((username . banned-contacts)
  277. (let ((found? (member "dddddddddddddddddddddddddddddddddddddddd"
  278. banned-contacts)))
  279. (if (string=? #$username username)
  280. found?
  281. (not found?)))))
  282. (car results)))))
  283. marionette))
  284. (unless #$provisioning? (test-skip 1))
  285. (test-assert "jami service actions, enable/disable accounts"
  286. (marionette-eval
  287. '(begin
  288. (use-modules (gnu services herd)
  289. (rnrs base))
  290. (with-shepherd-action 'jami
  291. ('disable-account #$username) _
  292. (with-shepherd-action 'jami ('list-accounts) results
  293. (let ((account (assoc-ref (car results) #$username)))
  294. (assert (string= "false"
  295. (assoc-ref account "Account.enable"))))))
  296. (with-shepherd-action 'jami
  297. ('enable-account #$username) _
  298. (with-shepherd-action 'jami ('list-accounts) results
  299. (let ((account (assoc-ref (car results) #$username)))
  300. (assert (string= "true"
  301. (assoc-ref account "Account.enable")))))))
  302. marionette))
  303. (unless #$provisioning? (test-skip 1))
  304. (test-assert "jami account parameters"
  305. (marionette-eval
  306. '(begin
  307. (use-modules (gnu services herd)
  308. (rnrs base)
  309. (srfi srfi-1))
  310. (with-shepherd-action 'jami ('list-account-details) results
  311. (let ((account-details (assoc-ref (car results)
  312. #$username)))
  313. (assert (lset<=
  314. equal?
  315. '(("Account.hostname" .
  316. "bootstrap.me;fallback.another.host")
  317. ("Account.peerDiscovery" . "false")
  318. ("Account.rendezVous" . "true")
  319. ("RingNS.uri" . "https://my.name.server"))
  320. account-details)))))
  321. marionette))
  322. (test-end))))
  323. (gexp->derivation (if provisioning?
  324. (if partial?
  325. "jami-provisioning-partial-test"
  326. "jami-provisioning-test")
  327. "jami-test")
  328. test))
  329. (define %test-jami
  330. (system-test
  331. (name "jami")
  332. (description "Basic tests for the jami service.")
  333. (value (run-jami-test))))
  334. (define %test-jami-provisioning
  335. (system-test
  336. (name "jami-provisioning")
  337. (description "Provisioning test for the jami service.")
  338. (value (run-jami-test #:provisioning? #t))))
  339. ;;; Thi test verifies that <jami-account> values can be left unspecified
  340. ;;; without causing any issue (see: https://issues.guix.gnu.org/56799).
  341. (define %test-jami-provisioning-partial
  342. (system-test
  343. (name "jami-provisioning-partial")
  344. (description "Provisioning test for the jami service, when some of the
  345. 'maybe' fields aren't provided (such that their value end up being
  346. *unspecified*.")
  347. (value (run-jami-test #:provisioning? #t #:partial? #t))))