aboutsummaryrefslogtreecommitdiff
path: root/gnu/tests/databases.scm
blob: 31d5ae4c6a1192b550ca00d43759d6a54f74efc7 (about) (plain) 7'>57585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
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
2018-11-23
Update NEWS.Ludovic Courtès
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2017 Christopher Baines <mail@cbaines.net>
;;; Copyright © 2020 Marius Bakke <marius@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 databases)
  #:use-module (gnu tests)
  #:use-module (gnu system)
  #:use-module (gnu system file-systems)
  #:use-module (gnu system shadow)
  #:use-module (gnu system vm)
  #:use-module (gnu services)
  #:use-module (gnu services databases)
  #:use-module (gnu services networking)
  #:use-module (gnu packages databases)
  #:use-module (guix gexp)
  #:use-module (guix store)
  #:export (%test-memcached
            %test-mongodb
            %test-postgresql
            %test-mysql))

(define %memcached-os
  (simple-operating-system
   (service dhcp-client-service-type)
   (service memcached-service-type)))

(define* (run-memcached-test #:optional (port 11211))
  "Run tests in %MEMCACHED-OS, forwarding PORT."
  (define os
    (marionette-operating-system
     %memcached-os
     #:imported-modules '((gnu services herd)
                          (guix combinators))))

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

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

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

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

          (test-begin "memcached")

          ;; Wait for memcached to be up and running.
          (test-assert "service running"
            (marionette-eval
             '(begin
                (use-modules (gnu services herd))
                (match (start-service 'memcached)
                  (#f #f)
                  (('service response-parts ...)
                   (match (assq-ref response-parts 'running)
                     ((pid) (number? pid))))))
             marionette))

          (let* ((ai (car (getaddrinfo "localhost"
                                       #$(number->string port))))
                 (s  (socket (addrinfo:fam ai)
                             (addrinfo:socktype ai)
                             (addrinfo:protocol ai)))
                 (key "testkey")
                 (value "guix"))
            (connect s (addrinfo:addr ai))

            (test-equal "set"
              "STORED\r"
              (begin
                (simple-format s "set ~A 0 60 ~A\r\n~A\r\n"
                               key
                               (string-length value)
                               value)
                (read-line s)))

            (test-equal "get"
              (simple-format #f "VALUE ~A 0 ~A\r~A\r"
                             key
                             (string-length value)
                             value)
              (begin
                (simple-format s "get ~A\r\n" key)
                (string-append
                 (read-line s)
                 (read-line s))))

            (close-port s))

          ;; There should be a log file in here.
          (test-assert "log file"
            (marionette-eval
             '(file-exists? "/var/log/memcached")
             marionette))

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

  (gexp->derivation "memcached-test" test))

(define %test-memcached
  (system-test
   (name "memcached")
   (description "Connect to a running MEMCACHED server.")
   (value (run-memcached-test))))

(define %mongodb-os
  (operating-system
    (inherit
     (simple-operating-system
      (service dhcp-client-service-type)
      (service mongodb-service-type)))
    (packages (cons* mongodb
                     %base-packages))))

(define* (run-mongodb-test #:optional (port 27017))
  "Run tests in %MONGODB-OS, forwarding PORT."
  (define os
    (marionette-operating-system
     %mongodb-os
     #:imported-modules '((gnu services herd)
                          (guix combinators))))

  (define vm
    (virtual-machine
     (operating-system os)
     (memory-size 1024)
     (disk-image-size (* 1024 (expt 2 20)))
     (port-forwardings `((27017 . ,port)))))

  (define test
    (with-imported-modules '((gnu build marionette))
      #~(begin
          (use-modules (srfi srfi-11) (srfi srfi-64)
                       (gnu build marionette)
                       (ice-9 popen)
                       (ice-9 rdelim))

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

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

          (test-begin "mongodb")

          (test-assert "service running"
            (marionette-eval
             '(begin
                (use-modules (gnu services herd))
                (match (start-service 'mongodb)
                  (#f #f)
                  (('service response-parts ...)
                   (match (assq-ref response-parts 'running)
                     ((pid) (number? pid))))))
             marionette))

          (test-eq "test insert"
            0
            (system* (string-append #$mongodb "/bin/mongo")
                     "test"
                     "--eval"
                     "db.testCollection.insert({data: 'test-data'})"))

          (test-equal "test find"
            "test-data"
            (let* ((port (open-pipe*
                          OPEN_READ
                          (string-append #$mongodb "/bin/mongo")
                          "test"
                          "--quiet"
                          "--eval"
                          "db.testCollection.findOne().data"))
                   (output (read-line port))
                   (status (close-pipe port)))
              output))

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

  (gexp->derivation "mongodb-test" test))

(define %test-mongodb
  (system-test
   (name "mongodb")
   (description "Connect to a running MONGODB server.")
   (value (run-mongodb-test))))


;;;
;;; The PostgreSQL service.
;;;

(define %postgresql-os
  (simple-operating-system
   (service postgresql-service-type
            (postgresql-configuration
             (postgresql postgresql-10)))))

(define (run-postgresql-test)
  "Run tests in %POSTGRESQL-OS."
  (define os
    (marionette-operating-system
     %postgresql-os
     #:imported-modules '((gnu services herd)
                          (guix combinators))))

  (define vm
    (virtual-machine
     (operating-system os)
     (memory-size 512)))

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

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

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

          (test-begin "postgresql")

          (test-assert "service running"
            (marionette-eval
             '(begin
                (use-modules (gnu services herd))
                (start-service 'postgres))
             marionette))

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

  (gexp->derivation "postgresql-test" test))

(define %test-postgresql
  (system-test
   (name "postgresql")
   (description "Start the PostgreSQL service.")
   (value (run-postgresql-test))))


;;;
;;; The MySQL service.
;;;

(define %mysql-os
  (simple-operating-system
   (service mysql-service-type)))

(define* (run-mysql-test)
  "Run tests in %MYSQL-OS."
  (define os
    (marionette-operating-system
     %mysql-os
     #:imported-modules '((gnu services herd)
                          (guix combinators))))

  (define vm
    (virtual-machine
     (operating-system os)
     (memory-size 512)))

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

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

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

          (test-begin "mysql")

          (test-assert "service running"
            (marionette-eval
             '(begin
                (use-modules (gnu services herd))
                (match (start-service 'mysql)
                  (#f #f)
                  (('service response-parts ...)
                   (match (assq-ref response-parts 'running)
                     ((pid) (number? pid))))))
             marionette))

          (test-assert "mysql_upgrade completed"
            (wait-for-file "/var/lib/mysql/mysql_upgrade_info" marionette))

          (test-eq "create database"
            0
            (marionette-eval
             '(begin
                (system* #$(file-append mariadb "/bin/mysql")
                         "-e" "CREATE DATABASE guix;"))
             marionette))

          (test-eq "create table"
            0
            (marionette-eval
             '(begin
                (system*
                 #$(file-append mariadb "/bin/mysql") "guix"
                 "-e" "CREATE TABLE facts (id INT, data VARCHAR(12));"))
             marionette))

          (test-eq "insert data"
            0
            (marionette-eval
             '(begin
                (system* #$(file-append mariadb "/bin/mysql") "guix"
                         "-e" "INSERT INTO facts VALUES (1, 'awesome')"))
             marionette))

          (test-equal "retrieve data"
            "awesome\n"
            (marionette-eval
             '(begin
                (use-modules (ice-9 popen))
                (let* ((port (open-pipe*
                              OPEN_READ
                              #$(file-append mariadb "/bin/mysql") "guix"
                              "-NB" "-e" "SELECT data FROM facts WHERE id=1;"))
                       (output (get-string-all port)))
                  (close-pipe port)
                  output))
             marionette))

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

  (gexp->derivation "mysql-test" test))

(define %test-mysql
  (system-test
   (name "mysql")
   (description "Start the MySQL service.")
   (value (run-mysql-test))))