;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2012 Nikita Karetnikov ;;; Copyright © 2013, 2017, 2020, 2021 Ludovic Courtès ;;; Copyright © 2013, 2015 Andreas Enge ;;; Copyright © 2015, 2016, 2017, 2018, 2019, 2021 Efraim Flashner ;;; Copyright © 2015, 2017 Leo Famulari ;;; Copyright © 2015, 2017 Cyril Roelandt ;;; Copyright © 2016 Sou Bunnbu ;;; Copyright © 2016 Hartmut Goebel ;;; Copyright © 2016 Danny Milosavljevic ;;; Copyright © 2016, 2020 Marius Bakke ;;; Copyright © 2016, 2017, 2018, 2020 Tobias Geerinckx-Rice ;;; Copyright © 2017 Ben Woodcroft ;;; Copyright © 2017 Nikita ;;; Copyright © 2017 Julien Lepiller ;;; Copyright © 2018 Alex Vong ;;; Copyright © 2019 Kyle Meyer
aboutsummaryrefslogtreecommitdiff
blob: 0ba0c839de6a72b26fd8645310adf388e2f952a7 (about) (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2017 Clément Lassieur <clement@lassieur.org>
;;; Copyright © 2017 Ludovic Courtès <ludo@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 messaging)
  #:use-module (gnu tests)
  #:use-module (gnu system)
  #:use-module (gnu system vm)
  #:use-module (gnu services)
  #:use-module (gnu services messaging)
  #:use-module (gnu services networking)
  #:use-module (gnu packages messaging)
  #:use-module (guix gexp)
  #:use-module (guix store)
  #:export (%test-prosody))

(define (run-xmpp-test name xmpp-service pid-file create-account)
  "Run a test of an OS running XMPP-SERVICE, which writes its PID to PID-FILE."
  (define os
    (marionette-operating-system
     (simple-operating-system (dhcp-client-service)
                              xmpp-service)
     #:imported-modules '((gnu services herd))))

  (define port 15222)

  (define vm
    (virtual-machine
     (operating-system os)
     (port-forwardings `((,port . 5222)))))

  (define username "alice")
  (define server "localhost")
  (define jid (string-append username "@" server))
  (define password "correct horse battery staple")
  (define message "hello world")
  (define witness "/tmp/freetalk-witness")

  (define script.ft
    (scheme-file
     "script.ft"
     #~(begin
         (define (handle-received-message time from nickname message)
           (define (touch file-name)
             (call-with-output-file file-name (const #t)))
           (when (equal? message #$message)
             (touch #$witness)))
         (add-hook! ft-message-receive-hook handle-received-message)

         (ft-set-jid! #$jid)
         (ft-set-password! #$password)
         (ft-set-server! #$server)
         (ft-set-port! #$port)
         (ft-set-sslconn! #f)
         (ft-connect-blocking)
         (ft-send-message #$jid #$message)

         (ft-set-daemon)
         (ft-main-loop))))

  (define test
    (with-imported-modules '((gnu build marionette))
      #~(begin
          (use-modules (gnu build marionette)
                       (srfi srfi-64))

          (define marionette
            (make-marionette (list #$vm)))

          (define (host-wait-for-file file)
            ;; Wait until FILE exists in the host.
            (let loop ((i 60))
              (cond ((file-exists? file)
                     #t)
                    ((> i 0)
                     (begin
                       (sleep 1))
                     (loop (- i 1)))
                    (else
                     (error "file didn't show up" file)))))

          (mkdir #$output)
          (chdir #$output)

          (test-begin "xmpp")

          ;; Wait for XMPP service to be up and running.
          (test-eq "service running"
            'running!
            (marionette-eval
             '(begin
                (use-modules (gnu services herd))
                (start-service 'xmpp-daemon)
                'running!)
             marionette))

          ;; Check XMPP service's PID.
          (test-assert "service process id"
            (let ((pid (number->string (wait-for-file #$pid-file
                                                      marionette))))
              (marionette-eval `(file-exists? (string-append "/proc/" ,pid))
                               marionette)))

          ;; Alice sends an XMPP message to herself, with Freetalk.
          (test-assert "client-to-server communication"
            (let ((freetalk-bin (string-append #$freetalk "/bin/freetalk")))
              (marionette-eval '(system* #$create-account #$jid #$password)
                               marionette)
              ;; Freetalk requires write access to $HOME.
              (setenv "HOME" "/tmp")
              (system* freetalk-bin "-s" #$script.ft)
              (host-wait-for-file #$witness)))

          (test-end)
          (exit (= (test-runner-fail-count (test-runner-current)) 0)))))

  (gexp->derivation name test))

(define %create-prosody-account
  (program-file
   "create-account"
   #~(begin
       (use-modules (ice-9 match))
       (match (command-line)
         ((command jid password)
          (let ((password-input (format #f "\"~a~%~a\"" password password))
                (prosodyctl #$(file-append prosody "/bin/prosodyctl")))
            (system (string-join
                     `("echo" ,password-input "|" ,prosodyctl "adduser" ,jid)
                     " "))))))))

(define %test-prosody
  (let* ((config (prosody-configuration
                  (virtualhosts
                   (list
                    (virtualhost-configuration
                     (domain "localhost")))))))
    (system-test
     (name "prosody")
     (description "Connect to a running Prosody daemon.")
     (value (run-xmpp-test name
                           (service prosody-service-type config)
                           (prosody-configuration-pidfile config)
                           %create-prosody-account)))))
' ;; It's optional, remove this constrain where python-pytz is updated. #:test-flags #~(list "-k" "not test_with_pytz"))) (native-inputs (list python-poetry-core python-pytest)) (propagated-inputs (list python-cffi python-h3-3 python-numba python-numpy python-pytz)) (home-page "https://timezonefinder.michelfe.it/gui") (synopsis "Finding the timezone of any coordinates on Earth offline") (description "This is a python package for looking up the corresponding timezone for given coordinates on earth entirely offline.") (license expat))) (define-public python-tzlocal (package (name "python-tzlocal") (version "5.2") (source (origin (method git-fetch) (uri (git-reference (url "https://github.com/regebro/tzlocal") (commit version))) (file-name (git-file-name name version)) (sha256 (base32 "1apa3i5fsfw28jnaaaa7jr976y5wbifl3h04id0bvplvsb9zpmy7")))) (build-system pyproject-build-system) (propagated-inputs (list python-tzdata)) (native-inputs (list python-check-manifest python-pytest python-pytest-cov python-pytest-mock)) (home-page "https://github.com/regebro/tzlocal") (synopsis "Local timezone information for Python") (description "Tzlocal returns a tzinfo object with the local timezone information. This module attempts to fix a glaring hole in pytz, that there is no way to get the local timezone information, unless you know the zoneinfo name, and under several distributions that's hard or impossible to figure out.") (license expat))) (define-public python-isodate (package (name "python-isodate") (version "0.6.1") (source (origin (method url-fetch) (uri (pypi-uri "isodate" version)) (sha256 (base32 "1sdx4z0x6kv1qxjfi0gd82wfg16wca04q0nb93ba1c78wwfqiia8")))) (build-system python-build-system) (native-inputs (list python-six)) (home-page "https://github.com/gweis/isodate/") (synopsis "Python date parser and formatter") (description "Python-isodate is a python module for parsing and formatting ISO 8601 dates, time and duration.") (license bsd-3))) (define-public python-iso8601 (package (name "python-iso8601") (version "1.0.2") (source (origin (method url-fetch) (uri (pypi-uri "iso8601" version)) (sha256 (base32 "1ccl6plks706hxm35cn1wsvxhqh3bfwi5cjgjpdxjib81qi07x97")))) (build-system python-build-system) (arguments '(#:phases (modify-phases %standard-phases (replace 'check (lambda _ (invoke "pytest" "-vv" "iso8601")))))) (native-inputs (list python-pytest python-pytz)) (home-page "https://github.com/micktwomey/pyiso8601") (synopsis "Module to parse ISO 8601 dates") (description "This module parses the most common forms of ISO 8601 date strings (e.g. @code{2007-01-14T20:34:22+00:00}) into @code{datetime} objects.") (license expat))) (define-public python-monotonic (package (name "python-monotonic") (version "1.5") (source (origin (method url-fetch) (uri (pypi-uri "monotonic" version)) (sha256 (base32 "1c6z46yb600klbfhqadyl7vq0jdjdxkm72k43ra3iw3d0xakv593")))) (build-system python-build-system) (arguments '(#:tests? #f)) ; no tests (home-page "https://github.com/atdt/monotonic") (synopsis "Implementation of time.monotonic() for Python 2 & < 3.3") (description "This module provides a @code{monotonic()} function which returns the value (in fractional seconds) of a clock which never goes backwards.") (license asl2.0))) (define-public python-pyrfc3339 (package (name "python-pyrfc3339") (version "1.1") (source (origin (method url-fetch) (uri (pypi-uri "pyRFC3339" version)) (sha256 (base32 "06jv7ar7lpvvk0dixzwdr3wgm0g1lipxs429s2z7knwwa7hwpf41")))) (build-system python-build-system) (propagated-inputs (list python-pytz)) (native-inputs (list python-nose)) (home-page "https://github.com/kurtraschke/pyRFC3339") (synopsis "Python timestamp library") (description "Python library for generating and parsing RFC 3339-compliant timestamps.") (license expat))) (define-public python-arrow (package (name "python-arrow") (version "1.2.3") (source (origin (method url-fetch) (uri (pypi-uri "arrow" version)) (sha256 (base32 "189knrgxb3x21lzvqac6qlpd32308hcmpccxdlvr5wmrl46b6d1r")))) (build-system python-build-system) (arguments `(#:phases (modify-phases %standard-phases (replace 'check (lambda* (#:key tests? #:allow-other-keys) (when tests? (invoke "pytest" "-vv" "tests" ;; python-dateutil doesn't recognize America/Nuuk. ;; Remove when python-dateutil > 2.8.1. "-k" "not test_parse_tz_name_zzz"))))))) (native-inputs (list ;; For testing python-chai python-pytest python-pytest-cov python-pytest-mock python-pytz python-simplejson)) (propagated-inputs (list python-dateutil)) (home-page "https://github.com/arrow-py/arrow") (synopsis "Dates and times for Python") (description "Arrow is a Python library to creating, manipulating, formatting and converting dates, times, and timestamps. It implements and updates the datetime type.") (license asl2.0))) (define-public python-aniso8601 (package (name "python-aniso8601") (version "9.0.1") (source (origin (method url-fetch) (uri (pypi-uri "aniso8601" version)) (sha256 (base32 "0wxry6riyqajl02mkad8g2q98sx5jr13zndj3fandpzfcxv13qvj")))) (build-system python-build-system) (home-page "https://bitbucket.org/nielsenb/aniso8601") (synopsis "Python library for parsing ISO 8601 strings") (description "This package contains a library for parsing ISO 8601 datetime strings.") (license bsd-3))) (define-public datefudge (package (name "datefudge") ;; XXX When updating this package, make sure to do something about the ;; archive.org backup URI. (version "1.23") (source (origin ;; Source code is available from ;; . However, ;; for bootstrapping reasons, we do not rely on 'git-fetch' here ;; (since Git -> GnuTLS -> datefudge). (method url-fetch) (uri (list ;; For some reason this tarball was removed from Debian's ;; servers. Remove this archive.org URL when updating ;; datefudge, or add the new tarball to archive.org and ;; update the URL. (string-append "https://archive.org/download/datefudge_" version ".tar_202112/" "datefudge_" version ".tar.xz") (string-append "mirror://debian/pool/main/d/datefudge/datefudge_" version ".tar.xz"))) (sha256 (base32 "0ifnlb0mc8qc2kb5042pbz0ns6rwcb7201di8wyrsphl0yhnhxiv")) (patches (search-patches "datefudge-gettimeofday.patch")))) (build-system gnu-build-system) (arguments `(#:test-target "test" #:make-flags (list "CC=gcc" (string-append "prefix=" (assoc-ref %outputs "out"))) #:phases (modify-phases %standard-phases (add-after 'unpack 'patch-makefile (lambda _ (substitute* "Makefile" ((" -o root -g root") "") (("VERSION := \\$\\(shell dpkg-parsechangelog .*") (string-append "VERSION = " ,version))) #t)) (delete 'configure)))) (native-inputs (list perl)) (home-page "https://salsa.debian.org/debian/datefudge") (synopsis "Pretend the system date is different") (description "Utility that fakes the system time by pre-loading a small library that modifies the @code{time}, @code{gettimeofday} and @code{clock_gettime} system calls.") (license gpl2))) (define-public tz (package (name "tz") (version "0.6.1") (source (origin (method git-fetch) (uri (git-reference (url "https://github.com/oz/tz") (commit (string-append "v" version)))) (file-name (git-file-name name version)) (sha256 (base32 "1nbl13xd95np89sbx8fn0jqrh1iy17hsy70kq31hmcvyns8dljhg")))) (build-system go-build-system) (arguments `(#:go ,go-1.17 #:import-path "github.com/oz/tz" #:phases (modify-phases %standard-phases (replace 'check (lambda* (#:key import-path tests? #:allow-other-keys) (when tests? (invoke "go" "test" "-cover" import-path))))))) (inputs `(("github.com/charmbracelet/bubbletea" ,go-github-com-charmbracelet-bubbletea) ("github.com/muesli/termenv" ,go-github-com-muesli-termenv))) (home-page "https://github.com/oz/tz") (synopsis "TUI time zone helper") (description "@command{tz} helps you schedule things across time zones. It is an interactive TUI program that displays time across a few time zones of your choosing.") (license gpl3+))) (define-public countdown (package (name "countdown") (version "1.0.0") (source (origin (method git-fetch) (uri (git-reference (url "https://github.com/antonmedv/countdown") (commit (string-append "v" version)))) (file-name (git-file-name name version)) (sha256 (base32 "0pdaw1krr0bsl4amhwx03v2b02iznvwvqn7af5zp4fkzjaj14cdw")))) (build-system go-build-system) (arguments '(#:import-path "github.com/antonmedv/countdown")) (native-inputs `(("runewidth" ,go-github-com-mattn-go-runewidth) ("termbox" ,go-github.com-nsf-termbox-go))) (home-page "https://github.com/antonmedv/countdown") (synopsis "Counts to zero with a text user interface") (description "Countdown provides a fancy text display while it counts down to zero from a starting point you provide. The user can pause and resume the countdown from the text user interface.") (license expat)))