derivations: Add 'map-derivation'.
[jackhill/guix/guix.git] / tests / store.scm
CommitLineData
233e7676 1;;; GNU Guix --- Functional package management for GNU
0f3d2504 2;;; Copyright © 2012, 2013 Ludovic Courtès <ludo@gnu.org>
3259877d 3;;;
233e7676 4;;; This file is part of GNU Guix.
3259877d 5;;;
233e7676 6;;; GNU Guix is free software; you can redistribute it and/or modify it
3259877d
LC
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;;;
233e7676 11;;; GNU Guix is distributed in the hope that it will be useful, but
3259877d
LC
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
233e7676 17;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
3259877d
LC
18
19
20(define-module (test-store)
21 #:use-module (guix store)
22 #:use-module (guix utils)
72626a71 23 #:use-module (guix hash)
3259877d 24 #:use-module (guix base32)
0f3d2504
LC
25 #:use-module (guix packages)
26 #:use-module (guix derivations)
fe0cff14 27 #:use-module (guix nar)
fae31edc 28 #:use-module (gnu packages)
1ffa7090 29 #:use-module (gnu packages bootstrap)
3259877d 30 #:use-module (ice-9 match)
fe0cff14 31 #:use-module (rnrs io ports)
f65cf81a 32 #:use-module (web uri)
3259877d
LC
33 #:use-module (srfi srfi-1)
34 #:use-module (srfi srfi-11)
c3eb878f 35 #:use-module (srfi srfi-34)
3259877d
LC
36 #:use-module (srfi srfi-64))
37
38;; Test the (guix store) module.
39
40(define %store
41 (false-if-exception (open-connection)))
42
43(when %store
44 ;; Make sure we build everything by ourselves.
45 (set-build-options %store #:use-substitutes? #f))
46
47(define %seed
48 (seed->random-state (logxor (getpid) (car (gettimeofday)))))
49
50(define (random-text)
51 (number->string (random (expt 2 256) %seed) 16))
52
53\f
54(test-begin "store")
55
2c6ab6cc
LC
56(test-equal "store-path-hash-part"
57 "283gqy39v3g9dxjy26rynl0zls82fmcg"
58 (store-path-hash-part
59 (string-append (%store-prefix)
60 "/283gqy39v3g9dxjy26rynl0zls82fmcg-guile-2.0.7")))
61
62(test-equal "store-path-hash-part #f"
63 #f
64 (store-path-hash-part
65 (string-append (%store-prefix)
66 "/foo/bar/283gqy39v3g9dxjy26rynl0zls82fmcg-guile-2.0.7")))
67
3259877d
LC
68(test-skip (if %store 0 10))
69
70(test-assert "dead-paths"
cfbf9160 71 (let ((p (add-text-to-store %store "random-text" (random-text))))
3259877d
LC
72 (member p (dead-paths %store))))
73
74;; FIXME: Find a test for `live-paths'.
75;;
76;; (test-assert "temporary root is in live-paths"
77;; (let* ((p1 (add-text-to-store %store "random-text"
78;; (random-text) '()))
79;; (b (add-text-to-store %store "link-builder"
80;; (format #f "echo ~a > $out" p1)
81;; '()))
a987d2c0
LC
82;; (d1 (derivation %store "link"
83;; "/bin/sh" `("-e" ,b)
84;; #:inputs `((,b) (,p1))))
59688fc4 85;; (p2 (derivation->output-path d1)))
3259877d
LC
86;; (and (add-temp-root %store p2)
87;; (build-derivations %store (list d1))
88;; (valid-path? %store p1)
89;; (member (pk p2) (live-paths %store)))))
90
91(test-assert "dead path can be explicitly collected"
92 (let ((p (add-text-to-store %store "random-text"
93 (random-text) '())))
94 (let-values (((paths freed) (delete-paths %store (list p))))
95 (and (equal? paths (list p))
96 (> freed 0)
97 (not (file-exists? p))))))
98
fae31edc
LC
99(test-assert "references"
100 (let* ((t1 (add-text-to-store %store "random1"
cfbf9160 101 (random-text)))
fae31edc
LC
102 (t2 (add-text-to-store %store "random2"
103 (random-text) (list t1))))
104 (and (equal? (list t1) (references %store t2))
105 (equal? (list t2) (referrers %store t1))
106 (null? (references %store t1))
107 (null? (referrers %store t2)))))
108
3f1e6939
LC
109(test-assert "requisites"
110 (let* ((t1 (add-text-to-store %store "random1"
111 (random-text) '()))
112 (t2 (add-text-to-store %store "random2"
113 (random-text) (list t1)))
114 (t3 (add-text-to-store %store "random3"
115 (random-text) (list t2)))
116 (t4 (add-text-to-store %store "random4"
117 (random-text) (list t1 t3))))
118 (define (same? x y)
119 (and (= (length x) (length y))
120 (lset= equal? x y)))
121
122 (and (same? (requisites %store t1) (list t1))
123 (same? (requisites %store t2) (list t1 t2))
124 (same? (requisites %store t3) (list t1 t2 t3))
125 (same? (requisites %store t4) (list t1 t2 t3 t4)))))
126
fae31edc
LC
127(test-assert "derivers"
128 (let* ((b (add-text-to-store %store "build" "echo $foo > $out" '()))
129 (s (add-to-store %store "bash" #t "sha256"
130 (search-bootstrap-binary "bash"
131 (%current-system))))
a987d2c0
LC
132 (d (derivation %store "the-thing"
133 s `("-e" ,b)
134 #:env-vars `(("foo" . ,(random-text)))
135 #:inputs `((,b) (,s))))
59688fc4 136 (o (derivation->output-path d)))
fae31edc 137 (and (build-derivations %store (list d))
59688fc4 138 (equal? (query-derivation-outputs %store (derivation-file-name d))
fae31edc
LC
139 (list o))
140 (equal? (valid-derivers %store o)
59688fc4 141 (list (derivation-file-name d))))))
fae31edc 142
eddd4077
LC
143(test-assert "log-file, derivation"
144 (let* ((b (add-text-to-store %store "build" "echo $foo > $out" '()))
145 (s (add-to-store %store "bash" #t "sha256"
146 (search-bootstrap-binary "bash"
147 (%current-system))))
148 (d (derivation %store "the-thing"
149 s `("-e" ,b)
150 #:env-vars `(("foo" . ,(random-text)))
151 #:inputs `((,b) (,s)))))
152 (and (build-derivations %store (list d))
153 (file-exists? (pk (log-file %store (derivation-file-name d)))))))
154
155(test-assert "log-file, output file name"
156 (let* ((b (add-text-to-store %store "build" "echo $foo > $out" '()))
157 (s (add-to-store %store "bash" #t "sha256"
158 (search-bootstrap-binary "bash"
159 (%current-system))))
160 (d (derivation %store "the-thing"
161 s `("-e" ,b)
162 #:env-vars `(("foo" . ,(random-text)))
163 #:inputs `((,b) (,s))))
164 (o (derivation->output-path d)))
165 (and (build-derivations %store (list d))
166 (file-exists? (pk (log-file %store o)))
167 (string=? (log-file %store (derivation-file-name d))
168 (log-file %store o)))))
169
0f3d2504
LC
170(test-assert "no substitutes"
171 (let* ((s (open-connection))
172 (d1 (package-derivation s %bootstrap-guile (%current-system)))
173 (d2 (package-derivation s %bootstrap-glibc (%current-system)))
59688fc4 174 (o (map derivation->output-path (list d1 d2))))
0f3d2504 175 (set-build-options s #:use-substitutes? #f)
59688fc4
LC
176 (and (not (has-substitutes? s (derivation-file-name d1)))
177 (not (has-substitutes? s (derivation-file-name d2)))
0f3d2504
LC
178 (null? (substitutable-paths s o))
179 (null? (substitutable-path-info s o)))))
180
f65cf81a
LC
181(test-skip (if (getenv "GUIX_BINARY_SUBSTITUTE_URL") 0 1))
182
183(test-assert "substitute query"
184 (let* ((s (open-connection))
185 (d (package-derivation s %bootstrap-guile (%current-system)))
59688fc4 186 (o (derivation->output-path d))
f65cf81a
LC
187 (dir (and=> (getenv "GUIX_BINARY_SUBSTITUTE_URL")
188 (compose uri-path string->uri))))
189 ;; Create fake substituter data, to be read by `substitute-binary'.
190 (call-with-output-file (string-append dir "/nix-cache-info")
191 (lambda (p)
192 (format p "StoreDir: ~a\nWantMassQuery: 0\n"
fe0cff14 193 (%store-prefix))))
f65cf81a
LC
194 (call-with-output-file (string-append dir "/" (store-path-hash-part o)
195 ".narinfo")
196 (lambda (p)
197 (format p "StorePath: ~a
198URL: ~a
199Compression: none
200NarSize: 1234
201References:
202System: ~a
203Deriver: ~a~%"
204 o ; StorePath
205 (string-append dir "/example.nar") ; URL
206 (%current-system) ; System
59688fc4
LC
207 (basename
208 (derivation-file-name d))))) ; Deriver
f65cf81a 209
eba783b7
LC
210 ;; Remove entry from the local cache.
211 (false-if-exception
212 (delete-file (string-append (getenv "XDG_CACHE_HOME")
213 "/guix/substitute-binary/"
214 (store-path-hash-part o))))
215
f65cf81a
LC
216 ;; Make sure `substitute-binary' correctly communicates the above data.
217 (set-build-options s #:use-substitutes? #t)
218 (and (has-substitutes? s o)
219 (equal? (list o) (substitutable-paths s (list o)))
220 (match (pk 'spi (substitutable-path-info s (list o)))
221 (((? substitutable? s))
59688fc4 222 (and (string=? (substitutable-deriver s) (derivation-file-name d))
f65cf81a
LC
223 (null? (substitutable-references s))
224 (equal? (substitutable-nar-size s) 1234)))))))
225
fe0cff14
LC
226(test-assert "substitute"
227 (let* ((s (open-connection))
228 (c (random-text)) ; contents of the output
229 (d (build-expression->derivation
230 s "substitute-me" (%current-system)
231 `(call-with-output-file %output
232 (lambda (p)
233 (exit 1) ; would actually fail
234 (display ,c p)))
235 '()
236 #:guile-for-build
237 (package-derivation s %bootstrap-guile (%current-system))))
59688fc4 238 (o (derivation->output-path d))
fe0cff14
LC
239 (dir (and=> (getenv "GUIX_BINARY_SUBSTITUTE_URL")
240 (compose uri-path string->uri))))
241 ;; Create fake substituter data, to be read by `substitute-binary'.
242 (call-with-output-file (string-append dir "/nix-cache-info")
243 (lambda (p)
244 (format p "StoreDir: ~a\nWantMassQuery: 0\n"
245 (%store-prefix))))
246 (call-with-output-file (string-append dir "/example.out")
247 (lambda (p)
248 (display c p)))
249 (call-with-output-file (string-append dir "/example.nar")
250 (lambda (p)
251 (write-file (string-append dir "/example.out") p)))
252 (call-with-output-file (string-append dir "/" (store-path-hash-part o)
253 ".narinfo")
254 (lambda (p)
255 (format p "StorePath: ~a
256URL: ~a
257Compression: none
258NarSize: 1234
259NarHash: sha256:~a
260References:
261System: ~a
262Deriver: ~a~%"
263 o ; StorePath
264 "example.nar" ; relative URL
265 (call-with-input-file (string-append dir "/example.nar")
266 (compose bytevector->nix-base32-string sha256
267 get-bytevector-all))
268 (%current-system) ; System
59688fc4
LC
269 (basename
270 (derivation-file-name d))))) ; Deriver
fe0cff14
LC
271
272 ;; Make sure we use `substitute-binary'.
273 (set-build-options s #:use-substitutes? #t)
274 (and (has-substitutes? s o)
275 (build-derivations s (list d))
276 (equal? c (call-with-input-file o get-string-all)))))
277
c3eb878f
LC
278(test-assert "substitute --fallback"
279 (let* ((s (open-connection))
280 (t (random-text)) ; contents of the output
281 (d (build-expression->derivation
282 s "substitute-me-not" (%current-system)
283 `(call-with-output-file %output
284 (lambda (p)
285 (display ,t p)))
286 '()
287 #:guile-for-build
288 (package-derivation s %bootstrap-guile (%current-system))))
59688fc4 289 (o (derivation->output-path d))
c3eb878f
LC
290 (dir (and=> (getenv "GUIX_BINARY_SUBSTITUTE_URL")
291 (compose uri-path string->uri))))
292 ;; Create fake substituter data, to be read by `substitute-binary'.
293 (call-with-output-file (string-append dir "/nix-cache-info")
294 (lambda (p)
295 (format p "StoreDir: ~a\nWantMassQuery: 0\n"
296 (%store-prefix))))
297 (call-with-output-file (string-append dir "/" (store-path-hash-part o)
298 ".narinfo")
299 (lambda (p)
300 (format p "StorePath: ~a
301URL: ~a
302Compression: none
303NarSize: 1234
304NarHash: sha256:0mdqa9w1p6cmli6976v4wi0sw9r4p5prkj7lzfd1877wk11c9c73
305References:
306System: ~a
307Deriver: ~a~%"
308 o ; StorePath
309 "does-not-exist.nar" ; relative URL
310 (%current-system) ; System
59688fc4
LC
311 (basename
312 (derivation-file-name d))))) ; Deriver
c3eb878f
LC
313
314 ;; Make sure we use `substitute-binary'.
315 (set-build-options s #:use-substitutes? #t)
316 (and (has-substitutes? s o)
317 (guard (c ((nix-protocol-error? c)
318 ;; The substituter failed as expected. Now make sure that
319 ;; #:fallback? #t works correctly.
320 (set-build-options s
321 #:use-substitutes? #t
322 #:fallback? #t)
323 (and (build-derivations s (list d))
324 (equal? t (call-with-input-file o get-string-all)))))
325 ;; Should fail.
326 (build-derivations s (list d))
327 #f))))
328
3259877d
LC
329(test-end "store")
330
331\f
332(exit (= (test-runner-fail-count (test-runner-current)) 0))