epiphany w/ gtk4 and webkitgtk 2.38
[jackhill/guix/guix.git] / tests / gexp.scm
CommitLineData
21b679f6 1;;; GNU Guix --- Functional package management for GNU
bc1ad696 2;;; Copyright © 2014-2022 Ludovic Courtès <ludo@gnu.org>
5aec62ee 3;;; Copyright © 2021-2022 Maxime Devos <maximedevos@telenet.be>
21b679f6
LC
4;;;
5;;; This file is part of GNU Guix.
6;;;
7;;; GNU Guix is free software; you can redistribute it and/or modify it
8;;; under the terms of the GNU General Public License as published by
9;;; the Free Software Foundation; either version 3 of the License, or (at
10;;; your option) any later version.
11;;;
12;;; GNU Guix is distributed in the hope that it will be useful, but
13;;; WITHOUT ANY WARRANTY; without even the implied warranty of
14;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15;;; GNU General Public License for more details.
16;;;
17;;; You should have received a copy of the GNU General Public License
18;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
19
20(define-module (test-gexp)
21 #:use-module (guix store)
22 #:use-module (guix monads)
23 #:use-module (guix gexp)
24 #:use-module (guix derivations)
79c0c8cd 25 #:use-module (guix packages)
838e17d8 26 #:use-module (guix build-system trivial)
c1bc358f 27 #:use-module (guix tests)
4ff76a0a 28 #:use-module ((guix build utils) #:select (with-directory-excursion))
1ae16033 29 #:use-module ((guix utils) #:select (call-with-temporary-directory))
ca155a20 30 #:use-module ((guix ui) #:select (load*))
21b679f6
LC
31 #:use-module (gnu packages)
32 #:use-module (gnu packages base)
33 #:use-module (gnu packages bootstrap)
ca465a9c 34 #:use-module ((guix diagnostics) #:select (guix-warning-port))
21b679f6 35 #:use-module (srfi srfi-1)
c8351d9a 36 #:use-module (srfi srfi-34)
21b679f6
LC
37 #:use-module (srfi srfi-64)
38 #:use-module (rnrs io ports)
39 #:use-module (ice-9 match)
2cf0ea0d 40 #:use-module (ice-9 regex)
0687fc9c
LC
41 #:use-module (ice-9 popen)
42 #:use-module (ice-9 ftw))
21b679f6
LC
43
44;; Test the (guix gexp) module.
45
46(define %store
c1bc358f 47 (open-connection-for-tests))
21b679f6 48
ef8de985
LC
49;; Globally disable grafts because they can trigger early builds.
50(%graft? #f)
51
21b679f6 52;; For white-box testing.
1f976033
LC
53(define (gexp-inputs x)
54 ((@@ (guix gexp) gexp-inputs) x))
1f976033
LC
55(define (gexp-outputs x)
56 ((@@ (guix gexp) gexp-outputs) x))
57(define (gexp->sexp . x)
58 (apply (@@ (guix gexp) gexp->sexp) x))
21b679f6 59
667b2508 60(define* (gexp->sexp* exp #:optional target)
b57de6fe 61 (run-with-store %store (gexp->sexp exp (%current-system) target)
c1bc358f 62 #:guile-for-build (%guile-for-build)))
21b679f6 63
fc6d6aee 64(define (gexp-input->tuple input)
4fa9d48f
LC
65 (list (gexp-input-thing input) (gexp-input-output input)
66 (gexp-input-native? input)))
fc6d6aee 67
838e17d8
LC
68(define %extension-package
69 ;; Example of a package to use when testing 'with-extensions'.
70 (dummy-package "extension"
71 (build-system trivial-build-system)
72 (arguments
73 `(#:guile ,%bootstrap-guile
74 #:modules ((guix build utils))
75 #:builder
76 (begin
77 (use-modules (guix build utils))
78 (let* ((out (string-append (assoc-ref %outputs "out")
79 "/share/guile/site/"
80 (effective-version))))
81 (mkdir-p out)
82 (call-with-output-file (string-append out "/hg2g.scm")
83 (lambda (port)
e033700f
LC
84 (define defmod 'define-module) ;fool Geiser
85 (write `(,defmod (hg2g)
838e17d8
LC
86 #:export (the-answer))
87 port)
88 (write '(define the-answer 42) port)))))))))
89
21b679f6
LC
90\f
91(test-begin "gexp")
92
d9e0ae07
MD
93(test-equal "no references"
94 '(display "hello gexp->approximate-sexp!")
95 (gexp->approximate-sexp #~(display "hello gexp->approximate-sexp!")))
96
97(test-equal "unquoted gexp"
98 '(display "hello")
99 (let ((inside #~"hello"))
100 (gexp->approximate-sexp #~(display #$inside))))
101
102(test-equal "unquoted gexp (native)"
103 '(display "hello")
104 (let ((inside #~"hello"))
105 (gexp->approximate-sexp #~(display #+inside))))
106
107(test-equal "spliced gexp"
108 '(display '(fresh vegetables))
109 (let ((inside #~(fresh vegetables)))
110 (gexp->approximate-sexp #~(display '(#$@inside)))))
111
112(test-equal "unspliced gexp, approximated"
113 ;; (*approximate*) is really an implementation detail
114 '(display '(*approximate*))
115 (let ((inside (file-append coreutils "/bin/hello")))
116 (gexp->approximate-sexp #~(display '(#$@inside)))))
117
118(test-equal "unquoted gexp, approximated"
119 '(display '(*approximate*))
120 (let ((inside (file-append coreutils "/bin/hello")))
121 (gexp->approximate-sexp #~(display '#$inside))))
122
5aec62ee
MD
123;; See <https://issues.guix.gnu.org/54236>.
124(test-equal "unquoted sexp (not a gexp!)"
125 '(list #(foo) (foo) () "foo" foo #xf00)
126 (let ((inside/vector #(foo))
127 (inside/list '(foo))
128 (inside/empty '())
129 (inside/string "foo")
130 (inside/symbol 'foo)
131 (inside/number #xf00))
132 (gexp->approximate-sexp
133 #~(list #$inside/vector #$inside/list #$inside/empty #$inside/string
134 #$inside/symbol #$inside/number))))
135
21b679f6
LC
136(test-equal "no refs"
137 '(display "hello!")
138 (let ((exp (gexp (display "hello!"))))
139 (and (gexp? exp)
140 (null? (gexp-inputs exp))
141 (gexp->sexp* exp))))
142
da86e90e
LC
143(test-equal "sexp->gexp"
144 '(a b (c d) e)
145 (let ((exp (sexp->gexp '(a b (c d) e))))
146 (and (gexp? exp)
147 (null? (gexp-inputs exp))
148 (gexp->sexp* exp))))
149
2e5c3d91
MD
150(test-equal "gexp->approximate-sexp, outputs"
151 '(list 'out:foo (*approximate*) 'out:bar (*approximate*))
152 (gexp->approximate-sexp
153 #~(list 'out:foo #$output:foo 'out:bar #$output:bar)))
154
21b679f6
LC
155(test-equal "unquote"
156 '(display `(foo ,(+ 2 3)))
157 (let ((exp (gexp (display `(foo ,(+ 2 3))))))
158 (and (gexp? exp)
159 (null? (gexp-inputs exp))
160 (gexp->sexp* exp))))
161
162(test-assert "one input package"
163 (let ((exp (gexp (display (ungexp coreutils)))))
164 (and (gexp? exp)
165 (match (gexp-inputs exp)
fc6d6aee
LC
166 ((input)
167 (eq? (gexp-input-thing input) coreutils)))
21b679f6
LC
168 (equal? `(display ,(derivation->output-path
169 (package-derivation %store coreutils)))
170 (gexp->sexp* exp)))))
5e2e4a51
LC
171
172(test-assert "one input package, dotted list"
173 (let ((exp (gexp (coreutils . (ungexp coreutils)))))
174 (and (gexp? exp)
175 (match (gexp-inputs exp)
fc6d6aee
LC
176 ((input)
177 (eq? (gexp-input-thing input) coreutils)))
5e2e4a51
LC
178 (equal? `(coreutils . ,(derivation->output-path
179 (package-derivation %store coreutils)))
180 (gexp->sexp* exp)))))
21b679f6 181
79c0c8cd
LC
182(test-assert "one input origin"
183 (let ((exp (gexp (display (ungexp (package-source coreutils))))))
184 (and (gexp? exp)
185 (match (gexp-inputs exp)
fc6d6aee
LC
186 ((input)
187 (and (eq? (gexp-input-thing input) (package-source coreutils))
188 (string=? (gexp-input-output input) "out"))))
79c0c8cd
LC
189 (equal? `(display ,(derivation->output-path
190 (package-source-derivation
191 %store (package-source coreutils))))
192 (gexp->sexp* exp)))))
193
d9ae938f
LC
194(test-assert "one local file"
195 (let* ((file (search-path %load-path "guix.scm"))
196 (local (local-file file))
197 (exp (gexp (display (ungexp local))))
020f3e41 198 (intd (add-to-store %store (basename file) #f
d9ae938f
LC
199 "sha256" file)))
200 (and (gexp? exp)
201 (match (gexp-inputs exp)
fc6d6aee
LC
202 ((input)
203 (and (eq? (gexp-input-thing input) local)
204 (string=? (gexp-input-output input) "out"))))
d9ae938f
LC
205 (equal? `(display ,intd) (gexp->sexp* exp)))))
206
7833db1f
LC
207(test-assert "one local file, symlink"
208 (let ((file (search-path %load-path "guix.scm"))
209 (link (tmpnam)))
210 (dynamic-wind
211 (const #t)
212 (lambda ()
213 (symlink (canonicalize-path file) link)
214 (let* ((local (local-file link "my-file" #:recursive? #f))
215 (exp (gexp (display (ungexp local))))
216 (intd (add-to-store %store "my-file" #f
217 "sha256" file)))
218 (and (gexp? exp)
219 (match (gexp-inputs exp)
fc6d6aee
LC
220 ((input)
221 (and (eq? (gexp-input-thing input) local)
222 (string=? (gexp-input-output input) "out"))))
7833db1f
LC
223 (equal? `(display ,intd) (gexp->sexp* exp)))))
224 (lambda ()
225 (false-if-exception (delete-file link))))))
226
4ff76a0a
LC
227(test-equal "local-file, relative file name"
228 (canonicalize-path (search-path %load-path "guix/base32.scm"))
229 (let ((directory (dirname (search-path %load-path
230 "guix/build-system/gnu.scm"))))
231 (with-directory-excursion directory
232 (let ((file (local-file "../guix/base32.scm")))
233 (local-file-absolute-file-name file)))))
234
99c45877
LC
235(test-equal "local-file, non-literal relative file name"
236 (canonicalize-path (search-path %load-path "guix/base32.scm"))
237 (let ((directory (dirname (search-path %load-path
238 "guix/build-system/gnu.scm"))))
239 (with-directory-excursion directory
240 (let ((file (local-file (string-copy "../base32.scm"))))
241 (local-file-absolute-file-name file)))))
242
ca155a20
LC
243(test-assert "local-file, relative file name, within gexp"
244 (let* ((file (search-path %load-path "guix/base32.scm"))
245 (interned (add-to-store %store "base32.scm" #f "sha256" file)))
246 (equal? `(the file is ,interned)
247 (gexp->sexp*
248 #~(the file is #$(local-file "../guix/base32.scm"))))))
249
250(test-assert "local-file, relative file name, within gexp, compiled"
251 ;; In Guile 3.0.8, everything read by the #~ and #$ read hash extensions
252 ;; would lack source location info, which in turn would lead
253 ;; (current-source-directory), called by 'local-file', to return #f, thereby
254 ;; breaking 'local-file' resolution. See
255 ;; <https://issues.guix.gnu.org/54003>.
256 (let ((file (tmpnam)))
257 (call-with-output-file file
258 (lambda (port)
259 (display (string-append "#~(this file is #$(local-file \""
260 (basename file) "\" \"t.scm\"))")
261 port)))
262
263 (let* ((interned (add-to-store %store "t.scm" #f "sha256" file))
264 (module (make-fresh-user-module)))
265 (module-use! module (resolve-interface '(guix gexp)))
266 (equal? `(this file is ,interned)
267 (gexp->sexp* (load* file module))))))
268
0687fc9c
LC
269(test-assertm "local-file, #:select?"
270 (mlet* %store-monad ((select? -> (lambda (file stat)
271 (member (basename file)
272 '("guix.scm" "tests"
273 "gexp.scm"))))
274 (file -> (local-file ".." "directory"
275 #:recursive? #t
276 #:select? select?))
277 (dir (lower-object file)))
278 (return (and (store-path? dir)
279 (equal? (scandir dir)
280 '("." ".." "guix.scm" "tests"))
281 (equal? (scandir (string-append dir "/tests"))
282 '("." ".." "gexp.scm"))))))
283
558e8b11
LC
284(test-assert "one plain file"
285 (let* ((file (plain-file "hi" "Hello, world!"))
286 (exp (gexp (display (ungexp file))))
287 (expected (add-text-to-store %store "hi" "Hello, world!")))
288 (and (gexp? exp)
289 (match (gexp-inputs exp)
fc6d6aee
LC
290 ((input)
291 (and (eq? (gexp-input-thing input) file)
292 (string=? (gexp-input-output input) "out"))))
558e8b11
LC
293 (equal? `(display ,expected) (gexp->sexp* exp)))))
294
21b679f6
LC
295(test-assert "same input twice"
296 (let ((exp (gexp (begin
297 (display (ungexp coreutils))
298 (display (ungexp coreutils))))))
299 (and (gexp? exp)
300 (match (gexp-inputs exp)
fc6d6aee
LC
301 ((input)
302 (and (eq? (gexp-input-thing input) coreutils)
303 (string=? (gexp-input-output input) "out"))))
21b679f6
LC
304 (let ((e `(display ,(derivation->output-path
305 (package-derivation %store coreutils)))))
306 (equal? `(begin ,e ,e) (gexp->sexp* exp))))))
307
308(test-assert "two input packages, one derivation, one file"
309 (let* ((drv (build-expression->derivation
310 %store "foo" 'bar
311 #:guile-for-build (package-derivation %store %bootstrap-guile)))
312 (txt (add-text-to-store %store "foo" "Hello, world!"))
313 (exp (gexp (begin
314 (display (ungexp coreutils))
315 (display (ungexp %bootstrap-guile))
316 (display (ungexp drv))
317 (display (ungexp txt))))))
318 (define (match-input thing)
fc6d6aee
LC
319 (lambda (input)
320 (eq? (gexp-input-thing input) thing)))
21b679f6
LC
321
322 (and (gexp? exp)
323 (= 4 (length (gexp-inputs exp)))
324 (every (lambda (input)
325 (find (match-input input) (gexp-inputs exp)))
326 (list drv coreutils %bootstrap-guile txt))
327 (let ((e0 `(display ,(derivation->output-path
328 (package-derivation %store coreutils))))
329 (e1 `(display ,(derivation->output-path
330 (package-derivation %store %bootstrap-guile))))
331 (e2 `(display ,(derivation->output-path drv)))
332 (e3 `(display ,txt)))
333 (equal? `(begin ,e0 ,e1 ,e2 ,e3) (gexp->sexp* exp))))))
334
a9e5e92f
LC
335(test-assert "file-append"
336 (let* ((drv (package-derivation %store %bootstrap-guile))
337 (fa (file-append %bootstrap-guile "/bin/guile"))
338 (exp #~(here we go #$fa)))
339 (and (match (gexp->sexp* exp)
340 (('here 'we 'go (? string? result))
341 (string=? result
342 (string-append (derivation->output-path drv)
343 "/bin/guile"))))
344 (match (gexp-inputs exp)
fc6d6aee
LC
345 ((input)
346 (and (eq? (gexp-input-thing input) fa)
347 (string=? (gexp-input-output input) "out")))))))
a9e5e92f
LC
348
349(test-assert "file-append, output"
350 (let* ((drv (package-derivation %store glibc))
351 (fa (file-append glibc "/lib" "/debug"))
352 (exp #~(foo #$fa:debug)))
353 (and (match (gexp->sexp* exp)
354 (('foo (? string? result))
355 (string=? result
356 (string-append (derivation->output-path drv "debug")
357 "/lib/debug"))))
358 (match (gexp-inputs exp)
fc6d6aee
LC
359 ((input)
360 (and (eq? (gexp-input-thing input) fa)
361 (string=? (gexp-input-output input) "debug")))))))
a9e5e92f
LC
362
363(test-assert "file-append, nested"
364 (let* ((drv (package-derivation %store glibc))
365 (dir (file-append glibc "/bin"))
366 (slash (file-append dir "/"))
367 (file (file-append slash "getent"))
368 (exp #~(foo #$file)))
369 (and (match (gexp->sexp* exp)
370 (('foo (? string? result))
371 (string=? result
372 (string-append (derivation->output-path drv)
373 "/bin/getent"))))
374 (match (gexp-inputs exp)
fc6d6aee
LC
375 ((input)
376 (eq? (gexp-input-thing input) file))))))
a9e5e92f 377
abf43d45
LC
378(test-assert "file-append, raw store item"
379 (let* ((obj (plain-file "example.txt" "Hello!"))
380 (a (file-append obj "/a"))
381 (b (file-append a "/b"))
382 (c (file-append b "/c"))
383 (exp #~(list #$c))
384 (item (run-with-store %store (lower-object obj)))
385 (lexp (run-with-store %store (lower-gexp exp))))
386 (and (equal? (lowered-gexp-sexp lexp)
387 `(list ,(string-append item "/a/b/c")))
388 (equal? (lowered-gexp-sources lexp)
389 (list item))
390 (null? (lowered-gexp-inputs lexp)))))
391
cf2ac04f
LC
392(test-assertm "with-parameters for %current-system"
393 (mlet* %store-monad ((system -> (match (%current-system)
394 ("aarch64-linux" "x86_64-linux")
395 (_ "aarch64-linux")))
396 (drv (package->derivation coreutils system))
397 (obj -> (with-parameters ((%current-system system))
398 coreutils))
399 (result (lower-object obj)))
400 (return (string=? (derivation-file-name drv)
401 (derivation-file-name result)))))
402
403(test-assertm "with-parameters for %current-target-system"
404 (mlet* %store-monad ((target -> "riscv64-linux-gnu")
405 (drv (package->cross-derivation coreutils target))
406 (obj -> (with-parameters
407 ((%current-target-system target))
408 coreutils))
409 (result (lower-object obj)))
410 (return (string=? (derivation-file-name drv)
411 (derivation-file-name result)))))
412
413(test-assert "with-parameters + file-append"
414 (let* ((system (match (%current-system)
415 ("aarch64-linux" "x86_64-linux")
416 (_ "aarch64-linux")))
417 (drv (package-derivation %store coreutils system))
418 (param (make-parameter 7))
419 (exp #~(here we go #$(with-parameters ((%current-system system)
420 (param 42))
421 (if (= (param) 42)
422 (file-append coreutils "/bin/touch")
423 %bootstrap-guile)))))
424 (match (gexp->sexp* exp)
425 (('here 'we 'go (? string? result))
426 (string=? result
427 (string-append (derivation->output-path drv)
428 "/bin/touch"))))))
644cb40c 429(test-equal "let-system"
4fa9d48f 430 (list `(begin ,(%current-system) #t) '(system-binding)
644cb40c
LC
431 'low '() '())
432 (let* ((exp #~(begin
433 #$(let-system system system)
434 #t))
435 (low (run-with-store %store (lower-gexp exp))))
436 (list (lowered-gexp-sexp low)
437 (match (gexp-inputs exp)
fc6d6aee
LC
438 ((input)
439 (and (eq? (struct-vtable (gexp-input-thing input))
440 (@@ (guix gexp) <system-binding>))
441 (string=? (gexp-input-output input) "out")
442 '(system-binding)))
644cb40c 443 (x x))
644cb40c
LC
444 'low
445 (lowered-gexp-inputs low)
446 (lowered-gexp-sources low))))
447
448(test-equal "let-system, target"
449 (list `(list ,(%current-system) #f)
450 `(list ,(%current-system) "aarch64-linux-gnu"))
451 (let ((exp #~(list #$@(let-system (system target)
452 (list system target)))))
453 (list (gexp->sexp* exp)
454 (gexp->sexp* exp "aarch64-linux-gnu"))))
455
456(test-equal "let-system, ungexp-native, target"
457 `(here it is: ,(%current-system) #f)
458 (let ((exp #~(here it is: #+@(let-system (system target)
459 (list system target)))))
460 (gexp->sexp* exp "aarch64-linux-gnu")))
461
462(test-equal "let-system, nested"
463 (list `(system* ,(string-append "qemu-system-" (%current-system))
464 "-m" "256")
644cb40c
LC
465 '(system-binding))
466 (let ((exp #~(system*
467 #+(let-system (system target)
468 (file-append (@@ (gnu packages virtualization)
469 qemu)
470 "/bin/qemu-system-"
471 system))
472 "-m" "256")))
473 (list (match (gexp->sexp* exp)
474 (('system* command rest ...)
475 `(system* ,(and (string-prefix? (%store-prefix) command)
476 (basename command))
477 ,@rest))
478 (x x))
4fa9d48f 479 (match (gexp-inputs exp)
fc6d6aee
LC
480 ((input)
481 (and (eq? (struct-vtable (gexp-input-thing input))
482 (@@ (guix gexp) <system-binding>))
483 (string=? (gexp-input-output input) "out")
4fa9d48f 484 (gexp-input-native? input)
fc6d6aee 485 '(system-binding)))
644cb40c 486 (x x)))))
cf2ac04f 487
6b30eb18
LC
488(test-assert "let-system in file-append"
489 (let ((mixed (file-append (let-system (system target)
490 (if (not target) grep sed))
491 "/bin"))
492 (grep (file-append grep "/bin"))
493 (sed (file-append sed "/bin")))
494 (and (equal? (gexp->sexp* #~(list #$mixed))
495 (gexp->sexp* #~(list #$grep)))
496 (equal? (gexp->sexp* #~(list #$mixed) "powerpc64le-linux-gnu")
497 (gexp->sexp* #~(list #$sed) "powerpc64le-linux-gnu")))))
498
667b2508
LC
499(test-assert "ungexp + ungexp-native"
500 (let* ((exp (gexp (list (ungexp-native %bootstrap-guile)
501 (ungexp coreutils)
502 (ungexp-native glibc)
503 (ungexp binutils))))
d276a7dd 504 (target "mips64el-linux-gnu")
667b2508
LC
505 (guile (derivation->output-path
506 (package-derivation %store %bootstrap-guile)))
507 (cu (derivation->output-path
508 (package-cross-derivation %store coreutils target)))
509 (libc (derivation->output-path
510 (package-derivation %store glibc)))
511 (bu (derivation->output-path
512 (package-cross-derivation %store binutils target))))
513 (and (lset= equal?
4fa9d48f
LC
514 `((,%bootstrap-guile "out" #t)
515 (,coreutils "out" #f)
516 (,glibc "out" #t)
517 (,binutils "out" #f))
fc6d6aee 518 (map gexp-input->tuple (gexp-inputs exp)))
667b2508
LC
519 (equal? `(list ,guile ,cu ,libc ,bu)
520 (gexp->sexp* exp target)))))
521
1123759b 522(test-equal "ungexp + ungexp-native, nested"
4fa9d48f 523 `((,%bootstrap-guile "out" #f) (,coreutils "out" #t))
1123759b
LC
524 (let* ((exp (gexp (list (ungexp-native (gexp (ungexp coreutils)))
525 (ungexp %bootstrap-guile)))))
4fa9d48f 526 (map gexp-input->tuple (gexp-inputs exp))))
1123759b 527
5b14a790 528(test-equal "ungexp + ungexp-native, nested, special mixture"
4fa9d48f 529 `((,coreutils "out" #t))
5b14a790 530
5b14a790
LC
531 (let* ((foo (gexp (foo (ungexp-native coreutils))))
532 (exp (gexp (bar (ungexp foo)))))
4fa9d48f 533 (map gexp-input->tuple (gexp-inputs exp))))
5b14a790 534
21b679f6
LC
535(test-assert "input list"
536 (let ((exp (gexp (display
537 '(ungexp (list %bootstrap-guile coreutils)))))
538 (guile (derivation->output-path
539 (package-derivation %store %bootstrap-guile)))
540 (cu (derivation->output-path
541 (package-derivation %store coreutils))))
542 (and (lset= equal?
4fa9d48f 543 `((,%bootstrap-guile "out" #f) (,coreutils "out" #f))
fc6d6aee 544 (map gexp-input->tuple (gexp-inputs exp)))
21b679f6
LC
545 (equal? `(display '(,guile ,cu))
546 (gexp->sexp* exp)))))
547
667b2508 548(test-assert "input list + ungexp-native"
d276a7dd 549 (let* ((target "mips64el-linux-gnu")
667b2508
LC
550 (exp (gexp (display
551 (cons '(ungexp-native (list %bootstrap-guile coreutils))
552 '(ungexp (list glibc binutils))))))
553 (guile (derivation->output-path
554 (package-derivation %store %bootstrap-guile)))
555 (cu (derivation->output-path
556 (package-derivation %store coreutils)))
557 (xlibc (derivation->output-path
558 (package-cross-derivation %store glibc target)))
559 (xbu (derivation->output-path
560 (package-cross-derivation %store binutils target))))
561 (and (lset= equal?
4fa9d48f
LC
562 `((,%bootstrap-guile "out" #t) (,coreutils "out" #t)
563 (,glibc "out" #f) (,binutils "out" #f))
fc6d6aee 564 (map gexp-input->tuple (gexp-inputs exp)))
667b2508
LC
565 (equal? `(display (cons '(,guile ,cu) '(,xlibc ,xbu)))
566 (gexp->sexp* exp target)))))
567
21b679f6 568(test-assert "input list splicing"
a482cfdc 569 (let* ((inputs (list (gexp-input glibc "debug") %bootstrap-guile))
21b679f6
LC
570 (outputs (list (derivation->output-path
571 (package-derivation %store glibc)
572 "debug")
573 (derivation->output-path
574 (package-derivation %store %bootstrap-guile))))
575 (exp (gexp (list (ungexp-splicing (cons (+ 2 3) inputs))))))
576 (and (lset= equal?
4fa9d48f 577 `((,glibc "debug" #f) (,%bootstrap-guile "out" #f))
fc6d6aee 578 (map gexp-input->tuple (gexp-inputs exp)))
21b679f6
LC
579 (equal? (gexp->sexp* exp)
580 `(list ,@(cons 5 outputs))))))
581
667b2508 582(test-assert "input list splicing + ungexp-native-splicing"
5b14a790
LC
583 (let* ((inputs (list (gexp-input glibc "debug" #:native? #t)
584 %bootstrap-guile))
0dbea56b
LC
585 (exp (gexp (list (ungexp-native-splicing (cons (+ 2 3) inputs))))))
586 (and (lset= equal?
4fa9d48f
LC
587 `((,glibc "debug" #t) (,%bootstrap-guile "out" #t))
588 (map gexp-input->tuple (gexp-inputs exp)))
0dbea56b
LC
589 (equal? (gexp->sexp* exp) ;native
590 (gexp->sexp* exp "mips64el-linux")))))
591
578dfbe0
LC
592(test-assert "gexp list splicing + ungexp-splicing"
593 (let* ((inner (gexp (ungexp-native glibc)))
594 (exp (gexp (list (ungexp-splicing (list inner))))))
4fa9d48f
LC
595 (and (equal? `((,glibc "out" #t))
596 (map gexp-input->tuple (gexp-inputs exp)))
578dfbe0
LC
597 (equal? (gexp->sexp* exp) ;native
598 (gexp->sexp* exp "mips64el-linux")))))
599
4b23c466
LC
600(test-equal "output list"
601 2
602 (let ((exp (gexp (begin (mkdir (ungexp output))
603 (mkdir (ungexp output "bar"))))))
604 (length (gexp-outputs exp)))) ;XXX: <output-ref> is private
605
606(test-assert "output list, combined gexps"
607 (let* ((exp0 (gexp (mkdir (ungexp output))))
608 (exp1 (gexp (mkdir (ungexp output "foo"))))
609 (exp2 (gexp (begin (display "hi!") (ungexp exp0) (ungexp exp1)))))
610 (and (lset= equal?
611 (append (gexp-outputs exp0) (gexp-outputs exp1))
612 (gexp-outputs exp2))
613 (= 2 (length (gexp-outputs exp2))))))
614
7e75a673
LC
615(test-equal "output list, combined gexps, duplicate output"
616 1
617 (let* ((exp0 (gexp (mkdir (ungexp output))))
618 (exp1 (gexp (begin (mkdir (ungexp output)) (ungexp exp0))))
619 (exp2 (gexp (begin (mkdir (ungexp output)) (ungexp exp1)))))
620 (length (gexp-outputs exp2))))
621
f9efe568
LC
622(test-assert "output list + ungexp-splicing list, combined gexps"
623 (let* ((exp0 (gexp (mkdir (ungexp output))))
624 (exp1 (gexp (mkdir (ungexp output "foo"))))
625 (exp2 (gexp (begin (display "hi!")
626 (ungexp-splicing (list exp0 exp1))))))
627 (and (lset= equal?
628 (append (gexp-outputs exp0) (gexp-outputs exp1))
629 (gexp-outputs exp2))
630 (= 2 (length (gexp-outputs exp2))))))
631
21b679f6
LC
632(test-assertm "gexp->file"
633 (mlet* %store-monad ((exp -> (gexp (display (ungexp %bootstrap-guile))))
634 (guile (package-file %bootstrap-guile))
b57de6fe 635 (sexp (gexp->sexp exp (%current-system) #f))
21b679f6
LC
636 (drv (gexp->file "foo" exp))
637 (out -> (derivation->output-path drv))
638 (done (built-derivations (list drv)))
e74f64b9 639 (refs (references* out)))
21b679f6
LC
640 (return (and (equal? sexp (call-with-input-file out read))
641 (equal? (list guile) refs)))))
642
a9e5e92f
LC
643(test-assertm "gexp->file + file-append"
644 (mlet* %store-monad ((exp -> #~#$(file-append %bootstrap-guile
645 "/bin/guile"))
646 (guile (package-file %bootstrap-guile))
647 (drv (gexp->file "foo" exp))
648 (out -> (derivation->output-path drv))
649 (done (built-derivations (list drv)))
e74f64b9 650 (refs (references* out)))
a9e5e92f
LC
651 (return (and (equal? (string-append guile "/bin/guile")
652 (call-with-input-file out read))
653 (equal? (list guile) refs)))))
654
4fbd1a2b
LC
655(test-assertm "gexp->file + #:splice?"
656 (mlet* %store-monad ((exp -> (list
657 #~(define foo 'bar)
658 #~(define guile #$%bootstrap-guile)))
659 (guile (package-file %bootstrap-guile))
660 (drv (gexp->file "splice" exp #:splice? #t))
661 (out -> (derivation->output-path drv))
662 (done (built-derivations (list drv)))
663 (refs (references* out)))
664 (pk 'splice out)
665 (return (and (equal? `((define foo 'bar)
666 (define guile ,guile)
667 ,(call-with-input-string "" read))
668 (call-with-input-file out
669 (lambda (port)
670 (list (read port) (read port) (read port)))))
671 (equal? (list guile) refs)))))
672
21b679f6
LC
673(test-assertm "gexp->derivation"
674 (mlet* %store-monad ((file (text-file "foo" "Hello, world!"))
675 (exp -> (gexp
676 (begin
677 (mkdir (ungexp output))
678 (chdir (ungexp output))
679 (symlink
680 (string-append (ungexp %bootstrap-guile)
681 "/bin/guile")
682 "foo")
683 (symlink (ungexp file)
684 (ungexp output "2nd")))))
685 (drv (gexp->derivation "foo" exp))
686 (out -> (derivation->output-path drv))
687 (out2 -> (derivation->output-path drv "2nd"))
688 (done (built-derivations (list drv)))
e74f64b9
LC
689 (refs (references* out))
690 (refs2 (references* out2))
21b679f6
LC
691 (guile (package-file %bootstrap-guile "bin/guile")))
692 (return (and (string=? (readlink (string-append out "/foo")) guile)
693 (string=? (readlink out2) file)
694 (equal? refs (list (dirname (dirname guile))))
8856f409
LC
695 (equal? refs2 (list file))
696 (null? (derivation-properties drv))))))
697
698(test-assertm "gexp->derivation properties"
699 (mlet %store-monad ((drv (gexp->derivation "foo"
700 #~(mkdir #$output)
701 #:properties '((type . test)))))
702 (return (equal? '((type . test))
703 (derivation-properties drv)))))
21b679f6 704
ce45eb4c 705(test-assertm "gexp->derivation vs. grafts"
ef8de985
LC
706 (mlet* %store-monad ((graft? (set-grafting #f))
707 (p0 -> (dummy-package "dummy"
ce45eb4c
LC
708 (arguments
709 '(#:implicit-inputs? #f))))
710 (r -> (package (inherit p0) (name "DuMMY")))
711 (p1 -> (package (inherit p0) (replacement r)))
712 (exp0 -> (gexp (frob (ungexp p0) (ungexp output))))
713 (exp1 -> (gexp (frob (ungexp p1) (ungexp output))))
714 (void (set-guile-for-build %bootstrap-guile))
ef8de985
LC
715 (drv0 (gexp->derivation "t" exp0 #:graft? #t))
716 (drv1 (gexp->derivation "t" exp1 #:graft? #t))
717 (drv1* (gexp->derivation "t" exp1 #:graft? #f))
718 (_ (set-grafting graft?)))
ce45eb4c
LC
719 (return (and (not (string=? (derivation->output-path drv0)
720 (derivation->output-path drv1)))
721 (string=? (derivation->output-path drv0)
722 (derivation->output-path drv1*))))))
723
21b679f6
LC
724(test-assertm "gexp->derivation, composed gexps"
725 (mlet* %store-monad ((exp0 -> (gexp (begin
726 (mkdir (ungexp output))
727 (chdir (ungexp output)))))
728 (exp1 -> (gexp (symlink
729 (string-append (ungexp %bootstrap-guile)
730 "/bin/guile")
731 "foo")))
732 (exp -> (gexp (begin (ungexp exp0) (ungexp exp1))))
733 (drv (gexp->derivation "foo" exp))
734 (out -> (derivation->output-path drv))
735 (done (built-derivations (list drv)))
736 (guile (package-file %bootstrap-guile "bin/guile")))
737 (return (string=? (readlink (string-append out "/foo"))
738 guile))))
739
5d098459
LC
740(test-assertm "gexp->derivation, default system"
741 ;; The default system should be the one at '>>=' time, not the one at
742 ;; invocation time. See <http://bugs.gnu.org/18002>.
743 (let ((system (%current-system))
744 (mdrv (parameterize ((%current-system "foobar64-linux"))
745 (gexp->derivation "foo"
746 (gexp
747 (mkdir (ungexp output)))))))
748 (mlet %store-monad ((drv mdrv))
749 (return (string=? system (derivation-system drv))))))
750
d9ae938f
LC
751(test-assertm "gexp->derivation, local-file"
752 (mlet* %store-monad ((file -> (search-path %load-path "guix.scm"))
020f3e41 753 (intd (interned-file file #:recursive? #f))
d9ae938f
LC
754 (local -> (local-file file))
755 (exp -> (gexp (begin
756 (stat (ungexp local))
757 (symlink (ungexp local)
758 (ungexp output)))))
759 (drv (gexp->derivation "local-file" exp)))
760 (mbegin %store-monad
761 (built-derivations (list drv))
762 (return (string=? (readlink (derivation->output-path drv))
763 intd)))))
764
68a61e9f 765(test-assertm "gexp->derivation, cross-compilation"
d276a7dd 766 (mlet* %store-monad ((target -> "mips64el-linux-gnu")
68a61e9f
LC
767 (exp -> (gexp (list (ungexp coreutils)
768 (ungexp output))))
769 (xdrv (gexp->derivation "foo" exp
770 #:target target))
e74f64b9 771 (refs (references*
68a61e9f
LC
772 (derivation-file-name xdrv)))
773 (xcu (package->cross-derivation coreutils
774 target))
775 (cu (package->derivation coreutils)))
776 (return (and (member (derivation-file-name xcu) refs)
777 (not (member (derivation-file-name cu) refs))))))
778
667b2508 779(test-assertm "gexp->derivation, ungexp-native"
d276a7dd 780 (mlet* %store-monad ((target -> "mips64el-linux-gnu")
667b2508
LC
781 (exp -> (gexp (list (ungexp-native coreutils)
782 (ungexp output))))
783 (xdrv (gexp->derivation "foo" exp
784 #:target target))
785 (drv (gexp->derivation "foo" exp)))
786 (return (string=? (derivation-file-name drv)
787 (derivation-file-name xdrv)))))
788
789(test-assertm "gexp->derivation, ungexp + ungexp-native"
d276a7dd 790 (mlet* %store-monad ((target -> "mips64el-linux-gnu")
667b2508
LC
791 (exp -> (gexp (list (ungexp-native coreutils)
792 (ungexp glibc)
793 (ungexp output))))
794 (xdrv (gexp->derivation "foo" exp
795 #:target target))
e74f64b9 796 (refs (references*
667b2508
LC
797 (derivation-file-name xdrv)))
798 (xglibc (package->cross-derivation glibc target))
799 (cu (package->derivation coreutils)))
800 (return (and (member (derivation-file-name cu) refs)
801 (member (derivation-file-name xglibc) refs)))))
802
803(test-assertm "gexp->derivation, ungexp-native + composed gexps"
d276a7dd 804 (mlet* %store-monad ((target -> "mips64el-linux-gnu")
667b2508
LC
805 (exp0 -> (gexp (list 1 2
806 (ungexp coreutils))))
807 (exp -> (gexp (list 0 (ungexp-native exp0))))
808 (xdrv (gexp->derivation "foo" exp
809 #:target target))
810 (drv (gexp->derivation "foo" exp)))
811 (return (string=? (derivation-file-name drv)
812 (derivation-file-name xdrv)))))
813
6fd1a796
LC
814(test-assertm "gexp->derivation, store copy"
815 (let ((build-one #~(call-with-output-file #$output
816 (lambda (port)
817 (display "This is the one." port))))
818 (build-two (lambda (one)
819 #~(begin
820 (mkdir #$output)
821 (symlink #$one (string-append #$output "/one"))
822 (call-with-output-file (string-append #$output "/two")
823 (lambda (port)
824 (display "This is the second one." port))))))
b53833b2 825 (build-drv #~(begin
7b8d239e
LC
826 (use-modules (guix build store-copy)
827 (guix build utils)
828 (srfi srfi-1))
829
830 (define (canonical-file? file)
831 ;; Copied from (guix tests).
832 (let ((st (lstat file)))
833 (or (not (string-prefix? (%store-directory) file))
834 (eq? 'symlink (stat:type st))
835 (and (= 1 (stat:mtime st))
836 (zero? (logand #o222 (stat:mode st)))))))
6fd1a796 837
b53833b2 838 (mkdir #$output)
6a060ff2
LC
839 (populate-store '("graph") #$output
840 #:deduplicate? #f)
7b8d239e
LC
841
842 ;; Check whether 'populate-store' canonicalizes
843 ;; permissions and timestamps.
844 (unless (every canonical-file? (find-files #$output))
845 (error "not canonical!" #$output)))))
6fd1a796
LC
846 (mlet* %store-monad ((one (gexp->derivation "one" build-one))
847 (two (gexp->derivation "two" (build-two one)))
b53833b2 848 (drv (gexp->derivation "store-copy" build-drv
6fd1a796 849 #:references-graphs
b53833b2 850 `(("graph" ,two))
6fd1a796
LC
851 #:modules
852 '((guix build store-copy)
d4e9317b
LC
853 (guix progress)
854 (guix records)
6892f0a2 855 (guix sets)
6fd1a796
LC
856 (guix build utils))))
857 (ok? (built-derivations (list drv)))
858 (out -> (derivation->output-path drv)))
859 (let ((one (derivation->output-path one))
860 (two (derivation->output-path two)))
861 (return (and ok?
862 (file-exists? (string-append out "/" one))
863 (file-exists? (string-append out "/" two))
864 (file-exists? (string-append out "/" two "/two"))
865 (string=? (readlink (string-append out "/" two "/one"))
866 one)))))))
867
aa72d9af
LC
868(test-assertm "imported-files"
869 (mlet* %store-monad
870 ((files -> `(("x" . ,(search-path %load-path "ice-9/q.scm"))
871 ("a/b/c" . ,(search-path %load-path
872 "guix/derivations.scm"))
873 ("p/q" . ,(search-path %load-path "guix.scm"))
874 ("p/z" . ,(search-path %load-path "guix/store.scm"))))
8df2eca6 875 (dir (imported-files files)))
aa72d9af 876 (mbegin %store-monad
8df2eca6
LC
877 (return
878 (every (match-lambda
879 ((path . source)
880 (equal? (call-with-input-file (string-append dir "/" path)
881 get-bytevector-all)
882 (call-with-input-file source
883 get-bytevector-all))))
884 files)))))
aa72d9af 885
d938a58b
LC
886(test-assertm "imported-files with file-like objects"
887 (mlet* %store-monad ((plain -> (plain-file "foo" "bar!"))
888 (q-scm -> (search-path %load-path "ice-9/q.scm"))
889 (files -> `(("a/b/c" . ,q-scm)
890 ("p/q" . ,plain)))
891 (drv (imported-files files)))
892 (mbegin %store-monad
8c7bebd6 893 (built-derivations (list (pk 'drv drv)))
d938a58b
LC
894 (mlet %store-monad ((dir -> (derivation->output-path drv))
895 (plain* (text-file "foo" "bar!"))
896 (q-scm* (interned-file q-scm "c")))
897 (return
f39397b2
LC
898 (and (file=? (string-append dir "/a/b/c") q-scm* stat)
899 (file=? (string-append dir "/p/q") plain* stat)))))))
d938a58b 900
0bb9929e
LC
901(test-equal "gexp-modules & ungexp"
902 '((bar) (foo))
903 ((@@ (guix gexp) gexp-modules)
904 #~(foo #$(with-imported-modules '((foo)) #~+)
905 #+(with-imported-modules '((bar)) #~-))))
906
907(test-equal "gexp-modules & ungexp-splicing"
908 '((foo) (bar))
909 ((@@ (guix gexp) gexp-modules)
910 #~(foo #$@(list (with-imported-modules '((foo)) #~+)
911 (with-imported-modules '((bar)) #~-)))))
912
932d1600
LC
913(test-assert "gexp-modules deletes duplicates" ;<https://bugs.gnu.org/32966>
914 (let ((make-file (lambda ()
915 ;; Use 'eval' to make sure we get an object that's not
916 ;; 'eq?' nor 'equal?' due to the closures it embeds.
917 (eval '(scheme-file "bar.scm" #~(define-module (bar)))
918 (current-module)))))
919 (define result
920 ((@@ (guix gexp) gexp-modules)
921 (with-imported-modules `(((bar) => ,(make-file))
922 ((bar) => ,(make-file))
923 (foo) (foo))
924 #~+)))
925
926 (match result
927 (((('bar) '=> (? scheme-file?)) ('foo)) #t))))
928
2363bdd7
LC
929(test-equal "gexp-modules and literal Scheme object"
930 '()
931 (gexp-modules #t))
932
ca465a9c
LC
933(test-assert "gexp-modules, warning"
934 (string-match "tests/gexp.scm:[0-9]+:[0-9]+: warning: \
935importing.* \\(guix config\\) from the host"
936 (call-with-output-string
937 (lambda (port)
938 (parameterize ((guix-warning-port port))
939 (let* ((x (with-imported-modules '((guix config))
940 #~(+ 1 2 3)))
941 (y #~(+ 39 #$x)))
942 (gexp-modules y)))))))
943
aa72d9af
LC
944(test-assertm "gexp->derivation #:modules"
945 (mlet* %store-monad
946 ((build -> #~(begin
947 (use-modules (guix build utils))
948 (mkdir-p (string-append #$output "/guile/guix/nix"))
949 #t))
950 (drv (gexp->derivation "test-with-modules" build
951 #:modules '((guix build utils)))))
952 (mbegin %store-monad
953 (built-derivations (list drv))
954 (let* ((p (derivation->output-path drv))
955 (s (stat (string-append p "/guile/guix/nix"))))
956 (return (eq? (stat:type s) 'directory))))))
957
0bb9929e
LC
958(test-assertm "gexp->derivation & with-imported-modules"
959 ;; Same test as above, but using 'with-imported-modules'.
960 (mlet* %store-monad
961 ((build -> (with-imported-modules '((guix build utils))
962 #~(begin
963 (use-modules (guix build utils))
964 (mkdir-p (string-append #$output "/guile/guix/nix"))
965 #t)))
966 (drv (gexp->derivation "test-with-modules" build)))
967 (mbegin %store-monad
968 (built-derivations (list drv))
969 (let* ((p (derivation->output-path drv))
970 (s (stat (string-append p "/guile/guix/nix"))))
971 (return (eq? (stat:type s) 'directory))))))
972
973(test-assertm "gexp->derivation & nested with-imported-modules"
974 (mlet* %store-monad
975 ((build1 -> (with-imported-modules '((guix build utils))
976 #~(begin
977 (use-modules (guix build utils))
978 (mkdir-p (string-append #$output "/guile/guix/nix"))
979 #t)))
980 (build2 -> (with-imported-modules '((guix build bournish))
981 #~(begin
982 (use-modules (guix build bournish)
983 (system base compile))
984 #+build1
985 (call-with-output-file (string-append #$output "/b")
986 (lambda (port)
987 (write
988 (read-and-compile (open-input-string "cd /foo")
989 #:from %bournish-language
990 #:to 'scheme)
991 port))))))
992 (drv (gexp->derivation "test-with-modules" build2)))
993 (mbegin %store-monad
994 (built-derivations (list drv))
995 (let* ((p (derivation->output-path drv))
996 (s (stat (string-append p "/guile/guix/nix")))
997 (b (string-append p "/b")))
998 (return (and (eq? (stat:type s) 'directory)
999 (equal? '(chdir "/foo")
1000 (call-with-input-file b read))))))))
1001
d938a58b
LC
1002(test-assertm "gexp->derivation & with-imported-module & computed module"
1003 (mlet* %store-monad
4fbd1a2b 1004 ((module -> (scheme-file "x" #~(;; splice!
d938a58b
LC
1005 (define-module (foo bar)
1006 #:export (the-answer))
1007
4fbd1a2b
LC
1008 (define the-answer 42))
1009 #:splice? #t))
d938a58b
LC
1010 (build -> (with-imported-modules `(((foo bar) => ,module)
1011 (guix build utils))
1012 #~(begin
1013 (use-modules (guix build utils)
1014 (foo bar))
1015 mkdir-p
1016 (call-with-output-file #$output
1017 (lambda (port)
1018 (write the-answer port))))))
1019 (drv (gexp->derivation "thing" build))
1020 (out -> (derivation->output-path drv)))
1021 (mbegin %store-monad
1022 (built-derivations (list drv))
1023 (return (= 42 (call-with-input-file out read))))))
1024
838e17d8
LC
1025(test-equal "gexp-extensions & ungexp"
1026 (list sed grep)
1027 ((@@ (guix gexp) gexp-extensions)
1028 #~(foo #$(with-extensions (list grep) #~+)
1029 #+(with-extensions (list sed) #~-))))
1030
1031(test-equal "gexp-extensions & ungexp-splicing"
1032 (list grep sed)
1033 ((@@ (guix gexp) gexp-extensions)
1034 #~(foo #$@(list (with-extensions (list grep) #~+)
1035 (with-imported-modules '((foo))
1036 (with-extensions (list sed) #~-))))))
1037
1038(test-equal "gexp-extensions and literal Scheme object"
1039 '()
1040 ((@@ (guix gexp) gexp-extensions) #t))
1041
1042(test-assertm "gexp->derivation & with-extensions"
1043 ;; Create a fake Guile extension and make sure it is accessible both to the
1044 ;; imported modules and to the derivation build script.
1045 (mlet* %store-monad
1046 ((extension -> %extension-package)
1047 (module -> (scheme-file "x" #~( ;; splice!
1048 (define-module (foo)
1049 #:use-module (hg2g)
1050 #:export (multiply))
1051
1052 (define (multiply x)
1053 (* the-answer x)))
1054 #:splice? #t))
1055 (build -> (with-extensions (list extension)
1056 (with-imported-modules `((guix build utils)
1057 ((foo) => ,module))
1058 #~(begin
1059 (use-modules (guix build utils)
1060 (hg2g) (foo))
1061 (call-with-output-file #$output
1062 (lambda (port)
1063 (write (list the-answer (multiply 2))
1064 port)))))))
1065 (drv (gexp->derivation "thingie" build
1066 ;; %BOOTSTRAP-GUILE is 2.0.
1067 #:effective-version "2.0"))
1068 (out -> (derivation->output-path drv)))
1069 (mbegin %store-monad
1070 (built-derivations (list drv))
1071 (return (equal? '(42 84) (call-with-input-file out read))))))
1072
2ca41030
LC
1073(test-assertm "lower-gexp"
1074 (mlet* %store-monad
1075 ((extension -> %extension-package)
1076 (extension-drv (package->derivation %extension-package))
1077 (coreutils-drv (package->derivation coreutils))
1078 (exp -> (with-extensions (list extension)
1079 (with-imported-modules `((guix build utils))
1080 #~(begin
1081 (use-modules (guix build utils)
1082 (hg2g))
1083 #$coreutils:debug
1084 mkdir-p
1085 the-answer))))
1086 (lexp (lower-gexp exp
1087 #:effective-version "2.0")))
1088 (define (matching-input drv output)
1089 (lambda (input)
38685774
LC
1090 (and (eq? (derivation-input-derivation input) drv)
1091 (equal? (derivation-input-sub-derivations input)
1092 (list output)))))
2ca41030
LC
1093
1094 (mbegin %store-monad
1095 (return (and (find (matching-input extension-drv "out")
1096 (lowered-gexp-inputs (pk 'lexp lexp)))
1097 (find (matching-input coreutils-drv "debug")
1098 (lowered-gexp-inputs lexp))
1099 (member (string-append
1100 (derivation->output-path extension-drv)
1101 "/share/guile/site/2.0")
1102 (lowered-gexp-load-path lexp))
1103 (= 2 (length (lowered-gexp-load-path lexp)))
1104 (member (string-append
1105 (derivation->output-path extension-drv)
1106 "/lib/guile/2.0/site-ccache")
1107 (lowered-gexp-load-compiled-path lexp))
1108 (= 2 (length (lowered-gexp-load-compiled-path lexp)))
b9373e26
LC
1109 (eq? (derivation-input-derivation (lowered-gexp-guile lexp))
1110 (%guile-for-build)))))))
2ca41030 1111
d63ee94d
LC
1112(test-assertm "lower-gexp, raw-derivation-file"
1113 (mlet* %store-monad ((thing -> (program-file "prog" #~(display "hi!")))
1114 (exp -> #~(list #$(raw-derivation-file thing)))
1115 (drv (lower-object thing))
1116 (lexp (lower-gexp exp #:effective-version "2.0")))
1117 (return (and (equal? `(list ,(derivation-file-name drv))
1118 (lowered-gexp-sexp lexp))
1119 (equal? (list (derivation-file-name drv))
1120 (lowered-gexp-sources lexp))
1121 (null? (lowered-gexp-inputs lexp))))))
1122
24ab804c
LC
1123(test-eq "lower-gexp, non-self-quoting input"
1124 +
1125 (guard (c ((gexp-input-error? c)
1126 (gexp-error-invalid-input c)))
1127 (run-with-store %store
1128 (lower-gexp #~(foo #$+)))))
1129
ab7010af
MB
1130(test-equal "lower-gexp, character literal"
1131 '(#\+)
1132 (lowered-gexp-sexp
1133 (run-with-store %store
1134 (lower-gexp #~(#\+)))))
1135
b53833b2
LC
1136(test-assertm "gexp->derivation #:references-graphs"
1137 (mlet* %store-monad
72cd8ec0 1138 ((one (text-file "one" (random-text)))
b53833b2
LC
1139 (two (gexp->derivation "two"
1140 #~(symlink #$one #$output:chbouib)))
66a35ceb 1141 (build -> (with-imported-modules '((guix build store-copy)
d4e9317b
LC
1142 (guix progress)
1143 (guix records)
6892f0a2 1144 (guix sets)
66a35ceb
LC
1145 (guix build utils))
1146 #~(begin
1147 (use-modules (guix build store-copy))
1148 (with-output-to-file #$output
1149 (lambda ()
6892f0a2
LC
1150 (write (map store-info-item
1151 (call-with-input-file "guile"
1152 read-reference-graph)))))
66a35ceb
LC
1153 (with-output-to-file #$output:one
1154 (lambda ()
6892f0a2
LC
1155 (write (map store-info-item
1156 (call-with-input-file "one"
1157 read-reference-graph)))))
66a35ceb
LC
1158 (with-output-to-file #$output:two
1159 (lambda ()
6892f0a2
LC
1160 (write (map store-info-item
1161 (call-with-input-file "two"
1162 read-reference-graph))))))))
66a35ceb 1163 (drv (gexp->derivation "ref-graphs" build
b53833b2
LC
1164 #:references-graphs `(("one" ,one)
1165 ("two" ,two "chbouib")
66a35ceb 1166 ("guile" ,%bootstrap-guile))))
b53833b2
LC
1167 (ok? (built-derivations (list drv)))
1168 (guile-drv (package->derivation %bootstrap-guile))
686784d0
LC
1169 (bash (interned-file (search-bootstrap-binary "bash"
1170 (%current-system))
1171 "bash" #:recursive? #t))
b53833b2
LC
1172 (g-one -> (derivation->output-path drv "one"))
1173 (g-two -> (derivation->output-path drv "two"))
1174 (g-guile -> (derivation->output-path drv)))
1175 (return (and ok?
1176 (equal? (call-with-input-file g-one read) (list one))
72cd8ec0
LC
1177 (lset= string=?
1178 (call-with-input-file g-two read)
1179 (list one (derivation->output-path two "chbouib")))
686784d0
LC
1180
1181 ;; Note: %BOOTSTRAP-GUILE depends on the bootstrap Bash.
72cd8ec0
LC
1182 (lset= string=?
1183 (call-with-input-file g-guile read)
1184 (list (derivation->output-path guile-drv) bash))))))
b53833b2 1185
9fc4e949
LC
1186(test-assertm "gexp->derivation #:references-graphs cross-compilation"
1187 ;; The objects passed in #:references-graphs implicitly refer to
1188 ;; cross-compiled derivations. Make sure this is the case.
1189 (mlet* %store-monad ((drv1 (lower-object coreutils (%current-system)
1190 #:target "i586-pc-gnu"))
1191 (drv2 (lower-object coreutils (%current-system)
1192 #:target #f))
1193 (drv3 (gexp->derivation "three"
1194 #~(symlink #$coreutils #$output)
1195 #:target "i586-pc-gnu"
1196 #:references-graphs
1197 `(("coreutils" ,coreutils))))
1198 (refs (references* (derivation-file-name drv3))))
1199 (return (and (member (derivation-file-name drv1) refs)
1200 (not (member (derivation-file-name drv2) refs))))))
1201
c8351d9a
LC
1202(test-assertm "gexp->derivation #:allowed-references"
1203 (mlet %store-monad ((drv (gexp->derivation "allowed-refs"
1204 #~(begin
1205 (mkdir #$output)
1206 (chdir #$output)
1207 (symlink #$output "self")
1208 (symlink #$%bootstrap-guile
1209 "guile"))
1210 #:allowed-references
1211 (list "out" %bootstrap-guile))))
1212 (built-derivations (list drv))))
1213
accb682c
LC
1214(test-assertm "gexp->derivation #:allowed-references, specific output"
1215 (mlet* %store-monad ((in (gexp->derivation "thing"
1216 #~(begin
1217 (mkdir #$output:ok)
1218 (mkdir #$output:not-ok))))
1219 (drv (gexp->derivation "allowed-refs"
1220 #~(begin
1221 (pk #$in:not-ok)
1222 (mkdir #$output)
1223 (chdir #$output)
1224 (symlink #$output "self")
1225 (symlink #$in:ok "ok"))
1226 #:allowed-references
1227 (list "out"
1228 (gexp-input in "ok")))))
1229 (built-derivations (list drv))))
1230
c8351d9a
LC
1231(test-assert "gexp->derivation #:allowed-references, disallowed"
1232 (let ((drv (run-with-store %store
1233 (gexp->derivation "allowed-refs"
1234 #~(begin
1235 (mkdir #$output)
1236 (chdir #$output)
1237 (symlink #$%bootstrap-guile "guile"))
1238 #:allowed-references '()))))
f9e8a123 1239 (guard (c ((store-protocol-error? c) #t))
c8351d9a
LC
1240 (build-derivations %store (list drv))
1241 #f)))
1242
3f4ecf32
LC
1243(test-assertm "gexp->derivation #:disallowed-references, allowed"
1244 (mlet %store-monad ((drv (gexp->derivation "disallowed-refs"
1245 #~(begin
1246 (mkdir #$output)
1247 (chdir #$output)
1248 (symlink #$output "self")
1249 (symlink #$%bootstrap-guile
1250 "guile"))
1251 #:disallowed-references '())))
1252 (built-derivations (list drv))))
1253
1254
1255(test-assert "gexp->derivation #:disallowed-references"
1256 (let ((drv (run-with-store %store
1257 (gexp->derivation "disallowed-refs"
1258 #~(begin
1259 (mkdir #$output)
1260 (chdir #$output)
1261 (symlink #$%bootstrap-guile "guile"))
1262 #:disallowed-references (list %bootstrap-guile)))))
f9e8a123 1263 (guard (c ((store-protocol-error? c) #t))
3f4ecf32
LC
1264 (build-derivations %store (list drv))
1265 #f)))
1266
c17b5ab4 1267(define shebang
c1bc358f 1268 (string-append "#!" (derivation->output-path (%guile-for-build))
c17b5ab4
LC
1269 "/bin/guile --no-auto-compile"))
1270
1271;; If we're going to hit the silly shebang limit (128 chars on Linux-based
1272;; systems), then skip the following test.
47b3124a 1273(test-skip (if (> (string-length shebang) 127) 2 0))
c17b5ab4 1274
21b679f6
LC
1275(test-assertm "gexp->script"
1276 (mlet* %store-monad ((n -> (random (expt 2 50)))
1277 (exp -> (gexp
1278 (system*
1279 (string-append (ungexp %bootstrap-guile)
1280 "/bin/guile")
1281 "-c" (object->string
1282 '(display (expt (ungexp n) 2))))))
1283 (drv (gexp->script "guile-thing" exp
1284 #:guile %bootstrap-guile))
1285 (out -> (derivation->output-path drv))
1286 (done (built-derivations (list drv))))
1287 (let* ((pipe (open-input-pipe out))
1288 (str (get-string-all pipe)))
1289 (return (and (zero? (close-pipe pipe))
1290 (= (expt n 2) (string->number str)))))))
1291
92bcccc5 1292(test-assert "gexp->script #:module-path"
1ae16033
LC
1293 (call-with-temporary-directory
1294 (lambda (directory)
1295 (define str
1296 "Fake (guix base32) module!")
1297
1298 (mkdir (string-append directory "/guix"))
1299 (call-with-output-file (string-append directory "/guix/base32.scm")
1300 (lambda (port)
1301 (write `(begin (define-module (guix base32))
1302 (define-public %fake! ,str))
1303 port)))
1304
92bcccc5
LF
1305 (run-with-store %store
1306 (mlet* %store-monad ((exp -> (with-imported-modules '((guix base32))
1307 (gexp (begin
1308 (use-modules (guix base32))
1309 (write (list %load-path
1310 %fake!))))))
1311 (drv (gexp->script "guile-thing" exp
1312 #:guile %bootstrap-guile
1313 #:module-path (list directory)))
1314 (out -> (derivation->output-path drv))
1315 (done (built-derivations (list drv))))
1316 (let* ((pipe (open-input-pipe out))
1317 (data (read pipe)))
1318 (return (and (zero? (close-pipe pipe))
1319 (match data
1320 ((load-path str*)
1321 (and (string=? str* str)
1322 (not (member directory load-path)))))))))))))
1ae16033 1323
15a01c72
LC
1324(test-assertm "program-file"
1325 (let* ((n (random (expt 2 50)))
0bb9929e
LC
1326 (exp (with-imported-modules '((guix build utils))
1327 (gexp (begin
1328 (use-modules (guix build utils))
1329 (display (ungexp n))))))
15a01c72 1330 (file (program-file "program" exp
15a01c72
LC
1331 #:guile %bootstrap-guile)))
1332 (mlet* %store-monad ((drv (lower-object file))
1333 (out -> (derivation->output-path drv)))
1334 (mbegin %store-monad
1335 (built-derivations (list drv))
1336 (let* ((pipe (open-input-pipe out))
1337 (str (get-string-all pipe)))
1338 (return (and (zero? (close-pipe pipe))
1339 (= n (string->number str)))))))))
1340
92bcccc5 1341(test-assert "program-file #:module-path"
427ec19e
LC
1342 (call-with-temporary-directory
1343 (lambda (directory)
1344 (define text (random-text))
1345
1346 (call-with-output-file (string-append directory "/stupid-module.scm")
1347 (lambda (port)
1348 (write `(begin (define-module (stupid-module))
1349 (define-public %stupid-thing ,text))
1350 port)))
1351
1352 (let* ((exp (with-imported-modules '((stupid-module))
1353 (gexp (begin
1354 (use-modules (stupid-module))
1355 (display %stupid-thing)))))
1356 (file (program-file "program" exp
1357 #:guile %bootstrap-guile
1358 #:module-path (list directory))))
92bcccc5
LF
1359 (run-with-store %store
1360 (mlet* %store-monad ((drv (lower-object file))
1361 (out -> (derivation->output-path drv)))
1362 (mbegin %store-monad
1363 (built-derivations (list drv))
1364 (let* ((pipe (open-input-pipe out))
1365 (str (get-string-all pipe)))
1366 (return (and (zero? (close-pipe pipe))
1367 (string=? text str)))))))))))
427ec19e 1368
838e17d8
LC
1369(test-assertm "program-file & with-extensions"
1370 (let* ((exp (with-extensions (list %extension-package)
1371 (gexp (begin
1372 (use-modules (hg2g))
1373 (display the-answer)))))
1374 (file (program-file "program" exp
1375 #:guile %bootstrap-guile)))
1376 (mlet* %store-monad ((drv (lower-object file))
1377 (out -> (derivation->output-path drv)))
1378 (mbegin %store-monad
1379 (built-derivations (list drv))
1380 (let* ((pipe (open-input-pipe out))
1381 (str (get-string-all pipe)))
1382 (return (and (zero? (close-pipe pipe))
1383 (= 42 (string->number str)))))))))
1384
2e8cabb8
LC
1385(test-assertm "program-file #:system"
1386 (let* ((exp (with-imported-modules '((guix build utils))
1387 (gexp (begin
1388 (use-modules (guix build utils))
1389 (display "hi!")))))
1390 (system (if (string=? (%current-system) "x86_64-linux")
1391 "armhf-linux"
1392 "x86_64-linux"))
1393 (file (program-file "program" exp)))
1394 (mlet %store-monad ((drv (lower-object file system)))
1395 (return (and (string=? (derivation-system drv) system)
1396 (find (lambda (input)
1397 (let ((drv (pk (derivation-input-derivation input))))
1398 (and (string=? (derivation-name drv)
1399 "module-import-compiled")
1400 (string=? (derivation-system drv)
1401 system))))
1402 (derivation-inputs drv)))))))
1403
e1c153e0
LC
1404(test-assertm "scheme-file"
1405 (let* ((text (plain-file "foo" "Hello, world!"))
1406 (scheme (scheme-file "bar" #~(list "foo" #$text))))
1407 (mlet* %store-monad ((drv (lower-object scheme))
1408 (text (lower-object text))
1409 (out -> (derivation->output-path drv)))
1410 (mbegin %store-monad
1411 (built-derivations (list drv))
e74f64b9 1412 (mlet %store-monad ((refs (references* out)))
e1c153e0
LC
1413 (return (and (equal? refs (list text))
1414 (equal? `(list "foo" ,text)
1415 (call-with-input-file out read)))))))))
1416
d63ee94d
LC
1417(test-assertm "raw-derivation-file"
1418 (let* ((exp #~(let ((drv #$(raw-derivation-file coreutils)))
1419 (when (file-exists? drv)
1420 (symlink drv #$output)))))
1421 (mlet* %store-monad ((dep (lower-object coreutils))
1422 (drv (gexp->derivation "drv-ref" exp))
1423 (out -> (derivation->output-path drv)))
1424 (mbegin %store-monad
1425 (built-derivations (list drv))
1426 (mlet %store-monad ((refs (references* out)))
1427 (return (and (member (derivation-file-name dep)
1428 (derivation-sources drv))
1429 (not (member (derivation-file-name dep)
1430 (map derivation-input-path
1431 (derivation-inputs drv))))
1432 (equal? (readlink out) (derivation-file-name dep))
1433 (equal? refs (list (derivation-file-name dep))))))))))
1434
462a3fa3 1435(test-assert "text-file*"
e74f64b9
LC
1436 (run-with-store %store
1437 (mlet* %store-monad
1438 ((drv (package->derivation %bootstrap-guile))
1439 (guile -> (derivation->output-path drv))
1440 (file (text-file "bar" "This is bar."))
1441 (text (text-file* "foo"
1442 %bootstrap-guile "/bin/guile "
1443 (gexp-input %bootstrap-guile "out") "/bin/guile "
1444 drv "/bin/guile "
1445 file))
1446 (done (built-derivations (list text)))
1447 (out -> (derivation->output-path text))
1448 (refs (references* out)))
1449 ;; Make sure we get the right references and the right content.
1450 (return (and (lset= string=? refs (list guile file))
1451 (equal? (call-with-input-file out get-string-all)
1452 (string-append guile "/bin/guile "
1453 guile "/bin/guile "
1454 guile "/bin/guile "
1455 file)))))
1456 #:guile-for-build (package-derivation %store %bootstrap-guile)))
462a3fa3 1457
b751cde3
LC
1458(test-assertm "mixed-text-file"
1459 (mlet* %store-monad ((file -> (mixed-text-file "mixed"
bc1ad696 1460 #:guile %bootstrap-guile
b751cde3
LC
1461 "export PATH="
1462 %bootstrap-guile "/bin"))
1463 (drv (lower-object file))
1464 (out -> (derivation->output-path drv))
1465 (guile-drv (package->derivation %bootstrap-guile))
1466 (guile -> (derivation->output-path guile-drv)))
1467 (mbegin %store-monad
1468 (built-derivations (list drv))
e74f64b9 1469 (mlet %store-monad ((refs (references* out)))
b751cde3
LC
1470 (return (and (string=? (string-append "export PATH=" guile "/bin")
1471 (call-with-input-file out get-string-all))
1472 (equal? refs (list guile))))))))
1473
5dec93bb
LC
1474(test-assertm "file-union"
1475 (mlet* %store-monad ((union -> (file-union "union"
1476 `(("a" ,(plain-file "a" "1"))
1477 ("b/c/d" ,(plain-file "d" "2"))
bc1ad696
LC
1478 ("e" ,(plain-file "e" "3")))
1479 #:guile %bootstrap-guile))
5dec93bb
LC
1480 (drv (lower-object union))
1481 (out -> (derivation->output-path drv)))
1482 (define (contents=? file str)
1483 (string=? (call-with-input-file (string-append out "/" file)
1484 get-string-all)
1485 str))
1486
1487 (mbegin %store-monad
1488 (built-derivations (list drv))
1489 (return (and (contents=? "a" "1")
1490 (contents=? "b/c/d" "2")
1491 (contents=? "e" "3"))))))
1492
a8afb9ae
LC
1493(test-assert "gexp->derivation vs. %current-target-system"
1494 (let ((mval (gexp->derivation "foo"
1495 #~(begin
1496 (mkdir #$output)
1497 (foo #+gnu-make))
1498 #:target #f)))
1499 ;; The value of %CURRENT-TARGET-SYSTEM at bind-time should have no
1500 ;; influence.
1501 (parameterize ((%current-target-system "fooooo"))
1502 (derivation? (run-with-store %store mval)))))
1503
c2b84676
LC
1504(test-assertm "lower-object"
1505 (mlet %store-monad ((drv1 (lower-object %bootstrap-guile))
1506 (drv2 (lower-object (package-source coreutils)))
1507 (item (lower-object (plain-file "foo" "Hello!"))))
1508 (return (and (derivation? drv1) (derivation? drv2)
1509 (store-path? item)))))
1510
91937029
LC
1511(test-assertm "lower-object, computed-file"
1512 (let* ((text (plain-file "foo" "Hello!"))
1513 (exp #~(begin
1514 (mkdir #$output)
1515 (symlink #$%bootstrap-guile
1516 (string-append #$output "/guile"))
1517 (symlink #$text (string-append #$output "/text"))))
bc1ad696
LC
1518 (computed (computed-file "computed" exp
1519 #:guile %bootstrap-guile)))
91937029
LC
1520 (mlet* %store-monad ((text (lower-object text))
1521 (guile-drv (lower-object %bootstrap-guile))
1522 (comp-drv (lower-object computed))
1523 (comp -> (derivation->output-path comp-drv)))
1524 (mbegin %store-monad
1525 (built-derivations (list comp-drv))
1526 (return (and (string=? (readlink (string-append comp "/guile"))
1527 (derivation->output-path guile-drv))
1528 (string=? (readlink (string-append comp "/text"))
1529 text)))))))
1530
df46bef4
LC
1531(test-assert "lower-object, computed-file + grafts"
1532 ;; The reference graph should refer to grafted packages when grafts are
1533 ;; enabled. See <https://issues.guix.gnu.org/50676>.
1534 (let* ((base (package
1535 (inherit (dummy-package "trivial"))
1536 (build-system trivial-build-system)
1537 (arguments
1538 `(#:guile ,%bootstrap-guile
1539 #:builder (mkdir %output)))))
1540 (pkg (package
1541 (inherit base)
1542 (version "1.1")
1543 (replacement (package
1544 (inherit base)
1545 (version "9.9")))))
1546 (exp #~(begin
1547 (use-modules (ice-9 rdelim))
1548 (let ((item (call-with-input-file "graph" read-line)))
1549 (call-with-output-file #$output
1550 (lambda (port)
1551 (display item port))))))
1552 (computed (computed-file "computed" exp
1553 #:options
bc1ad696
LC
1554 `(#:references-graphs (("graph" ,pkg)))
1555 #:guile %bootstrap-guile))
df46bef4
LC
1556 (drv0 (package-derivation %store pkg #:graft? #t))
1557 (drv1 (parameterize ((%graft? #t))
1558 (run-with-store %store
1559 (lower-object computed)))))
1560 (build-derivations %store (list drv1))
1561
1562 ;; The graph obtained in COMPUTED should refer to the grafted version of
1563 ;; PKG, not to PKG itself.
1564 (string=? (call-with-input-file (derivation->output-path drv1)
1565 get-string-all)
1566 (derivation->output-path drv0))))
1567
9ec154f5
LC
1568(test-equal "lower-object, computed-file, #:system"
1569 '("mips64el-linux")
1570 (run-with-store %store
1571 (let* ((exp #~(symlink #$coreutils #$output))
1572 (computed (computed-file "computed" exp
1573 #:guile %bootstrap-guile)))
1574 ;; Make sure that the SYSTEM argument to 'lower-object' is honored.
1575 (mlet* %store-monad ((drv (lower-object computed "mips64el-linux"))
1576 (refs (references* (derivation-file-name drv))))
1577 (return (delete-duplicates
1578 (filter-map (lambda (file)
1579 (and (string-suffix? ".drv" file)
1580 (let ((drv (read-derivation-from-file
1581 file)))
1582 (derivation-system drv))))
1583 (cons (derivation-file-name drv)
1584 refs))))))))
1585
7f6dd3be
LC
1586(test-assertm "lower-object, computed-file, #:target"
1587 (let* ((target "i586-pc-gnu")
1588 (computed (computed-file "computed-cross"
1589 #~(symlink #$coreutils output)
1590 #:guile (default-guile))))
1591 ;; When lowered to TARGET, the derivation of COMPUTED should run natively,
1592 ;; using a native Guile, but it should refer to the target COREUTILS.
1593 (mlet* %store-monad ((drv (lower-object computed (%current-system)
1594 #:target target))
1595 (refs (references* (derivation-file-name drv)))
1596 (guile (lower-object (default-guile)
1597 (%current-system)
1598 #:target #f))
1599 (cross (lower-object coreutils #:target target))
1600 (native (lower-object coreutils #:target #f)))
1601 (return (and (string=? (derivation-system (pk 'drv drv)) (%current-system))
1602 (string=? (derivation-builder drv)
1603 (string-append (derivation->output-path guile)
1604 "/bin/guile"))
1605 (not (member (derivation-file-name native) refs))
1606 (member (derivation-file-name cross) refs))))))
1607
774f8804
LC
1608(test-assertm "references-file"
1609 (let* ((exp #~(symlink #$%bootstrap-guile #$output))
1610 (computed (computed-file "computed" exp
1611 #:guile %bootstrap-guile))
1612 (refs (references-file computed "refs"
1613 #:guile %bootstrap-guile)))
1614 (mlet* %store-monad ((drv0 (lower-object %bootstrap-guile))
1615 (drv1 (lower-object computed))
1616 (drv2 (lower-object refs)))
1617 (mbegin %store-monad
1618 (built-derivations (list drv2))
1619 (mlet %store-monad ((refs ((store-lift requisites)
1620 (list (derivation->output-path drv1)))))
1621 (return (lset= string=?
1622 (call-with-input-file (derivation->output-path drv2)
1623 read)
1624 refs)))))))
1625
3e43166f
LC
1626(test-assert "lower-object & gexp-input-error?"
1627 (guard (c ((gexp-input-error? c)
1628 (gexp-error-invalid-input c)))
1629 (run-with-store %store
1630 (lower-object (current-module))
1631 #:guile-for-build (%guile-for-build))))
1632
2cf0ea0d
LC
1633(test-assert "printer"
1634 (string-match "^#<gexp \\(string-append .*#<package coreutils.*\
18fc84bc 1635 \"/bin/uname\"\\) [[:graph:]]+tests/gexp\\.scm:[0-9]+:[0-9]+ [[:xdigit:]]+>$"
2cf0ea0d
LC
1636 (with-output-to-string
1637 (lambda ()
1638 (write
1639 (gexp (string-append (ungexp coreutils)
1640 "/bin/uname")))))))
1641
1642(test-assert "printer vs. ungexp-splicing"
1643 (string-match "^#<gexp .* [[:xdigit:]]+>$"
1644 (with-output-to-string
1645 (lambda ()
1646 ;; #~(begin #$@#~())
1647 (write
1648 (gexp (begin (ungexp-splicing (gexp ())))))))))
1649
21b679f6
LC
1650(test-equal "sugar"
1651 '(gexp (foo (ungexp bar) (ungexp baz "out")
1652 (ungexp (chbouib 42))
667b2508
LC
1653 (ungexp-splicing (list x y z))
1654 (ungexp-native foo) (ungexp-native foo "out")
1655 (ungexp-native (chbouib 42))
1656 (ungexp-native-splicing (list x y z))))
1657 '#~(foo #$bar #$baz:out #$(chbouib 42) #$@(list x y z)
1658 #+foo #+foo:out #+(chbouib 42) #+@(list x y z)))
21b679f6 1659
9a2f99f4
MO
1660(test-assertm "gexp->file, cross-compilation"
1661 (mlet* %store-monad ((target -> "aarch64-linux-gnu")
1662 (exp -> (gexp (list (ungexp coreutils))))
1663 (xdrv (gexp->file "foo" exp #:target target))
1664 (refs (references*
1665 (derivation-file-name xdrv)))
1666 (xcu (package->cross-derivation coreutils
1667 target))
1668 (cu (package->derivation coreutils)))
1669 (return (and (member (derivation-file-name xcu) refs)
1670 (not (member (derivation-file-name cu) refs))))))
1671
1672(test-assertm "gexp->file, cross-compilation with default target"
1673 (mlet* %store-monad ((target -> "aarch64-linux-gnu")
1674 (_ (set-current-target target))
1675 (exp -> (gexp (list (ungexp coreutils))))
1676 (xdrv (gexp->file "foo" exp))
1677 (refs (references*
1678 (derivation-file-name xdrv)))
1679 (xcu (package->cross-derivation coreutils
1680 target))
1681 (cu (package->derivation coreutils)))
1682 (return (and (member (derivation-file-name xcu) refs)
1683 (not (member (derivation-file-name cu) refs))))))
1684
1685(test-assertm "gexp->script, cross-compilation"
1686 (mlet* %store-monad ((target -> "aarch64-linux-gnu")
1687 (exp -> (gexp (list (ungexp coreutils))))
1688 (xdrv (gexp->script "foo" exp #:target target))
1689 (refs (references*
1690 (derivation-file-name xdrv)))
1691 (xcu (package->cross-derivation coreutils
1692 target))
1693 (cu (package->derivation coreutils)))
1694 (return (and (member (derivation-file-name xcu) refs)
1695 (not (member (derivation-file-name cu) refs))))))
1696
1697(test-assertm "gexp->script, cross-compilation with default target"
1698 (mlet* %store-monad ((target -> "aarch64-linux-gnu")
1699 (_ (set-current-target target))
1700 (exp -> (gexp (list (ungexp coreutils))))
1701 (xdrv (gexp->script "foo" exp))
1702 (refs (references*
1703 (derivation-file-name xdrv)))
1704 (xcu (package->cross-derivation coreutils
1705 target))
1706 (cu (package->derivation coreutils)))
1707 (return (and (member (derivation-file-name xcu) refs)
1708 (not (member (derivation-file-name cu) refs))))))
1709
21b679f6
LC
1710(test-end "gexp")
1711
21b679f6
LC
1712;; Local Variables:
1713;; eval: (put 'test-assertm 'scheme-indent-function 1)
1714;; End: