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