You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1185 lines
56 KiB

  1. ;;; GNU Guix --- Functional package management for GNU
  2. ;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018 Ludovic Courtès <ludo@gnu.org>
  3. ;;;
  4. ;;; This file is part of GNU Guix.
  5. ;;;
  6. ;;; GNU Guix is free software; you can redistribute it and/or modify it
  7. ;;; under the terms of the GNU General Public License as published by
  8. ;;; the Free Software Foundation; either version 3 of the License, or (at
  9. ;;; your option) any later version.
  10. ;;;
  11. ;;; GNU Guix is distributed in the hope that it will be useful, but
  12. ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. ;;; GNU General Public License for more details.
  15. ;;;
  16. ;;; You should have received a copy of the GNU General Public License
  17. ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
  18. (unsetenv "http_proxy")
  19. (define-module (test-derivations)
  20. #:use-module (guix derivations)
  21. #:use-module (guix grafts)
  22. #:use-module (guix store)
  23. #:use-module (guix utils)
  24. #:use-module (gcrypt hash)
  25. #:use-module (guix base32)
  26. #:use-module (guix tests)
  27. #:use-module (guix tests http)
  28. #:use-module ((guix packages) #:select (package-derivation base32))
  29. #:use-module ((guix build utils) #:select (executable-file?))
  30. #:use-module ((gnu packages) #:select (search-bootstrap-binary))
  31. #:use-module (gnu packages bootstrap)
  32. #:use-module ((gnu packages guile) #:select (guile-1.8))
  33. #:use-module (srfi srfi-1)
  34. #:use-module (srfi srfi-11)
  35. #:use-module (srfi srfi-26)
  36. #:use-module (srfi srfi-34)
  37. #:use-module (srfi srfi-64)
  38. #:use-module (rnrs io ports)
  39. #:use-module (rnrs bytevectors)
  40. #:use-module (web uri)
  41. #:use-module (ice-9 rdelim)
  42. #:use-module (ice-9 regex)
  43. #:use-module (ice-9 ftw)
  44. #:use-module (ice-9 match))
  45. (define %store
  46. (open-connection-for-tests))
  47. ;; Globally disable grafts because they can trigger early builds.
  48. (%graft? #f)
  49. (define (bootstrap-binary name)
  50. (let ((bin (search-bootstrap-binary name (%current-system))))
  51. (and %store
  52. (add-to-store %store name #t "sha256" bin))))
  53. (define %bash
  54. (bootstrap-binary "bash"))
  55. (define %mkdir
  56. (bootstrap-binary "mkdir"))
  57. (define* (directory-contents dir #:optional (slurp get-bytevector-all))
  58. "Return an alist representing the contents of DIR."
  59. (define prefix-len (string-length dir))
  60. (sort (file-system-fold (const #t) ; enter?
  61. (lambda (path stat result) ; leaf
  62. (alist-cons (string-drop path prefix-len)
  63. (call-with-input-file path slurp)
  64. result))
  65. (lambda (path stat result) result) ; down
  66. (lambda (path stat result) result) ; up
  67. (lambda (path stat result) result) ; skip
  68. (lambda (path stat errno result) result) ; error
  69. '()
  70. dir)
  71. (lambda (e1 e2)
  72. (string<? (car e1) (car e2)))))
  73. ;; Avoid collisions with other tests.
  74. (%http-server-port 10500)
  75. (test-begin "derivations")
  76. (test-assert "parse & export"
  77. (let* ((f (search-path %load-path "tests/test.drv"))
  78. (b1 (call-with-input-file f get-bytevector-all))
  79. (d1 (read-derivation (open-bytevector-input-port b1)))
  80. (b2 (call-with-bytevector-output-port (cut write-derivation d1 <>)))
  81. (d2 (read-derivation (open-bytevector-input-port b2))))
  82. (and (equal? b1 b2)
  83. (equal? d1 d2))))
  84. (test-skip (if %store 0 12))
  85. (test-assert "add-to-store, flat"
  86. ;; Use 'readlink*' in case spec.scm is a symlink, as is the case when Guile
  87. ;; was installed with Stow.
  88. (let* ((file (readlink*
  89. (search-path %load-path "language/tree-il/spec.scm")))
  90. (drv (add-to-store %store "flat-test" #f "sha256" file)))
  91. (and (eq? 'regular (stat:type (stat drv)))
  92. (valid-path? %store drv)
  93. (equal? (call-with-input-file file get-bytevector-all)
  94. (call-with-input-file drv get-bytevector-all)))))
  95. (test-assert "add-to-store, recursive"
  96. (let* ((dir (dirname
  97. (readlink* (search-path %load-path
  98. "language/tree-il/spec.scm"))))
  99. (drv (add-to-store %store "dir-tree-test" #t "sha256" dir)))
  100. (and (eq? 'directory (stat:type (stat drv)))
  101. (valid-path? %store drv)
  102. (equal? (directory-contents dir)
  103. (directory-contents drv)))))
  104. (test-assert "derivation with no inputs"
  105. (let* ((builder (add-text-to-store %store "my-builder.sh"
  106. "echo hello, world\n"
  107. '()))
  108. (drv (derivation %store "foo"
  109. %bash `("-e" ,builder)
  110. #:env-vars '(("HOME" . "/homeless")))))
  111. (and (store-path? (derivation-file-name drv))
  112. (valid-path? %store (derivation-file-name drv)))))
  113. (test-assert "build derivation with 1 source"
  114. (let* ((builder (add-text-to-store %store "my-builder.sh"
  115. "echo hello, world > \"$out\"\n"
  116. '()))
  117. (drv (derivation %store "foo"
  118. %bash `(,builder)
  119. #:env-vars '(("HOME" . "/homeless")
  120. ("zzz" . "Z!")
  121. ("AAA" . "A!"))
  122. #:inputs `((,%bash) (,builder))))
  123. (succeeded?
  124. (build-derivations %store (list drv))))
  125. (and succeeded?
  126. (let ((path (derivation->output-path drv)))
  127. (and (valid-path? %store path)
  128. (string=? (call-with-input-file path read-line)
  129. "hello, world"))))))
  130. (test-assert "derivation with local file as input"
  131. (let* ((builder (add-text-to-store
  132. %store "my-builder.sh"
  133. "(while read line ; do echo \"$line\" ; done) < $in > $out"
  134. '()))
  135. (input (search-path %load-path "ice-9/boot-9.scm"))
  136. (input* (add-to-store %store (basename input)
  137. #t "sha256" input))
  138. (drv (derivation %store "derivation-with-input-file"
  139. %bash `(,builder)
  140. ;; Cheat to pass the actual file name to the
  141. ;; builder.
  142. #:env-vars `(("in" . ,input*))
  143. #:inputs `((,%bash)
  144. (,builder)
  145. (,input))))) ; ← local file name
  146. (and (build-derivations %store (list drv))
  147. ;; Note: we can't compare the files because the above trick alters
  148. ;; the contents.
  149. (valid-path? %store (derivation->output-path drv)))))
  150. (test-assert "derivation fails but keep going"
  151. ;; In keep-going mode, 'build-derivations' should fail because of D1, but it
  152. ;; must return only after D2 has succeeded.
  153. (with-store store
  154. (let* ((d1 (derivation %store "fails"
  155. %bash `("-c" "false")
  156. #:inputs `((,%bash))))
  157. (d2 (build-expression->derivation %store "sleep-then-succeed"
  158. `(begin
  159. ,(random-text)
  160. ;; XXX: Hopefully that's long
  161. ;; enough that D1 has already
  162. ;; failed.
  163. (sleep 2)
  164. (mkdir %output)))))
  165. (set-build-options %store
  166. #:use-substitutes? #f
  167. #:keep-going? #t)
  168. (guard (c ((nix-protocol-error? c)
  169. (and (= 100 (nix-protocol-error-status c))
  170. (string-contains (nix-protocol-error-message c)
  171. (derivation-file-name d1))
  172. (not (valid-path? %store (derivation->output-path d1)))
  173. (valid-path? %store (derivation->output-path d2)))))
  174. (build-derivations %store (list d1 d2))
  175. #f))))
  176. (test-assert "identical files are deduplicated"
  177. (let* ((build1 (add-text-to-store %store "one.sh"
  178. "echo hello, world > \"$out\"\n"
  179. '()))
  180. (build2 (add-text-to-store %store "two.sh"
  181. "# Hey!\necho hello, world > \"$out\"\n"
  182. '()))
  183. (drv1 (derivation %store "foo"
  184. %bash `(,build1)
  185. #:inputs `((,%bash) (,build1))))
  186. (drv2 (derivation %store "bar"
  187. %bash `(,build2)
  188. #:inputs `((,%bash) (,build2)))))
  189. (and (build-derivations %store (list drv1 drv2))
  190. (let ((file1 (derivation->output-path drv1))
  191. (file2 (derivation->output-path drv2)))
  192. (and (valid-path? %store file1) (valid-path? %store file2)
  193. (string=? (call-with-input-file file1 get-string-all)
  194. "hello, world\n")
  195. (= (stat:ino (lstat file1))
  196. (stat:ino (lstat file2))))))))
  197. (test-equal "built-in-builders"
  198. '("download")
  199. (built-in-builders %store))
  200. (test-assert "unknown built-in builder"
  201. (let ((drv (derivation %store "ohoh" "builtin:does-not-exist" '())))
  202. (guard (c ((nix-protocol-error? c)
  203. (string-contains (nix-protocol-error-message c) "failed")))
  204. (build-derivations %store (list drv))
  205. #f)))
  206. (unless (http-server-can-listen?)
  207. (test-skip 1))
  208. (test-assert "'download' built-in builder"
  209. (let ((text (random-text)))
  210. (with-http-server 200 text
  211. (let* ((drv (derivation %store "world"
  212. "builtin:download" '()
  213. #:env-vars `(("url"
  214. . ,(object->string (%local-url))))
  215. #:hash-algo 'sha256
  216. #:hash (sha256 (string->utf8 text)))))
  217. (and (build-derivations %store (list drv))
  218. (string=? (call-with-input-file (derivation->output-path drv)
  219. get-string-all)
  220. text))))))
  221. (unless (http-server-can-listen?)
  222. (test-skip 1))
  223. (test-assert "'download' built-in builder, invalid hash"
  224. (with-http-server 200 "hello, world!"
  225. (let* ((drv (derivation %store "world"
  226. "builtin:download" '()
  227. #:env-vars `(("url"
  228. . ,(object->string (%local-url))))
  229. #:hash-algo 'sha256
  230. #:hash (sha256 (random-bytevector 100))))) ;wrong
  231. (guard (c ((nix-protocol-error? c)
  232. (string-contains (nix-protocol-error-message c) "failed")))
  233. (build-derivations %store (list drv))
  234. #f))))
  235. (unless (http-server-can-listen?)
  236. (test-skip 1))
  237. (test-assert "'download' built-in builder, not found"
  238. (with-http-server 404 "not found"
  239. (let* ((drv (derivation %store "will-never-be-found"
  240. "builtin:download" '()
  241. #:env-vars `(("url"
  242. . ,(object->string (%local-url))))
  243. #:hash-algo 'sha256
  244. #:hash (sha256 (random-bytevector 100)))))
  245. (guard (c ((nix-protocol-error? c)
  246. (string-contains (nix-protocol-error-message (pk c)) "failed")))
  247. (build-derivations %store (list drv))
  248. #f))))
  249. (test-assert "'download' built-in builder, not fixed-output"
  250. (let* ((source (add-text-to-store %store "hello" "hi!"))
  251. (url (string-append "file://" source))
  252. (drv (derivation %store "world"
  253. "builtin:download" '()
  254. #:env-vars `(("url" . ,(object->string url))))))
  255. (guard (c ((nix-protocol-error? c)
  256. (string-contains (nix-protocol-error-message c) "failed")))
  257. (build-derivations %store (list drv))
  258. #f)))
  259. (unless (http-server-can-listen?)
  260. (test-skip 1))
  261. (test-assert "'download' built-in builder, check mode"
  262. ;; Make sure rebuilding the 'builtin:download' derivation in check mode
  263. ;; works. See <http://bugs.gnu.org/25089>.
  264. (let* ((text (random-text))
  265. (drv (derivation %store "world"
  266. "builtin:download" '()
  267. #:env-vars `(("url"
  268. . ,(object->string (%local-url))))
  269. #:hash-algo 'sha256
  270. #:hash (sha256 (string->utf8 text)))))
  271. (and (with-http-server 200 text
  272. (build-derivations %store (list drv)))
  273. (with-http-server 200 text
  274. (build-derivations %store (list drv)
  275. (build-mode check)))
  276. (string=? (call-with-input-file (derivation->output-path drv)
  277. get-string-all)
  278. text))))
  279. (test-equal "derivation-name"
  280. "foo-0.0"
  281. (let ((drv (derivation %store "foo-0.0" %bash '())))
  282. (derivation-name drv)))
  283. (test-equal "derivation-output-names"
  284. '(("out") ("bar" "chbouib"))
  285. (let ((drv1 (derivation %store "foo-0.0" %bash '()))
  286. (drv2 (derivation %store "foo-0.0" %bash '()
  287. #:outputs '("bar" "chbouib"))))
  288. (list (derivation-output-names drv1)
  289. (derivation-output-names drv2))))
  290. (test-assert "offloadable-derivation?"
  291. (and (offloadable-derivation? (derivation %store "foo" %bash '()))
  292. (offloadable-derivation? ;see <http://bugs.gnu.org/18747>
  293. (derivation %store "foo" %bash '()
  294. #:substitutable? #f))
  295. (not (offloadable-derivation?
  296. (derivation %store "foo" %bash '()
  297. #:local-build? #t)))))
  298. (test-assert "substitutable-derivation?"
  299. (and (substitutable-derivation? (derivation %store "foo" %bash '()))
  300. (substitutable-derivation? ;see <http://bugs.gnu.org/18747>
  301. (derivation %store "foo" %bash '()
  302. #:local-build? #t))
  303. (not (substitutable-derivation?
  304. (derivation %store "foo" %bash '()
  305. #:substitutable? #f)))))
  306. (test-assert "fixed-output-derivation?"
  307. (let* ((builder (add-text-to-store %store "my-fixed-builder.sh"
  308. "echo -n hello > $out" '()))
  309. (hash (sha256 (string->utf8 "hello")))
  310. (drv (derivation %store "fixed"
  311. %bash `(,builder)
  312. #:inputs `((,builder))
  313. #:hash hash #:hash-algo 'sha256)))
  314. (fixed-output-derivation? drv)))
  315. (test-assert "fixed-output derivation"
  316. (let* ((builder (add-text-to-store %store "my-fixed-builder.sh"
  317. "echo -n hello > $out" '()))
  318. (hash (sha256 (string->utf8 "hello")))
  319. (drv (derivation %store "fixed"
  320. %bash `(,builder)
  321. #:inputs `((,builder)) ; optional
  322. #:hash hash #:hash-algo 'sha256))
  323. (succeeded? (build-derivations %store (list drv))))
  324. (and succeeded?
  325. (let ((p (derivation->output-path drv)))
  326. (and (equal? (string->utf8 "hello")
  327. (call-with-input-file p get-bytevector-all))
  328. (bytevector? (query-path-hash %store p)))))))
  329. (test-assert "fixed-output derivation: output paths are equal"
  330. (let* ((builder1 (add-text-to-store %store "fixed-builder1.sh"
  331. "echo -n hello > $out" '()))
  332. (builder2 (add-text-to-store %store "fixed-builder2.sh"
  333. "echo hey; echo -n hello > $out" '()))
  334. (hash (sha256 (string->utf8 "hello")))
  335. (drv1 (derivation %store "fixed"
  336. %bash `(,builder1)
  337. #:hash hash #:hash-algo 'sha256))
  338. (drv2 (derivation %store "fixed"
  339. %bash `(,builder2)
  340. #:hash hash #:hash-algo 'sha256))
  341. (succeeded? (build-derivations %store (list drv1 drv2))))
  342. (and succeeded?
  343. (equal? (derivation->output-path drv1)
  344. (derivation->output-path drv2)))))
  345. (test-assert "fixed-output derivation, recursive"
  346. (let* ((builder (add-text-to-store %store "my-fixed-builder.sh"
  347. "echo -n hello > $out" '()))
  348. (hash (sha256 (string->utf8 "hello")))
  349. (drv (derivation %store "fixed-rec"
  350. %bash `(,builder)
  351. #:inputs `((,builder))
  352. #:hash (base32 "0sg9f58l1jj88w6pdrfdpj5x9b1zrwszk84j81zvby36q9whhhqa")
  353. #:hash-algo 'sha256
  354. #:recursive? #t))
  355. (succeeded? (build-derivations %store (list drv))))
  356. (and succeeded?
  357. (let ((p (derivation->output-path drv)))
  358. (and (equal? (string->utf8 "hello")
  359. (call-with-input-file p get-bytevector-all))
  360. (bytevector? (query-path-hash %store p)))))))
  361. (test-assert "derivation with a fixed-output input"
  362. ;; A derivation D using a fixed-output derivation F doesn't has the same
  363. ;; output path when passed F or F', as long as F and F' have the same output
  364. ;; path.
  365. (let* ((builder1 (add-text-to-store %store "fixed-builder1.sh"
  366. "echo -n hello > $out" '()))
  367. (builder2 (add-text-to-store %store "fixed-builder2.sh"
  368. "echo hey; echo -n hello > $out" '()))
  369. (hash (sha256 (string->utf8 "hello")))
  370. (fixed1 (derivation %store "fixed"
  371. %bash `(,builder1)
  372. #:hash hash #:hash-algo 'sha256))
  373. (fixed2 (derivation %store "fixed"
  374. %bash `(,builder2)
  375. #:hash hash #:hash-algo 'sha256))
  376. (fixed-out (derivation->output-path fixed1))
  377. (builder3 (add-text-to-store
  378. %store "final-builder.sh"
  379. ;; Use Bash hackery to avoid Coreutils.
  380. "echo $in ; (read -u 3 c; echo $c) 3< $in > $out" '()))
  381. (final1 (derivation %store "final"
  382. %bash `(,builder3)
  383. #:env-vars `(("in" . ,fixed-out))
  384. #:inputs `((,%bash) (,builder3) (,fixed1))))
  385. (final2 (derivation %store "final"
  386. %bash `(,builder3)
  387. #:env-vars `(("in" . ,fixed-out))
  388. #:inputs `((,%bash) (,builder3) (,fixed2))))
  389. (succeeded? (build-derivations %store
  390. (list final1 final2))))
  391. (and succeeded?
  392. (equal? (derivation->output-path final1)
  393. (derivation->output-path final2)))))
  394. (test-assert "multiple-output derivation"
  395. (let* ((builder (add-text-to-store %store "my-fixed-builder.sh"
  396. "echo one > $out ; echo two > $second"
  397. '()))
  398. (drv (derivation %store "fixed"
  399. %bash `(,builder)
  400. #:env-vars '(("HOME" . "/homeless")
  401. ("zzz" . "Z!")
  402. ("AAA" . "A!"))
  403. #:inputs `((,%bash) (,builder))
  404. #:outputs '("out" "second")))
  405. (succeeded? (build-derivations %store (list drv))))
  406. (and succeeded?
  407. (let ((one (derivation->output-path drv "out"))
  408. (two (derivation->output-path drv "second")))
  409. (and (lset= equal?
  410. (derivation->output-paths drv)
  411. `(("out" . ,one) ("second" . ,two)))
  412. (eq? 'one (call-with-input-file one read))
  413. (eq? 'two (call-with-input-file two read)))))))
  414. (test-assert "multiple-output derivation, non-alphabetic order"
  415. ;; Here, the outputs are not listed in alphabetic order. Yet, the store
  416. ;; path computation must reorder them first.
  417. (let* ((builder (add-text-to-store %store "my-fixed-builder.sh"
  418. "echo one > $out ; echo two > $AAA"
  419. '()))
  420. (drv (derivation %store "fixed"
  421. %bash `(,builder)
  422. #:inputs `((,%bash) (,builder))
  423. #:outputs '("out" "AAA")))
  424. (succeeded? (build-derivations %store (list drv))))
  425. (and succeeded?
  426. (let ((one (derivation->output-path drv "out"))
  427. (two (derivation->output-path drv "AAA")))
  428. (and (eq? 'one (call-with-input-file one read))
  429. (eq? 'two (call-with-input-file two read)))))))
  430. (test-assert "read-derivation vs. derivation"
  431. ;; Make sure 'derivation' and 'read-derivation' return objects that are
  432. ;; identical.
  433. (let* ((sources (unfold (cut >= <> 10)
  434. (lambda (n)
  435. (add-text-to-store %store
  436. (format #f "input~a" n)
  437. (random-text)))
  438. 1+
  439. 0))
  440. (inputs (map (lambda (file)
  441. (derivation %store "derivation-input"
  442. %bash '()
  443. #:inputs `((,%bash) (,file))))
  444. sources))
  445. (builder (add-text-to-store %store "builder.sh"
  446. "echo one > $one ; echo two > $two"
  447. '()))
  448. (drv (derivation %store "derivation"
  449. %bash `(,builder)
  450. #:inputs `((,%bash) (,builder)
  451. ,@(map list (append sources inputs)))
  452. #:outputs '("two" "one")))
  453. (drv* (call-with-input-file (derivation-file-name drv)
  454. read-derivation)))
  455. (equal? drv* drv)))
  456. (test-assert "multiple-output derivation, derivation-path->output-path"
  457. (let* ((builder (add-text-to-store %store "builder.sh"
  458. "echo one > $out ; echo two > $second"
  459. '()))
  460. (drv (derivation %store "multiple"
  461. %bash `(,builder)
  462. #:outputs '("out" "second")))
  463. (drv-file (derivation-file-name drv))
  464. (one (derivation->output-path drv "out"))
  465. (two (derivation->output-path drv "second"))
  466. (first (derivation-path->output-path drv-file "out"))
  467. (second (derivation-path->output-path drv-file "second")))
  468. (and (not (string=? one two))
  469. (string-suffix? "-second" two)
  470. (string=? first one)
  471. (string=? second two))))
  472. (test-assert "user of multiple-output derivation"
  473. ;; Check whether specifying several inputs coming from the same
  474. ;; multiple-output derivation works.
  475. (let* ((builder1 (add-text-to-store %store "my-mo-builder.sh"
  476. "echo one > $out ; echo two > $two"
  477. '()))
  478. (mdrv (derivation %store "multiple-output"
  479. %bash `(,builder1)
  480. #:inputs `((,%bash) (,builder1))
  481. #:outputs '("out" "two")))
  482. (builder2 (add-text-to-store %store "my-mo-user-builder.sh"
  483. "read x < $one;
  484. read y < $two;
  485. echo \"($x $y)\" > $out"
  486. '()))
  487. (udrv (derivation %store "multiple-output-user"
  488. %bash `(,builder2)
  489. #:env-vars `(("one"
  490. . ,(derivation->output-path
  491. mdrv "out"))
  492. ("two"
  493. . ,(derivation->output-path
  494. mdrv "two")))
  495. #:inputs `((,%bash)
  496. (,builder2)
  497. ;; two occurrences of MDRV:
  498. (,mdrv)
  499. (,mdrv "two")))))
  500. (and (build-derivations %store (list (pk 'udrv udrv)))
  501. (let ((p (derivation->output-path udrv)))
  502. (and (valid-path? %store p)
  503. (equal? '(one two) (call-with-input-file p read)))))))
  504. (test-assert "derivation with #:references-graphs"
  505. (let* ((input1 (add-text-to-store %store "foo" "hello"
  506. (list %bash)))
  507. (input2 (add-text-to-store %store "bar"
  508. (number->string (random 7777))
  509. (list input1)))
  510. (builder (add-text-to-store %store "build-graph"
  511. (format #f "
  512. ~a $out
  513. (while read l ; do echo $l ; done) < bash > $out/bash
  514. (while read l ; do echo $l ; done) < input1 > $out/input1
  515. (while read l ; do echo $l ; done) < input2 > $out/input2"
  516. %mkdir)
  517. (list %mkdir)))
  518. (drv (derivation %store "closure-graphs"
  519. %bash `(,builder)
  520. #:references-graphs
  521. `(("bash" . ,%bash)
  522. ("input1" . ,input1)
  523. ("input2" . ,input2))
  524. #:inputs `((,%bash) (,builder))))
  525. (out (derivation->output-path drv)))
  526. (define (deps path . deps)
  527. (let ((count (length deps)))
  528. (string-append path "\n\n" (number->string count) "\n"
  529. (string-join (sort deps string<?) "\n")
  530. (if (zero? count) "" "\n"))))
  531. (and (build-derivations %store (list drv))
  532. (equal? (directory-contents out get-string-all)
  533. `(("/bash" . ,(string-append %bash "\n\n0\n"))
  534. ("/input1" . ,(if (string>? input1 %bash)
  535. (string-append (deps %bash)
  536. (deps input1 %bash))
  537. (string-append (deps input1 %bash)
  538. (deps %bash))))
  539. ("/input2" . ,(string-concatenate
  540. (map cdr
  541. (sort
  542. (map (lambda (p d)
  543. (cons p (apply deps p d)))
  544. (list %bash input1 input2)
  545. (list '() (list %bash) (list input1)))
  546. (lambda (x y)
  547. (match x
  548. ((p1 . _)
  549. (match y
  550. ((p2 . _)
  551. (string<? p1 p2)))))))))))))))
  552. (test-assert "derivation #:allowed-references, ok"
  553. (let ((drv (derivation %store "allowed" %bash
  554. '("-c" "echo hello > $out")
  555. #:inputs `((,%bash))
  556. #:allowed-references '())))
  557. (build-derivations %store (list drv))))
  558. (test-assert "derivation #:allowed-references, not allowed"
  559. (let* ((txt (add-text-to-store %store "foo" "Hello, world."))
  560. (drv (derivation %store "disallowed" %bash
  561. `("-c" ,(string-append "echo " txt "> $out"))
  562. #:inputs `((,%bash) (,txt))
  563. #:allowed-references '())))
  564. (guard (c ((nix-protocol-error? c)
  565. ;; There's no specific error message to check for.
  566. #t))
  567. (build-derivations %store (list drv))
  568. #f)))
  569. (test-assert "derivation #:allowed-references, self allowed"
  570. (let ((drv (derivation %store "allowed" %bash
  571. '("-c" "echo $out > $out")
  572. #:inputs `((,%bash))
  573. #:allowed-references '("out"))))
  574. (build-derivations %store (list drv))))
  575. (test-assert "derivation #:allowed-references, self not allowed"
  576. (let ((drv (derivation %store "disallowed" %bash
  577. `("-c" ,"echo $out > $out")
  578. #:inputs `((,%bash))
  579. #:allowed-references '())))
  580. (guard (c ((nix-protocol-error? c)
  581. ;; There's no specific error message to check for.
  582. #t))
  583. (build-derivations %store (list drv))
  584. #f)))
  585. (test-assert "derivation #:disallowed-references, ok"
  586. (let ((drv (derivation %store "disallowed" %bash
  587. '("-c" "echo hello > $out")
  588. #:inputs `((,%bash))
  589. #:disallowed-references '("out"))))
  590. (build-derivations %store (list drv))))
  591. (test-assert "derivation #:disallowed-references, not ok"
  592. (let* ((txt (add-text-to-store %store "foo" "Hello, world."))
  593. (drv (derivation %store "disdisallowed" %bash
  594. `("-c" ,(string-append "echo " txt "> $out"))
  595. #:inputs `((,%bash) (,txt))
  596. #:disallowed-references (list txt))))
  597. (guard (c ((nix-protocol-error? c)
  598. ;; There's no specific error message to check for.
  599. #t))
  600. (build-derivations %store (list drv))
  601. #f)))
  602. ;; Here we should get the value of $NIX_STATE_DIR that the daemon sees, which
  603. ;; is a unique value for each test process; this value is the same as the one
  604. ;; we see in the process executing this file since it is set by 'test-env'.
  605. (test-equal "derivation #:leaked-env-vars"
  606. (getenv "NIX_STATE_DIR")
  607. (let* ((value (getenv "NIX_STATE_DIR"))
  608. (drv (derivation %store "leaked-env-vars" %bash
  609. '("-c" "echo -n $NIX_STATE_DIR > $out")
  610. #:hash (sha256 (string->utf8 value))
  611. #:hash-algo 'sha256
  612. #:inputs `((,%bash))
  613. #:leaked-env-vars '("NIX_STATE_DIR"))))
  614. (and (build-derivations %store (list drv))
  615. (call-with-input-file (derivation->output-path drv)
  616. get-string-all))))
  617. (define %coreutils
  618. (false-if-exception
  619. (and (network-reachable?)
  620. (package-derivation %store %bootstrap-coreutils&co))))
  621. (test-skip (if %coreutils 0 1))
  622. (test-assert "build derivation with coreutils"
  623. (let* ((builder
  624. (add-text-to-store %store "build-with-coreutils.sh"
  625. "echo $PATH ; mkdir --version ; mkdir $out ; touch $out/good"
  626. '()))
  627. (drv
  628. (derivation %store "foo"
  629. %bash `(,builder)
  630. #:env-vars `(("PATH" .
  631. ,(string-append
  632. (derivation->output-path %coreutils)
  633. "/bin")))
  634. #:inputs `((,builder)
  635. (,%coreutils))))
  636. (succeeded?
  637. (build-derivations %store (list drv))))
  638. (and succeeded?
  639. (let ((p (derivation->output-path drv)))
  640. (and (valid-path? %store p)
  641. (file-exists? (string-append p "/good")))))))
  642. (test-skip (if (%guile-for-build) 0 8))
  643. (test-equal "build-expression->derivation and invalid module name"
  644. '(file-search-error "guix/module/that/does/not/exist.scm")
  645. (guard (c ((file-search-error? c)
  646. (list 'file-search-error
  647. (file-search-error-file-name c))))
  648. (build-expression->derivation %store "foo" #t
  649. #:modules '((guix module that
  650. does not exist)))))
  651. (test-equal "build-expression->derivation and builder encoding"
  652. '("UTF-8" #t)
  653. (let* ((exp '(λ (α) (+ α 1)))
  654. (drv (build-expression->derivation %store "foo" exp)))
  655. (match (derivation-builder-arguments drv)
  656. ((... builder)
  657. (with-fluids ((%default-port-encoding "UTF-8"))
  658. (call-with-input-file builder
  659. (lambda (port)
  660. (list (port-encoding port)
  661. (->bool
  662. (string-contains (get-string-all port)
  663. "(λ (α) (+ α 1))"))))))))))
  664. (test-assert "build-expression->derivation and derivation-prerequisites"
  665. (let ((drv (build-expression->derivation %store "fail" #f)))
  666. (any (match-lambda
  667. (($ <derivation-input> path)
  668. (string=? path (derivation-file-name (%guile-for-build)))))
  669. (derivation-prerequisites drv))))
  670. (test-assert "derivation-prerequisites and valid-derivation-input?"
  671. (let* ((a (build-expression->derivation %store "a" '(mkdir %output)))
  672. (b (build-expression->derivation %store "b" `(list ,(random-text))))
  673. (c (build-expression->derivation %store "c" `(mkdir %output)
  674. #:inputs `(("a" ,a) ("b" ,b)))))
  675. ;; Make sure both A and %BOOTSTRAP-GUILE are built (the latter could have
  676. ;; be removed by tests/guix-gc.sh.)
  677. (build-derivations %store
  678. (list a (package-derivation %store %bootstrap-guile)))
  679. (match (derivation-prerequisites c
  680. (cut valid-derivation-input? %store
  681. <>))
  682. ((($ <derivation-input> file ("out")))
  683. (string=? file (derivation-file-name b)))
  684. (x
  685. (pk 'fail x #f)))))
  686. (test-assert "build-expression->derivation without inputs"
  687. (let* ((builder '(begin
  688. (mkdir %output)
  689. (call-with-output-file (string-append %output "/test")
  690. (lambda (p)
  691. (display '(hello guix) p)))))
  692. (drv (build-expression->derivation %store "goo" builder))
  693. (succeeded? (build-derivations %store (list drv))))
  694. (and succeeded?
  695. (let ((p (derivation->output-path drv)))
  696. (equal? '(hello guix)
  697. (call-with-input-file (string-append p "/test") read))))))
  698. (test-assert "build-expression->derivation and max-silent-time"
  699. (let* ((store (let ((s (open-connection)))
  700. (set-build-options s #:max-silent-time 1)
  701. s))
  702. (builder '(begin (sleep 100) (mkdir %output) #t))
  703. (drv (build-expression->derivation store "silent" builder))
  704. (out-path (derivation->output-path drv)))
  705. (guard (c ((nix-protocol-error? c)
  706. (and (string-contains (nix-protocol-error-message c)
  707. "failed")
  708. (not (valid-path? store out-path)))))
  709. (build-derivations store (list drv))
  710. #f)))
  711. (test-assert "build-expression->derivation and timeout"
  712. (let* ((store (let ((s (open-connection)))
  713. (set-build-options s #:timeout 1)
  714. s))
  715. (builder '(begin (sleep 100) (mkdir %output) #t))
  716. (drv (build-expression->derivation store "slow" builder))
  717. (out-path (derivation->output-path drv)))
  718. (guard (c ((nix-protocol-error? c)
  719. (and (string-contains (nix-protocol-error-message c)
  720. "failed")
  721. (not (valid-path? store out-path)))))
  722. (build-derivations store (list drv))
  723. #f)))
  724. (test-assert "build-expression->derivation and derivation-prerequisites-to-build"
  725. (let ((drv (build-expression->derivation %store "fail" #f)))
  726. ;; The only direct dependency is (%guile-for-build) and it's already
  727. ;; built.
  728. (null? (derivation-prerequisites-to-build %store drv))))
  729. (test-assert "derivation-prerequisites-to-build when outputs already present"
  730. (let* ((builder '(begin (mkdir %output) #t))
  731. (input-drv (build-expression->derivation %store "input" builder))
  732. (input-path (derivation-output-path
  733. (assoc-ref (derivation-outputs input-drv)
  734. "out")))
  735. (drv (build-expression->derivation %store "something" builder
  736. #:inputs
  737. `(("i" ,input-drv))))
  738. (output (derivation->output-path drv)))
  739. ;; Make sure these things are not already built.
  740. (when (valid-path? %store input-path)
  741. (delete-paths %store (list input-path)))
  742. (when (valid-path? %store output)
  743. (delete-paths %store (list output)))
  744. (and (equal? (map derivation-input-path
  745. (derivation-prerequisites-to-build %store drv))
  746. (list (derivation-file-name input-drv)))
  747. ;; Build DRV and delete its input.
  748. (build-derivations %store (list drv))
  749. (delete-paths %store (list input-path))
  750. (not (valid-path? %store input-path))
  751. ;; Now INPUT-PATH is missing, yet it shouldn't be listed as a
  752. ;; prerequisite to build because DRV itself is already built.
  753. (null? (derivation-prerequisites-to-build %store drv)))))
  754. (test-assert "derivation-prerequisites-to-build and substitutes"
  755. (let* ((store (open-connection))
  756. (drv (build-expression->derivation store "prereq-subst"
  757. (random 1000)))
  758. (output (derivation->output-path drv)))
  759. ;; Make sure substitutes are usable.
  760. (set-build-options store #:use-substitutes? #t
  761. #:substitute-urls (%test-substitute-urls))
  762. (with-derivation-narinfo drv
  763. (let-values (((build download)
  764. (derivation-prerequisites-to-build store drv))
  765. ((build* download*)
  766. (derivation-prerequisites-to-build store drv
  767. #:substitutable-info
  768. (const #f))))
  769. (and (null? build)
  770. (equal? (map substitutable-path download) (list output))
  771. (null? download*)
  772. (null? build*))))))
  773. (test-assert "derivation-prerequisites-to-build and substitutes, non-substitutable build"
  774. (let* ((store (open-connection))
  775. (drv (build-expression->derivation store "prereq-no-subst"
  776. (random 1000)
  777. #:substitutable? #f))
  778. (output (derivation->output-path drv)))
  779. ;; Make sure substitutes are usable.
  780. (set-build-options store #:use-substitutes? #t
  781. #:substitute-urls (%test-substitute-urls))
  782. (with-derivation-narinfo drv
  783. (let-values (((build download)
  784. (derivation-prerequisites-to-build store drv)))
  785. ;; Despite being available as a substitute, DRV will be built locally
  786. ;; due to #:substitutable? #f.
  787. (and (null? download)
  788. (match build
  789. (((? derivation-input? input))
  790. (string=? (derivation-input-path input)
  791. (derivation-file-name drv)))))))))
  792. (test-assert "derivation-prerequisites-to-build and substitutes, local build"
  793. (with-store store
  794. (let* ((drv (build-expression->derivation store "prereq-subst-local"
  795. (random 1000)
  796. #:local-build? #t))
  797. (output (derivation->output-path drv)))
  798. ;; Make sure substitutes are usable.
  799. (set-build-options store #:use-substitutes? #t
  800. #:substitute-urls (%test-substitute-urls))
  801. (with-derivation-narinfo drv
  802. (let-values (((build download)
  803. (derivation-prerequisites-to-build store drv)))
  804. ;; #:local-build? is *not* synonymous with #:substitutable?, so we
  805. ;; must be able to substitute DRV's output.
  806. ;; See <http://bugs.gnu.org/18747>.
  807. (and (null? build)
  808. (match download
  809. (((= substitutable-path item))
  810. (string=? item (derivation->output-path drv))))))))))
  811. (test-assert "derivation-prerequisites-to-build in 'check' mode"
  812. (with-store store
  813. (let* ((dep (build-expression->derivation store "dep"
  814. `(begin ,(random-text)
  815. (mkdir %output))))
  816. (drv (build-expression->derivation store "to-check"
  817. '(mkdir %output)
  818. #:inputs `(("dep" ,dep)))))
  819. (build-derivations store (list drv))
  820. (delete-paths store (list (derivation->output-path dep)))
  821. ;; In 'check' mode, DEP must be rebuilt.
  822. (and (null? (derivation-prerequisites-to-build store drv))
  823. (match (derivation-prerequisites-to-build store drv
  824. #:mode (build-mode
  825. check))
  826. ((input)
  827. (string=? (derivation-input-path input)
  828. (derivation-file-name dep))))))))
  829. (test-assert "substitution-oracle and #:substitute? #f"
  830. (with-store store
  831. (let* ((dep (build-expression->derivation store "dep"
  832. `(begin ,(random-text)
  833. (mkdir %output))))
  834. (drv (build-expression->derivation store "not-subst"
  835. `(begin ,(random-text)
  836. (mkdir %output))
  837. #:substitutable? #f
  838. #:inputs `(("dep" ,dep))))
  839. (query #f))
  840. (define (record-substitutable-path-query store paths)
  841. (when query
  842. (error "already called!" query))
  843. (set! query paths)
  844. '())
  845. (mock ((guix store) substitutable-path-info
  846. record-substitutable-path-query)
  847. (let ((pred (substitution-oracle store (list drv))))
  848. (pred (derivation->output-path drv))))
  849. ;; Make sure the oracle didn't try to get substitute info for DRV since
  850. ;; DRV is mark as non-substitutable. Assume that GUILE-FOR-BUILD is
  851. ;; already in store and thus not part of QUERY.
  852. (equal? (pk 'query query)
  853. (list (derivation->output-path dep))))))
  854. (test-assert "build-expression->derivation with expression returning #f"
  855. (let* ((builder '(begin
  856. (mkdir %output)
  857. #f)) ; fail!
  858. (drv (build-expression->derivation %store "fail" builder))
  859. (out-path (derivation->output-path drv)))
  860. (guard (c ((nix-protocol-error? c)
  861. ;; Note that the output path may exist at this point, but it
  862. ;; is invalid.
  863. (and (string-match "build .* failed"
  864. (nix-protocol-error-message c))
  865. (not (valid-path? %store out-path)))))
  866. (build-derivations %store (list drv))
  867. #f)))
  868. (test-assert "build-expression->derivation with two outputs"
  869. (let* ((builder '(begin
  870. (call-with-output-file (assoc-ref %outputs "out")
  871. (lambda (p)
  872. (display '(hello) p)))
  873. (call-with-output-file (assoc-ref %outputs "second")
  874. (lambda (p)
  875. (display '(world) p)))))
  876. (drv (build-expression->derivation %store "double" builder
  877. #:outputs '("out"
  878. "second")))
  879. (succeeded? (build-derivations %store (list drv))))
  880. (and succeeded?
  881. (let ((one (derivation->output-path drv))
  882. (two (derivation->output-path drv "second")))
  883. (and (equal? '(hello) (call-with-input-file one read))
  884. (equal? '(world) (call-with-input-file two read)))))))
  885. (test-skip (if %coreutils 0 1))
  886. (test-assert "build-expression->derivation with one input"
  887. (let* ((builder '(call-with-output-file %output
  888. (lambda (p)
  889. (let ((cu (assoc-ref %build-inputs "cu")))
  890. (close 1)
  891. (dup2 (port->fdes p) 1)
  892. (execl (string-append cu "/bin/uname")
  893. "uname" "-a")))))
  894. (drv (build-expression->derivation %store "uname" builder
  895. #:inputs
  896. `(("cu" ,%coreutils))))
  897. (succeeded? (build-derivations %store (list drv))))
  898. (and succeeded?
  899. (let ((p (derivation->output-path drv)))
  900. (string-contains (call-with-input-file p read-line) "GNU")))))
  901. (test-assert "build-expression->derivation with modules"
  902. (let* ((builder `(begin
  903. (use-modules (guix build utils))
  904. (let ((out (assoc-ref %outputs "out")))
  905. (mkdir-p (string-append out "/guile/guix/nix"))
  906. #t)))
  907. (drv (build-expression->derivation %store "test-with-modules"
  908. builder
  909. #:modules
  910. '((guix build utils)))))
  911. (and (build-derivations %store (list drv))
  912. (let* ((p (derivation->output-path drv))
  913. (s (stat (string-append p "/guile/guix/nix"))))
  914. (eq? (stat:type s) 'directory)))))
  915. (test-assert "build-expression->derivation: same fixed-output path"
  916. (let* ((builder1 '(call-with-output-file %output
  917. (lambda (p)
  918. (write "hello" p))))
  919. (builder2 '(call-with-output-file (pk 'difference-here! %output)
  920. (lambda (p)
  921. (write "hello" p))))
  922. (hash (sha256 (string->utf8 "hello")))
  923. (input1 (build-expression->derivation %store "fixed" builder1
  924. #:hash hash
  925. #:hash-algo 'sha256))
  926. (input2 (build-expression->derivation %store "fixed" builder2
  927. #:hash hash
  928. #:hash-algo 'sha256))
  929. (succeeded? (build-derivations %store (list input1 input2))))
  930. (and succeeded?
  931. (not (string=? (derivation-file-name input1)
  932. (derivation-file-name input2)))
  933. (string=? (derivation->output-path input1)
  934. (derivation->output-path input2)))))
  935. (test-assert "build-expression->derivation with a fixed-output input"
  936. (let* ((builder1 '(call-with-output-file %output
  937. (lambda (p)
  938. (write "hello" p))))
  939. (builder2 '(call-with-output-file (pk 'difference-here! %output)
  940. (lambda (p)
  941. (write "hello" p))))
  942. (hash (sha256 (string->utf8 "hello")))
  943. (input1 (build-expression->derivation %store "fixed" builder1
  944. #:hash hash
  945. #:hash-algo 'sha256))
  946. (input2 (build-expression->derivation %store "fixed" builder2
  947. #:hash hash
  948. #:hash-algo 'sha256))
  949. (builder3 '(let ((input (assoc-ref %build-inputs "input")))
  950. (call-with-output-file %output
  951. (lambda (out)
  952. (format #f "My input is ~a.~%" input)))))
  953. (final1 (build-expression->derivation %store "final" builder3
  954. #:inputs
  955. `(("input" ,input1))))
  956. (final2 (build-expression->derivation %store "final" builder3
  957. #:inputs
  958. `(("input" ,input2)))))
  959. (and (string=? (derivation->output-path final1)
  960. (derivation->output-path final2))
  961. (string=? (derivation->output-path final1)
  962. (derivation-path->output-path
  963. (derivation-file-name final1)))
  964. (build-derivations %store (list final1 final2)))))
  965. (test-assert "build-expression->derivation produces recursive fixed-output"
  966. (let* ((builder '(begin
  967. (use-modules (srfi srfi-26))
  968. (mkdir %output)
  969. (chdir %output)
  970. (call-with-output-file "exe"
  971. (cut display "executable" <>))
  972. (chmod "exe" #o777)
  973. (symlink "exe" "symlink")
  974. (mkdir "subdir")))
  975. (drv (build-expression->derivation %store "fixed-rec" builder
  976. #:hash-algo 'sha256
  977. #:hash (base32
  978. "10k1lw41wyrjf9mxydi0is5nkpynlsvgslinics4ppir13g7d74p")
  979. #:recursive? #t)))
  980. (and (build-derivations %store (list drv))
  981. (let* ((dir (derivation->output-path drv))
  982. (exe (string-append dir "/exe"))
  983. (link (string-append dir "/symlink"))
  984. (subdir (string-append dir "/subdir")))
  985. (and (executable-file? exe)
  986. (string=? "executable"
  987. (call-with-input-file exe get-string-all))
  988. (string=? "exe" (readlink link))
  989. (file-is-directory? subdir))))))
  990. (test-assert "build-expression->derivation uses recursive fixed-output"
  991. (let* ((builder '(call-with-output-file %output
  992. (lambda (port)
  993. (display "hello" port))))
  994. (fixed (build-expression->derivation %store "small-fixed-rec"
  995. builder
  996. #:hash-algo 'sha256
  997. #:hash (base32
  998. "0sg9f58l1jj88w6pdrfdpj5x9b1zrwszk84j81zvby36q9whhhqa")
  999. #:recursive? #t))
  1000. (in (derivation->output-path fixed))
  1001. (builder `(begin
  1002. (mkdir %output)
  1003. (chdir %output)
  1004. (symlink ,in "symlink")))
  1005. (drv (build-expression->derivation %store "fixed-rec-user"
  1006. builder
  1007. #:inputs `(("fixed" ,fixed)))))
  1008. (and (build-derivations %store (list drv))
  1009. (let ((out (derivation->output-path drv)))
  1010. (string=? (readlink (string-append out "/symlink")) in)))))
  1011. (test-assert "build-expression->derivation with #:references-graphs"
  1012. (let* ((input (add-text-to-store %store "foo" "hello"
  1013. (list %bash %mkdir)))
  1014. (builder '(copy-file "input" %output))
  1015. (drv (build-expression->derivation %store "references-graphs"
  1016. builder
  1017. #:references-graphs
  1018. `(("input" . ,input))))
  1019. (out (derivation->output-path drv)))
  1020. (define (deps path . deps)
  1021. (let ((count (length deps)))
  1022. (string-append path "\n\n" (number->string count) "\n"
  1023. (string-join (sort deps string<?) "\n")
  1024. (if (zero? count) "" "\n"))))
  1025. (and (build-derivations %store (list drv))
  1026. (equal? (call-with-input-file out get-string-all)
  1027. (string-concatenate
  1028. (map cdr
  1029. (sort (map (lambda (p d)
  1030. (cons p (apply deps p d)))
  1031. (list input %bash %mkdir)
  1032. (list (list %bash %mkdir)
  1033. '() '()))
  1034. (lambda (x y)
  1035. (match x
  1036. ((p1 . _)
  1037. (match y
  1038. ((p2 . _)
  1039. (string<? p1 p2)))))))))))))
  1040. (test-equal "map-derivation"
  1041. "hello"
  1042. (let* ((joke (package-derivation %store guile-1.8))
  1043. (good (package-derivation %store %bootstrap-guile))
  1044. (drv1 (build-expression->derivation %store "original-drv1"
  1045. #f ; systematically fail
  1046. #:guile-for-build joke))
  1047. (drv2 (build-expression->derivation %store "original-drv2"
  1048. '(call-with-output-file %output
  1049. (lambda (p)
  1050. (display "hello" p)))))
  1051. (drv3 (build-expression->derivation %store "drv-to-remap"
  1052. '(let ((in (assoc-ref
  1053. %build-inputs "in")))
  1054. (copy-file in %output))
  1055. #:inputs `(("in" ,drv1))
  1056. #:guile-for-build joke))
  1057. (drv4 (map-derivation %store drv3 `((,drv1 . ,drv2)
  1058. (,joke . ,good))))
  1059. (out (derivation->output-path drv4)))
  1060. (and (build-derivations %store (list (pk 'remapped drv4)))
  1061. (call-with-input-file out get-string-all))))
  1062. (test-equal "map-derivation, sources"
  1063. "hello"
  1064. (let* ((script1 (add-text-to-store %store "fail.sh" "exit 1"))
  1065. (script2 (add-text-to-store %store "hi.sh" "echo -n hello > $out"))
  1066. (bash-full (package-derivation %store (@ (gnu packages bash) bash)))
  1067. (drv1 (derivation %store "drv-to-remap"
  1068. ;; XXX: This wouldn't work in practice, but if
  1069. ;; we append "/bin/bash" then we can't replace
  1070. ;; it with the bootstrap bash, which is a
  1071. ;; single file.
  1072. (derivation->output-path bash-full)
  1073. `("-e" ,script1)
  1074. #:inputs `((,bash-full) (,script1))))
  1075. (drv2 (map-derivation %store drv1
  1076. `((,bash-full . ,%bash)
  1077. (,script1 . ,script2))))
  1078. (out (derivation->output-path drv2)))
  1079. (and (build-derivations %store (list (pk 'remapped* drv2)))
  1080. (call-with-input-file out get-string-all))))
  1081. (test-end)
  1082. ;; Local Variables:
  1083. ;; eval: (put 'with-http-server 'scheme-indent-function 2)
  1084. ;; End: