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