substitute: Gracefully handle invalid store file names.
[jackhill/guix/guix.git] / tests / grafts.scm
CommitLineData
7adf9b84
LC
1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2014, 2015, 2016 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
19(define-module (test-grafts)
c22a1324
LC
20 #:use-module (guix gexp)
21 #:use-module (guix monads)
7adf9b84
LC
22 #:use-module (guix derivations)
23 #:use-module (guix store)
24 #:use-module (guix utils)
25 #:use-module (guix grafts)
26 #:use-module (guix tests)
27 #:use-module ((gnu packages) #:select (search-bootstrap-binary))
c22a1324
LC
28 #:use-module (gnu packages bootstrap)
29 #:use-module (srfi srfi-1)
7adf9b84
LC
30 #:use-module (srfi srfi-64)
31 #:use-module (rnrs io ports))
32
33(define %store
34 (open-connection-for-tests))
35
36(define (bootstrap-binary name)
37 (let ((bin (search-bootstrap-binary name (%current-system))))
38 (and %store
39 (add-to-store %store name #t "sha256" bin))))
40
41(define %bash
42 (bootstrap-binary "bash"))
43(define %mkdir
44 (bootstrap-binary "mkdir"))
45
46\f
47(test-begin "grafts")
48
c22a1324 49(test-assert "graft-derivation, grafted item is a direct dependency"
7adf9b84
LC
50 (let* ((build `(begin
51 (mkdir %output)
52 (chdir %output)
53 (symlink %output "self")
54 (call-with-output-file "text"
55 (lambda (output)
56 (format output "foo/~a/bar" ,%mkdir)))
57 (symlink ,%bash "sh")))
c22a1324 58 (orig (build-expression->derivation %store "grafted" build
7adf9b84
LC
59 #:inputs `(("a" ,%bash)
60 ("b" ,%mkdir))))
61 (one (add-text-to-store %store "bash" "fake bash"))
62 (two (build-expression->derivation %store "mkdir"
63 '(call-with-output-file %output
64 (lambda (port)
65 (display "fake mkdir" port)))))
c22a1324
LC
66 (grafted (graft-derivation %store orig
67 (list (graft
68 (origin %bash)
69 (replacement one))
70 (graft
71 (origin %mkdir)
72 (replacement two))))))
73 (and (build-derivations %store (list grafted))
74 (let ((two (derivation->output-path two))
75 (grafted (derivation->output-path grafted)))
7adf9b84 76 (and (string=? (format #f "foo/~a/bar" two)
c22a1324 77 (call-with-input-file (string-append grafted "/text")
7adf9b84 78 get-string-all))
c22a1324
LC
79 (string=? (readlink (string-append grafted "/sh")) one)
80 (string=? (readlink (string-append grafted "/self"))
81 grafted))))))
82
83;; Make sure 'derivation-file-name' always gets to see an absolute file name.
84(fluid-set! %file-port-name-canonicalization 'absolute)
85
86(test-assert "graft-derivation, grafted item is an indirect dependency"
87 (let* ((build `(begin
88 (mkdir %output)
89 (chdir %output)
90 (symlink %output "self")
91 (call-with-output-file "text"
92 (lambda (output)
93 (format output "foo/~a/bar" ,%mkdir)))
94 (symlink ,%bash "sh")))
95 (dep (build-expression->derivation %store "dep" build
96 #:inputs `(("a" ,%bash)
97 ("b" ,%mkdir))))
98 (orig (build-expression->derivation %store "thing"
99 '(symlink
100 (assoc-ref %build-inputs
101 "dep")
102 %output)
103 #:inputs `(("dep" ,dep))))
104 (one (add-text-to-store %store "bash" "fake bash"))
105 (two (build-expression->derivation %store "mkdir"
106 '(call-with-output-file %output
107 (lambda (port)
108 (display "fake mkdir" port)))))
109 (grafted (graft-derivation %store orig
110 (list (graft
111 (origin %bash)
112 (replacement one))
113 (graft
114 (origin %mkdir)
115 (replacement two))))))
116 (and (build-derivations %store (list grafted))
117 (let* ((two (derivation->output-path two))
118 (grafted (derivation->output-path grafted))
119 (dep (readlink grafted)))
120 (and (string=? (format #f "foo/~a/bar" two)
121 (call-with-input-file (string-append dep "/text")
122 get-string-all))
123 (string=? (readlink (string-append dep "/sh")) one)
124 (string=? (readlink (string-append dep "/self")) dep)
125 (equal? (references %store grafted) (list dep))
126 (lset= string=?
127 (list one two dep)
128 (references %store dep)))))))
129
130(test-assert "graft-derivation, no dependencies on grafted output"
131 (run-with-store %store
132 (mlet* %store-monad ((fake (text-file "bash" "Fake bash."))
133 (graft -> (graft
134 (origin %bash)
135 (replacement fake)))
136 (drv (gexp->derivation "foo" #~(mkdir #$output)))
137 (grafted ((store-lift graft-derivation) drv
138 (list graft))))
139 (return (eq? grafted drv)))))
7adf9b84 140
f376dc3a
LC
141(test-assert "graft-derivation, multiple outputs"
142 (let* ((build `(begin
143 (symlink (assoc-ref %build-inputs "a")
144 (assoc-ref %outputs "one"))
145 (symlink (assoc-ref %outputs "one")
146 (assoc-ref %outputs "two"))))
147 (orig (build-expression->derivation %store "grafted" build
148 #:inputs `(("a" ,%bash))
149 #:outputs '("one" "two")))
150 (repl (add-text-to-store %store "bash" "fake bash"))
151 (grafted (graft-derivation %store orig
152 (list (graft
153 (origin %bash)
154 (replacement repl))))))
155 (and (build-derivations %store (list grafted))
156 (let ((one (derivation->output-path grafted "one"))
157 (two (derivation->output-path grafted "two")))
158 (and (string=? (readlink one) repl)
159 (string=? (readlink two) one))))))
160
7adf9b84 161(test-end)