Merge remote-tracking branch 'origin/master' into core-updates-frozen
[jackhill/guix/guix.git] / tests / builders.scm
1 ;;; GNU Guix --- Functional package management for GNU
2 ;;; Copyright © 2012, 2013, 2014, 2015, 2018, 2019, 2021 Ludovic Courtès <ludo@gnu.org>
3 ;;; Copyright © 2021 Lars-Dominik Braun <lars@6xq.net>
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
21 (define-module (tests builders)
22 #:use-module (guix download)
23 #:use-module (guix build-system)
24 #:use-module (guix build-system gnu)
25 #:use-module (guix build gnu-build-system)
26 #:use-module (guix build utils)
27 #:use-module (guix build-system python)
28 #:use-module (guix grafts)
29 #:use-module (guix store)
30 #:use-module (guix monads)
31 #:use-module (guix utils)
32 #:use-module (guix base32)
33 #:use-module (guix derivations)
34 #:use-module (gcrypt hash)
35 #:use-module (guix tests)
36 #:use-module (guix packages)
37 #:use-module (gnu packages bootstrap)
38 #:use-module (ice-9 match)
39 #:use-module (ice-9 textual-ports)
40 #:use-module (srfi srfi-1)
41 #:use-module (srfi srfi-11)
42 #:use-module (srfi srfi-34)
43 #:use-module (srfi srfi-64))
44
45 ;; Test the higher-level builders.
46
47 (define %store
48 (open-connection-for-tests))
49
50 (define url-fetch*
51 (store-lower url-fetch))
52
53 ;; Globally disable grafts because they can trigger early builds.
54 (%graft? #f)
55
56 \f
57 (test-begin "builders")
58
59 (unless (network-reachable?) (test-skip 1))
60 (test-assert "url-fetch"
61 (let* ((url '("http://ftp.gnu.org/gnu/hello/hello-2.8.tar.gz"
62 "ftp://ftp.gnu.org/gnu/hello/hello-2.8.tar.gz"))
63 (hash (nix-base32-string->bytevector
64 "0wqd8sjmxfskrflaxywc7gqw7sfawrfvdxd9skxawzfgyy0pzdz6"))
65 (drv (url-fetch* %store url 'sha256 hash
66 #:guile %bootstrap-guile))
67 (out-path (derivation->output-path drv)))
68 (and (build-derivations %store (list drv))
69 (file-exists? out-path)
70 (valid-path? %store out-path))))
71
72 (test-assert "url-fetch, file"
73 (let* ((file (search-path %load-path "guix.scm"))
74 (hash (call-with-input-file file port-sha256))
75 (out (url-fetch* %store file 'sha256 hash)))
76 (and (file-exists? out)
77 (valid-path? %store out))))
78
79 (test-assert "url-fetch, file URI"
80 (let* ((file (search-path %load-path "guix.scm"))
81 (hash (call-with-input-file file port-sha256))
82 (out (url-fetch* %store
83 (string-append "file://" (canonicalize-path file))
84 'sha256 hash)))
85 (and (file-exists? out)
86 (valid-path? %store out))))
87
88 (test-assert "gnu-build-system"
89 (build-system? gnu-build-system))
90
91 (define unpack (assoc-ref %standard-phases 'unpack))
92
93 (define compressors '(("gzip" . "gz")
94 ("xz" . "xz")
95 ("bzip2" . "bz2")
96 (#f . #f)))
97
98 (for-each
99 (match-lambda
100 ((comp . ext)
101
102 (unless (network-reachable?) (test-skip 1)) ;for bootstrap binaries
103 (test-equal (string-append "gnu-build-system unpack phase, "
104 "single file (compression: "
105 (if comp comp "None") ")")
106 "expected text"
107 (let*-values
108 (((name) "test")
109 ((compressed-name) (if ext
110 (string-append name "." ext)
111 name))
112 ((file hash) (test-file %store compressed-name "expected text")))
113 (call-with-temporary-directory
114 (lambda (dir)
115 (with-directory-excursion dir
116 (unpack #:source file)
117 (call-with-input-file name get-string-all))))))))
118 compressors)
119
120 \f
121 ;;;
122 ;;; Test the sanity-check phase of the Python build system.
123 ;;;
124
125 (define* (make-python-dummy name #:key (setup-py-extra "")
126 (init-py "") (use-setuptools? #t))
127 (dummy-package (string-append "python-dummy-" name)
128 (version "0.1")
129 (build-system python-build-system)
130 (arguments
131 `(#:tests? #f
132 #:use-setuptools? ,use-setuptools?
133 #:phases
134 (modify-phases %standard-phases
135 (replace 'unpack
136 (lambda _
137 (mkdir-p "dummy")
138 (with-output-to-file "dummy/__init__.py"
139 (lambda _
140 (display ,init-py)))
141 (with-output-to-file "setup.py"
142 (lambda _
143 (format #t "\
144 ~a
145 setup(
146 name='dummy-~a',
147 version='0.1',
148 packages=['dummy'],
149 ~a
150 )"
151 (if ,use-setuptools?
152 "from setuptools import setup"
153 "from distutils.core import setup")
154 ,name ,setup-py-extra))))))))))
155
156 (define python-dummy-ok
157 (make-python-dummy "ok"))
158
159 ;; distutil won't install any metadata, so make sure our script does not fail
160 ;; on a otherwise fine package.
161 (define python-dummy-no-setuptools
162 (make-python-dummy
163 "no-setuptools" #:use-setuptools? #f))
164
165 (define python-dummy-fail-requirements
166 (make-python-dummy "fail-requirements"
167 #:setup-py-extra "install_requires=['nonexistent'],"))
168
169 (define python-dummy-fail-import
170 (make-python-dummy "fail-import" #:init-py "import nonexistent"))
171
172 (define python-dummy-fail-console-script
173 (make-python-dummy "fail-console-script"
174 #:setup-py-extra (string-append "entry_points={'console_scripts': "
175 "['broken = dummy:nonexistent']},")))
176
177 (define (check-build-success store p)
178 (unless store (test-skip 1))
179 (test-assert (string-append "python-build-system: " (package-name p))
180 (let* ((drv (package-derivation store p)))
181 (build-derivations store (list drv)))))
182
183 (define (check-build-failure store p)
184 (unless store (test-skip 1))
185 (test-assert (string-append "python-build-system: " (package-name p))
186 (let ((drv (package-derivation store p)))
187 (guard (c ((store-protocol-error? c)
188 (pk 'failure c #t))) ;good!
189 (build-derivations store (list drv))
190 #f)))) ;bad: it should have failed
191
192 (with-external-store store
193 (for-each (lambda (p) (check-build-success store p))
194 (list
195 python-dummy-ok
196 python-dummy-no-setuptools))
197 (for-each (lambda (p) (check-build-failure store p))
198 (list
199 python-dummy-fail-requirements
200 python-dummy-fail-import
201 python-dummy-fail-console-script)))
202
203 (test-end "builders")