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