| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | |
| 10 | |
| 11 | |
| 12 | |
| 13 | |
| 14 | |
| 15 | |
| 16 | |
| 17 | |
| 18 | |
| 19 | |
| 20 | |
| 21 | |
| 22 | |
| 23 |
|
| 24 | (define-module (gnu tests messaging)
|
| 25 | #:use-module (gnu tests)
|
| 26 | #:use-module (gnu system)
|
| 27 | #:use-module (gnu system vm)
|
| 28 | #:use-module (gnu services)
|
| 29 | #:use-module (gnu services base)
|
| 30 | #:use-module (gnu services messaging)
|
| 31 | #:use-module (gnu services networking)
|
| 32 | #:use-module (gnu services shepherd)
|
| 33 | #:use-module (gnu services ssh)
|
| 34 | #:use-module (gnu packages)
|
| 35 | #:use-module (gnu packages irc)
|
| 36 | #:use-module (gnu packages messaging)
|
| 37 | #:use-module (gnu packages networking)
|
| 38 | #:use-module (gnu packages screen)
|
| 39 | #:use-module (gnu packages tls)
|
| 40 | #:use-module (guix gexp)
|
| 41 | #:use-module (guix store)
|
| 42 | #:use-module (guix modules)
|
| 43 | #:export (%test-prosody
|
| 44 | %test-bitlbee
|
| 45 | %test-ngircd
|
| 46 | %test-pounce
|
| 47 | %test-quassel
|
| 48 | %test-mosquitto
|
| 49 | %test-soju))
|
| 50 |
|
| 51 | (define (run-xmpp-test name xmpp-service pid-file create-account)
|
| 52 | "Run a test of an OS running XMPP-SERVICE, which writes its PID to PID-FILE."
|
| 53 | (define os
|
| 54 | (marionette-operating-system
|
| 55 | (simple-operating-system (service dhcpcd-service-type)
|
| 56 | xmpp-service)
|
| 57 | #:imported-modules '((gnu services herd))))
|
| 58 |
|
| 59 | (define port 15222)
|
| 60 |
|
| 61 | (define vm
|
| 62 | (virtual-machine
|
| 63 | (operating-system os)
|
| 64 | (port-forwardings `((,port . 5222)))))
|
| 65 |
|
| 66 | (define username "alice")
|
| 67 | (define server "localhost")
|
| 68 | (define jid (string-append username "@" server))
|
| 69 | (define password "correct horse battery staple")
|
| 70 | (define message "hello world")
|
| 71 | (define witness "/tmp/freetalk-witness")
|
| 72 |
|
| 73 | (define script.ft
|
| 74 | (scheme-file
|
| 75 | "script.ft"
|
| 76 | #~(begin
|
| 77 | (define (handle-received-message time from nickname message)
|
| 78 | (define (touch file-name)
|
| 79 | (call-with-output-file file-name (const #t)))
|
| 80 | (when (equal? message #$message)
|
| 81 | (touch #$witness)))
|
| 82 | (add-hook! ft-message-receive-hook handle-received-message)
|
| 83 |
|
| 84 | (ft-set-jid! #$jid)
|
| 85 | (ft-set-password! #$password)
|
| 86 | (ft-set-server! #$server)
|
| 87 | (ft-set-port! #$port)
|
| 88 | (ft-set-sslconn! #f)
|
| 89 | (ft-connect-blocking)
|
| 90 | (ft-send-message #$jid #$message)
|
| 91 |
|
| 92 | (ft-set-daemon)
|
| 93 | (ft-main-loop))))
|
| 94 |
|
| 95 | (define test
|
| 96 | (with-imported-modules '((gnu build marionette))
|
| 97 | #~(begin
|
| 98 | (use-modules (gnu build marionette)
|
| 99 | (srfi srfi-64))
|
| 100 |
|
| 101 | (define marionette
|
| 102 | (make-marionette (list #$vm)))
|
| 103 |
|
| 104 | (define (host-wait-for-file file)
|
| 105 | |
| 106 | (let loop ((i 60))
|
| 107 | (cond ((file-exists? file)
|
| 108 | #t)
|
| 109 | ((> i 0)
|
| 110 | (begin
|
| 111 | (sleep 1))
|
| 112 | (loop (- i 1)))
|
| 113 | (else
|
| 114 | (error "file didn't show up" file)))))
|
| 115 |
|
| 116 | (test-runner-current (system-test-runner #$output))
|
| 117 | (test-begin "xmpp")
|
| 118 |
|
| 119 | |
| 120 | (test-assert "service running"
|
| 121 | (marionette-eval
|
| 122 | '(begin
|
| 123 | (use-modules (gnu services herd))
|
| 124 | (start-service 'xmpp-daemon))
|
| 125 | marionette))
|
| 126 |
|
| 127 | |
| 128 | (test-assert "service process id"
|
| 129 | (let ((pid (number->string (wait-for-file #$pid-file
|
| 130 | marionette))))
|
| 131 | (marionette-eval `(file-exists? (string-append "/proc/" ,pid))
|
| 132 | marionette)))
|
| 133 |
|
| 134 | |
| 135 | (test-assert "client-to-server communication"
|
| 136 | (let ((freetalk-bin (string-append #$freetalk "/bin/freetalk")))
|
| 137 | (marionette-eval '(system* #$create-account #$jid #$password)
|
| 138 | marionette)
|
| 139 | |
| 140 | (setenv "HOME" "/tmp")
|
| 141 | (system* freetalk-bin "-s" #$script.ft)
|
| 142 | (host-wait-for-file #$witness)))
|
| 143 |
|
| 144 | (test-end))))
|
| 145 |
|
| 146 | (gexp->derivation name test))
|
| 147 |
|
| 148 | (define %create-prosody-account
|
| 149 | (program-file
|
| 150 | "create-account"
|
| 151 | #~(begin
|
| 152 | (use-modules (ice-9 match))
|
| 153 | (match (command-line)
|
| 154 | ((command jid password)
|
| 155 | (let ((password-input (format #f "\"~a~%~a\"" password password))
|
| 156 | (prosodyctl #$(file-append prosody "/bin/prosodyctl")))
|
| 157 | (system (string-join
|
| 158 | `("echo" ,password-input "|" ,prosodyctl "adduser" ,jid)
|
| 159 | " "))))))))
|
| 160 |
|
| 161 | (define %test-prosody
|
| 162 | (let* ((config (prosody-configuration
|
| 163 | (modules-enabled
|
| 164 | (cons "admin_shell" %default-modules-enabled))
|
| 165 | (insecure-sasl-mechanisms '())
|
| 166 | (virtualhosts
|
| 167 | (list
|
| 168 | (virtualhost-configuration
|
| 169 | (domain "localhost")))))))
|
| 170 | (system-test
|
| 171 | (name "prosody")
|
| 172 | (description "Connect to a running Prosody daemon.")
|
| 173 | (value (run-xmpp-test name
|
| 174 | (service prosody-service-type config)
|
| 175 | (prosody-configuration-pidfile config)
|
| 176 | %create-prosody-account)))))
|
| 177 |
|
| 178 |
|
| 179 | |
| 180 | |
| 181 | |
| 182 |
|
| 183 | (define (run-bitlbee-test)
|
| 184 | (define os
|
| 185 | (marionette-operating-system
|
| 186 | (simple-operating-system (service dhcpcd-service-type)
|
| 187 | (service bitlbee-service-type
|
| 188 | (bitlbee-configuration
|
| 189 | (interface "0.0.0.0"))))
|
| 190 | #:imported-modules (source-module-closure
|
| 191 | '((gnu services herd)))))
|
| 192 |
|
| 193 | (define vm
|
| 194 | (virtual-machine
|
| 195 | (operating-system os)
|
| 196 | (port-forwardings `((6667 . 6667)))))
|
| 197 |
|
| 198 | (define test
|
| 199 | (with-imported-modules '((gnu build marionette))
|
| 200 | #~(begin
|
| 201 | (use-modules (ice-9 rdelim)
|
| 202 | (srfi srfi-64)
|
| 203 | (gnu build marionette))
|
| 204 |
|
| 205 | (define marionette
|
| 206 | (make-marionette (list #$vm)))
|
| 207 |
|
| 208 | (test-runner-current (system-test-runner #$output))
|
| 209 | (test-begin "bitlbee")
|
| 210 |
|
| 211 | (test-assert "service started"
|
| 212 | (marionette-eval
|
| 213 | '(begin
|
| 214 | (use-modules (gnu services herd))
|
| 215 | (start-service 'bitlbee))
|
| 216 | marionette))
|
| 217 |
|
| 218 | (test-assert "connect"
|
| 219 | (let* ((address (make-socket-address AF_INET INADDR_LOOPBACK
|
| 220 | 6667))
|
| 221 | (sock (socket AF_INET SOCK_STREAM 0)))
|
| 222 | (connect sock address)
|
| 223 | |
| 224 | (->bool (string-contains (pk 'message (read-line sock))
|
| 225 | "BitlBee"))))
|
| 226 |
|
| 227 | (test-end))))
|
| 228 |
|
| 229 | (gexp->derivation "bitlbee-test" test))
|
| 230 |
|
| 231 | (define %test-bitlbee
|
| 232 | (system-test
|
| 233 | (name "bitlbee")
|
| 234 | (description "Connect to a BitlBee IRC server.")
|
| 235 | (value (run-bitlbee-test))))
|
| 236 |
|
| 237 |
|
| 238 | |
| 239 | |
| 240 | |
| 241 |
|
| 242 | (define %ngircd-os
|
| 243 | (operating-system
|
| 244 | (inherit %simple-os)
|
| 245 | (packages (cons* ii screen %base-packages))
|
| 246 | (services
|
| 247 | (cons*
|
| 248 | (service dhcpcd-service-type)
|
| 249 | (service ngircd-service-type
|
| 250 | (ngircd-configuration
|
| 251 | (debug? #t)
|
| 252 | (global
|
| 253 | (ngircd-global
|
| 254 | (server-uid 990)
|
| 255 | (server-gid 990)))
|
| 256 | |
| 257 | |
| 258 | |
| 259 | (limits (ngircd-limits))
|
| 260 | (options (ngircd-options))
|
| 261 | (ssl (ngircd-ssl))
|
| 262 | (operators (list (ngircd-operator
|
| 263 | (name "apteryx")
|
| 264 | (password "1234"))))
|
| 265 | (channels
|
| 266 | (list (ngircd-channel
|
| 267 | (name "#guix")
|
| 268 | (topic "GNU Guix | https://guix.gnu.org"))))))
|
| 269 | %base-services))))
|
| 270 |
|
| 271 | (define (run-ngircd-test)
|
| 272 | (define vm
|
| 273 | (virtual-machine
|
| 274 | (operating-system
|
| 275 | (marionette-operating-system
|
| 276 | %ngircd-os
|
| 277 | #:imported-modules (source-module-closure
|
| 278 | '((gnu build dbus-service)
|
| 279 | (guix build utils)
|
| 280 | (gnu services herd)))))))
|
| 281 |
|
| 282 | (define test
|
| 283 | (with-imported-modules '((gnu build marionette))
|
| 284 | #~(begin
|
| 285 | (use-modules (srfi srfi-64)
|
| 286 | (gnu build marionette))
|
| 287 |
|
| 288 | (define marionette
|
| 289 | (make-marionette (list #$vm)))
|
| 290 |
|
| 291 | (test-runner-current (system-test-runner #$output))
|
| 292 | (test-begin "ngircd")
|
| 293 |
|
| 294 | (test-assert "ngircd service runs"
|
| 295 | (marionette-eval
|
| 296 | '(begin
|
| 297 | (use-modules (gnu services herd))
|
| 298 | (wait-for-service 'ngircd))
|
| 299 | marionette))
|
| 300 |
|
| 301 | (test-assert "ngircd listens on TCP port 6667"
|
| 302 | (wait-for-tcp-port 6667 marionette))
|
| 303 |
|
| 304 | (test-assert "basic irc operations function as expected"
|
| 305 | (marionette-eval
|
| 306 | '(begin
|
| 307 | (use-modules ((gnu build dbus-service) #:select (with-retries))
|
| 308 | (ice-9 textual-ports))
|
| 309 |
|
| 310 | (define (write-command command)
|
| 311 | (call-with-output-file "in"
|
| 312 | (lambda (port)
|
| 313 | (display (string-append command "\n") port))))
|
| 314 |
|
| 315 | (define (grep-output text)
|
| 316 | (with-retries 5 1 |
| 317 | (string-contains (call-with-input-file "out" get-string-all)
|
| 318 | text)))
|
| 319 |
|
| 320 | (unless (zero? (system "ii -s localhost -i /tmp &"))
|
| 321 | (error "error connecting to irc server"))
|
| 322 |
|
| 323 | (with-retries 5 1
|
| 324 | (chdir "/tmp/localhost")) |
| 325 |
|
| 326 | (write-command "/join #guix")
|
| 327 | (grep-output "GNU Guix | https://guix.gnu.org")
|
| 328 |
|
| 329 | (write-command "/oper apteryx 1234")
|
| 330 | (grep-output "+o"))
|
| 331 | marionette))
|
| 332 |
|
| 333 | (test-end))))
|
| 334 |
|
| 335 | (gexp->derivation "ngircd-test" test))
|
| 336 |
|
| 337 | (define %test-ngircd
|
| 338 | (system-test
|
| 339 | (name "ngircd")
|
| 340 | (description "Connect to a ngircd IRC server.")
|
| 341 | (value (run-ngircd-test))))
|
| 342 |
|
| 343 |
|
| 344 | |
| 345 | |
| 346 | |
| 347 |
|
| 348 | |
| 349 | |
| 350 | |
| 351 | |
| 352 | |
| 353 | (define ngircd-tls-cert-service-type
|
| 354 | (shepherd-service-type
|
| 355 | 'ngircd-tls-cert
|
| 356 | (lambda _
|
| 357 | (shepherd-service
|
| 358 | (documentation "Generate TLS certificate/key for ngIRCd")
|
| 359 | (modules (append '((gnu build activation)
|
| 360 | (srfi srfi-26))
|
| 361 | %default-modules))
|
| 362 | (provision '(ngircd-tls-cert))
|
| 363 | (start
|
| 364 | (with-imported-modules (source-module-closure
|
| 365 | '((gnu build activation)))
|
| 366 | #~(lambda _
|
| 367 | (let ((certtool #$(file-append gnutls "/bin/certtool"))
|
| 368 | (user (getpwnam "ngircd")))
|
| 369 | (mkdir-p/perms "/etc/ngircd" user #o755)
|
| 370 | (call-with-output-file "/tmp/template"
|
| 371 | (cut format <> "expiration_days = -1~%"))
|
| 372 | |
| 373 | |
| 374 | (invoke certtool "--generate-privkey"
|
| 375 | "--outfile" "/etc/ngircd/ca-key.pem")
|
| 376 | (invoke certtool "--generate-self-signed"
|
| 377 | "--load-privkey" "/etc/ngircd/ca-key.pem"
|
| 378 | "--outfile" "/etc/ngircd/ca-cert.pem"
|
| 379 | "--template" "/tmp/template")
|
| 380 | (chdir "/etc/ngircd")
|
| 381 | (chown "ca-key.pem" (passwd:uid user) (passwd:gid user))
|
| 382 | (chmod "ca-key.pem" #o400)
|
| 383 | (chown "ca-cert.pem" (passwd:uid user) (passwd:gid user))
|
| 384 | (chmod "ca-cert.pem" #o444)
|
| 385 | (delete-file "/tmp/template")
|
| 386 | #t))))
|
| 387 | (one-shot? #t)))
|
| 388 | #t |
| 389 | (description "Generate a self-signed TLS certificate for ngIRCd")))
|
| 390 |
|
| 391 | |
| 392 | |
| 393 | |
| 394 | (define %pounce-os
|
| 395 | (operating-system
|
| 396 | (inherit %simple-os)
|
| 397 | (packages
|
| 398 | (append (list ii socat)
|
| 399 | |
| 400 | |
| 401 | |
| 402 | |
| 403 | |
| 404 | |
| 405 | |
| 406 | |
| 407 | |
| 408 | |
| 409 | %base-packages))
|
| 410 | (services
|
| 411 | (cons*
|
| 412 | (service dhcpcd-service-type)
|
| 413 | (service ngircd-tls-cert-service-type)
|
| 414 | (service ngircd-service-type
|
| 415 | (ngircd-configuration
|
| 416 | (debug? #t)
|
| 417 | (shepherd-requirement '(user-processes ngircd-tls-cert))
|
| 418 | (ssl (ngircd-ssl
|
| 419 | (ports (list 6697))
|
| 420 | (cert-file "/etc/ngircd/ca-cert.pem")
|
| 421 | (key-file "/etc/ngircd/ca-key.pem")))
|
| 422 | (channels (list (ngircd-channel (name "#irc"))))))
|
| 423 | (service pounce-service-type
|
| 424 | (pounce-configuration
|
| 425 | (host "localhost") |
| 426 | |
| 427 | (trust "/etc/ngircd/ca-cert.pem")
|
| 428 | (verbose? #t)
|
| 429 | |
| 430 | |
| 431 | (local-pass "\
|
| 432 | $6$rviyVy+iFC9vT37o$2RUAhhFzD8gklXRk9X5KuHYtp6APk8nEXf1uroY2/KlgO9nQ0O/Dj05fzJ\
|
| 433 | /qNlpJQOijJMOyKm4fXjw.Ck9F91")
|
| 434 | (local-port 7000) |
| 435 | (nick "apteryx")
|
| 436 | (join (list "#irc"))))
|
| 437 | %base-services))))
|
| 438 |
|
| 439 | (define (run-pounce-test)
|
| 440 | (define vm
|
| 441 | (virtual-machine
|
| 442 | (operating-system
|
| 443 | (marionette-operating-system
|
| 444 | %pounce-os
|
| 445 | #:imported-modules (source-module-closure
|
| 446 | '((gnu build dbus-service)
|
| 447 | (guix build utils)
|
| 448 | (gnu services herd)))))
|
| 449 | (memory-size 1024)))
|
| 450 |
|
| 451 | (define test
|
| 452 | (with-imported-modules '((gnu build marionette))
|
| 453 | #~(begin
|
| 454 | (use-modules (srfi srfi-64)
|
| 455 | (gnu build marionette))
|
| 456 |
|
| 457 | (define marionette
|
| 458 | (make-marionette (list #$vm)))
|
| 459 |
|
| 460 | (test-runner-current (system-test-runner #$output))
|
| 461 | (test-begin "pounce")
|
| 462 |
|
| 463 | (test-assert "IRC test server listens on TCP port 6697"
|
| 464 | (wait-for-tcp-port 6697 marionette))
|
| 465 |
|
| 466 | (test-assert "pounce service runs"
|
| 467 | (marionette-eval
|
| 468 | '(begin
|
| 469 | (use-modules (gnu services herd))
|
| 470 | (wait-for-service 'pounce))
|
| 471 | marionette))
|
| 472 |
|
| 473 | (test-assert "pounce listens on TCP port 7000"
|
| 474 | (wait-for-tcp-port 7000 marionette))
|
| 475 |
|
| 476 | (test-assert "pounce functions as an irc bouncer"
|
| 477 | (marionette-eval
|
| 478 | '(begin
|
| 479 | (use-modules ((gnu build dbus-service) #:select (with-retries))
|
| 480 | (guix build utils)
|
| 481 | (ice-9 textual-ports))
|
| 482 |
|
| 483 | (define (write-command command)
|
| 484 | (call-with-output-file "in"
|
| 485 | (lambda (port)
|
| 486 | (display (string-append command "\n") port))))
|
| 487 |
|
| 488 | (define (grep-output text)
|
| 489 | (with-retries 5 1 |
| 490 | (string-contains (call-with-input-file "out" get-string-all)
|
| 491 | (pk 'output-text: text))))
|
| 492 |
|
| 493 | (define (connect-to-ngircd)
|
| 494 | (mkdir-p "/tmp/pounce")
|
| 495 | (unless (zero? (system "ii -s localhost -i /tmp/ngircd \
|
| 496 | -n ayoli &"))
|
| 497 | (error "error connecting to irc server"))
|
| 498 | (with-retries 5 1 (file-exists? "/tmp/ngircd/localhost"))
|
| 499 | (with-directory-excursion "/tmp/ngircd/localhost"
|
| 500 | (write-command "/join #irc"))
|
| 501 | (with-retries 5 1
|
| 502 | (file-exists? "/tmp/ngircd/localhost/#irc")))
|
| 503 |
|
| 504 | (define (connect-to-pounce)
|
| 505 | (mkdir-p "/tmp/pounce")
|
| 506 | |
| 507 | |
| 508 | (system "socat UNIX-LISTEN:/tmp/pounce/socket \
|
| 509 | OPENSSL:localhost:7000,verify=0 &")
|
| 510 | (with-retries 5 1 (file-exists? "/tmp/pounce/socket"))
|
| 511 | (setenv "PASS" "1234")
|
| 512 | (unless (zero? (system "ii -s localhost -i /tmp/pounce \
|
| 513 | -u /tmp/pounce/socket -n apteryx -k PASS &"))
|
| 514 | (error "error connecting to pounce server"))
|
| 515 | (with-retries 5 1 (file-exists? "/tmp/pounce/localhost"))
|
| 516 | (with-directory-excursion "/tmp/pounce/localhost"
|
| 517 | (write-command "/join #irc"))
|
| 518 | (with-retries 5 1
|
| 519 | (file-exists? "/tmp/pounce/localhost/#irc")))
|
| 520 |
|
| 521 | (connect-to-ngircd)
|
| 522 | (connect-to-pounce)
|
| 523 |
|
| 524 | |
| 525 | (with-directory-excursion "/tmp/pounce/localhost/#irc"
|
| 526 | (write-command "hi! Does pounce work well as a bouncer?")
|
| 527 | (write-command "/quit"))
|
| 528 |
|
| 529 | |
| 530 | (with-directory-excursion "/tmp/ngircd/localhost/#irc"
|
| 531 | (write-command "apteryx: pounce does work well"))
|
| 532 |
|
| 533 | |
| 534 | |
| 535 | (with-retries 5 1 (not (file-exists? "/tmp/pounce/socket")))
|
| 536 | (connect-to-pounce)
|
| 537 | (with-directory-excursion "/tmp/pounce/localhost/#irc"
|
| 538 | (grep-output "apteryx: pounce does work well")))
|
| 539 | marionette))
|
| 540 | (test-end))))
|
| 541 |
|
| 542 | (gexp->derivation "pounce-test" test))
|
| 543 |
|
| 544 | (define %test-pounce
|
| 545 | (system-test
|
| 546 | (name "pounce")
|
| 547 | (description "Connect to a pounce IRC network bouncer.")
|
| 548 | (value (run-pounce-test))))
|
| 549 |
|
| 550 |
|
| 551 | |
| 552 | |
| 553 | |
| 554 |
|
| 555 | (define (run-quassel-test)
|
| 556 | (define os
|
| 557 | (marionette-operating-system
|
| 558 | (simple-operating-system (service dhcpcd-service-type)
|
| 559 | (service quassel-service-type))
|
| 560 | #:imported-modules (source-module-closure
|
| 561 | '((gnu services herd)))))
|
| 562 |
|
| 563 | (define vm
|
| 564 | (virtual-machine
|
| 565 | (operating-system os)
|
| 566 | (port-forwardings `((4242 . 4242)))))
|
| 567 |
|
| 568 | (define test
|
| 569 | (with-imported-modules '((gnu build marionette))
|
| 570 | #~(begin
|
| 571 | (use-modules (srfi srfi-64)
|
| 572 | (gnu build marionette))
|
| 573 |
|
| 574 | (define marionette
|
| 575 | (make-marionette (list #$vm)))
|
| 576 |
|
| 577 | (test-runner-current (system-test-runner #$output))
|
| 578 | (test-begin "quassel")
|
| 579 |
|
| 580 | (test-assert "service started"
|
| 581 | (marionette-eval
|
| 582 | '(begin
|
| 583 | (use-modules (gnu services herd))
|
| 584 | (wait-for-service 'quassel))
|
| 585 | marionette))
|
| 586 |
|
| 587 | (test-assert "certificate file"
|
| 588 | (marionette-eval
|
| 589 | '(file-exists? "/var/lib/quassel/quasselCert.pem")
|
| 590 | marionette))
|
| 591 |
|
| 592 | (test-end))))
|
| 593 |
|
| 594 | (gexp->derivation "quassel-test" test))
|
| 595 |
|
| 596 | (define %test-quassel
|
| 597 | (system-test
|
| 598 | (name "quassel")
|
| 599 | (description "Connect to a quassel IRC server.")
|
| 600 | (value (run-quassel-test))))
|
| 601 |
|
| 602 |
|
| 603 | |
| 604 | |
| 605 | |
| 606 |
|
| 607 | (define (run-mosquitto-test)
|
| 608 | (define os
|
| 609 | (marionette-operating-system
|
| 610 | (simple-operating-system (service dhcpcd-service-type)
|
| 611 | (service mosquitto-service-type))
|
| 612 | #:imported-modules (source-module-closure
|
| 613 | '((gnu services herd)))))
|
| 614 |
|
| 615 | (define vm
|
| 616 | (virtual-machine
|
| 617 | (operating-system os)))
|
| 618 |
|
| 619 | (define test
|
| 620 | (with-imported-modules '((gnu build marionette))
|
| 621 | #~(begin
|
| 622 | (use-modules (srfi srfi-64)
|
| 623 | (gnu build marionette))
|
| 624 |
|
| 625 | (define marionette
|
| 626 | (make-marionette (list #$vm)))
|
| 627 |
|
| 628 | (test-runner-current (system-test-runner #$output))
|
| 629 | (test-begin "mosquitto")
|
| 630 |
|
| 631 | (test-assert "service runs"
|
| 632 | (marionette-eval
|
| 633 | '(begin
|
| 634 | (use-modules (gnu services herd))
|
| 635 | (wait-for-service 'mosquitto))
|
| 636 | marionette))
|
| 637 |
|
| 638 | (test-assert "service listens on TCP port 1883"
|
| 639 | (wait-for-tcp-port 1883 marionette))
|
| 640 |
|
| 641 | (test-equal "service receives a message"
|
| 642 | 0
|
| 643 | (marionette-eval
|
| 644 | '(system* #$(file-append mosquitto "/bin/mosquitto_pub")
|
| 645 | "-t" "test-topic"
|
| 646 | "-m" "Hello, mosquitto!"
|
| 647 | "-r")
|
| 648 | marionette))
|
| 649 |
|
| 650 | (test-equal "service returns a message"
|
| 651 | "Hello, mosquitto!"
|
| 652 | (marionette-eval
|
| 653 | '(begin
|
| 654 | (use-modules (ice-9 popen)
|
| 655 | (ice-9 rdelim))
|
| 656 | (let* ((port (open-pipe* OPEN_READ
|
| 657 | #$(file-append
|
| 658 | mosquitto
|
| 659 | "/bin/mosquitto_sub")
|
| 660 | "-t" "test-topic"
|
| 661 | "-C" "1"))
|
| 662 | (msg (read-line port)))
|
| 663 | (close-pipe port)
|
| 664 | msg))
|
| 665 | marionette))
|
| 666 |
|
| 667 | (test-end))))
|
| 668 |
|
| 669 | (gexp->derivation "mosquitto-test" test))
|
| 670 |
|
| 671 | (define %test-mosquitto
|
| 672 | (system-test
|
| 673 | (name "mosquitto")
|
| 674 | (description "Test a running Mosquitto MQTT broker.")
|
| 675 | (value (run-mosquitto-test))))
|
| 676 |
|
| 677 |
|
| 678 | |
| 679 | |
| 680 | |
| 681 |
|
| 682 | (define %soju-os
|
| 683 | (operating-system
|
| 684 | (inherit %simple-os)
|
| 685 | (packages (cons* soju %base-packages))
|
| 686 | (services
|
| 687 | (cons*
|
| 688 | (service dhcpcd-service-type)
|
| 689 | (service soju-service-type
|
| 690 | (soju-configuration
|
| 691 | (debug? #t)
|
| 692 | (listen '("irc://localhost" "unix+admin:///var/lib/soju/soju.sock"))
|
| 693 | (title "soju IRC bouncer")
|
| 694 | (extra-content
|
| 695 | (list (plain-file "soju.conf" "hostname test.example.org")))))
|
| 696 | %base-services))))
|
| 697 |
|
| 698 | (define (run-soju-test)
|
| 699 | (define vm
|
| 700 | (virtual-machine
|
| 701 | (operating-system
|
| 702 | (marionette-operating-system
|
| 703 | %soju-os
|
| 704 | #:imported-modules (source-module-closure
|
| 705 | '((gnu services herd)))))))
|
| 706 |
|
| 707 | (define test
|
| 708 | (with-imported-modules '((gnu build marionette))
|
| 709 | #~(begin
|
| 710 | (use-modules (srfi srfi-64)
|
| 711 | (gnu build marionette))
|
| 712 |
|
| 713 | (define marionette
|
| 714 | (make-marionette (list #$vm)))
|
| 715 |
|
| 716 | (test-runner-current (system-test-runner #$output))
|
| 717 | (test-begin "soju")
|
| 718 |
|
| 719 | (marionette-eval
|
| 720 | '(begin
|
| 721 | (use-modules (gnu services herd))
|
| 722 | (wait-for-service 'user-processes))
|
| 723 | marionette)
|
| 724 |
|
| 725 | (test-equal "soju configuration file is well formed"
|
| 726 | "listen irc://localhost
|
| 727 | listen unix+admin:///var/lib/soju/soju.sock
|
| 728 | title \"soju IRC bouncer\"
|
| 729 | db sqlite3 /var/lib/soju/soju.db
|
| 730 | hostname test.example.org
|
| 731 | "
|
| 732 | (marionette-eval
|
| 733 | '(begin
|
| 734 | (use-modules (ice-9 popen)
|
| 735 | (ice-9 rdelim)
|
| 736 | (ice-9 textual-ports))
|
| 737 | (let* ((port (open-input-pipe "herd configuration soju"))
|
| 738 | (soju.conf (string-trim-both (read-line port))))
|
| 739 | (close-pipe port)
|
| 740 | (call-with-input-file soju.conf get-string-all)))
|
| 741 | marionette))
|
| 742 |
|
| 743 | (test-assert "soju service runs"
|
| 744 | (marionette-eval
|
| 745 | '(begin
|
| 746 | (use-modules (gnu services herd))
|
| 747 | (wait-for-service 'soju))
|
| 748 | marionette))
|
| 749 |
|
| 750 | (test-assert "soju listens on TCP port 6667"
|
| 751 | (wait-for-tcp-port 6667 marionette))
|
| 752 |
|
| 753 | (test-equal "sojuctl can create a user"
|
| 754 | "fishinthecalculator (admin): 0 networks"
|
| 755 | (marionette-eval
|
| 756 | '(begin
|
| 757 | (use-modules (ice-9 popen)
|
| 758 | (ice-9 rdelim))
|
| 759 | (system (string-join
|
| 760 | '("sojuctl" "-config" "$(herd configuration soju)"
|
| 761 | "user" "create" "-admin"
|
| 762 | "-username" "fishinthecalculator"
|
| 763 | "-password" "1234")
|
| 764 | " "))
|
| 765 | (let* ((port (open-input-pipe (string-join
|
| 766 | '("sojuctl" "-config"
|
| 767 | "$(herd configuration soju)"
|
| 768 | "user" "status")
|
| 769 | " ")))
|
| 770 | (msg (read-line port)))
|
| 771 | (close-pipe port)
|
| 772 | msg))
|
| 773 | marionette))
|
| 774 |
|
| 775 | (test-end))))
|
| 776 |
|
| 777 | (gexp->derivation "soju-test" test))
|
| 778 |
|
| 779 | (define %test-soju
|
| 780 | (system-test
|
| 781 | (name "soju")
|
| 782 | (description "Run a soju IRC bouncer.")
|
| 783 | (value (run-soju-test))))
|