gnu: diffoscope: Update to 100.
[jackhill/guix/guix.git] / tests / services.scm
CommitLineData
0adfe95a 1;;; GNU Guix --- Functional package management for GNU
d466b1fc 2;;; Copyright © 2015, 2016, 2017, 2018 Ludovic Courtès <ludo@gnu.org>
0adfe95a
LC
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
19(define-module (test-services)
20 #:use-module (gnu services)
7b44cae5 21 #:use-module (gnu services herd)
0190c1c0 22 #:use-module (gnu services shepherd)
0adfe95a
LC
23 #:use-module (srfi srfi-1)
24 #:use-module (srfi srfi-26)
25 #:use-module (srfi srfi-34)
49483f71
LC
26 #:use-module (srfi srfi-64)
27 #:use-module (ice-9 match))
0adfe95a 28
7b44cae5
LC
29(define live-service
30 (@@ (gnu services herd) live-service))
31
32\f
0adfe95a
LC
33(test-begin "services")
34
1bb895ea
LC
35(test-equal "services, default value"
36 '(42 123 234 error)
37 (let* ((t1 (service-type (name 't1) (extensions '())))
38 (t2 (service-type (name 't2) (extensions '())
39 (default-value 42))))
40 (list (service-value (service t2))
41 (service-value (service t2 123))
42 (service-value (service t1 234))
43 (guard (c ((missing-value-service-error? c) 'error))
44 (service t1)))))
45
5152d13b
LC
46(test-assert "service-back-edges"
47 (let* ((t1 (service-type (name 't1) (extensions '())
48 (compose +) (extend *)))
49 (t2 (service-type (name 't2)
50 (extensions
51 (list (service-extension t1 (const '()))))
52 (compose +) (extend *)))
53 (t3 (service-type (name 't3)
54 (extensions
55 (list (service-extension t2 identity)
56 (service-extension t1 list)))))
57 (s1 (service t1 #t))
58 (s2 (service t2 #t))
59 (s3 (service t3 #t))
60 (e (service-back-edges (list s1 s2 s3))))
61 (and (lset= eq? (e s1) (list s2 s3))
62 (lset= eq? (e s2) (list s3))
63 (null? (e s3)))))
64
0adfe95a
LC
65(test-equal "fold-services"
66 ;; Make sure 'fold-services' returns the right result. The numbers come
67 ;; from services of type T3; 'xyz 60' comes from the service of type T2,
68 ;; where 60 = 15 × 4 = (1 + 2 + 3 + 4 + 5) × 4.
69 '(initial-value 5 4 3 2 1 xyz 60)
70 (let* ((t1 (service-type (name 't1) (extensions '())
71 (compose concatenate)
72 (extend cons)))
73 (t2 (service-type (name 't2)
74 (extensions
75 (list (service-extension t1
76 (cut list 'xyz <>))))
77 (compose (cut reduce + 0 <>))
78 (extend *)))
79 (t3 (service-type (name 't3)
80 (extensions
81 (list (service-extension t2 identity)
82 (service-extension t1 list)))))
83 (r (fold-services (cons* (service t1 'initial-value)
84 (service t2 4)
85 (map (lambda (x)
86 (service t3 x))
87 (iota 5 1)))
88 #:target-type t1)))
89 (and (eq? (service-kind r) t1)
efe7d19a 90 (service-value r))))
0adfe95a
LC
91
92(test-assert "fold-services, ambiguity"
93 (let* ((t1 (service-type (name 't1) (extensions '())
94 (compose concatenate)
95 (extend cons)))
96 (t2 (service-type (name 't2)
97 (extensions
98 (list (service-extension t1 list)))))
99 (s (service t2 42)))
100 (guard (c ((ambiguous-target-service-error? c)
101 (and (eq? (ambiguous-target-service-error-target-type c)
102 t1)
103 (eq? (ambiguous-target-service-error-service c)
104 s))))
105 (fold-services (list (service t1 'first)
106 (service t1 'second)
107 s)
108 #:target-type t1)
109 #f)))
110
111(test-assert "fold-services, missing target"
112 (let* ((t1 (service-type (name 't1) (extensions '())))
113 (t2 (service-type (name 't2)
114 (extensions
115 (list (service-extension t1 list)))))
116 (s (service t2 42)))
117 (guard (c ((missing-target-service-error? c)
118 (and (eq? (missing-target-service-error-target-type c)
119 t1)
120 (eq? (missing-target-service-error-service c)
121 s))))
122 (fold-services (list s) #:target-type t1)
123 #f)))
124
d466b1fc
LC
125(test-assert "instantiate-missing-services"
126 (let* ((t1 (service-type (name 't1) (extensions '())
127 (default-value 'dflt)
128 (compose concatenate)
129 (extend cons)))
130 (t2 (service-type (name 't2)
131 (extensions
132 (list (service-extension t1 list)))))
133 (s1 (service t1 'hey!))
134 (s2 (service t2 42)))
135 (and (lset= equal?
136 (list (service t1) s2)
137 (instantiate-missing-services (list s2)))
138 (equal? (list s1 s2)
139 (instantiate-missing-services (list s1 s2))))))
140
141(test-assert "instantiate-missing-services, no default value"
142 (let* ((t1 (service-type (name 't1) (extensions '())))
143 (t2 (service-type (name 't2)
144 (extensions
145 (list (service-extension t1 list)))))
146 (s (service t2 42)))
147 (guard (c ((missing-target-service-error? c)
148 (and (eq? (missing-target-service-error-target-type c)
149 t1)
150 (eq? (missing-target-service-error-service c)
151 s))))
152 (instantiate-missing-services (list s))
153 #f)))
154
a5d78eb6
LC
155(test-assert "shepherd-service-lookup-procedure"
156 (let* ((s1 (shepherd-service (provision '(s1 s1b)) (start #f)))
157 (s2 (shepherd-service (provision '(s2 s2b)) (start #f)))
158 (s3 (shepherd-service (provision '(s3 s3b s3c)) (start #f)))
159 (lookup (shepherd-service-lookup-procedure (list s1 s2 s3))))
160 (and (eq? (lookup 's1) (lookup 's1b) s1)
161 (eq? (lookup 's2) (lookup 's2b) s2)
162 (eq? (lookup 's3) (lookup 's3b) s3))))
163
d4053c71
AK
164(test-assert "shepherd-service-back-edges"
165 (let* ((s1 (shepherd-service (provision '(s1)) (start #f)))
166 (s2 (shepherd-service (provision '(s2))
167 (requirement '(s1))
168 (start #f)))
169 (s3 (shepherd-service (provision '(s3))
170 (requirement '(s1 s2))
171 (start #f)))
172 (e (shepherd-service-back-edges (list s1 s2 s3))))
80a67734
LC
173 (and (lset= eq? (e s1) (list s2 s3))
174 (lset= eq? (e s2) (list s3))
175 (null? (e s3)))))
176
7b44cae5
LC
177(test-equal "shepherd-service-upgrade: nothing to do"
178 '(() ())
179 (call-with-values
180 (lambda ()
181 (shepherd-service-upgrade '() '()))
182 list))
183
184(test-equal "shepherd-service-upgrade: one unchanged, one upgraded, one new"
185 '(((bar)) ;unload
186 ((bar) (baz))) ;load
187 (call-with-values
188 (lambda ()
189 ;; Here 'foo' is not upgraded because it is still running, whereas
190 ;; 'bar' is upgraded because it is not currently running. 'baz' is
191 ;; loaded because it's a new service.
192 (shepherd-service-upgrade
193 (list (live-service '(foo) '() #t)
194 (live-service '(bar) '() #f)
195 (live-service '(root) '() #t)) ;essential!
196 (list (shepherd-service (provision '(foo))
197 (start #t))
198 (shepherd-service (provision '(bar))
199 (start #t))
200 (shepherd-service (provision '(baz))
201 (start #t)))))
202 (lambda (unload load)
203 (list (map live-service-provision unload)
204 (map shepherd-service-provision load)))))
205
206(test-equal "shepherd-service-upgrade: service depended on is not unloaded"
207 '(((baz)) ;unload
208 ()) ;load
209 (call-with-values
210 (lambda ()
211 ;; Service 'bar' is not among the target services; yet, it must not be
212 ;; unloaded because 'foo' depends on it.
213 (shepherd-service-upgrade
214 (list (live-service '(foo) '(bar) #t)
215 (live-service '(bar) '() #t) ;still used!
216 (live-service '(baz) '() #t))
217 (list (shepherd-service (provision '(foo))
218 (start #t)))))
219 (lambda (unload load)
220 (list (map live-service-provision unload)
221 (map shepherd-service-provision load)))))
222
223(test-equal "shepherd-service-upgrade: obsolete services that depend on each other"
224 '(((foo) (bar) (baz)) ;unload
225 ((qux))) ;load
226 (call-with-values
227 (lambda ()
228 ;; 'foo', 'bar', and 'baz' depend on each other, but all of them are
229 ;; obsolete, and thus should be unloaded.
230 (shepherd-service-upgrade
231 (list (live-service '(foo) '(bar) #t) ;obsolete
232 (live-service '(bar) '(baz) #t) ;obsolete
233 (live-service '(baz) '() #t)) ;obsolete
234 (list (shepherd-service (provision '(qux))
235 (start #t)))))
236 (lambda (unload load)
237 (list (map live-service-provision unload)
238 (map shepherd-service-provision load)))))
239
49483f71
LC
240(test-eq "lookup-service-types"
241 system-service-type
242 (and (null? (lookup-service-types 'does-not-exist-at-all))
243 (match (lookup-service-types 'system)
244 ((one) one)
245 (x x))))
246
0adfe95a 247(test-end)