diff options
Diffstat (limited to 'tests')
54 files changed, 2764 insertions, 359 deletions
diff --git a/tests/build-utils.scm b/tests/build-utils.scm index 654b480ed9..7f4f12ccc7 100644 --- a/tests/build-utils.scm +++ b/tests/build-utils.scm @@ -1,6 +1,9 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2012, 2015, 2016, 2019, 2020 Ludovic Courtès <[email protected]> ;;; Copyright © 2019 Ricardo Wurmus <[email protected]> +;;; Copyright © 2021 Maxim Cournoyer <[email protected]> +;;; Copyright © 2021 Maxime Devos <[email protected]> +;;; Copyright © 2021 Brendan Tildesley <[email protected]> ;;; ;;; This file is part of GNU Guix. ;;; @@ -18,7 +21,7 @@ ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. -(define-module (test-build-utils) +(define-module (test build-utils) #:use-module (guix tests) #:use-module (guix build utils) #:use-module ((guix utils) @@ -165,9 +168,7 @@ echo hello world")) "/some/path:/some/other/path")))) '(let ((cl (command-line))) (apply execl "/anything/cabbage-bash-1.2.3/bin/sh" - (car cl) - (cons (car cl) - (append '("") cl))))) + (car cl) (append (quote ()) cl)))) script-contents) (call-with-temporary-directory (lambda (directory) @@ -206,8 +207,7 @@ print('hello world')")) `(let ((cl (command-line))) (apply execl "/anything/cabbage-bash-1.2.3/bin/python3" (car cl) - (cons (car cl) - (append '("" "-and" "-args") cl))))) + (append '("-and" "-args") cl)))) script-contents) (call-with-temporary-directory (lambda (directory) @@ -241,4 +241,96 @@ print('hello world')")) "/some/other/path"))) #f))))) +(define (arg-test bash-args) + (call-with-temporary-directory + (lambda (directory) + (let ((script-file-name (string-append directory "/bash-test.sh"))) + (call-with-output-file script-file-name + (lambda (port) + (display (string-append "\ +#!" (which "bash") bash-args " +echo \"$#$0$*${A}\"") + port))) + + (display "Unwrapped script contents:\n") + (call-with-input-file script-file-name + (lambda (port) (display (get-string-all port)))) + (newline) (newline) + (chmod script-file-name #o777) + (setenv "A" "A") + (let* ((run-script (lambda _ + (open-pipe* + OPEN_READ + script-file-name "1" "2" "3 3" "4"))) + (pipe (run-script)) + (unwrapped-output (get-string-all pipe))) + (close-pipe pipe) + + (wrap-script script-file-name `("A" = ("A\nA"))) + + (display "Wrapped script contents:\n") + (call-with-input-file script-file-name + (lambda (port) (display (get-string-all port)))) + (newline) (newline) + + (let* ((pipe (run-script)) + (wrapped-output (get-string-all pipe))) + (close-pipe pipe) + (display "./bash-test.sh 1 2 3\\ 3 4 # Output:\n") + (display unwrapped-output) (newline) + (display "./bash-test.sh 1 2 3\\ 3 4 # Output (wrapped):\n") + (display wrapped-output) (newline) + (string=? (string-append unwrapped-output "A\n") + wrapped-output))))))) + +(test-assert "wrap-script, argument handling" + (arg-test "")) + +(test-assert "wrap-script, argument handling, bash --norc" + (arg-test " --norc")) + +(test-equal "substitute*, text contains a NUL byte, UTF-8" + "c\0d" + (with-fluids ((%default-port-encoding "UTF-8") + (%default-port-conversion-strategy 'error)) + ;; The GNU libc is locale sensitive. Depending on the value of LANG, the + ;; test could fail with "string contains #\\nul character: ~S" or "cannot + ;; convert wide string to output locale". + (setlocale LC_ALL "en_US.UTF-8") + (call-with-temporary-output-file + (lambda (file port) + (format port "a\0b") + (flush-output-port port) + + (substitute* file + (("a") "c") + (("b") "d")) + + (with-input-from-file file + (lambda _ + (get-string-all (current-input-port)))))))) + +(test-equal "search-input-file: exception if not found" + `((path) + (file . "does-not-exist")) + (guard (e ((search-error? e) + `((path . ,(search-error-path e)) + (file . ,(search-error-file e))))) + (search-input-file '() "does-not-exist"))) + +(test-equal "search-input-file: can find if existent" + (which "guile") + (search-input-file + `(("guile/bin" . ,(dirname (which "guile")))) + "guile")) + +(test-equal "search-input-file: can search in multiple directories" + (which "guile") + (call-with-temporary-directory + (lambda (directory) + (search-input-file + `(("irrelevant" . ,directory) + ("guile/bin" . ,(dirname (which "guile")))) + "guile")))) + (test-end) diff --git a/tests/builders.scm b/tests/builders.scm index fdcf38ded3..2853227465 100644 --- a/tests/builders.scm +++ b/tests/builders.scm @@ -1,5 +1,6 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2012, 2013, 2014, 2015, 2019 Ludovic Courtès <[email protected]> +;;; Copyright © 2012, 2013, 2014, 2015, 2018, 2019, 2021 Ludovic Courtès <[email protected]> +;;; Copyright © 2021 Lars-Dominik Braun <[email protected]> ;;; ;;; This file is part of GNU Guix. ;;; @@ -17,22 +18,28 @@ ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. -(define-module (test-builders) +(define-module (tests builders) #:use-module (guix download) #:use-module (guix build-system) #:use-module (guix build-system gnu) + #:use-module (guix build gnu-build-system) + #:use-module (guix build utils) + #:use-module (guix build-system python) + #:use-module (guix grafts) #:use-module (guix store) + #:use-module (guix monads) #:use-module (guix utils) #:use-module (guix base32) #:use-module (guix derivations) #:use-module (gcrypt hash) #:use-module (guix tests) - #:use-module ((guix packages) - #:select (package? - package-derivation package-native-search-paths)) + #:use-module (guix packages) #:use-module (gnu packages bootstrap) #:use-module (ice-9 match) + #:use-module (ice-9 textual-ports) #:use-module (srfi srfi-1) + #:use-module (srfi srfi-11) + #:use-module (srfi srfi-34) #:use-module (srfi srfi-64)) ;; Test the higher-level builders. @@ -43,6 +50,9 @@ (define url-fetch* (store-lower url-fetch)) +;; Globally disable grafts because they can trigger early builds. +(%graft? #f) + (test-begin "builders") @@ -78,4 +88,116 @@ (test-assert "gnu-build-system" (build-system? gnu-build-system)) +(define unpack (assoc-ref %standard-phases 'unpack)) + +(define compressors '(("gzip" . "gz") + ("xz" . "xz") + ("bzip2" . "bz2") + (#f . #f))) + +(for-each + (match-lambda + ((comp . ext) + + (unless (network-reachable?) (test-skip 1)) ;for bootstrap binaries + (test-equal (string-append "gnu-build-system unpack phase, " + "single file (compression: " + (if comp comp "None") ")") + "expected text" + (let*-values + (((name) "test") + ((compressed-name) (if ext + (string-append name "." ext) + name)) + ((file hash) (test-file %store compressed-name "expected text"))) + (call-with-temporary-directory + (lambda (dir) + (with-directory-excursion dir + (unpack #:source file) + (call-with-input-file name get-string-all)))))))) + compressors) + + +;;; +;;; Test the sanity-check phase of the Python build system. +;;; + +(define* (make-python-dummy name #:key (setup-py-extra "") + (init-py "") (use-setuptools? #t)) + (dummy-package (string-append "python-dummy-" name) + (version "0.1") + (build-system python-build-system) + (arguments + `(#:tests? #f + #:use-setuptools? ,use-setuptools? + #:phases + (modify-phases %standard-phases + (replace 'unpack + (lambda _ + (mkdir-p "dummy") + (with-output-to-file "dummy/__init__.py" + (lambda _ + (display ,init-py))) + (with-output-to-file "setup.py" + (lambda _ + (format #t "\ +~a +setup( + name='dummy-~a', + version='0.1', + packages=['dummy'], + ~a + )" + (if ,use-setuptools? + "from setuptools import setup" + "from distutils.core import setup") + ,name ,setup-py-extra)))))))))) + +(define python-dummy-ok + (make-python-dummy "ok")) + +;; distutil won't install any metadata, so make sure our script does not fail +;; on a otherwise fine package. +(define python-dummy-no-setuptools + (make-python-dummy + "no-setuptools" #:use-setuptools? #f)) + +(define python-dummy-fail-requirements + (make-python-dummy "fail-requirements" + #:setup-py-extra "install_requires=['nonexistent'],")) + +(define python-dummy-fail-import + (make-python-dummy "fail-import" #:init-py "import nonexistent")) + +(define python-dummy-fail-console-script + (make-python-dummy "fail-console-script" + #:setup-py-extra (string-append "entry_points={'console_scripts': " + "['broken = dummy:nonexistent']},"))) + +(define (check-build-success store p) + (unless store (test-skip 1)) + (test-assert (string-append "python-build-system: " (package-name p)) + (let* ((drv (package-derivation store p))) + (build-derivations store (list drv))))) + +(define (check-build-failure store p) + (unless store (test-skip 1)) + (test-assert (string-append "python-build-system: " (package-name p)) + (let ((drv (package-derivation store p))) + (guard (c ((store-protocol-error? c) + (pk 'failure c #t))) ;good! + (build-derivations store (list drv)) + #f)))) ;bad: it should have failed + +(with-external-store store + (for-each (lambda (p) (check-build-success store p)) + (list + python-dummy-ok + python-dummy-no-setuptools)) + (for-each (lambda (p) (check-build-failure store p)) + (list + python-dummy-fail-requirements + python-dummy-fail-import + python-dummy-fail-console-script))) + (test-end "builders") diff --git a/tests/channels.scm b/tests/channels.scm index 3e82315b0c..d45c450241 100644 --- a/tests/channels.scm +++ b/tests/channels.scm @@ -480,8 +480,8 @@ #t (with-fresh-gnupg-setup (list %ed25519-public-key-file %ed25519-secret-key-file - %ed25519bis-public-key-file - %ed25519bis-secret-key-file) + %ed25519-2-public-key-file + %ed25519-2-secret-key-file) (with-temporary-git-repository directory `((add ".guix-channel" ,(object->string @@ -507,7 +507,7 @@ (commit-id-string commit1) (openpgp-public-key-fingerprint (read-openpgp-packet - %ed25519bis-public-key-file)))) ;different key + %ed25519-2-public-key-file)))) ;different key (channel (channel (name 'example) (url (string-append "file://" directory)) (introduction intro)))) @@ -519,7 +519,7 @@ (oid->string (commit-id commit1)) (key-fingerprint %ed25519-public-key-file) (key-fingerprint - %ed25519bis-public-key-file)))))) + %ed25519-2-public-key-file)))))) (authenticate-channel channel directory (commit-id-string commit2) #:keyring-reference-prefix "") @@ -530,8 +530,8 @@ #t (with-fresh-gnupg-setup (list %ed25519-public-key-file %ed25519-secret-key-file - %ed25519bis-public-key-file - %ed25519bis-secret-key-file) + %ed25519-2-public-key-file + %ed25519-2-secret-key-file) (with-temporary-git-repository directory `((add ".guix-channel" ,(object->string @@ -552,12 +552,12 @@ (signer ,(key-fingerprint %ed25519-public-key-file))) (add "c.txt" "C") (commit "third commit" - (signer ,(key-fingerprint %ed25519bis-public-key-file))) + (signer ,(key-fingerprint %ed25519-2-public-key-file))) (branch "channel-keyring") (checkout "channel-keyring") (add "signer.key" ,(call-with-input-file %ed25519-public-key-file get-string-all)) - (add "other.key" ,(call-with-input-file %ed25519bis-public-key-file + (add "other.key" ,(call-with-input-file %ed25519-2-public-key-file get-string-all)) (commit "keyring commit") (checkout "master")) @@ -588,7 +588,7 @@ (unauthorized-commit-error-signing-key c)) (openpgp-public-key-fingerprint (read-openpgp-packet - %ed25519bis-public-key-file)))))) + %ed25519-2-public-key-file)))))) (authenticate-channel channel directory (commit-id-string commit3) #:keyring-reference-prefix "") diff --git a/tests/cran.scm b/tests/cran.scm index 70d2277198..5c820b1ab3 100644 --- a/tests/cran.scm +++ b/tests/cran.scm @@ -36,7 +36,7 @@ Author: Ricardo Wurmus Maintainer: Guix Schmeeks <[email protected]> URL: http://gnu.org/s/my-example Description: This is a long description -spanning multiple lines: and it could confuse the parser that +spanning multiple lines: and it could confuse the parser that this line is very long or perhaps the fact that there is a colon : on the lines. And: this line continues the description. biocViews: 0 @@ -117,21 +117,16 @@ Date/Publication: 2015-07-14 14:15:16 (? string? hash))))) ('properties ('quasiquote (('upstream-name . "My-Example")))) ('build-system 'r-build-system) - ('inputs - ('quasiquote - (("cairo" ('unquote 'cairo))))) + ('inputs ('list 'cairo)) ('propagated-inputs - ('quasiquote - (("r-bh" ('unquote 'r-bh)) - ("r-proto" ('unquote 'r-proto)) - ("r-rcpp" ('unquote 'r-rcpp)) - ("r-scales" ('unquote 'r-scales))))) + ('list 'r-bh 'r-proto 'r-rcpp 'r-scales)) ('home-page "http://gnu.org/s/my-example") ('synopsis "Example package") ('description - "This is a long description spanning multiple lines: \ -and it could confuse the parser that there is a colon : on the \ -lines. And: this line continues the description.") + "\ +This is a long description spanning multiple lines: and it could confuse the +parser that this line is very long or perhaps the fact that there is a colon : +on the lines. And: this line continues the description.") ('license 'gpl3+)) #t) (x diff --git a/tests/derivations.scm b/tests/derivations.scm index cd165d1be6..0775719ea3 100644 --- a/tests/derivations.scm +++ b/tests/derivations.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Ludovic Courtès <[email protected]> +;;; Copyright © 2012-2021 Ludovic Courtès <[email protected]> ;;; ;;; This file is part of GNU Guix. ;;; @@ -170,11 +170,15 @@ #f)))) (test-assert "identical files are deduplicated" - (let* ((build1 (add-text-to-store %store "one.sh" - "echo hello, world > \"$out\"\n" + ;; Note: DATA must be longer than %DEDUPLICATION-MINIMUM-SIZE. + (let* ((data (make-string 9000 #\a)) + (build1 (add-text-to-store %store "one.sh" + (string-append "echo -n " data + " > \"$out\"\n") '())) (build2 (add-text-to-store %store "two.sh" - "# Hey!\necho hello, world > \"$out\"\n" + (string-append "# Hey!\necho -n " + data " > \"$out\"\n") '())) (drv1 (derivation %store "foo" %bash `(,build1) @@ -187,7 +191,7 @@ (file2 (derivation->output-path drv2))) (and (valid-path? %store file1) (valid-path? %store file2) (string=? (call-with-input-file file1 get-string-all) - "hello, world\n") + data) (= (stat:ino (lstat file1)) (stat:ino (lstat file2)))))))) diff --git a/tests/egg.scm b/tests/egg.scm index 0884d8d429..a7d3378dd7 100644 --- a/tests/egg.scm +++ b/tests/egg.scm @@ -1,5 +1,6 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2021 Xinglu Chen <[email protected]> +;;; Copyright © 2021 Sarah Morgensen <[email protected]> ;;; ;;; This file is part of GNU Guix. ;;; @@ -72,7 +73,7 @@ (call-with-output-file egg-file (lambda (port) (write egg-test port))) - (matcher (egg->guix-package egg-name + (matcher (egg->guix-package egg-name #f #:file egg-file #:source (plain-file (string-append egg-name "-egg") @@ -86,16 +87,9 @@ ('build-system 'chicken-build-system) ('arguments ('quasiquote ('#:egg-name "foo"))) ('native-inputs - ('quasiquote - (("chicken-test" ('unquote chicken-test)) - ("chicken-srfi-1" ('unquote chicken-srfi-1)) - ("chicken-begin-syntax" ('unquote chicken-begin-syntax))))) - ('inputs - ('quasiquote - (("libgit2" ('unquote libgit2))))) - ('propagated-inputs - ('quasiquote - (("chicken-datatype" ('unquote chicken-datatype))))) + ('list 'chicken-test 'chicken-srfi-1 'chicken-begin-syntax)) + ('inputs ('list 'libgit2)) + ('propagated-inputs ('list 'chicken-datatype)) ('home-page "https://wiki.call-cc.org/egg/foo") ('synopsis "Example egg") ('description #f) @@ -108,16 +102,9 @@ ('source (? file-like? source)) ('build-system 'chicken-build-system) ('arguments ('quasiquote ('#:egg-name "bar"))) - ('native-inputs - ('quasiquote - (("chicken-test" ('unquote chicken-test)) - ("chicken-begin-syntax" ('unquote chicken-begin-syntax))))) - ('inputs - ('quasiquote - (("libgit2" ('unquote libgit2))))) - ('propagated-inputs - ('quasiquote - (("chicken-datatype" ('unquote chicken-datatype))))) + ('native-inputs ('list 'chicken-test 'chicken-begin-syntax)) + ('inputs ('list 'libgit2)) + ('propagated-inputs ('list 'chicken-datatype)) ('home-page "https://wiki.call-cc.org/egg/bar") ('synopsis "Example egg") ('description #f) diff --git a/tests/elpa.scm b/tests/elpa.scm index 01ef948b2e..1efdf2457f 100644 --- a/tests/elpa.scm +++ b/tests/elpa.scm @@ -2,6 +2,7 @@ ;;; Copyright © 2015 Federico Beffa <[email protected]> ;;; Copyright © 2020 Ludovic Courtès <[email protected]> ;;; Copyright © 2020 Martin Becze <[email protected]> +;;; Copyright © 2021 Xinglu Chen <[email protected]> ;;; ;;; This file is part of GNU Guix. ;;; @@ -20,6 +21,7 @@ (define-module (test-elpa) #:use-module (guix import elpa) + #:use-module (guix tests) #:use-module (guix tests http) #:use-module (srfi srfi-1) #:use-module (srfi srfi-64) @@ -71,6 +73,16 @@ (test-assert "elpa->guix-package test 1" (eval-test-with-elpa "auctex")) +(test-equal "guix-package->elpa-name: without 'upstream-name' property" + "auctex" + (guix-package->elpa-name (dummy-package "emacs-auctex"))) + +(test-equal "guix-package->elpa-name: with 'upstream-name' property" + "project" + (guix-package->elpa-name + (dummy-package "emacs-fake-name" + (properties '((upstream-name . "project")))))) + (test-end "elpa") ;; Local Variables: diff --git a/tests/gem.scm b/tests/gem.scm index 751bba656f..c8fe15398e 100644 --- a/tests/gem.scm +++ b/tests/gem.scm @@ -2,6 +2,7 @@ ;;; Copyright © 2015 David Thompson <[email protected]> ;;; Copyright © 2016 Ricardo Wurmus <[email protected]> ;;; Copyright © 2018 Oleg Pykhalov <[email protected]> +;;; Copyright © 2021 Sarah Morgensen <[email protected]> ;;; ;;; This file is part of GNU Guix. ;;; @@ -93,10 +94,7 @@ ('base32 "1a270mlajhrmpqbhxcqjqypnvgrq4pgixpv3w9gwp1wrrapnwrzk")))) ('build-system 'ruby-build-system) - ('propagated-inputs - ('quasiquote - (("bundler" ('unquote 'bundler)) - ("ruby-bar" ('unquote 'ruby-bar))))) + ('propagated-inputs ('list 'bundler 'ruby-bar)) ('synopsis "A cool gem") ('description "This package provides a cool gem") ('home-page "https://example.com") @@ -132,9 +130,7 @@ ('base32 "1a270mlajhrmpqbhxcqjqypnvgrq4pgixpv3w9gwp1wrrapnwrzk")))) ('build-system 'ruby-build-system) - ('propagated-inputs - ('quasiquote - (('"bundler" ('unquote 'bundler))))) + ('propagated-inputs ('list 'bundler)) ('synopsis "Another cool gem") ('description "Another cool gem") ('home-page "https://example.com") @@ -165,10 +161,7 @@ ('base32 "1a270mlajhrmpqbhxcqjqypnvgrq4pgixpv3w9gwp1wrrapnwrzk")))) ('build-system 'ruby-build-system) - ('propagated-inputs - ('quasiquote - (("bundler" ('unquote 'bundler)) - ("ruby-bar" ('unquote 'ruby-bar))))) + ('propagated-inputs ('list 'bundler 'ruby-bar)) ('synopsis "A cool gem") ('description "This package provides a cool gem") ('home-page "https://example.com") diff --git a/tests/gexp.scm b/tests/gexp.scm index 39a47d4e8c..ad8e1d57b8 100644 --- a/tests/gexp.scm +++ b/tests/gexp.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021 Ludovic Courtès <[email protected]> +;;; Copyright © 2014-2021 Ludovic Courtès <[email protected]> ;;; Copyright © 2021 Maxime Devos <[email protected]> ;;; ;;; This file is part of GNU Guix. @@ -127,6 +127,13 @@ (null? (gexp-inputs exp)) (gexp->sexp* exp)))) +(test-equal "sexp->gexp" + '(a b (c d) e) + (let ((exp (sexp->gexp '(a b (c d) e)))) + (and (gexp? exp) + (null? (gexp-inputs exp)) + (gexp->sexp* exp)))) + (test-equal "unquote" '(display `(foo ,(+ 2 3))) (let ((exp (gexp (display `(foo ,(+ 2 3)))))) @@ -434,6 +441,17 @@ '(system-binding))) (x x))))) +(test-assert "let-system in file-append" + (let ((mixed (file-append (let-system (system target) + (if (not target) grep sed)) + "/bin")) + (grep (file-append grep "/bin")) + (sed (file-append sed "/bin"))) + (and (equal? (gexp->sexp* #~(list #$mixed)) + (gexp->sexp* #~(list #$grep))) + (equal? (gexp->sexp* #~(list #$mixed) "powerpc64le-linux-gnu") + (gexp->sexp* #~(list #$sed) "powerpc64le-linux-gnu"))))) + (test-assert "ungexp + ungexp-native" (let* ((exp (gexp (list (ungexp-native %bootstrap-guile) (ungexp coreutils) @@ -827,19 +845,14 @@ (files -> `(("a/b/c" . ,q-scm) ("p/q" . ,plain))) (drv (imported-files files))) - (define (file=? file1 file2) - ;; Assume deduplication is in place. - (= (stat:ino (stat file1)) - (stat:ino (stat file2)))) - (mbegin %store-monad (built-derivations (list (pk 'drv drv))) (mlet %store-monad ((dir -> (derivation->output-path drv)) (plain* (text-file "foo" "bar!")) (q-scm* (interned-file q-scm "c"))) (return - (and (file=? (string-append dir "/a/b/c") q-scm*) - (file=? (string-append dir "/p/q") plain*))))))) + (and (file=? (string-append dir "/a/b/c") q-scm* stat) + (file=? (string-append dir "/p/q") plain* stat))))))) (test-equal "gexp-modules & ungexp" '((bar) (foo)) @@ -1468,6 +1481,42 @@ importing.* \\(guix config\\) from the host" (string=? (readlink (string-append comp "/text")) text))))))) +(test-assert "lower-object, computed-file + grafts" + ;; The reference graph should refer to grafted packages when grafts are + ;; enabled. See <https://issues.guix.gnu.org/50676>. + (let* ((base (package + (inherit (dummy-package "trivial")) + (build-system trivial-build-system) + (arguments + `(#:guile ,%bootstrap-guile + #:builder (mkdir %output))))) + (pkg (package + (inherit base) + (version "1.1") + (replacement (package + (inherit base) + (version "9.9"))))) + (exp #~(begin + (use-modules (ice-9 rdelim)) + (let ((item (call-with-input-file "graph" read-line))) + (call-with-output-file #$output + (lambda (port) + (display item port)))))) + (computed (computed-file "computed" exp + #:options + `(#:references-graphs (("graph" ,pkg))))) + (drv0 (package-derivation %store pkg #:graft? #t)) + (drv1 (parameterize ((%graft? #t)) + (run-with-store %store + (lower-object computed))))) + (build-derivations %store (list drv1)) + + ;; The graph obtained in COMPUTED should refer to the grafted version of + ;; PKG, not to PKG itself. + (string=? (call-with-input-file (derivation->output-path drv1) + get-string-all) + (derivation->output-path drv0)))) + (test-equal "lower-object, computed-file, #:system" '("mips64el-linux") (run-with-store %store diff --git a/tests/git-authenticate.scm b/tests/git-authenticate.scm index d87eacc659..f66ef191b0 100644 --- a/tests/git-authenticate.scm +++ b/tests/git-authenticate.scm @@ -161,14 +161,14 @@ (test-assert "signed commits, .guix-authorizations, unauthorized merge" (with-fresh-gnupg-setup (list %ed25519-public-key-file %ed25519-secret-key-file - %ed25519bis-public-key-file - %ed25519bis-secret-key-file) + %ed25519-2-public-key-file + %ed25519-2-secret-key-file) (with-temporary-git-repository directory `((add "signer1.key" ,(call-with-input-file %ed25519-public-key-file get-string-all)) (add "signer2.key" - ,(call-with-input-file %ed25519bis-public-key-file + ,(call-with-input-file %ed25519-2-public-key-file get-string-all)) (add ".guix-authorizations" ,(object->string @@ -184,7 +184,7 @@ (checkout "devel") (add "devel/1.txt" "1") (commit "first devel commit" - (signer ,(key-fingerprint %ed25519bis-public-key-file))) + (signer ,(key-fingerprint %ed25519-2-public-key-file))) (checkout "master") (add "b.txt" "B") (commit "second commit" @@ -203,7 +203,7 @@ (openpgp-public-key-fingerprint (unauthorized-commit-error-signing-key c)) (openpgp-public-key-fingerprint - (read-openpgp-packet %ed25519bis-public-key-file))))) + (read-openpgp-packet %ed25519-2-public-key-file))))) (and (authenticate-commits repository (list master1 master2) #:keyring-reference "master") @@ -230,14 +230,14 @@ (test-assert "signed commits, .guix-authorizations, authorized merge" (with-fresh-gnupg-setup (list %ed25519-public-key-file %ed25519-secret-key-file - %ed25519bis-public-key-file - %ed25519bis-secret-key-file) + %ed25519-2-public-key-file + %ed25519-2-secret-key-file) (with-temporary-git-repository directory `((add "signer1.key" ,(call-with-input-file %ed25519-public-key-file get-string-all)) (add "signer2.key" - ,(call-with-input-file %ed25519bis-public-key-file + ,(call-with-input-file %ed25519-2-public-key-file get-string-all)) (add ".guix-authorizations" ,(object->string @@ -258,12 +258,12 @@ %ed25519-public-key-file) (name "Alice")) (,(key-fingerprint - %ed25519bis-public-key-file)))))) + %ed25519-2-public-key-file)))))) (commit "first devel commit" (signer ,(key-fingerprint %ed25519-public-key-file))) (add "devel/2.txt" "2") (commit "second devel commit" - (signer ,(key-fingerprint %ed25519bis-public-key-file))) + (signer ,(key-fingerprint %ed25519-2-public-key-file))) (checkout "master") (add "b.txt" "B") (commit "second commit" @@ -273,7 +273,7 @@ ;; After the merge, the second signer is authorized. (add "c.txt" "C") (commit "third commit" - (signer ,(key-fingerprint %ed25519bis-public-key-file)))) + (signer ,(key-fingerprint %ed25519-2-public-key-file)))) (with-repository directory repository (let ((master1 (find-commit repository "first commit")) (master2 (find-commit repository "second commit")) @@ -328,4 +328,3 @@ 'failed))))))) (test-end "git-authenticate") - diff --git a/tests/gremlin.scm b/tests/gremlin.scm index b0bb7a8e49..3dbb8d3643 100644 --- a/tests/gremlin.scm +++ b/tests/gremlin.scm @@ -1,5 +1,7 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2015, 2018 Ludovic Courtès <[email protected]> +;;; Copyright © 2015, 2018, 2020, 2022 Ludovic Courtès <[email protected]> +;;; Copyright © 2022 Chris Marusich <[email protected]> +;;; Copyright © 2022 Pierre Langlois <[email protected]> ;;; ;;; This file is part of GNU Guix. ;;; @@ -18,14 +20,20 @@ (define-module (test-gremlin) #:use-module (guix elf) - #:use-module ((guix utils) #:select (call-with-temporary-directory)) + #:use-module (guix tests) + #:use-module ((guix utils) #:select (call-with-temporary-directory + target-aarch64?)) #:use-module (guix build utils) #:use-module (guix build gremlin) + #:use-module (gnu packages bootstrap) #:use-module (srfi srfi-1) #:use-module (srfi srfi-26) + #:use-module (srfi srfi-34) #:use-module (srfi srfi-64) #:use-module (rnrs io ports) #:use-module (ice-9 popen) + #:use-module (ice-9 rdelim) + #:use-module (ice-9 regex) #:use-module (ice-9 match)) (define %guile-executable @@ -57,6 +65,57 @@ (string-take lib (string-contains lib ".so"))) (elf-dynamic-info-needed dyninfo)))))) +(unless (and %guile-executable (not (getenv "LD_LIBRARY_PATH")) + (file-needed %guile-executable) ;statically linked? + ;; When Guix has been built on a foreign distro, using a + ;; toolchain and libraries from that foreign distro, it is not + ;; unusual for the runpath to be empty. + (pair? (file-runpath %guile-executable))) + (test-skip 1)) +(test-assert "file-needed/recursive" + (let* ((needed (file-needed/recursive %guile-executable)) + (pipe (dynamic-wind + (lambda () + ;; Tell ld.so to list loaded objects, like 'ldd' does. + (setenv "LD_TRACE_LOADED_OBJECTS" "yup")) + (lambda () + (open-pipe* OPEN_READ %guile-executable)) + (lambda () + (unsetenv "LD_TRACE_LOADED_OBJECTS"))))) + (define ldd-rx + (make-regexp "^[[:blank:]]+([[:graph:]]+ => )?([[:graph:]]+) .*$")) + + (define (read-ldd-output port) + ;; Read from PORT output in GNU ldd format. + (let loop ((result '())) + (match (read-line port) + ((? eof-object?) + (reverse result)) + ((= (cut regexp-exec ldd-rx <>) m) + (if m + (loop (cons (match:substring m 2) result)) + (loop result)))))) + (define ground-truth + (remove (lambda (entry) + ;; See vdso(7) for the list of vDSO names across + ;; architectures. + (or (string-prefix? "linux-vdso.so" entry) + (string-prefix? "linux-vdso32.so" entry) ;32-bit powerpc + (string-prefix? "linux-vdso64.so" entry) ;64-bit powerpc + (string-prefix? "linux-gate.so" entry) ;i386 + ;; FIXME: ELF files on aarch64 do not always include a + ;; NEEDED entry for the dynamic linker, and it is unclear + ;; if that is OK. See: https://issues.guix.gnu.org/52943 + (and (target-aarch64?) + (string-contains entry (glibc-dynamic-linker))))) + (read-ldd-output pipe))) + + (and (zero? (close-pipe pipe)) + ;; It's OK if file-needed/recursive returns multiple entries that are + ;; different strings referring to the same file. This appears to be a + ;; benign edge case. See: https://issues.guix.gnu.org/52940 + (lset= file=? (pk 'truth ground-truth) (pk 'needed needed))))) + (test-equal "expand-origin" '("OOO/../lib" "OOO" @@ -96,4 +155,49 @@ (close-pipe pipe) str))))))) +(unless c-compiler + (test-skip 1)) +(test-equal "set-file-runpath + file-runpath" + "hello\n" + (call-with-temporary-directory + (lambda (directory) + (with-directory-excursion directory + (call-with-output-file "t.c" + (lambda (port) + (display "int main () { puts(\"hello\"); }" port))) + + (invoke c-compiler "t.c" + "-Wl,--enable-new-dtags" "-Wl,-rpath=/xxxxxxxxx") + + (let ((original-runpath (file-runpath "a.out"))) + (and (member "/xxxxxxxxx" original-runpath) + (guard (c ((runpath-too-long-error? c) + (string=? "a.out" (runpath-too-long-error-file c)))) + (set-file-runpath "a.out" (list (make-string 777 #\y)))) + (let ((runpath (delete "/xxxxxxxxx" original-runpath))) + (set-file-runpath "a.out" runpath) + (equal? runpath (file-runpath "a.out"))) + (let* ((pipe (open-input-pipe "./a.out")) + (str (get-string-all pipe))) + (close-pipe pipe) + str))))))) + +(unless c-compiler + (test-skip 1)) +(test-equal "elf-dynamic-info-soname" + "libfoo.so.2" + (call-with-temporary-directory + (lambda (directory) + (with-directory-excursion directory + (call-with-output-file "t.c" + (lambda (port) + (display "// empty file" port))) + (invoke c-compiler "t.c" + "-shared" "-Wl,-soname,libfoo.so.2") + (let* ((dyninfo (elf-dynamic-info + (parse-elf (call-with-input-file "a.out" + get-bytevector-all)))) + (soname (elf-dynamic-info-soname dyninfo))) + soname))))) + (test-end "gremlin") diff --git a/tests/guix-authenticate.sh b/tests/guix-authenticate.sh index 3a05b232c1..0de6da1878 100644 --- a/tests/guix-authenticate.sh +++ b/tests/guix-authenticate.sh @@ -28,7 +28,7 @@ rm -f "$sig" "$hash" trap 'rm -f "$sig" "$hash"' EXIT -key="$abs_top_srcdir/tests/signing-key.sec" +key="$abs_top_srcdir/tests/keys/signing-key.sec" key_len="`echo -n $key | wc -c`" # A hexadecimal string as long as a sha256 hash. @@ -67,7 +67,7 @@ test "$code" -ne 0 # encoded independently of the current locale: <https://bugs.gnu.org/43421>. hash="636166e9636166e9636166e9636166e9636166e9636166e9636166e9636166e9" latin1_cafe="caf$(printf '\351')" -echo "sign 21:tests/signing-key.sec 64:$hash" | guix authenticate \ +echo "sign 26:tests/keys/signing-key.sec 64:$hash" | guix authenticate \ | LC_ALL=C grep "hash sha256 \"$latin1_cafe" # Test for <http://bugs.gnu.org/17312>: make sure 'guix authenticate' produces diff --git a/tests/guix-build.sh b/tests/guix-build.sh index e20702c521..86e41e2927 100644 --- a/tests/guix-build.sh +++ b/tests/guix-build.sh @@ -1,5 +1,5 @@ # GNU Guix --- Functional package management for GNU -# Copyright © 2012, 2013, 2014, 2016, 2017, 2018, 2019, 2020 Ludovic Courtès <[email protected]> +# Copyright © 2012, 2013, 2014, 2016, 2017, 2018, 2019, 2020, 2021 Ludovic Courtès <[email protected]> # Copyright © 2020 Marius Bakke <[email protected]> # Copyright © 2021 Chris Marusich <[email protected]> # @@ -77,6 +77,16 @@ module_dir="t-guix-build-$$" mkdir "$module_dir" trap "rm -rf $module_dir" EXIT +# Check error reporting for '-f'. +cat > "$module_dir/foo.scm" <<EOF +(use-modules (guix)) +) ;extra closing paren +EOF +! guix build -f "$module_dir/foo.scm" 2> "$module_dir/stderr" +grep "read error" "$module_dir/stderr" +rm "$module_dir/stderr" "$module_dir/foo.scm" + +# Check 'GUIX_PACKAGE_PATH' & co. cat > "$module_dir/foo.scm"<<EOF (define-module (foo) #:use-module (guix tests) @@ -278,7 +288,7 @@ guix build --target=arm-linux-gnueabihf --dry-run \ -e '(@ (gnu packages base) coreutils)' # Replacements. -drv1=`guix build guix [email protected][email protected] -d` +drv1=`guix build guix --with-input=guile-zstd=idutils -d` drv2=`guix build guix -d` test "$drv1" != "$drv2" diff --git a/tests/guix-environment-container.sh b/tests/guix-environment-container.sh index f2d15c8d0c..2e238c501d 100644 --- a/tests/guix-environment-container.sh +++ b/tests/guix-environment-container.sh @@ -44,6 +44,14 @@ else test $? = 42 fi +# Try '--root' and '--profile'. +root="$tmpdir/root" +guix environment -C --ad-hoc --bootstrap guile-bootstrap -r "$root" -- guile --version +guix environment -C -p "$root" --bootstrap -- guile --version +path1=$(guix environment -C -p "$root" --bootstrap -- guile -c '(display (getenv "PATH"))') +path2=$(guix environment -C --ad-hoc --bootstrap guile-bootstrap -- guile -c '(display (getenv "PATH"))') +test "$path1" = "$path2" + # Make sure "localhost" resolves. guix environment --container --ad-hoc --bootstrap guile-bootstrap \ -- guile -c '(exit (pair? (getaddrinfo "localhost" "80")))' diff --git a/tests/guix-environment.sh b/tests/guix-environment.sh index afadcbe195..95fe95b437 100644 --- a/tests/guix-environment.sh +++ b/tests/guix-environment.sh @@ -119,6 +119,13 @@ test `readlink "$gcroot"` = "$expected" guix environment --bootstrap -r "$gcroot" --ad-hoc guile-bootstrap \ -- guile -c 1 test `readlink "$gcroot"` = "$expected" + +# Make sure '-p' works as expected. +test $(guix environment -p "$gcroot" -- "$SHELL" -c 'echo $GUIX_ENVIRONMENT') = "$expected" +paths1="$(guix environment -p "$gcroot" --search-paths)" +paths2="$(guix environment --bootstrap --ad-hoc guile-bootstrap --search-paths)" +test "$paths1" = "$paths2" + rm "$gcroot" # Try '-r' with a relative file name. @@ -192,7 +199,7 @@ then # Make sure the bootstrap binaries are all listed where they belong. grep -E "^export PATH=\"$profile/bin\"" "$tmpdir/a" - grep -E "^export CPATH=\"$profile/include\"" "$tmpdir/a" + grep -E "^export C_INCLUDE_PATH=\"$profile/include\"" "$tmpdir/a" grep -E "^export LIBRARY_PATH=\"$profile/lib\"" "$tmpdir/a" for dep in bootstrap-binaries-0 gcc-bootstrap-0 glibc-bootstrap-0 do @@ -206,8 +213,8 @@ then # as returned by '--search-paths'. guix environment --bootstrap --no-substitutes --pure \ -e '(@ (guix tests) gnu-make-for-tests)' \ - -- /bin/sh -c 'echo $PATH $CPATH $LIBRARY_PATH' > "$tmpdir/b" - ( . "$tmpdir/a" ; echo $PATH $CPATH $LIBRARY_PATH ) > "$tmpdir/c" + -- /bin/sh -c 'echo $PATH $C_INCLUDE_PATH $LIBRARY_PATH' > "$tmpdir/b" + ( . "$tmpdir/a" ; echo $PATH $C_INCLUDE_PATH $LIBRARY_PATH ) > "$tmpdir/c" cmp "$tmpdir/b" "$tmpdir/c" rm "$tmpdir"/* @@ -228,7 +235,7 @@ then # Make sure the bootstrap binaries are all listed where they belong. grep -E "^export PATH=\"$profile/bin\"" "$tmpdir/a" - grep -E "^export CPATH=\"$profile/include\"" "$tmpdir/a" + grep -E "^export C_INCLUDE_PATH=\"$profile/include\"" "$tmpdir/a" grep -E "^export LIBRARY_PATH=\"$profile/lib\"" "$tmpdir/a" for dep in bootstrap-binaries-0 gcc-bootstrap-0 glibc-bootstrap-0 \ guile-bootstrap diff --git a/tests/guix-graph.sh b/tests/guix-graph.sh index 666660ab4b..e813e01c31 100644 --- a/tests/guix-graph.sh +++ b/tests/guix-graph.sh @@ -1,5 +1,5 @@ # GNU Guix --- Functional package management for GNU -# Copyright © 2015, 2016, 2019, 2020 Ludovic Courtès <[email protected]> +# Copyright © 2015-2016, 2019-2020, 2022 Ludovic Courtès <[email protected]> # Copyright © 2019 Simon Tournier <[email protected]> # # This file is part of GNU Guix. @@ -23,11 +23,10 @@ module_dir="t-guix-graph-$$" mkdir "$module_dir" -trap "rm -rf $module_dir" EXIT tmpfile1="$module_dir/t-guix-graph1-$$" tmpfile2="$module_dir/t-guix-graph2-$$" -trap 'rm -f "$tmpfile1" "$tmpfile2"' EXIT +trap 'rm -r "$module_dir"' EXIT cat > "$module_dir/foo.scm"<<EOF diff --git a/tests/guix-hash.sh b/tests/guix-hash.sh index c4461fa955..8b03c7985d 100644 --- a/tests/guix-hash.sh +++ b/tests/guix-hash.sh @@ -34,6 +34,15 @@ test `guix hash -f base32 /dev/null` = 4oymiquy7qobjgx36tejs35zeqt24qpemsnzgtfes test `guix hash -H sha512 -f hex /dev/null` = cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e test `guix hash -H sha1 -f base64 /dev/null` = "2jmj7l5rSw0yVb/vlWAYkK/YBwk=" +# Several files. +test "`guix hash /dev/null "$abs_top_srcdir/README"`" = "`guix hash /dev/null ; guix hash "$abs_top_srcdir/README"`" + +# Zero files. +! guix hash + +# idem as `cat /dev/null | git hash-object --stdin` +test `guix hash -S git -H sha1 -f hex /dev/null` = e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 + ! guix hash -H abcd1234 /dev/null mkdir "$tmpdir" @@ -42,25 +51,33 @@ chmod +x "$tmpdir/exe" ( cd "$tmpdir" ; ln -s exe symlink ) mkdir "$tmpdir/subdir" -test `guix hash -r "$tmpdir"` = 10k1lw41wyrjf9mxydi0is5nkpynlsvgslinics4ppir13g7d74p -test `guix hash -r "$tmpdir" -H sha512` = 301ra58c2vahczzxiyfin41mpyb0ljh4dh9zn3ijvwviaw1j40sfzw5skh9x945da88n3785ggifzig7acd6k72h0mpsc20m1f66m9n +test `guix hash -S nar "$tmpdir"` = 10k1lw41wyrjf9mxydi0is5nkpynlsvgslinics4ppir13g7d74p +test `guix hash -S nar "$tmpdir" -H sha512` = 301ra58c2vahczzxiyfin41mpyb0ljh4dh9zn3ijvwviaw1j40sfzw5skh9x945da88n3785ggifzig7acd6k72h0mpsc20m1f66m9n +test `guix hash -S git "$tmpdir"` = 1m9yxz99g7askm88h6hzyv4g2bfv57rp5wvwp3iq5ypsplq1xkkk +test `guix hash -S git "$tmpdir" -H sha512` = 158b10d1bsdk4pm8ym9cg9ckfak1b0cgpw7365cl6s341ir380mh2f4ylicyh8khyrfnwq5cn9766d7m8fbfwwl94ndkv456v6a8knr + +# Deprecated --recursive option +test `guix hash -r "$tmpdir" 2>/dev/null` = 10k1lw41wyrjf9mxydi0is5nkpynlsvgslinics4ppir13g7d74p +test `guix hash -r "$tmpdir" -H sha512 2>/dev/null` = 301ra58c2vahczzxiyfin41mpyb0ljh4dh9zn3ijvwviaw1j40sfzw5skh9x945da88n3785ggifzig7acd6k72h0mpsc20m1f66m9n # Without '-r', this should fail. ! guix hash "$tmpdir" # This should fail because /dev/null is a character device, which # the archive format doesn't support. -! guix hash -r /dev/null +! guix hash -S nar /dev/null # Adding a .git directory mkdir "$tmpdir/.git" touch "$tmpdir/.git/foo" # ...changes the hash -test `guix hash -r $tmpdir` = 0a50z04zyzf7pidwxv0nwbj82pgzbrhdy9562kncnvkcfvb48m59 +test `guix hash -S nar $tmpdir` = 0a50z04zyzf7pidwxv0nwbj82pgzbrhdy9562kncnvkcfvb48m59 +test `guix hash -S git $tmpdir` = 0ghlpca9xaswa1ay1g55dknwd9q899mi3ahfr43pq083v8wisjc7 # ...but remains the same when using `-x' -test `guix hash -r $tmpdir -x` = 10k1lw41wyrjf9mxydi0is5nkpynlsvgslinics4ppir13g7d74p +test `guix hash -S nar $tmpdir -x` = 10k1lw41wyrjf9mxydi0is5nkpynlsvgslinics4ppir13g7d74p +test `guix hash -S git $tmpdir -x` = 1m9yxz99g7askm88h6hzyv4g2bfv57rp5wvwp3iq5ypsplq1xkkk # Without '-r', this should fail. ! guix hash "$tmpdir" diff --git a/tests/guix-home.sh b/tests/guix-home.sh new file mode 100644 index 0000000000..e578559c97 --- /dev/null +++ b/tests/guix-home.sh @@ -0,0 +1,131 @@ + +# GNU Guix --- Functional package management for GNU +# Copyright © 2021 Andrew Tropin <[email protected]> +# Copyright © 2021 Oleg Pykhalov <[email protected]> +# +# This file is part of GNU Guix. +# +# GNU Guix is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or (at +# your option) any later version. +# +# GNU Guix is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. + +# +# Test the 'guix home' using the external store, if any. +# + +set -e + +guix home --version + +NIX_STORE_DIR="$(guile -c '(use-modules (guix config))(display %storedir)')" +localstatedir="$(guile -c '(use-modules (guix config))(display %localstatedir)')" +GUIX_DAEMON_SOCKET="$localstatedir/guix/daemon-socket/socket" +export NIX_STORE_DIR GUIX_DAEMON_SOCKET + +# Run tests only when a "real" daemon is available. +if ! guile -c '(use-modules (guix)) (exit (false-if-exception (open-connection)))' +then + exit 77 +fi + +STORE_PARENT="$(dirname "$NIX_STORE_DIR")" +export STORE_PARENT +if test "$STORE_PARENT" = "/"; then exit 77; fi + +test_directory="$(mktemp -d)" +trap 'chmod -Rf +w "$test_directory"; rm -rf "$test_directory"' EXIT + +( + cd "$test_directory" || exit 77 + + HOME="$test_directory" + export HOME + + # + # Test 'guix home reconfigure'. + # + + printf "# dot-bashrc test file for guix home" > "dot-bashrc" + + cat > "home.scm" <<'EOF' +(use-modules (guix gexp) + (gnu home) + (gnu home services) + (gnu home services shells) + (gnu services)) + +(home-environment + (services + (list + (simple-service 'test-config + home-files-service-type + (list `("config/test.conf" + ,(plain-file + "tmp-file.txt" + "the content of ~/.config/test.conf")))) + + (service home-bash-service-type + (home-bash-configuration + (guix-defaults? #t) + (bashrc + (list + (local-file (string-append (dirname (current-filename)) + "/dot-bashrc")))))) + + (simple-service 'home-bash-service-extension-test + home-bash-service-type + (home-bash-extension + (bashrc + (list + (plain-file + "bashrc-test-config.sh" + "# the content of bashrc-test-config.sh")))))))) +EOF + + guix home reconfigure "${test_directory}/home.scm" + test -d "${HOME}/.guix-home" + test -h "${HOME}/.bash_profile" + test -h "${HOME}/.bashrc" + test "$(tail -n 2 "${HOME}/.bashrc")" == "\ +# dot-bashrc test file for guix home +# the content of bashrc-test-config.sh" + grep -q "the content of ~/.config/test.conf" "${HOME}/.config/test.conf" + + # + # Test 'guix home describe'. + # + + configuration_file() + { + guix home describe \ + | grep 'configuration file:' \ + | cut -d : -f 2 \ + | xargs echo + } + test "$(cat "$(configuration_file)")" == "$(cat home.scm)" + + canonical_file_name() + { + guix home describe \ + | grep 'canonical file name:' \ + | cut -d : -f 2 \ + | xargs echo + } + test "$(canonical_file_name)" == "$(readlink "${HOME}/.guix-home")" + + # + # Test 'guix home search'. + # + + guix home search mcron | grep "^name: home-mcron" + guix home search job manager | grep "^name: home-mcron" +) diff --git a/tests/guix-package-net.sh b/tests/guix-package-net.sh index 6d21c6cff6..1cdeff773a 100644 --- a/tests/guix-package-net.sh +++ b/tests/guix-package-net.sh @@ -1,5 +1,5 @@ # GNU Guix --- Functional package management for GNU -# Copyright © 2012, 2013, 2014, 2015, 2017, 2019 Ludovic Courtès <[email protected]> +# Copyright © 2012-2015, 2017, 2019, 2022 Ludovic Courtès <[email protected]> # Copyright © 2013 Nikita Karetnikov <[email protected]> # Copyright © 2020 Simon Tournier <[email protected]> # @@ -50,7 +50,10 @@ profile="t-profile-$$" profile_alt="t-profile-alt-$$" rm -f "$profile" -trap 'rm -f "$profile" "$profile_alt" "$profile-"[0-9]* "$profile_alt-"[0-9]* ; rm -rf t-home-'"$$" EXIT +module_dir="t-guix-package-net-$$" +mkdir "$module_dir" + +trap 'rm -f "$profile" "$profile_alt" "$profile.lock" "$profile_alt.lock" "$profile-"[0-9]* "$profile_alt-"[0-9]* ; rm -r "$module_dir" t-home-'"$$" EXIT guix package --bootstrap -p "$profile" -i guile-bootstrap @@ -177,10 +180,6 @@ guix package -p "$profile" -p "$profile_alt" --search-paths \ | grep "LIBRARY_PATH.*$profile/lib.$profile_alt/lib" # Simulate an upgrade and make sure the package order is preserved. -module_dir="t-guix-package-net-$$" -trap 'rm -rf "$module_dir"' EXIT - -mkdir "$module_dir" cat > "$module_dir/new.scm" <<EOF (define-module (new) #:use-module (guix) @@ -197,6 +196,16 @@ EOF guix package --bootstrap -p "$profile" -i gcc-bootstrap installed="`guix package -p "$profile" -I | cut -f1`" +# Dry-run upgrade. Make sure no new generation is created when things are +# already in store and '-n' is used: <https://issues.guix.gnu.org/53267>. +V_MINOR=0 +export V_MINOR +profile_before="$(readlink "$profile")" +guix package -p "$profile" --bootstrap -L "$module_dir" -u # build the profile +guix package -p "$profile" --roll-back +guix package -p "$profile" --bootstrap -L "$module_dir" -u . -n # check '-n' +test "$(readlink "$profile")" = "$profile_before" + for i in 1 2 do V_MINOR="$i" diff --git a/tests/guix-shell.sh b/tests/guix-shell.sh new file mode 100644 index 0000000000..23ff1c5bcf --- /dev/null +++ b/tests/guix-shell.sh @@ -0,0 +1,116 @@ +# GNU Guix --- Functional package management for GNU +# Copyright © 2021 Ludovic Courtès <[email protected]> +# +# This file is part of GNU Guix. +# +# GNU Guix is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or (at +# your option) any later version. +# +# GNU Guix is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. + +# +# Test the 'guix shell' alias. +# + +guix shell --version + +configdir="t-guix-shell-config-$$" +tmpdir="t-guix-shell-$$" +trap 'rm -r "$tmpdir" "$configdir"' EXIT +mkdir "$tmpdir" "$configdir" "$configdir/guix" + +XDG_CONFIG_HOME="$(realpath $configdir)" +export XDG_CONFIG_HOME + +guix shell --bootstrap --pure guile-bootstrap -- guile --version + +# '--ad-hoc' is a thing of the past. +! guix shell --ad-hoc guile-bootstrap + +# Ignoring unauthorized files. +cat > "$tmpdir/guix.scm" <<EOF +This is a broken guix.scm file. +EOF +! (cd "$tmpdir"; SHELL="$(type -P true)" guix shell --bootstrap 2> "stderr") +grep "not authorized" "$tmpdir/stderr" +rm "$tmpdir/stderr" + +# Authorize the directory. +echo "$(realpath "$tmpdir")" > "$configdir/guix/shell-authorized-directories" + +# Ignoring 'manifest.scm' and 'guix.scm' in non-interactive use. +(cd "$tmpdir"; guix shell --bootstrap -- true) +mv "$tmpdir/guix.scm" "$tmpdir/manifest.scm" +(cd "$tmpdir"; guix shell --bootstrap -- true) +rm "$tmpdir/manifest.scm" + +# Honoring the local 'manifest.scm' file. +cat > "$tmpdir/manifest.scm" <<EOF +(specifications->manifest '("guile-bootstrap")) +EOF +cat > "$tmpdir/fake-shell.sh" <<EOF +#!$SHELL +# This fake shell allows us to test interactive use. +exec echo "\$GUIX_ENVIRONMENT" +EOF +chmod +x "$tmpdir/fake-shell.sh" +profile1="$(cd "$tmpdir"; SHELL="$(realpath fake-shell.sh)" guix shell --bootstrap)" +profile2="$(guix shell --bootstrap guile-bootstrap -- "$SHELL" -c 'echo $GUIX_ENVIRONMENT')" +test -n "$profile1" +test "$profile1" = "$profile2" +rm "$tmpdir/manifest.scm" + +# Do not read manifest when passed '-q'. +echo "Broken manifest." > "$tmpdir/manifest.scm" +(cd "$tmpdir"; SHELL="$(realpath fake-shell.sh)" guix shell --bootstrap -q) +rm "$tmpdir/manifest.scm" + +# Make sure '-D' affects only the immediately following '-f', and not packages +# that appear later: <https://issues.guix.gnu.org/52093>. +cat > "$tmpdir/empty-package.scm" <<EOF +(use-modules (guix) (guix tests) + (guix build-system trivial)) + +(dummy-package "empty-package" + (build-system trivial-build-system)) ;zero inputs +EOF + +guix shell --bootstrap --pure -D -f "$tmpdir/empty-package.scm" \ + guile-bootstrap -- guile --version +rm "$tmpdir/empty-package.scm" + +if guile -c '(getaddrinfo "www.gnu.org" "80" AI_NUMERICSERV)' 2> /dev/null +then + # Compute the build environment for the initial GNU Make. + guix shell --bootstrap --no-substitutes --search-paths --pure \ + -D -e '(@ (guix tests) gnu-make-for-tests)' > "$tmpdir/a" + + # Make sure bootstrap binaries are in the profile. + profile=`grep "^export PATH" "$tmpdir/a" | sed -r 's|^.*="(.*)/bin"|\1|'` + + # Make sure the bootstrap binaries are all listed where they belong. + grep -E "^export PATH=\"$profile/bin\"" "$tmpdir/a" + grep -E "^export C_INCLUDE_PATH=\"$profile/include\"" "$tmpdir/a" + grep -E "^export LIBRARY_PATH=\"$profile/lib\"" "$tmpdir/a" + for dep in bootstrap-binaries-0 gcc-bootstrap-0 glibc-bootstrap-0 + do + guix gc --references "$profile" | grep "$dep" + done + + # 'make-boot0' itself must not be listed. + ! guix gc --references "$profile" | grep make-boot0 + + # Honoring the local 'guix.scm' file. + echo '(@ (guix tests) gnu-make-for-tests)' > "$tmpdir/guix.scm" + (cd "$tmpdir"; guix shell --bootstrap --search-paths --pure > "b") + cmp "$tmpdir/a" "$tmpdir/b" + rm "$tmpdir/guix.scm" +fi diff --git a/tests/hackage.scm b/tests/hackage.scm index aca807027c..189b9af173 100644 --- a/tests/hackage.scm +++ b/tests/hackage.scm @@ -2,6 +2,7 @@ ;;; Copyright © 2015 Federico Beffa <[email protected]> ;;; Copyright © 2019 Robert Vollmert <[email protected]> ;;; Copyright © 2021 Xinglu Chen <[email protected]> +;;; Copyright © 2021 Sarah Morgensen <[email protected]> ;;; ;;; This file is part of GNU Guix. ;;; @@ -170,17 +171,12 @@ library ('source ('origin ('method 'url-fetch) - ('uri ('string-append - "https://hackage.haskell.org/package/foo/foo-" - 'version - ".tar.gz")) + ('uri ('hackage-uri "foo" 'version)) ('sha256 ('base32 (? string? hash))))) ('build-system 'haskell-build-system) - ('inputs - ('quasiquote - (("ghc-http" ('unquote 'ghc-http))))) + ('inputs ('list 'ghc-http)) ('home-page "http://test.org") ('synopsis (? string?)) ('description (? string?)) @@ -215,21 +211,13 @@ library ('source ('origin ('method 'url-fetch) - ('uri ('string-append - "https://hackage.haskell.org/package/foo/foo-" - 'version - ".tar.gz")) + ('uri ('hackage-uri "foo" 'version)) ('sha256 ('base32 (? string? hash))))) ('build-system 'haskell-build-system) - ('inputs - ('quasiquote - (("ghc-b" ('unquote 'ghc-b)) - ("ghc-http" ('unquote 'ghc-http))))) - ('native-inputs - ('quasiquote - (("ghc-haskell-gi" ('unquote 'ghc-haskell-gi))))) + ('inputs ('list 'ghc-b 'ghc-http)) + ('native-inputs ('list 'ghc-haskell-gi)) ('home-page "http://test.org") ('synopsis (? string?)) ('description (? string?)) @@ -343,17 +331,12 @@ executable cabal ('source ('origin ('method 'url-fetch) - ('uri ('string-append - "https://hackage.haskell.org/package/foo/foo-" - 'version - ".tar.gz")) + ('uri ('hackage-uri "foo" 'version)) ('sha256 ('base32 (? string? hash))))) ('build-system 'haskell-build-system) - ('inputs - ('quasiquote - (("ghc-http" ('unquote 'ghc-http))))) + ('inputs ('list 'ghc-http)) ('arguments ('quasiquote ('#:cabal-revision @@ -409,17 +392,12 @@ executable cabal ('source ('origin ('method 'url-fetch) - ('uri ('string-append - "https://hackage.haskell.org/package/foo/foo-" - 'version - ".tar.gz")) + ('uri ('hackage-uri "foo" 'version)) ('sha256 ('base32 (? string? hash))))) ('build-system 'haskell-build-system) - ('inputs - ('quasiquote - (("ghc-http" ('unquote 'ghc-http))))) + ('inputs ('list 'ghc-http)) ('home-page "http://test.org") ('synopsis (? string?)) ('description (? string?)) diff --git a/tests/home-import.scm b/tests/home-import.scm new file mode 100644 index 0000000000..6d373acf79 --- /dev/null +++ b/tests/home-import.scm @@ -0,0 +1,190 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2021 Xinglu Chen <[email protected]> +;;; Copyright © 2022 Arjan Adriaanse <[email protected]> +;;; +;;; This file is part of GNU Guix. +;;; +;;; GNU Guix is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or (at +;;; your option) any later version. +;;; +;;; GNU Guix is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. + +(define-module (test-home-import) + #:use-module (guix scripts home import) + #:use-module (guix utils) + #:use-module (guix build utils) + #:use-module (guix packages) + #:use-module (ice-9 match) + #:use-module ((guix profiles) #:hide (manifest->code)) + #:use-module ((guix build syscalls) #:select (mkdtemp!)) + #:use-module ((guix scripts package) + #:select (manifest-entry-version-prefix)) + #:use-module (gnu packages) + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-26) + #:use-module (srfi srfi-64)) + +;; Test the (guix scripts home import) tools. + +(test-begin "home-import") + +;; Example manifest entries. + +(define guile-2.0.9 + (manifest-entry + (name "guile") + (version "2.0.9") + (item "/gnu/store/..."))) + +(define glibc + (manifest-entry + (name "glibc") + (version "2.19") + (item "/gnu/store/..."))) + +(define gcc + (manifest-entry + (name "gcc") + (version "") + (output "lib") + (item "/gnu/store/..."))) + +;; Helpers for checking and generating home environments. + +(define %destination-directory "/tmp/guix-config") +(mkdir-p %destination-directory) + +(define %temporary-home-directory (mkdtemp! "/tmp/guix-home-import.XXXXXX")) + +(define-syntax-rule (define-home-environment-matcher name pattern) + (define (name obj) + (match obj + (pattern #t) + (x (pk 'fail x #f))))) + +(define (create-temporary-home files-alist) + "Create a temporary home directory in '%temporary-home-directory'. +FILES-ALIST is an association list of files and the content of the +corresponding file." + (define (create-file file content) + (let ((absolute-path (string-append %temporary-home-directory "/" file))) + (unless (file-exists? absolute-path) + (mkdir-p (dirname absolute-path))) + (call-with-output-file absolute-path + (cut display content <>)))) + + (for-each (match-lambda + ((file . content) (create-file file content))) + files-alist)) + +(define (eval-test-with-home-environment files-alist manifest matcher) + (create-temporary-home files-alist) + (setenv "HOME" %temporary-home-directory) + (mkdir-p %temporary-home-directory) + (let* ((home-environment (manifest+configuration-files->code + manifest %destination-directory)) + (result (matcher home-environment))) + (delete-file-recursively %temporary-home-directory) + result)) + +(define-home-environment-matcher match-home-environment-no-services + ('begin + ('use-modules + ('gnu 'home) + ('gnu 'packages) + ('gnu 'services)) + ('home-environment + ('packages + ('map ('compose 'list 'specification->package+output) + ('list "[email protected]" "gcc:lib" "[email protected]"))) + ('services + ('list))))) + +(define-home-environment-matcher match-home-environment-transformations + ('begin + ('use-modules + ('gnu 'home) + ('gnu 'packages) + ('gnu 'services) + ('guix 'transformations)) + + ('define transform ('options->transformation _)) + ('home-environment + ('packages + ('list (transform ('specification->package "[email protected]")) + ('list ('specification->package "gcc") "lib") + ('specification->package "[email protected]"))) + ('services ('list))))) + +(define-home-environment-matcher match-home-environment-no-services-nor-packages + ('begin + ('use-modules + ('gnu 'home) + ('gnu 'packages) + ('gnu 'services)) + ('home-environment + ('packages + ('map ('compose 'list 'specification->package+output) + ('list))) + ('services + ('list))))) + +(define-home-environment-matcher match-home-environment-bash-service + ('begin + ('use-modules + ('gnu 'home) + ('gnu 'packages) + ('gnu 'services) + ('guix 'gexp) + ('gnu 'home 'services 'shells)) + ('home-environment + ('packages + ('map ('compose 'list 'specification->package+output) + ('list))) + ('services + ('list ('service + 'home-bash-service-type + ('home-bash-configuration + ('aliases ('quote ())) + ('bashrc + ('list ('local-file "/tmp/guix-config/.bashrc" + "bashrc")))))))))) + + +(test-assert "manifest->code: No services" + (eval-test-with-home-environment + '() + (make-manifest (list guile-2.0.9 gcc glibc)) + match-home-environment-no-services)) + +(test-assert "manifest->code: No services, package transformations" + (eval-test-with-home-environment + '() + (make-manifest (list (manifest-entry + (inherit guile-2.0.9) + (properties `((transformations + . ((foo . "bar")))))) + gcc glibc)) + match-home-environment-transformations)) + +(test-assert "manifest->code: No packages nor services" + (eval-test-with-home-environment + '() + (make-manifest '()) + match-home-environment-no-services-nor-packages)) + +(test-assert "manifest->code: Bash service" + (eval-test-with-home-environment + '((".bashrc" . "echo 'hello guix'")) + (make-manifest '()) + match-home-environment-bash-service)) + +(test-end "home-import") diff --git a/tests/import-github.scm b/tests/import-github.scm new file mode 100644 index 0000000000..979a0fc12b --- /dev/null +++ b/tests/import-github.scm @@ -0,0 +1,139 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2022 Maxime Devos <[email protected]> +;;; +;;; This file is part of GNU Guix. +;;; +;;; GNU Guix is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or (at +;;; your option) any later version. +;;; +;;; GNU Guix is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. + +(define-module (test-import-github) + #:use-module (json) + #:use-module (srfi srfi-35) + #:use-module (srfi srfi-64) + #:use-module (guix git-download) + #:use-module (guix http-client) + #:use-module (guix import github) + #:use-module (guix packages) + #:use-module (guix tests) + #:use-module (guix upstream) + #:use-module (ice-9 match)) + +(test-begin "github") + +(define (call-with-releases thunk tags releases) + (mock ((guix http-client) http-fetch + (lambda* (uri #:key headers) + (unless (string-prefix? "mock://" uri) + (error "the URI ~a should not be used" uri)) + (define components + (string-split (substring uri 8) #\/)) + (pk 'stuff components headers) + (define (scm->json-port scm) + (open-input-string (scm->json-string scm))) + (match components + (("repos" "foo" "foomatics" "releases") + (scm->json-port releases)) + (("repos" "foo" "foomatics" "tags") + (scm->json-port tags)) + (rest (error "TODO ~a" rest))))) + (parameterize ((%github-api "mock://")) + (thunk)))) + +;; Copied from tests/minetest.scm +(define (upstream-source->sexp upstream-source) + (define url (upstream-source-urls upstream-source)) + (unless (git-reference? url) + (error "a <git-reference> is expected")) + `(,(upstream-source-package upstream-source) + ,(upstream-source-version upstream-source) + ,(git-reference-url url) + ,(git-reference-commit url))) + +(define* (expected-sexp new-version new-commit) + `("foomatics" ,new-version "https://github.com/foo/foomatics" ,new-commit)) + +(define (example-package old-version old-commit) + (package + (name "foomatics") + (version old-version) + (source + (origin + (method git-fetch) + (uri (git-reference + (url "https://github.com/foo/foomatics") + (commit old-commit))) + (sha256 #f) ; not important for following tests + (file-name (git-file-name name version)))) + (build-system #f) + (license #f) + (synopsis #f) + (description #f) + (home-page #f))) + +(define* (found-sexp old-version old-commit tags releases) + (and=> + (call-with-releases (lambda () + ((upstream-updater-latest %github-updater) + (example-package old-version old-commit))) + tags releases) + upstream-source->sexp)) + +(define-syntax-rule (test-release test-case old-version + old-commit new-version new-commit + tags releases) + (test-equal test-case + (expected-sexp new-version new-commit) + (found-sexp old-version old-commit tags releases))) + +(test-release "newest release is choosen" + "1.0.0" "v1.0.0" "1.9" "v1.9" + #() + ;; a mixture of current, older and newer versions + #((("tag_name" . "v0.0")) + (("tag_name" . "v1.0.1")) + (("tag_name" . "v1.9")) + (("tag_name" . "v1.0.0")) + (("tag_name" . "v1.0.2")))) + +(test-release "tags are used when there are no formal releases" + "1.0.0" "v1.0.0" "1.9" "v1.9" + ;; a mixture of current, older and newer versions + #((("name" . "v0.0")) + (("name" . "v1.0.1")) + (("name" . "v1.9")) + (("name" . "v1.0.0")) + (("name" . "v1.0.2"))) + #()) + +(test-release "\"version-\" prefixes are recognised" + "1.0.0" "v1.0.0" "1.9" "version-1.9" + #((("name" . "version-1.9"))) + #()) + +(test-release "prefixes are optional" + "1.0.0" "v1.0.0" "1.9" "1.9" + #((("name" . "1.9"))) + #()) + +(test-release "prefixing by package name is acceptable" + "1.0.0" "v1.0.0" "1.9" "foomatics-1.9" + #((("name" . "foomatics-1.9"))) + #()) + +(test-release "not all prefixes are acceptable" + "1.0.0" "v1.0.0" "1.0.0" "v1.0.0" + #((("name" . "v1.0.0")) + (("name" . "barstatics-1.9"))) + #()) + +(test-end "github") diff --git a/tests/civodul.key b/tests/keys/civodul.pub index 272600ac93..272600ac93 100644 --- a/tests/civodul.key +++ b/tests/keys/civodul.pub diff --git a/tests/dsa.key b/tests/keys/dsa.pub index 4727975c63..4727975c63 100644 --- a/tests/dsa.key +++ b/tests/keys/dsa.pub diff --git a/tests/ed25519bis.key b/tests/keys/ed25519-2.pub index f5329105d5..f5329105d5 100644 --- a/tests/ed25519bis.key +++ b/tests/keys/ed25519-2.pub diff --git a/tests/ed25519bis.sec b/tests/keys/ed25519-2.sec index 059765f557..059765f557 100644 --- a/tests/ed25519bis.sec +++ b/tests/keys/ed25519-2.sec diff --git a/tests/keys/ed25519-3.pub b/tests/keys/ed25519-3.pub new file mode 100644 index 0000000000..72f311984c --- /dev/null +++ b/tests/keys/ed25519-3.pub @@ -0,0 +1,9 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mDMEYVH/7xYJKwYBBAHaRw8BAQdALMLeUhjEG2/UPCJj2j/debFwwAK5gT3G0l5d +ILfFldm0FTxleGFtcGxlQGV4YW1wbGUuY29tPoiWBBMWCAA+FiEEjO6M85jMSK68 +7tINGBzA7NyoagkFAmFR/+8CGwMFCQPCZwAFCwkIBwIGFQoJCAsCBBYCAwECHgEC +F4AACgkQGBzA7Nyoagl3lgEAw6yqIlX11lTqwxBGhZk/Oy34O13cbJSZCGv+m0ja ++hcA/3DCNOmT+oXjgO/w6enQZUQ1m/d6dUjCc2wOLlLz+ZoG +=+r3i +-----END PGP PUBLIC KEY BLOCK----- diff --git a/tests/keys/ed25519-3.sec b/tests/keys/ed25519-3.sec new file mode 100644 index 0000000000..04128a4131 --- /dev/null +++ b/tests/keys/ed25519-3.sec @@ -0,0 +1,10 @@ +-----BEGIN PGP PRIVATE KEY BLOCK----- + +lFgEYVH/7xYJKwYBBAHaRw8BAQdALMLeUhjEG2/UPCJj2j/debFwwAK5gT3G0l5d +ILfFldkAAP92goSbbzQ0ttElr9lr5Cm6rmQtqUZ2Cu/Jk9fvfZROwxI0tBU8ZXhh +bXBsZUBleGFtcGxlLmNvbT6IlgQTFggAPhYhBIzujPOYzEiuvO7SDRgcwOzcqGoJ +BQJhUf/vAhsDBQkDwmcABQsJCAcCBhUKCQgLAgQWAgMBAh4BAheAAAoJEBgcwOzc +qGoJd5YBAMOsqiJV9dZU6sMQRoWZPzst+Dtd3GyUmQhr/ptI2voXAP9wwjTpk/qF +44Dv8Onp0GVENZv3enVIwnNsDi5S8/maBg== +=EmOt +-----END PGP PRIVATE KEY BLOCK----- diff --git a/tests/ed25519.key b/tests/keys/ed25519.pub index f6bf906783..f6bf906783 100644 --- a/tests/ed25519.key +++ b/tests/keys/ed25519.pub diff --git a/tests/ed25519.sec b/tests/keys/ed25519.sec index 068738dfab..068738dfab 100644 --- a/tests/ed25519.sec +++ b/tests/keys/ed25519.sec diff --git a/tests/rsa.key b/tests/keys/rsa.pub index 0ef9145ef0..0ef9145ef0 100644 --- a/tests/rsa.key +++ b/tests/keys/rsa.pub diff --git a/tests/signing-key.pub b/tests/keys/signing-key.pub index 092424a15d..092424a15d 100644 --- a/tests/signing-key.pub +++ b/tests/keys/signing-key.pub diff --git a/tests/signing-key.sec b/tests/keys/signing-key.sec index 558e189102..558e189102 100644 --- a/tests/signing-key.sec +++ b/tests/keys/signing-key.sec diff --git a/tests/lint.scm b/tests/lint.scm index e96265a55a..76c2a70b3a 100644 --- a/tests/lint.scm +++ b/tests/lint.scm @@ -107,7 +107,7 @@ "Texinfo markup in description is invalid" (single-lint-warning-message (check-description-style - (dummy-package "x" (description "f{oo}b@r"))))) + (dummy-package "x" (description (identity "f{oo}b@r")))))) (test-equal "description: does not start with an upper-case letter" "description should start with an upper-case letter or digit" @@ -177,6 +177,20 @@ (description "Whitespace. ")))) (check-description-style pkg)))) +(test-equal "description: pluralized 'This package'" + "description contains typo 'This packages', should be 'This package'" + (single-lint-warning-message + (let ((pkg (dummy-package "x" + (description "This packages is a typo.")))) + (check-description-style pkg)))) + +(test-equal "description: grammar 'allows to'" + "description contains typo 'allows to'" + (single-lint-warning-message + (let ((pkg (dummy-package "x" + (description "This package allows to do stuff.")))) + (check-description-style pkg)))) + (test-equal "synopsis: not a string" "invalid synopsis: #f" (single-lint-warning-message @@ -195,7 +209,7 @@ "Texinfo markup in synopsis is invalid" (single-lint-warning-message (check-synopsis-style - (dummy-package "x" (synopsis "Bad $@ texinfo"))))) + (dummy-package "x" (synopsis (identity "Bad $@ texinfo")))))) (test-equal "synopsis: does not start with an upper-case letter" "synopsis should start with an upper-case letter or digit" @@ -366,6 +380,20 @@ `(("python-setuptools" ,python-setuptools)))))) (check-inputs-should-not-be-an-input-at-all pkg)))) +(test-assert "input labels: no warnings" + (let ((pkg (dummy-package "x" + (inputs `(("glib" ,glib) + ("pkg-config" ,pkg-config)))))) + (null? (check-input-labels pkg)))) + +(test-equal "input labels: one warning" + "label 'pkgkonfig' does not match package name 'pkg-config'" + (single-lint-warning-message + (let ((pkg (dummy-package "x" + (inputs `(("glib" ,glib) + ("pkgkonfig" ,pkg-config)))))) + (check-input-labels pkg)))) + (test-equal "explicit #:sh argument to 'wrap-program' is acceptable" '() (let* ((phases @@ -492,17 +520,17 @@ (file-name "x.patch"))))))))) (check-patch-file-names pkg))) -(test-equal "patches: file name too long" +(test-equal "patches: file name too long, which may break 'make dist'" (string-append "x-" - (make-string 100 #\a) - ".patch: file name is too long") + (make-string 152 #\a) + ".patch: file name is too long, which may break 'make dist'") (single-lint-warning-message (let ((pkg (dummy-package "x" (source (dummy-origin (patches (list (string-append "x-" - (make-string 100 #\a) + (make-string 152 #\a) ".patch")))))))) (check-patch-file-names pkg)))) @@ -572,7 +600,7 @@ (single-lint-warning-message (check-patch-headers pkg))))) (test-equal "derivation: invalid arguments" - "failed to create x86_64-linux derivation: (wrong-type-arg \"map\" \"Wrong type argument: ~S\" (invalid-module) ())" + "failed to create x86_64-linux derivation: (match-error \"match\" \"no matching pattern\" invalid-module)" (match (let ((pkg (dummy-package "x" (arguments '(#:imported-modules (invalid-module)))))) @@ -1319,7 +1347,11 @@ (let* ((stackage (string-append "{ \"packages\": [{" " \"name\":\"pandoc\"," " \"synopsis\":\"synopsis\"," - " \"version\":\"1.0\" }]}")) + " \"version\":\"1.0\" }]," + " \"snapshot\": {" + " \"ghc\": \"8.6.5\"," + " \"name\": \"lts-14.27\"" + " }}")) (packages (map (lambda (version) (dummy-package "ghc-pandoc" diff --git a/tests/minetest.scm b/tests/minetest.scm index abb26d0a03..cbb9e83889 100644 --- a/tests/minetest.scm +++ b/tests/minetest.scm @@ -17,10 +17,18 @@ ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. (define-module (test-minetest) + #:use-module (guix build-system minetest) + #:use-module (guix upstream) #:use-module (guix memoization) #:use-module (guix import minetest) #:use-module (guix import utils) #:use-module (guix tests) + #:use-module (guix packages) + #:use-module (guix git-download) + #:use-module ((gnu packages minetest) + #:select (minetest minetest-technic)) + #:use-module ((gnu packages base) + #:select (hello)) #:use-module (json) #:use-module (ice-9 match) #:use-module (srfi srfi-1) @@ -375,8 +383,119 @@ during a dynamic extent where that package is available on ContentDB." (list z y x) (sort-packages (list x y z)))) + + +;; Update detection +(define (upstream-source->sexp upstream-source) + (define url (upstream-source-urls upstream-source)) + (unless (git-reference? url) + (error "a <git-reference> is expected")) + `(,(upstream-source-package upstream-source) + ,(upstream-source-version upstream-source) + ,(git-reference-url url) + ,(git-reference-commit url))) + +(define* (expected-sexp #:key + (repo "https://example.org/foo.git") + (guix-name "minetest-foo") + (new-version "0.8") + (commit "44941798d222901b8f381b3210957d880b90a2fc") + #:allow-other-keys) + `(,guix-name ,new-version ,repo ,commit)) + +(define* (example-package #:key + (source 'auto) + (repo "https://example.org/foo.git") + (old-version "0.8") + (commit "44941798d222901b8f381b3210957d880b90a2fc") + #:allow-other-keys) + (package + (name "minetest-foo") + (version old-version) + (source + (if (eq? source 'auto) + (origin + (method git-fetch) + (uri (git-reference + (url repo) + (commit commit #;"808f9ffbd3106da4c92d2367b118b98196c9e81e"))) + (sha256 #f) ; not important for the following tests + (file-name (git-file-name name version))) + source)) + (build-system minetest-mod-build-system) + (license #f) + (synopsis #f) + (description #f) + (home-page #f) + (properties '((upstream-name . "Author/foo"))))) + +(define-syntax-rule (test-release test-case . arguments) + (test-equal test-case + (expected-sexp . arguments) + (and=> + (call-with-packages + (cut latest-minetest-release (example-package . arguments)) + (list . arguments)) + upstream-source->sexp))) + +(define-syntax-rule (test-no-release test-case . arguments) + (test-equal test-case + #f + (call-with-packages + (cut latest-minetest-release (example-package . arguments)) + (list . arguments)))) + +(test-release "same version" + #:old-version "0.8" #:title "0.8" #:new-version "0.8" + #:commit "44941798d222901b8f381b3210957d880b90a2fc") + +(test-release "new version (dotted)" + #:old-version "0.8" #:title "0.9.0" #:new-version "0.9.0" + #:commit "c8855b991880897b2658dc90164e29c96e2aeb3a") + +(test-release "new version (date)" + #:old-version "2014-11-17" #:title "2015-11-04" + #:new-version "2015-11-04" + #:commit "c8855b991880897b2658dc90164e29c96e2aeb3a") + +(test-release "new version (git -> dotted)" + #:old-version + (git-version "0.8" "1" "90422555f114d3af35e7cc4b5b6d59a5c226adc4") + #:title "0.9.0" #:new-version "0.9.0" + #:commit "90422555f114d3af35e7cc4b5b6d59a5c226adc4") + +;; There might actually be a new release, but guix cannot compare dates +;; with regular version numbers. +(test-no-release "dotted -> date" + #:old-version "0.8" #:title "2015-11-04" + #:commit "c8855b991880897b2658dc90164e29c96e2aeb3a") + +(test-no-release "date -> dotted" + #:old-version "2014-11-07" #:title "0.8" + #:commit "c8855b991880897b2658dc90164e29c96e2aeb3a") + +;; Don't let "guix refresh -t minetest" tell there are new versions +;; if Guix has insufficient information to actually perform the update, +;; when using --with-latest or "guix refresh -u". +(test-no-release "no commit information, no new release" + #:old-version "0.8" #:title "0.9.0" #:new-version "0.9.0" + #:commit #false) + +(test-assert "minetest is not a minetest mod" + (not (minetest-package? minetest))) +(test-assert "GNU hello is not a minetest mod" + (not (minetest-package? hello))) +(test-assert "technic is a minetest mod" + (minetest-package? minetest-technic)) +(test-assert "upstream-name is required" + (not (minetest-package? + (package (inherit minetest-technic) + (properties '()))))) + (test-end "minetest") ;;; Local Variables: ;;; eval: (put 'test-package* 'scheme-indent-function 1) +;;; eval: (put 'test-release 'scheme-indent-function 1) +;;; eval: (put 'test-no-release 'scheme-indent-function 1) ;;; End: diff --git a/tests/modules.scm b/tests/modules.scm index 57019c600c..e70d2d9e08 100644 --- a/tests/modules.scm +++ b/tests/modules.scm @@ -39,10 +39,10 @@ (live-module-closure '((gnu build install))) (source-module-closure '((gnu build install))))) -(test-assert "closure of (gnu build vm)" +(test-assert "closure of (gnu build image)" (lset= equal? - (live-module-closure '((gnu build vm))) - (source-module-closure '((gnu build vm))))) + (live-module-closure '((gnu build image))) + (source-module-closure '((gnu build image))))) (test-equal "&missing-dependency-error" '(something that does not exist) diff --git a/tests/nar.scm b/tests/nar.scm index ba4881caaa..98752f2088 100644 --- a/tests/nar.scm +++ b/tests/nar.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Ludovic Courtès <[email protected]> +;;; Copyright © 2012-2021 Ludovic Courtès <[email protected]> ;;; ;;; This file is part of GNU Guix. ;;; @@ -486,8 +486,9 @@ ;; their mtime and permissions were not reset. Ensure that this bug is ;; gone. (with-store store - (let* ((text1 (random-text)) - (text2 (random-text)) + ;; Note: TEXT1 and TEXT2 must be longer than %DEDUPLICATION-MINIMUM-SIZE. + (let* ((text1 (string-concatenate (make-list 200 (random-text)))) + (text2 (string-concatenate (make-list 200 (random-text)))) (tree `("tree" directory ("a" regular (data ,text1)) ("b" directory diff --git a/tests/opam.scm b/tests/opam.scm index 31b4ea41ff..b5f02f809b 100644 --- a/tests/opam.scm +++ b/tests/opam.scm @@ -1,6 +1,7 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2018 Julien Lepiller <[email protected]> ;;; Copyright © 2021 Xinglu Chen <[email protected]> +;;; Copyright © 2021 Sarah Morgensen <[email protected]> ;;; ;;; This file is part of GNU Guix. ;;; @@ -101,13 +102,9 @@ url { ('base32 (? string? hash))))) ('build-system 'ocaml-build-system) - ('propagated-inputs - ('quasiquote - (("ocaml-zarith" ('unquote 'ocaml-zarith))))) + ('propagated-inputs ('list 'ocaml-zarith)) ('native-inputs - ('quasiquote - (("ocaml-alcotest" ('unquote 'ocaml-alcotest)) - ("ocamlbuild" ('unquote 'ocamlbuild))))) + ('list 'ocaml-alcotest 'ocamlbuild)) ('home-page "https://example.org/") ('synopsis "Some example package") ('description "This package is just an example.") diff --git a/tests/openpgp.scm b/tests/openpgp.scm index c2be26fa49..1f20466772 100644 --- a/tests/openpgp.scm +++ b/tests/openpgp.scm @@ -59,18 +59,22 @@ vBSFjNSiVHsuAA== (define %civodul-fingerprint "3CE4 6455 8A84 FDC6 9DB4 0CFB 090B 1199 3D9A EBB5") -(define %civodul-key-id #x090B11993D9AEBB5) ;civodul.key - -;; Test keys. They were generated in a container along these lines: -;; guix environment -CP --ad-hoc gnupg pinentry -;; then, within the container: -;; mkdir ~/.gnupg -;; echo pinentry-program ~/.guix-profile/bin/pinentry-tty > ~/.gnupg/gpg-agent.conf -;; gpg --quick-gen-key '<[email protected]>' rsa -;; or similar. -(define %rsa-key-id #xAE25DA2A70DEED59) ;rsa.key -(define %dsa-key-id #x587918047BE8BD2C) ;dsa.key -(define %ed25519-key-id #x771F49CBFAAE072D) ;ed25519.key +(define %civodul-key-id #x090B11993D9AEBB5) ;civodul.pub + +#| +Test keys in ./tests/keys. They were generated in a container along these lines: + guix environment -CP --ad-hoc gnupg pinentry coreutils +then, within the container: + mkdir ~/.gnupg && chmod -R og-rwx ~/.gnupg + gpg --batch --passphrase '' --quick-gen-key '<[email protected]>' ed25519 + gpg --armor --export [email protected] + gpg --armor --export-secret-key [email protected] + # echo pinentry-program ~/.guix-profile/bin/pinentry-curses > ~/.gnupg/gpg-agent.conf +or similar. +|# +(define %rsa-key-id #xAE25DA2A70DEED59) ;rsa.pub +(define %dsa-key-id #x587918047BE8BD2C) ;dsa.pub +(define %ed25519-key-id #x771F49CBFAAE072D) ;ed25519.pub (define %rsa-key-fingerprint (base16-string->bytevector @@ -168,7 +172,7 @@ Pz7oopeN72xgggYUNT37ezqN3MeCqw0= (not (port-ascii-armored? (open-bytevector-input-port %binary-sample)))) (test-assert "get-openpgp-keyring" - (let* ((key (search-path %load-path "tests/civodul.key")) + (let* ((key (search-path %load-path "tests/keys/civodul.pub")) (keyring (get-openpgp-keyring (open-bytevector-input-port (call-with-input-file key read-radix-64))))) @@ -228,8 +232,10 @@ Pz7oopeN72xgggYUNT37ezqN3MeCqw0= (verify-openpgp-signature signature keyring (open-input-string "Hello!\n")))) (list status (openpgp-public-key-id key))))) - (list "tests/rsa.key" "tests/dsa.key" - "tests/ed25519.key" "tests/ed25519.key" "tests/ed25519.key") + (list "tests/keys/rsa.pub" "tests/keys/dsa.pub" + "tests/keys/ed25519.pub" + "tests/keys/ed25519.pub" + "tests/keys/ed25519.pub") (list %hello-signature/rsa %hello-signature/dsa %hello-signature/ed25519/sha256 %hello-signature/ed25519/sha512 @@ -248,9 +254,9 @@ Pz7oopeN72xgggYUNT37ezqN3MeCqw0= (call-with-input-file key read-radix-64)) keyring))) %empty-keyring - '("tests/rsa.key" "tests/dsa.key" - "tests/ed25519.key" "tests/ed25519.key" - "tests/ed25519.key")))) + '("tests/keys/rsa.pub" "tests/keys/dsa.pub" + "tests/keys/ed25519.pub" "tests/keys/ed25519.pub" + "tests/keys/ed25519.pub")))) (map (lambda (signature) (let ((signature (string->openpgp-packet signature))) (let-values (((status key) diff --git a/tests/pack.scm b/tests/pack.scm index e9b4c36e0e..98bfedf21c 100644 --- a/tests/pack.scm +++ b/tests/pack.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2017, 2018, 2019, 2020 Ludovic Courtès <[email protected]> +;;; Copyright © 2017, 2018, 2019, 2020, 2021 Ludovic Courtès <[email protected]> ;;; Copyright © 2018 Ricardo Wurmus <[email protected]> ;;; Copyright © 2021 Maxim Cournoyer <[email protected]> ;;; @@ -54,7 +54,7 @@ ;; Compressor that uses the bootstrap 'gzip'. ((@ (guix scripts pack) compressor) "gzip" ".gz" - #~(#+(file-append %bootstrap-coreutils&co "/bin/gzip") "-6n"))) + #~(list #+(file-append %bootstrap-coreutils&co "/bin/gzip") "-6n"))) (define %tar-bootstrap %bootstrap-coreutils&co) diff --git a/tests/packages.scm b/tests/packages.scm index 3756877270..3506f94f91 100644 --- a/tests/packages.scm +++ b/tests/packages.scm @@ -1,6 +1,8 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021 Ludovic Courtès <[email protected]> -;;; Copyright © Jan (janneke) Nieuwenhuizen <[email protected]> +;;; Copyright © 2018 Jan (janneke) Nieuwenhuizen <[email protected]> +;;; Copyright © 2021 Maxim Cournoyer <[email protected]> +;;; Copyright © 2021 Maxime Devos <[email protected]> ;;; ;;; This file is part of GNU Guix. ;;; @@ -17,13 +19,14 @@ ;;; You should have received a copy of the GNU General Public License ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. -(define-module (test-packages) +(define-module (tests packages) #:use-module (guix tests) #:use-module (guix store) #:use-module (guix monads) #:use-module (guix grafts) - #:use-module ((guix gexp) #:select (local-file local-file-file)) + #:use-module (guix gexp) #:use-module (guix utils) + #:use-module ((guix build utils) #:select (tarball?)) #:use-module ((guix diagnostics) ;; Rename the 'location' binding to allow proper syntax ;; matching when setting the 'location' field of a package. @@ -32,6 +35,7 @@ (else name)))) #:use-module ((gcrypt hash) #:prefix gcrypt:) #:use-module (guix derivations) + #:use-module (guix download) #:use-module (guix packages) #:use-module (guix grafts) #:use-module (guix search-paths) @@ -51,6 +55,7 @@ #:use-module (gnu packages version-control) #:use-module (gnu packages xml) #:use-module (srfi srfi-1) + #:use-module (srfi srfi-11) #:use-module (srfi srfi-26) #:use-module (srfi srfi-34) #:use-module (srfi srfi-35) @@ -133,7 +138,7 @@ ;; inputs. See <https://bugs.gnu.org/35872>. (let* ((dep (dummy-package "dep" (version "2"))) (old (dummy-package "foo" (version "1") - (propagated-inputs `(("dep" ,dep))))) + (propagated-inputs (list dep)))) (drv (package-derivation %store old)) (tx (mock ((gnu packages) find-best-packages-by-name (const (list old))) @@ -221,7 +226,7 @@ (bar (dummy-package "bar" (version "0") (replacement old))) (new (dummy-package "foo" (version "1") - (inputs `(("bar" ,bar))))) + (inputs (list bar)))) (tx (mock ((gnu packages) find-best-packages-by-name (const (list new))) (transaction-upgrade-entry @@ -282,13 +287,13 @@ (test-assert "package-transitive-inputs" (let* ((a (dummy-package "a")) (b (dummy-package "b" - (propagated-inputs `(("a" ,a))))) + (propagated-inputs (list a)))) (c (dummy-package "c" - (inputs `(("a" ,a))))) + (inputs (list a)))) (d (dummy-package "d" (propagated-inputs `(("x" "something.drv"))))) (e (dummy-package "e" - (inputs `(("b" ,b) ("c" ,c) ("d" ,d)))))) + (inputs (list b c d))))) (and (null? (package-transitive-inputs a)) (equal? `(("a" ,a)) (package-transitive-inputs b)) (equal? `(("a" ,a)) (package-transitive-inputs c)) @@ -334,25 +339,39 @@ (b (dummy-package "b" (build-system trivial-build-system) (supported-systems '("x" "y")) - (inputs `(("a" ,a))))) + (inputs (list a)))) (c (dummy-package "c" (build-system trivial-build-system) (supported-systems '("y" "z")) - (inputs `(("b" ,b))))) + (inputs (list b)))) (d (dummy-package "d" (build-system trivial-build-system) (supported-systems '("x" "y" "z")) - (inputs `(("b" ,b) ("c" ,c))))) + (inputs (list b c)))) (e (dummy-package "e" (build-system trivial-build-system) (supported-systems '("x" "y" "z")) - (inputs `(("d" ,d)))))) + (inputs (list d))))) (list (package-transitive-supported-systems a) (package-transitive-supported-systems b) (package-transitive-supported-systems c) (package-transitive-supported-systems d) (package-transitive-supported-systems e)))) +(test-assert "package-development-inputs" + ;; Note: Due to propagated inputs, 'package-development-inputs' returns a + ;; couple more inputs, such as 'linux-libre-headers'. + (lset<= equal? + `(("source" ,(package-source hello)) ,@(standard-packages)) + (package-development-inputs hello))) + +(test-assert "package-development-inputs, cross-compilation" + (lset<= equal? + `(("source" ,(package-source hello)) + ,@(standard-cross-packages "mips64el-linux-gnu" 'host) + ,@(standard-cross-packages "mips64el-linux-gnu" 'target)) + (package-development-inputs hello #:target "mips64el-linux-gnu"))) + (test-assert "package-closure" (let-syntax ((dummy-package/no-implicit (syntax-rules () @@ -362,13 +381,13 @@ (build-system trivial-build-system)))))) (let* ((a (dummy-package/no-implicit "a")) (b (dummy-package/no-implicit "b" - (propagated-inputs `(("a" ,a))))) + (propagated-inputs (list a)))) (c (dummy-package/no-implicit "c" - (inputs `(("a" ,a))))) + (inputs (list a)))) (d (dummy-package/no-implicit "d" - (native-inputs `(("b" ,b))))) + (native-inputs (list b)))) (e (dummy-package/no-implicit "e" - (inputs `(("c" ,c) ("d" ,d)))))) + (inputs (list c d))))) (lset= eq? (list a b c d e) (package-closure (list e)) @@ -391,12 +410,11 @@ (u (dummy-origin)) (i (dummy-origin)) (a (dummy-package "a")) - (b (dummy-package "b" - (inputs `(("a" ,a) ("i" ,i))))) + (b (dummy-package "b" (inputs (list a i)))) (c (package (inherit b) (source o))) (d (dummy-package "d" (build-system trivial-build-system) - (source u) (inputs `(("c" ,c)))))) + (source u) (inputs (list c))))) (test-assert "package-direct-sources, no source" (null? (package-direct-sources a))) (test-equal "package-direct-sources, #f source" @@ -464,7 +482,7 @@ (supported-systems '("x86_64-linux")))) (p (dummy-package "foo" (build-system gnu-build-system) - (inputs `(("d" ,d))) + (inputs (list d)) (supported-systems '("x86_64-linux" "armhf-linux"))))) (and (supported-package? p "x86_64-linux") (not (supported-package? p "i686-linux")) @@ -589,6 +607,11 @@ (build-derivations %store (list drv)) (call-with-input-file output get-string-all))) + +;;; +;;; Source derivation with snippets. +;;; + (unless (network-reachable?) (test-skip 1)) (test-equal "package-source-derivation, snippet" "OK" @@ -644,11 +667,96 @@ (and (build-derivations %store (list (pk 'snippet-drv drv))) (call-with-input-file out get-string-all)))) +;; Note: lzip is not part of bootstrap-coreutils&co, so is not included to +;; avoid having to rebuild the world. +(define compressors '(("gzip" . "gz") + ("xz" . "xz") + ("bzip2" . "bz2") + (#f . #f))) + +(for-each + (match-lambda + ((comp . ext) + (unless (network-reachable?) (test-skip 1)) + (test-equal (string-append "origin->derivation, single file with snippet " + "(compression: " (if comp comp "None") ")") + "2 + 2 = 4" + (let*-values + (((name) "maths") + ((compressed-name) (if comp + (string-append name "." ext) + name)) + ((file hash) (test-file %store compressed-name "2 + 2 = 5")) + ;; Create an origin using the above computed file and its hash. + ((source) (origin + (method url-fetch) + (uri (string-append "file://" file)) + (file-name compressed-name) + (patch-inputs `(("tar" ,%bootstrap-coreutils&co) + ("xz" ,%bootstrap-coreutils&co) + ("bzip2" ,%bootstrap-coreutils&co) + ("gzip" ,%bootstrap-coreutils&co))) + (patch-guile %bootstrap-guile) + (modules '((guix build utils))) + (snippet `(substitute* ,name + (("5") "4"))) + (hash (content-hash hash)))) + ;; Build origin. + ((drv) (run-with-store %store (origin->derivation source))) + ((out) (derivation->output-path drv))) + ;; Decompress the resulting tar.xz and return its content. + (and (build-derivations %store (list drv)) + (if (tarball? out) + (let* ((bin #~(string-append #+%bootstrap-coreutils&co + "/bin")) + (f (computed-file + name + (with-imported-modules '((guix build utils)) + #~(begin + (use-modules (guix build utils)) + (setenv "PATH" #+bin) + (invoke "tar" "xvf" #+out) + (copy-file #+name #$output))))) + (drv (run-with-store %store (lower-object f))) + (_ (build-derivations %store (list drv)))) + (call-with-input-file (derivation->output-path drv) + get-string-all)) + (call-with-input-file out get-string-all))))))) + compressors) + (test-assert "return value" (let ((drv (package-derivation %store (dummy-package "p")))) (and (derivation? drv) (file-exists? (derivation-file-name drv))))) +(test-assert "package-derivation, inputs deduplicated" + (let* ((dep (dummy-package "dep")) + (p0 (dummy-package "p" (inputs (list dep)))) + (p1 (package (inherit p0) + (inputs `(("dep" ,(package (inherit dep))) + ,@(package-inputs p0)))))) + ;; Here P1 ends up with two non-eq? copies of DEP, under the same label. + ;; They should be deduplicated so that P0 and P1 lead to the same + ;; derivation rather than P1 ending up with duplicate entries in its + ;; '%build-inputs' variable. + (string=? (derivation-file-name (package-derivation %store p0)) + (derivation-file-name (package-derivation %store p1))))) + +(test-assert "package-derivation, different system" + ;; Make sure the 'system' argument of 'package-derivation' is respected. + (let* ((system (if (string=? (%current-system) "x86_64-linux") + "aarch64-linux" + "x86_64-linux")) + (drv (package-derivation %store (dummy-package "p") + system #:graft? #f))) + (define right-system? + (mlambdaq (drv) + (and (string=? (derivation-system drv) system) + (every (compose right-system? derivation-input-derivation) + (derivation-inputs drv))))) + + (right-system? drv))) + (test-assert "package-output" (let* ((package (dummy-package "p")) (drv (package-derivation %store package))) @@ -676,7 +784,7 @@ (let ((dummy (dummy-package "foo" (inputs `(("x" ,(current-module))))))) (test-equal "&package-input-error" - (list dummy (current-module)) + (list dummy `("x" ,(current-module))) (guard (c ((package-input-error? c) (list (package-error-package c) (package-error-invalid-input c)))) @@ -687,7 +795,7 @@ (parameterize ((%graft? #f)) (let* ((dep (dummy-package "dep")) (p (dummy-package "p" - (inputs `(("dep" ,dep "non-existent")))))) + (inputs (list `(,dep "non-existent")))))) (guard (c ((derivation-missing-output-error? c) (and (string=? (derivation-missing-output c) "non-existent") (equal? (package-derivation %store dep) @@ -788,21 +896,47 @@ (build-derivations %store (list d)) #f))) +(test-assert "trivial with #:allowed-references + grafts" + (let* ((g (package + (inherit %bootstrap-guile) + (replacement (package + (inherit %bootstrap-guile) + (version "9.9"))))) + (p (package + (inherit (dummy-package "trivial")) + (build-system trivial-build-system) + (inputs (list g)) + (arguments + `(#:guile ,g + #:allowed-references (,g) + #:builder (mkdir %output))))) + (d0 (package-derivation %store p #:graft? #f)) + (d1 (parameterize ((%graft? #t)) + (package-derivation %store p #:graft? #t)))) + ;; D1 should be equal to D2 because there's nothing to graft. In + ;; particular, its #:disallowed-references should be lowered in the same + ;; way (ungrafted) whether or not #:graft? is true. + (string=? (derivation-file-name d1) (derivation-file-name d0)))) + (test-assert "search paths" (let* ((p (make-prompt-tag "return-search-paths")) + (t (make-parameter "guile-0")) (s (build-system - (name 'raw) - (description "Raw build system with direct store access") - (lower (lambda* (name #:key source inputs system target - #:allow-other-keys) - (bag - (name name) - (system system) (target target) - (build-inputs inputs) - (build - (lambda* (store name inputs + (name 'raw) + (description "Raw build system with direct store access") + (lower (lambda* (name #:key source inputs system target + #:allow-other-keys) + (bag + (name name) + (system system) (target target) + (build-inputs inputs) + (build + (lambda* (name inputs #:key outputs system search-paths) - search-paths))))))) + (if (string=? name (t)) + (abort-to-prompt p search-paths) + (gexp->derivation name + #~(mkdir #$output)))))))))) (x (list (search-path-specification (variable "GUILE_LOAD_PATH") (files '("share/guile/site/2.0"))) @@ -827,8 +961,10 @@ (lambda (k search-paths) search-paths)))))) (and (null? (collect (package-derivation %store a))) - (equal? x (collect (package-derivation %store b))) - (equal? x (collect (package-derivation %store c))))))) + (parameterize ((t "guile-foo-0")) + (equal? x (collect (package-derivation %store b)))) + (parameterize ((t "guile-bar-0")) + (equal? x (collect (package-derivation %store c)))))))) (test-assert "package-transitive-native-search-paths" (let* ((sp (lambda (name) @@ -839,12 +975,12 @@ (p1 (dummy-package "p1" (native-search-paths (sp "PATH1")))) (p2 (dummy-package "p2" (native-search-paths (sp "PATH2")) - (inputs `(("p0" ,p0))) - (propagated-inputs `(("p1" ,p1))))) + (inputs (list p0)) + (propagated-inputs (list p1)))) (p3 (dummy-package "p3" (native-search-paths (sp "PATH3")) - (native-inputs `(("p0" ,p0))) - (propagated-inputs `(("p2" ,p2)))))) + (native-inputs (list p0)) + (propagated-inputs (list p2))))) (lset= string=? '("PATH1" "PATH2" "PATH3") (map search-path-specification-variable @@ -898,7 +1034,7 @@ (dep* (package (inherit dep) (replacement new))) (dummy (dummy-package "dummy" (arguments '(#:implicit-inputs? #f)) - (inputs `(("dep" ,dep*)))))) + (inputs (list dep*))))) (equal? (package-grafts %store dummy) (list (graft (origin (package-derivation %store dep)) @@ -930,11 +1066,11 @@ (dep (package (inherit new) (version "0.0"))) (dep* (package (inherit dep) (replacement new))) (prop (dummy-package "propagated" - (propagated-inputs `(("dep" ,dep*))) + (propagated-inputs (list dep*)) (arguments '(#:implicit-inputs? #f)))) (dummy (dummy-package "dummy" (arguments '(#:implicit-inputs? #f)) - (inputs `(("prop" ,prop)))))) + (inputs (list prop))))) (equal? (package-grafts %store dummy) (list (graft (origin (package-derivation %store dep)) @@ -947,16 +1083,16 @@ (dep (package (inherit new) (version "0") (replacement new))) (p1 (dummy-package "intermediate1" (arguments '(#:implicit-inputs? #f)) - (inputs `(("dep" ,dep))))) + (inputs (list dep)))) (p2 (dummy-package "intermediate2" (arguments '(#:implicit-inputs? #f)) ;; Here we copy DEP to have an equivalent package that is not ;; 'eq?' to DEP. This is similar to what happens with ;; 'package-with-explicit-inputs' & co. - (inputs `(("dep" ,(package (inherit dep))))))) + (inputs (list (package (inherit dep)))))) (p3 (dummy-package "final" (arguments '(#:implicit-inputs? #f)) - (inputs `(("p1" ,p1) ("p2" ,p2)))))) + (inputs (list p1 p2))))) (equal? (package-grafts %store p3) (list (graft (origin (package-derivation %store @@ -974,8 +1110,7 @@ (p0* (package (inherit p0) (version "1.1"))) (p1 (dummy-package "p1" (arguments '(#:implicit-inputs? #f)) - (inputs `(("p0" ,p0) - ("p0:lib" ,p0 "lib")))))) + (inputs (list p0 `(,p0 "lib")))))) (lset= equal? (pk (package-grafts %store p1)) (list (graft (origin (package-derivation %store p0)) @@ -1023,7 +1158,7 @@ #t))))) (p2r (dummy-package "P2" (build-system trivial-build-system) - (inputs `(("p1" ,p1))) + (inputs (list p1)) (arguments `(#:guile ,%bootstrap-guile #:builder (let ((out (assoc-ref %outputs "out"))) @@ -1044,7 +1179,7 @@ #t))))) (p3 (dummy-package "p3" (build-system trivial-build-system) - (inputs `(("p2" ,p2))) + (inputs (list p2)) (arguments `(#:guile ,%bootstrap-guile #:builder (let ((out (assoc-ref %outputs "out"))) @@ -1102,18 +1237,18 @@ (bag (name name) (system system) (target target) (build-inputs native-inputs) (host-inputs inputs) - (build (lambda* (store name inputs - #:key system target - #:allow-other-keys) - (build-expression->derivation - store "foo" '(mkdir %output)))))))) + (build (lambda* (name inputs + #:key system target + #:allow-other-keys) + (gexp->derivation "foo" + #~(mkdir #$output)))))))) (bs (build-system (name 'build-system-without-cross-compilation) (description "Does not support cross compilation.") (lower lower))) (dep (dummy-package "dep" (build-system bs))) (pkg (dummy-package "example" - (native-inputs `(("dep" ,dep))))) + (native-inputs (list dep)))) (do-not-build (lambda (continue store lst . _) lst))) (equal? (with-build-handler do-not-build (parameterize ((%current-target-system "powerpc64le-linux-gnu") @@ -1140,9 +1275,9 @@ (test-assert "package->bag, propagated inputs" (let* ((dep (dummy-package "dep")) (prop (dummy-package "prop" - (propagated-inputs `(("dep" ,dep))))) + (propagated-inputs (list dep)))) (dummy (dummy-package "dummy" - (inputs `(("prop" ,prop))))) + (inputs (list prop)))) (inputs (bag-transitive-inputs (package->bag dummy #:graft? #f)))) (match (assoc "dep" inputs) (("dep" package) @@ -1155,7 +1290,7 @@ `(("libxml2" ,libxml2)) '())))) (pkg (dummy-package "foo" - (native-inputs `(("dep" ,dep))))) + (native-inputs (list dep)))) (bag (package->bag pkg (%current-system) "i586-gnu"))) (equal? (parameterize ((%current-system "x86_64-linux")) (bag-transitive-inputs bag)) @@ -1168,19 +1303,20 @@ `(("libxml2" ,libxml2)) '())))) (pkg (dummy-package "foo" - (native-inputs `(("dep" ,dep))))) + (native-inputs (list dep)))) (bag (package->bag pkg (%current-system) "foo86-hurd"))) (equal? (parameterize ((%current-target-system "foo64-gnu")) (bag-transitive-inputs bag)) (parameterize ((%current-target-system #f)) (bag-transitive-inputs bag))))) -(test-assert "bag->derivation" +(test-assertm "bag->derivation" (parameterize ((%graft? #f)) (let ((bag (package->bag gnu-make)) (drv (package-derivation %store gnu-make))) (parameterize ((%current-system "foox86-hurd")) ;should have no effect - (equal? drv (bag->derivation %store bag)))))) + (mlet %store-monad ((bag-drv (bag->derivation bag))) + (return (equal? drv bag-drv))))))) (test-assert "bag->derivation, cross-compilation" (parameterize ((%graft? #f)) @@ -1189,7 +1325,8 @@ (drv (package-cross-derivation %store gnu-make target))) (parameterize ((%current-system "foox86-hurd") ;should have no effect (%current-target-system "foo64-linux-gnu")) - (equal? drv (bag->derivation %store bag)))))) + (mlet %store-monad ((bag-drv (bag->derivation bag))) + (return (equal? drv bag-drv))))))) (when (or (not (network-reachable?)) (shebang-too-long?)) (test-skip 1)) @@ -1472,11 +1609,11 @@ (build-system trivial-build-system))) (glib (dummy-package "glib" (build-system trivial-build-system) - (propagated-inputs `(("libffi" ,libffi))))) + (propagated-inputs (list libffi)))) (gobject (dummy-package "gobject-introspection" (build-system trivial-build-system) - (inputs `(("glib" ,glib))) - (propagated-inputs `(("libffi" ,libffi))))) + (inputs (list glib)) + (propagated-inputs (list libffi)))) (rewrite (package-input-rewriting/spec `(("glib" . ,identity))))) (and (= (length (package-transitive-inputs gobject)) @@ -1493,11 +1630,11 @@ (build-system trivial-build-system))) (glib (dummy-package "glib" (build-system trivial-build-system) - (propagated-inputs `(("libffi" ,libffi))))) + (propagated-inputs (list libffi)))) (gobject (dummy-package "gobject-introspection" (build-system trivial-build-system) - (inputs `(("glib" ,glib))) - (propagated-inputs `(("libffi" ,libffi))))) + (inputs (list glib)) + (propagated-inputs (list libffi)))) (rewrite (package-input-rewriting `((,glib . ,glib))))) (and (= (length (package-transitive-inputs gobject)) (length (package-transitive-inputs (rewrite gobject)))) @@ -1775,6 +1912,39 @@ (package-location (specification->package "guile@2")) (specification->location "guile@2")) +(test-eq "this-package-input, exists" + hello + (package-arguments + (dummy-package "a" + (inputs `(("hello" ,hello))) + (arguments (this-package-input "hello"))))) + +(test-eq "this-package-input, exists in propagated-inputs" + hello + (package-arguments + (dummy-package "a" + (propagated-inputs `(("hello" ,hello))) + (arguments (this-package-input "hello"))))) + +(test-eq "this-package-input, does not exist" + #f + (package-arguments + (dummy-package "a" + (arguments (this-package-input "hello"))))) + +(test-eq "this-package-native-input, exists" + hello + (package-arguments + (dummy-package "a" + (native-inputs `(("hello" ,hello))) + (arguments (this-package-native-input "hello"))))) + +(test-eq "this-package-native-input, does not exists" + #f + (package-arguments + (dummy-package "a" + (arguments (this-package-native-input "hello"))))) + (test-end "packages") ;;; Local Variables: diff --git a/tests/print.scm b/tests/print.scm index 3386590d3a..d9710d1ed3 100644 --- a/tests/print.scm +++ b/tests/print.scm @@ -22,6 +22,7 @@ #:use-module (guix download) #:use-module (guix packages) #:use-module ((guix licenses) #:prefix license:) + #:use-module ((gnu packages) #:select (search-patches)) #:use-module (srfi srfi-64)) (define-syntax-rule (define-with-source object source expr) @@ -60,8 +61,79 @@ (base32 "070pwb7brdcn1mfvplkd56vjc7lbz4iznzkqvfsakvgbv68k71ah")))) (build-system (@ (guix build-system gnu) gnu-build-system)) - (inputs `(("coreutils" ,(@ (gnu packages base) coreutils)) - ("glibc" ,(@ (gnu packages base) glibc) "debug"))) + (inputs (list (@ (gnu packages base) coreutils) + `(,(@ (gnu packages base) glibc) "debug"))) + (home-page "http://gnu.org") + (synopsis "Dummy") + (description "This is a dummy package.") + (license license:gpl3+))) + +(define-with-source pkg-with-origin-input pkg-with-origin-input-source + (package + (name "test") + (version "1.2.3") + (source (origin + (method url-fetch) + (uri (list (string-append "file:///tmp/test-" + version ".tar.gz") + (string-append "http://example.org/test-" + version ".tar.gz"))) + (sha256 + (base32 + "070pwb7brdcn1mfvplkd56vjc7lbz4iznzkqvfsakvgbv68k71ah")) + (patches (search-patches "guile-linux-syscalls.patch" + "guile-relocatable.patch")))) + (build-system (@ (guix build-system gnu) gnu-build-system)) + (inputs + `(("o" ,(origin + (method url-fetch) + (uri "http://example.org/somefile.txt") + (sha256 + (base32 + "0000000000000000000000000000000000000000000000000000")))))) + (home-page "http://gnu.org") + (synopsis "Dummy") + (description "This is a dummy package.") + (license license:gpl3+))) + +(define-with-source pkg-with-origin-patch pkg-with-origin-patch-source + (package + (name "test") + (version "1.2.3") + (source (origin + (method url-fetch) + (uri (string-append "file:///tmp/test-" + version ".tar.gz")) + (sha256 + (base32 + "070pwb7brdcn1mfvplkd56vjc7lbz4iznzkqvfsakvgbv68k71ah")) + (patches + (list (origin + (method url-fetch) + (uri "http://example.org/x.patch") + (sha256 + (base32 + "0000000000000000000000000000000000000000000000000000"))))))) + (build-system (@ (guix build-system gnu) gnu-build-system)) + (home-page "http://gnu.org") + (synopsis "Dummy") + (description "This is a dummy package.") + (license license:gpl3+))) + +(define-with-source pkg-with-arguments pkg-with-arguments-source + (package + (name "test") + (version "1.2.3") + (source (origin + (method url-fetch) + (uri (string-append "file:///tmp/test-" + version ".tar.gz")) + (sha256 + (base32 + "070pwb7brdcn1mfvplkd56vjc7lbz4iznzkqvfsakvgbv68k71ah")))) + (build-system (@ (guix build-system gnu) gnu-build-system)) + (arguments + `(#:disallowed-references (,(@ (gnu packages base) coreutils)))) (home-page "http://gnu.org") (synopsis "Dummy") (description "This is a dummy package.") @@ -75,4 +147,16 @@ `(define-public test ,pkg-with-inputs-source) (package->code pkg-with-inputs)) +(test-equal "package with origin input" + `(define-public test ,pkg-with-origin-input-source) + (package->code pkg-with-origin-input)) + +(test-equal "package with origin patch" + `(define-public test ,pkg-with-origin-patch-source) + (package->code pkg-with-origin-patch)) + +(test-equal "package with arguments" + `(define-public test ,pkg-with-arguments-source) + (package->code pkg-with-arguments)) + (test-end "print") diff --git a/tests/profiles.scm b/tests/profiles.scm index 06a0387221..cac5b73347 100644 --- a/tests/profiles.scm +++ b/tests/profiles.scm @@ -265,6 +265,13 @@ (manifest-transaction-removal-candidate? guile-2.0.9 t) (null? install) (null? downgrade) (null? upgrade))))) +(test-assert "package->development-manifest" + (let ((manifest (package->development-manifest packages:hello))) + (every (lambda (name) + (manifest-installed? manifest + (manifest-pattern (name name)))) + '("gcc" "binutils" "glibc" "coreutils" "grep" "sed")))) + (test-assertm "profile-derivation" (mlet* %store-monad ((entry -> (package->manifest-entry %bootstrap-guile)) diff --git a/tests/publish.scm b/tests/publish.scm index c3d086995a..e3c27c5eea 100644 --- a/tests/publish.scm +++ b/tests/publish.scm @@ -1,7 +1,7 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2015 David Thompson <[email protected]> ;;; Copyright © 2020 by Amar M. Singh <[email protected]> -;;; Copyright © 2016, 2017, 2018, 2019, 2020, 2021 Ludovic Courtès <[email protected]> +;;; Copyright © 2016-2022 Ludovic Courtès <[email protected]> ;;; ;;; This file is part of GNU Guix. ;;; @@ -679,7 +679,7 @@ References: ~%" (response-code (http-get nar))))))))) (test-equal "/log/NAME" - `(200 #t application/x-bzip2) + `(200 #t text/plain (gzip)) (let ((drv (run-with-store %store (gexp->derivation "with-log" #~(call-with-output-file #$output @@ -695,10 +695,11 @@ References: ~%" (base (basename (derivation-file-name drv))) (log (string-append (dirname %state-directory) "/log/guix/drvs/" (string-take base 2) - "/" (string-drop base 2) ".bz2"))) + "/" (string-drop base 2) ".gz"))) (list (response-code response) (= (response-content-length response) (stat:size (stat log))) - (first (response-content-type response)))))) + (first (response-content-type response)) + (response-content-encoding response))))) (test-equal "negative TTL" `(404 42) diff --git a/tests/pypi.scm b/tests/pypi.scm index 70f4298a90..1ea5f02643 100644 --- a/tests/pypi.scm +++ b/tests/pypi.scm @@ -249,20 +249,21 @@ Requires-Dist: pytest (>=3.1.0); extra == 'testing' ('base32 (? string? hash))))) ('build-system 'python-build-system) - ('propagated-inputs - ('quasiquote - (("python-bar" ('unquote 'python-bar)) - ("python-foo" ('unquote 'python-foo))))) - ('native-inputs - ('quasiquote - (("python-pytest" ('unquote 'python-pytest))))) + ('propagated-inputs ('list 'python-bar 'python-foo)) + ('native-inputs ('list 'python-pytest)) ('home-page "http://example.com") ('synopsis "summary") ('description "summary") ('license 'license:lgpl2.0)) - (string=? (bytevector->nix-base32-string - test-source-hash) - hash)) + (and (string=? (bytevector->nix-base32-string + test-source-hash) + hash) + (equal? (pypi->guix-package "foo" #:version "1.0.0") + (pypi->guix-package "foo")) + (catch 'quit + (lambda () + (pypi->guix-package "foo" #:version "42")) + (const #t)))) (x (pk 'fail x #f)))))) @@ -318,13 +319,8 @@ Requires-Dist: pytest (>=3.1.0); extra == 'testing' ('base32 (? string? hash))))) ('build-system 'python-build-system) - ('propagated-inputs - ('quasiquote - (("python-bar" ('unquote 'python-bar)) - ("python-baz" ('unquote 'python-baz))))) - ('native-inputs - ('quasiquote - (("python-pytest" ('unquote 'python-pytest))))) + ('propagated-inputs ('list 'python-bar 'python-baz)) + ('native-inputs ('list 'python-pytest)) ('home-page "http://example.com") ('synopsis "summary") ('description "summary") @@ -420,13 +416,8 @@ Requires-Dist: pytest (>=3.1.0); extra == 'testing' (? string? hash))))) ('properties ('quote (("upstream-name" . "foo-99")))) ('build-system 'python-build-system) - ('propagated-inputs - ('quasiquote - (("python-bar" ('unquote 'python-bar)) - ("python-foo" ('unquote 'python-foo))))) - ('native-inputs - ('quasiquote - (("python-pytest" ('unquote 'python-pytest))))) + ('propagated-inputs ('list 'python-bar 'python-foo)) + ('native-inputs ('list 'python-pytest)) ('home-page "http://example.com") ('synopsis "summary") ('description "summary") diff --git a/tests/store-deduplication.scm b/tests/store-deduplication.scm index b1c2d93bbd..2950fbc1a3 100644 --- a/tests/store-deduplication.scm +++ b/tests/store-deduplication.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2018, 2020 Ludovic Courtès <[email protected]> +;;; Copyright © 2018, 2020-2021 Ludovic Courtès <[email protected]> ;;; ;;; This file is part of GNU Guix. ;;; @@ -30,13 +30,40 @@ (test-begin "store-deduplication") +(test-equal "deduplicate, below %deduplication-minimum-size" + (list #t (make-list 5 1)) + + (call-with-temporary-directory + (lambda (store) + ;; Note: DATA must be longer than %DEDUPLICATION-MINIMUM-SIZE. + (let ((data "Hello, world!") + (identical (map (lambda (n) + (string-append store "/" (number->string n) + "/a/b/c")) + (iota 5)))) + (for-each (lambda (file) + (mkdir-p (dirname file)) + (call-with-output-file file + (lambda (port) + (put-bytevector port (string->utf8 data))))) + identical) + + (deduplicate store (nar-sha256 store) #:store store) + + ;; (system (string-append "ls -lRia " store)) + (list (= (length (delete-duplicates + (map (compose stat:ino stat) identical))) + (length identical)) + (map (compose stat:nlink stat) identical)))))) + (test-equal "deduplicate" (cons* #t #f ;inode comparisons 2 (make-list 5 6)) ;'nlink' values (call-with-temporary-directory (lambda (store) - (let ((data (string->utf8 "Hello, world!")) + ;; Note: DATA must be longer than %DEDUPLICATION-MINIMUM-SIZE. + (let ((data (string-concatenate (make-list 1000 "Hello, world!"))) (identical (map (lambda (n) (string-append store "/" (number->string n) "/a/b/c")) @@ -46,7 +73,7 @@ (mkdir-p (dirname file)) (call-with-output-file file (lambda (port) - (put-bytevector port data)))) + (put-bytevector port (string->utf8 data))))) identical) ;; Make the parent of IDENTICAL read-only. This should not prevent ;; deduplication from inserting its hard link. @@ -54,7 +81,7 @@ (call-with-output-file unique (lambda (port) - (put-bytevector port (string->utf8 "This is unique.")))) + (put-bytevector port (string->utf8 (string-reverse data))))) (deduplicate store (nar-sha256 store) #:store store) @@ -77,8 +104,10 @@ (lambda (store) (let ((true-link link) (links 0) - (data1 (string->utf8 "Hello, world!")) - (data2 (string->utf8 "Hi, world!")) + (data1 (string->utf8 + (string-concatenate (make-list 1000 "Hello, world!")))) + (data2 (string->utf8 + (string-concatenate (make-list 1000 "Hi, world!")))) (identical (map (lambda (n) (string-append store "/" (number->string n) "/a/b/c")) diff --git a/tests/store.scm b/tests/store.scm index 95f47c3af3..5df28adf0d 100644 --- a/tests/store.scm +++ b/tests/store.scm @@ -490,6 +490,34 @@ (equal? (map derivation-file-name (drop d 16)) batch3) lst))))) +(test-equal "map/accumulate-builds and different store" + '(d2) ;see <https://issues.guix.gnu.org/46756> + (let* ((b (add-text-to-store %store "build" "echo $foo > $out" '())) + (s (add-to-store %store "bash" #t "sha256" + (search-bootstrap-binary "bash" + (%current-system)))) + (d1 (derivation %store "first" + s `("-e" ,b) + #:env-vars `(("foo" . ,(random-text))) + #:sources (list b s))) + (d2 (derivation %store "second" + s `("-e" ,b) + #:env-vars `(("foo" . ,(random-text)) + ("bar" . "baz")) + #:sources (list b s)))) + (with-store alternate-store + (with-build-handler (lambda (continue store things mode) + ;; If this handler is called, it means that + ;; 'map/accumulate-builds' triggered a build, + ;; which it shouldn't since the inner + ;; 'build-derivations' call is for another store. + 'failed) + (map/accumulate-builds %store + (lambda (drv) + (build-derivations alternate-store (list d2)) + 'd2) + (list d1)))))) + (test-assert "mapm/accumulate-builds" (let* ((d1 (run-with-store %store (gexp->derivation "foo" #~(mkdir #$output)))) @@ -570,7 +598,8 @@ (d (build-expression->derivation %store "foo" `(display ,s) #:guile-for-build - (package-derivation s %bootstrap-guile (%current-system))))) + (package-derivation %store %bootstrap-guile + (%current-system))))) (guard (c ((store-protocol-error? c) #t)) (build-derivations %store (list d)))))))) "Here’s a Greek letter: λ.")) @@ -731,7 +760,9 @@ (test-assert "substitute, deduplication" (with-store s - (let* ((c (random-text)) ; contents of the output + ;; Note: C must be longer than %DEDUPLICATION-MINIMUM-SIZE. + (let* ((c (string-concatenate + (make-list 200 (random-text)))) ; contents of the output (g (package-derivation s %bootstrap-guile)) (d1 (build-expression->derivation s "substitute-me" `(begin ,c (exit 1)) @@ -912,6 +943,84 @@ (build-derivations s (list d)) #f)))))) +(test-equal "substitute query and large size" + (+ 100 (expt 2 63)) ;<https://issues.guix.gnu.org/51983> + (with-store s + (let* ((size (+ 100 (expt 2 63))) ;does not fit in signed 'long long' + (item (string-append (%store-prefix) + "/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-bad-size"))) + ;; Create fake substituter data, to be read by 'guix substitute'. + (call-with-output-file (string-append (%substitute-directory) + "/" (store-path-hash-part item) + ".narinfo") + (lambda (port) + (format port "StorePath: ~a +URL: http://example.org +Compression: none +NarSize: ~a +NarHash: sha256:0fj9vhblff2997pi7qjj7lhmy7wzhnjwmkm2hmq6gr4fzmg10s0w +References: +System: x86_64-linux~%" + item size))) + + ;; Remove entry from the local cache. + (false-if-exception + (delete-file-recursively (string-append (getenv "XDG_CACHE_HOME") + "/guix/substitute"))) + + ;; Make sure 'guix substitute' correctly communicates the above + ;; data. + (set-build-options s #:use-substitutes? #t + #:substitute-urls (%test-substitute-urls)) + (match (pk 'spi (substitutable-path-info s (list item))) + (((? substitutable? s)) + (and (equal? (substitutable-path s) item) + (substitutable-nar-size s))))))) + +(test-equal "substitute and large size" + (+ 100 (expt 2 31)) ;<https://issues.guix.gnu.org/46212> + (with-store s + (let* ((size (+ 100 (expt 2 31))) ;does not fit in signed 'int' + (item (string-append (%store-prefix) + "/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-bad-size-" + (random-text))) + (nar (string-append (%substitute-directory) "/nar"))) + ;; Create a dummy nar to allow for substitution. + (call-with-output-file nar + (lambda (port) + (write-file-tree (store-path-package-name item) port + #:file-type+size (lambda _ + (values 'regular 12)) + #:file-port (lambda _ + (open-input-string "Hello world."))))) + + ;; Create fake substituter data, to be read by 'guix substitute'. + (call-with-output-file (string-append (%substitute-directory) + "/" (store-path-hash-part item) + ".narinfo") + (lambda (port) + (format port "StorePath: ~a +URL: file://~a +Compression: none +NarSize: ~a +NarHash: sha256:~a +References: +System: x86_64-linux~%" + item nar size + (bytevector->nix-base32-string (gcrypt:file-sha256 nar))))) + + ;; Remove entry from the local cache. + (false-if-exception + (delete-file-recursively (string-append (getenv "XDG_CACHE_HOME") + "/guix/substitute"))) + + ;; Make sure 'guix substitute' correctly communicates the above + ;; data. + (set-build-options s #:use-substitutes? #t + #:substitute-urls (%test-substitute-urls)) + (ensure-path s item) + (path-info-nar-size (query-path-info s item))))) + (test-assert "export/import several paths" (let* ((texts (unfold (cut >= <> 10) (lambda _ (random-text)) diff --git a/tests/style.scm b/tests/style.scm new file mode 100644 index 0000000000..8c6d37a661 --- /dev/null +++ b/tests/style.scm @@ -0,0 +1,518 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2021 Ludovic Courtès <[email protected]> +;;; +;;; This file is part of GNU Guix. +;;; +;;; GNU Guix is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or (at +;;; your option) any later version. +;;; +;;; GNU Guix is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. + +(define-module (tests-style) + #:use-module (guix packages) + #:use-module (guix scripts style) + #:use-module ((guix utils) #:select (call-with-temporary-directory)) + #:use-module ((guix build utils) #:select (substitute*)) + #:use-module (guix gexp) ;for the reader extension + #:use-module (guix diagnostics) + #:use-module (gnu packages acl) + #:use-module (gnu packages multiprecision) + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-64) + #:use-module (ice-9 match) + #:use-module (ice-9 rdelim) + #:use-module (ice-9 pretty-print)) + +(define (call-with-test-package inputs proc) + (call-with-temporary-directory + (lambda (directory) + (call-with-output-file (string-append directory "/my-packages.scm") + (lambda (port) + (pretty-print + `(begin + (define-module (my-packages) + #:use-module (guix) + #:use-module (guix licenses) + #:use-module (gnu packages acl) + #:use-module (gnu packages base) + #:use-module (gnu packages multiprecision) + #:use-module (srfi srfi-1)) + + (define base + (package + (inherit coreutils) + (inputs '()) + (native-inputs '()) + (propagated-inputs '()))) + + (define (sdl-union . lst) + (package + (inherit base) + (name "sdl-union"))) + + (define-public my-coreutils + (package + (inherit base) + ,@inputs + (name "my-coreutils")))) + port))) + + (proc directory)))) + +(define test-directory + ;; Directory where the package definition lives. + (make-parameter #f)) + +(define-syntax-rule (with-test-package fields exp ...) + (call-with-test-package fields + (lambda (directory) + (define file + (string-append directory "/my-packages.scm")) + + ;; Run as a separate process to make sure FILE is reloaded. + (system* "guix" "style" "-L" directory "-S" "inputs" + "my-coreutils") + (system* "cat" file) + + (load file) + (parameterize ((test-directory directory)) + exp ...)))) + +(define* (read-lines port line #:optional (count 1)) + "Read COUNT lines from PORT, starting from LINE." + (let loop ((lines '()) + (count count)) + (cond ((< (port-line port) (- line 1)) + (read-char port) + (loop lines count)) + ((zero? count) + (string-concatenate-reverse lines)) + (else + (match (read-line port 'concat) + ((? eof-object?) + (loop lines 0)) + (line + (loop (cons line lines) (- count 1)))))))) + +(define* (read-package-field package field #:optional (count 1)) + (let* ((location (package-field-location package field)) + (file (location-file location)) + (line (location-line location))) + (call-with-input-file (if (string-prefix? "/" file) + file + (string-append (test-directory) "/" + file)) + (lambda (port) + (read-lines port line count))))) + +(define-syntax-rule (test-pretty-print str args ...) + "Test equality after a round-trip where STR is passed to +'read-with-comments' and the resulting sexp is then passed to +'pretty-print-with-comments'." + (test-equal str + (call-with-output-string + (lambda (port) + (let ((exp (call-with-input-string str + read-with-comments))) + (pretty-print-with-comments port exp args ...)))))) + + +(test-begin "style") + +(test-equal "nothing to rewrite" + '() + (with-test-package '() + (package-direct-inputs (@ (my-packages) my-coreutils)))) + +(test-equal "input labels, mismatch" + (list `(("foo" ,gmp) ("bar" ,acl)) + " (inputs `((\"foo\" ,gmp) (\"bar\" ,acl)))\n") + (with-test-package '((inputs `(("foo" ,gmp) ("bar" ,acl)))) + (list (package-direct-inputs (@ (my-packages) my-coreutils)) + (read-package-field (@ (my-packages) my-coreutils) 'inputs)))) + +(test-equal "input labels, simple" + (list `(("gmp" ,gmp) ("acl" ,acl)) + " (inputs (list gmp acl))\n") + (with-test-package '((inputs `(("gmp" ,gmp) ("acl" ,acl)))) + (list (package-direct-inputs (@ (my-packages) my-coreutils)) + (read-package-field (@ (my-packages) my-coreutils) 'inputs)))) + +(test-equal "input labels, long list with one item per line" + (list (concatenate (make-list 4 `(("gmp" ,gmp) ("acl" ,acl)))) + "\ + (list gmp + acl + gmp + acl + gmp + acl + gmp + acl))\n") + (with-test-package '((inputs `(("gmp" ,gmp) ("acl" ,acl) + ("gmp" ,gmp) ("acl" ,acl) + ("gmp" ,gmp) ("acl" ,acl) + ("gmp" ,gmp) ("acl" ,acl)))) + (list (package-direct-inputs (@ (my-packages) my-coreutils)) + (read-package-field (@ (my-packages) my-coreutils) 'inputs 8)))) + +(test-equal "input labels, sdl-union" + "\ + (list gmp acl + (sdl-union 1 2 3 4)))\n" + (with-test-package '((inputs `(("gmp" ,gmp) ("acl" ,acl) + ("sdl-union" ,(sdl-union 1 2 3 4))))) + (read-package-field (@ (my-packages) my-coreutils) 'inputs 2))) + +(test-equal "input labels, output" + (list `(("gmp" ,gmp "debug") ("acl" ,acl)) + " (inputs (list `(,gmp \"debug\") acl))\n") + (with-test-package '((inputs `(("gmp" ,gmp "debug") ("acl" ,acl)))) + (list (package-direct-inputs (@ (my-packages) my-coreutils)) + (read-package-field (@ (my-packages) my-coreutils) 'inputs)))) + +(test-equal "input labels, prepend" + (list `(("gmp" ,gmp) ("acl" ,acl)) + "\ + (modify-inputs (package-propagated-inputs coreutils) + (prepend gmp acl)))\n") + (with-test-package '((inputs `(("gmp" ,gmp) ("acl" ,acl) + ,@(package-propagated-inputs coreutils)))) + (list (package-inputs (@ (my-packages) my-coreutils)) + (read-package-field (@ (my-packages) my-coreutils) 'inputs 2)))) + +(test-equal "input labels, prepend + delete" + (list `(("gmp" ,gmp) ("acl" ,acl)) + "\ + (modify-inputs (package-propagated-inputs coreutils) + (delete \"gmp\") + (prepend gmp acl)))\n") + (with-test-package '((inputs `(("gmp" ,gmp) + ("acl" ,acl) + ,@(alist-delete "gmp" + (package-propagated-inputs coreutils))))) + (list (package-inputs (@ (my-packages) my-coreutils)) + (read-package-field (@ (my-packages) my-coreutils) 'inputs 3)))) + +(test-equal "input labels, prepend + delete multiple" + (list `(("gmp" ,gmp) ("acl" ,acl)) + "\ + (modify-inputs (package-propagated-inputs coreutils) + (delete \"foo\" \"bar\" \"baz\") + (prepend gmp acl)))\n") + (with-test-package '((inputs `(("gmp" ,gmp) + ("acl" ,acl) + ,@(fold alist-delete + (package-propagated-inputs coreutils) + '("foo" "bar" "baz"))))) + (list (package-inputs (@ (my-packages) my-coreutils)) + (read-package-field (@ (my-packages) my-coreutils) 'inputs 3)))) + +(test-equal "input labels, replace" + (list '() ;there's no "gmp" input to replace + "\ + (modify-inputs (package-propagated-inputs coreutils) + (replace \"gmp\" gmp)))\n") + (with-test-package '((inputs `(("gmp" ,gmp) + ,@(alist-delete "gmp" + (package-propagated-inputs coreutils))))) + (list (package-inputs (@ (my-packages) my-coreutils)) + (read-package-field (@ (my-packages) my-coreutils) 'inputs 2)))) + +(test-equal "input labels, 'safe' policy" + (list `(("gmp" ,gmp) ("acl" ,acl)) + "\ + (inputs (list gmp acl))\n") + (call-with-test-package '((inputs `(("GMP" ,gmp) ("ACL" ,acl))) + (arguments '())) ;no build system arguments + (lambda (directory) + (define file + (string-append directory "/my-packages.scm")) + + (system* "guix" "style" "-L" directory "my-coreutils" + "-S" "inputs" + "--input-simplification=safe") + + (load file) + (list (package-inputs (@ (my-packages) my-coreutils)) + (read-package-field (@ (my-packages) my-coreutils) 'inputs))))) + +(test-equal "input labels, 'safe' policy, nothing changed" + (list `(("GMP" ,gmp) ("ACL" ,acl)) + "\ + (inputs `((\"GMP\" ,gmp) (\"ACL\" ,acl)))\n") + (call-with-test-package '((inputs `(("GMP" ,gmp) ("ACL" ,acl))) + ;; Non-empty argument list, so potentially unsafe + ;; input simplification. + (arguments + '(#:configure-flags + (assoc-ref %build-inputs "GMP")))) + (lambda (directory) + (define file + (string-append directory "/my-packages.scm")) + + (system* "guix" "style" "-L" directory "my-coreutils" + "-S" "inputs" + "--input-simplification=safe") + + (load file) + (list (package-inputs (@ (my-packages) my-coreutils)) + (read-package-field (@ (my-packages) my-coreutils) 'inputs))))) + +(test-equal "input labels, margin comment" + (list `(("gmp" ,gmp)) + `(("acl" ,acl)) + " (inputs (list gmp)) ;margin comment\n" + " (native-inputs (list acl)) ;another one\n") + (call-with-test-package '((inputs `(("gmp" ,gmp))) + (native-inputs `(("acl" ,acl)))) + (lambda (directory) + (define file + (string-append directory "/my-packages.scm")) + + (substitute* file + (("\"gmp\"(.*)$" _ rest) + (string-append "\"gmp\"" (string-trim-right rest) + " ;margin comment\n")) + (("\"acl\"(.*)$" _ rest) + (string-append "\"acl\"" (string-trim-right rest) + " ;another one\n"))) + (system* "cat" file) + + (system* "guix" "style" "-L" directory "-S" "inputs" + "my-coreutils") + + (load file) + (list (package-inputs (@ (my-packages) my-coreutils)) + (package-native-inputs (@ (my-packages) my-coreutils)) + (read-package-field (@ (my-packages) my-coreutils) 'inputs) + (read-package-field (@ (my-packages) my-coreutils) 'native-inputs))))) + +(test-equal "input labels, margin comment on long list" + (list (concatenate (make-list 4 `(("gmp" ,gmp) ("acl" ,acl)))) + "\ + (list gmp ;margin comment + acl + gmp ;margin comment + acl + gmp ;margin comment + acl + gmp ;margin comment + acl))\n") + (call-with-test-package '((inputs `(("gmp" ,gmp) ("acl" ,acl) + ("gmp" ,gmp) ("acl" ,acl) + ("gmp" ,gmp) ("acl" ,acl) + ("gmp" ,gmp) ("acl" ,acl)))) + (lambda (directory) + (define file + (string-append directory "/my-packages.scm")) + + (substitute* file + (("\"gmp\"(.*)$" _ rest) + (string-append "\"gmp\"" (string-trim-right rest) + " ;margin comment\n"))) + (system* "cat" file) + + (system* "guix" "style" "-L" directory "-S" "inputs" + "my-coreutils") + + (load file) + (list (package-inputs (@ (my-packages) my-coreutils)) + (read-package-field (@ (my-packages) my-coreutils) 'inputs 8))))) + +(test-equal "input labels, line comment" + (list `(("gmp" ,gmp) ("acl" ,acl)) + "\ + (inputs (list gmp + ;; line comment! + acl))\n") + (call-with-test-package '((inputs `(("gmp" ,gmp) ("acl" ,acl)))) + (lambda (directory) + (define file + (string-append directory "/my-packages.scm")) + + (substitute* file + ((",gmp\\)(.*)$" _ rest) + (string-append ",gmp)\n ;; line comment!\n" rest))) + + (system* "guix" "style" "-L" directory "-S" "inputs" + "my-coreutils") + + (load file) + (list (package-inputs (@ (my-packages) my-coreutils)) + (read-package-field (@ (my-packages) my-coreutils) 'inputs 3))))) + +(test-equal "input labels, modify-inputs and margin comment" + (list `(("gmp" ,gmp) ("acl" ,acl) ("mpfr" ,mpfr)) + "\ + (modify-inputs (package-propagated-inputs coreutils) + (prepend gmp ;margin comment + acl ;another one + mpfr)))\n") + (call-with-test-package '((inputs + `(("gmp" ,gmp) ("acl" ,acl) ("mpfr" ,mpfr) + ,@(package-propagated-inputs coreutils)))) + (lambda (directory) + (define file + (string-append directory "/my-packages.scm")) + + (substitute* file + ((",gmp\\)(.*)$" _ rest) + (string-append ",gmp) ;margin comment\n" rest)) + ((",acl\\)(.*)$" _ rest) + (string-append ",acl) ;another one\n" rest))) + + (system* "guix" "style" "-L" directory "-S" "inputs" + "my-coreutils") + + (load file) + (list (package-inputs (@ (my-packages) my-coreutils)) + (read-package-field (@ (my-packages) my-coreutils) 'inputs 4))))) + +(test-pretty-print "(list 1 2 3 4)") +(test-pretty-print "(list 1 + 2 + 3 + 4)" + #:long-list 3 + #:indent 20) +(test-pretty-print "\ +(list abc + def)" + #:max-width 11) +(test-pretty-print "\ +(#:foo + #:bar)" + #:max-width 10) + +(test-pretty-print "\ +(#:first 1 + #:second 2 + #:third 3)") + +(test-pretty-print "\ +((x + 1) + (y + 2) + (z + 3))" + #:max-width 3) + +(test-pretty-print "\ +(let ((x 1) + (y 2) + (z 3) + (p 4)) + (+ x y))" + #:max-width 11) + +(test-pretty-print "\ +(lambda (x y) + ;; This is a procedure. + (let ((z (+ x y))) + (* z z)))") + +(test-pretty-print "\ +#~(string-append #$coreutils \"/bin/uname\")") + +(test-pretty-print "\ +(package + (inherit coreutils) + (version \"42\"))") + +(test-pretty-print "\ +(modify-phases %standard-phases + (add-after 'unpack 'post-unpack + (lambda _ + #t)) + (add-before 'check 'pre-check + (lambda* (#:key inputs #:allow-other-keys) + do things ...)))") + +(test-pretty-print "\ +(#:phases (modify-phases sdfsdf + (add-before 'x 'y + (lambda _ + xyz))))") + +(test-pretty-print "\ +(description \"abcdefghijkl +mnopqrstuvwxyz.\")" + #:max-width 30) + +(test-pretty-print "\ +(description + \"abcdefghijkl +mnopqrstuvwxyz.\")" + #:max-width 12) + +(test-pretty-print "\ +(description + \"abcdefghijklmnopqrstuvwxyz\")" + #:max-width 33) + +(test-pretty-print "\ +(modify-phases %standard-phases + (replace 'build + ;; Nicely indented in 'modify-phases' context. + (lambda _ + #t)))") + +(test-pretty-print "\ +(modify-inputs inputs + ;; Regular indentation for 'replace' here. + (replace \"gmp\" gmp))") + +(test-pretty-print "\ +(package + ;; Here 'sha256', 'base32', and 'arguments' must be + ;; immediately followed by a newline. + (source (origin + (method url-fetch) + (sha256 + (base32 + \"not a real base32 string\")))) + (arguments + '(#:phases %standard-phases + #:tests? #f)))") + +(test-equal "pretty-print-with-comments, canonicalize-comment" + "\ +(list abc + ;; Not a margin comment. + ;; Ditto. + ;; + ;; There's a blank line above. + def ;margin comment + ghi)" + (let ((sexp (call-with-input-string + "\ +(list abc + ;Not a margin comment. + ;;; Ditto. + ;;;;; + ; There's a blank line above. + def ;; margin comment + ghi)" + read-with-comments))) + (call-with-output-string + (lambda (port) + (pretty-print-with-comments port sexp + #:format-comment + canonicalize-comment))))) + +(test-end) + +;; Local Variables: +;; eval: (put 'with-test-package 'scheme-indent-function 1) +;; eval: (put 'call-with-test-package 'scheme-indent-function 1) +;; End: diff --git a/tests/syscalls.scm b/tests/syscalls.scm index 706dd4177f..c9e011f453 100644 --- a/tests/syscalls.scm +++ b/tests/syscalls.scm @@ -26,6 +26,7 @@ #:use-module (srfi srfi-1) #:use-module (srfi srfi-26) #:use-module (srfi srfi-64) + #:use-module (srfi srfi-71) #:use-module (system foreign) #:use-module ((ice-9 ftw) #:select (scandir)) #:use-module (ice-9 match)) @@ -582,6 +583,40 @@ (test-assert "terminal-rows" (> (terminal-rows) 0)) +(test-assert "openpty" + (let ((head inferior (openpty))) + (and (integer? head) (integer? inferior) + (let ((port (fdopen inferior "r+0"))) + (and (isatty? port) + (begin + (close-port port) + (close-fdes head) + #t)))))) + +(test-equal "openpty + login-tty" + '(hello world) + (let ((head inferior (openpty))) + (match (primitive-fork) + (0 + (dynamic-wind + (const #t) + (lambda () + (setvbuf (current-input-port) 'none) + (close-fdes head) + (login-tty inferior) + (write (read)) + (read)) ;this gets EIO when HEAD is closed + (lambda () + (primitive-_exit 42)))) + (pid + (close-fdes inferior) + (let ((head (fdopen head "r+0"))) + (write '(hello world) head) + (let ((result (read head))) + (close-port head) + (waitpid pid) + result)))))) + (test-assert "utmpx-entries" (match (utmpx-entries) (((? utmpx? entries) ...) diff --git a/tests/texlive.scm b/tests/texlive.scm index a6f08046a8..f718e3a0a0 100644 --- a/tests/texlive.scm +++ b/tests/texlive.scm @@ -30,87 +30,174 @@ (test-begin "texlive") -(define xml - "\ -<entry id=\"foo\"> - <name>foo</name> - <caption>Foomatic frobnication in LuaLaTeX</caption> - <authorref id=\"rekado\"/> - <license type=\"lppl1.3\"/> - <version number=\"2.6a\"/> - <description> - <p> - Foo is a package for LuaLaTeX. It provides an interface to frobnicate gimbals - in a foomatic way with the LuaTeX engine. - </p> - <p> - The package requires the bar and golly - bundles for extremely special specialties. - </p> - </description> - <ctan path=\"/macros/latex/contrib/foo\" file=\"true\"/> - <texlive location=\"foo\"/> - <keyval key=\"topic\" value=\"tests\"/> - null -</entry>") +(define %fake-tlpdb + '(("stricttex" + . ((name + . "stricttex") + (shortdesc + . "Strictly balanced brackets and numbers in command names") + (longdesc + . "This is a small, LuaLaTeX-only package providing you with three, +sometimes useful features: It allows you to make brackets [...] \"strict\", +meaning that each [ must be balanced by a ]. It allows you to use numbers in +command names, so that you can do stuff like \\newcommand\\pi12{\\pi_{12}}. It +allows you to use numbers and primes in command names, so that you can do +stuff like \\newcommand\\pi'12{\\pi '_{12}}.") + (docfiles + . ("texmf-dist/doc/lualatex/stricttex/README.md" + "texmf-dist/doc/lualatex/stricttex/stricttex.pdf")) + (runfiles + . ("texmf-dist/tex/lualatex/stricttex/stricttex.lua" + "texmf-dist/tex/lualatex/stricttex/stricttex.sty")) + (catalogue-license . "lppl1.3c"))) + ("texsis" + . ((name + . "texsis") + (shortdesc + . "Plain TeX macros for Physicists") + (longdesc + . "TeXsis is a TeX macro package which provides useful features for +typesetting research papers and related documents. For example, it includes +support specifically for: Automatic numbering of equations, figures, tables +and references; Simplified control of type sizes, line spacing, footnotes, +running headlines and footlines, and tables of contents, figures and tables; +Specialized document formats for research papers, preprints and \"e-prints\", +conference proceedings, theses, books, referee reports, letters, and +memoranda; Simplified means of constructing an index for a book or thesis; +Easy to use double column formatting; Specialized environments for lists, +theorems and proofs, centered or non-justified text, and listing computer +code; Specialized macros for easily constructing ruled tables. TeXsis was +originally developed for physicists, but others may also find it useful. It is +completely compatible with Plain TeX.") + (depend . ("cm" "hyphen-base" "knuth-lib" "plain" "tex")) + (docfiles + . ("texmf-dist/doc/man/man1/texsis.1" + "texmf-dist/doc/man/man1/texsis.man1.pdf" + "texmf-dist/doc/otherformats/texsis/base/COPYING" + "texmf-dist/doc/otherformats/texsis/base/Example.tex" + "texmf-dist/doc/otherformats/texsis/base/Fonts.tex" + "texmf-dist/doc/otherformats/texsis/base/INSTALL" + "texmf-dist/doc/otherformats/texsis/base/Install.tex" + "texmf-dist/doc/otherformats/texsis/base/MANIFEST" + "texmf-dist/doc/otherformats/texsis/base/Manual.fgl" + "texmf-dist/doc/otherformats/texsis/base/Manual.ref" + "texmf-dist/doc/otherformats/texsis/base/Manual.tbl" + "texmf-dist/doc/otherformats/texsis/base/Manual.tex" + "texmf-dist/doc/otherformats/texsis/base/NEWS" + "texmf-dist/doc/otherformats/texsis/base/README" + "texmf-dist/doc/otherformats/texsis/base/TXSapxF.doc" + "texmf-dist/doc/otherformats/texsis/base/TXScover.doc" + "texmf-dist/doc/otherformats/texsis/base/TXSdcol.doc" + "texmf-dist/doc/otherformats/texsis/base/TXSdoc.doc" + "texmf-dist/doc/otherformats/texsis/base/TXSdoc0.doc" + "texmf-dist/doc/otherformats/texsis/base/TXSdocM.doc" + "texmf-dist/doc/otherformats/texsis/base/TXSend.doc" + "texmf-dist/doc/otherformats/texsis/base/TXSenvmt.doc" + "texmf-dist/doc/otherformats/texsis/base/TXSeqns.doc" + "texmf-dist/doc/otherformats/texsis/base/TXSfigs.doc" + "texmf-dist/doc/otherformats/texsis/base/TXSfmts.doc" + "texmf-dist/doc/otherformats/texsis/base/TXSfonts.doc" + "texmf-dist/doc/otherformats/texsis/base/TXSinstl.doc" + "texmf-dist/doc/otherformats/texsis/base/TXSintro.doc" + "texmf-dist/doc/otherformats/texsis/base/TXSletr.doc" + "texmf-dist/doc/otherformats/texsis/base/TXSmisc.doc" + "texmf-dist/doc/otherformats/texsis/base/TXSprns.doc" + "texmf-dist/doc/otherformats/texsis/base/TXSrefs.doc" + "texmf-dist/doc/otherformats/texsis/base/TXSrevs.doc" + "texmf-dist/doc/otherformats/texsis/base/TXSruled.doc" + "texmf-dist/doc/otherformats/texsis/base/TXSsects.doc" + "texmf-dist/doc/otherformats/texsis/base/TXSsite.000" + "texmf-dist/doc/otherformats/texsis/base/TXSsymb.doc" + "texmf-dist/doc/otherformats/texsis/base/TXStags.doc" + "texmf-dist/doc/otherformats/texsis/base/index.tex" + "texmf-dist/doc/otherformats/texsis/base/letr" + "texmf-dist/doc/otherformats/texsis/base/penguin.eps" + "texmf-dist/doc/otherformats/texsis/base/penguin2.eps" + "texmf-dist/doc/otherformats/texsis/base/texsis.el" + "texmf-dist/doc/otherformats/texsis/base/texsis.lsm")) + (runfiles + . ("texmf-dist/bibtex/bst/texsis/texsis.bst" + "texmf-dist/tex/texsis/base/AIP.txs" + "texmf-dist/tex/texsis/base/CVformat.txs" + "texmf-dist/tex/texsis/base/Elsevier.txs" + "texmf-dist/tex/texsis/base/Exam.txs" + "texmf-dist/tex/texsis/base/Formletr.txs" + "texmf-dist/tex/texsis/base/IEEE.txs" + "texmf-dist/tex/texsis/base/PhysRev.txs" + "texmf-dist/tex/texsis/base/Spanish.txs" + "texmf-dist/tex/texsis/base/Swedish.txs" + "texmf-dist/tex/texsis/base/TXSconts.tex" + "texmf-dist/tex/texsis/base/TXSdcol.tex" + "texmf-dist/tex/texsis/base/TXSenvmt.tex" + "texmf-dist/tex/texsis/base/TXSeqns.tex" + "texmf-dist/tex/texsis/base/TXSfigs.tex" + "texmf-dist/tex/texsis/base/TXSfmts.tex" + "texmf-dist/tex/texsis/base/TXSfonts.tex" + "texmf-dist/tex/texsis/base/TXShead.tex" + "texmf-dist/tex/texsis/base/TXSinit.tex" + "texmf-dist/tex/texsis/base/TXSletr.tex" + "texmf-dist/tex/texsis/base/TXSmacs.tex" + "texmf-dist/tex/texsis/base/TXSmemo.tex" + "texmf-dist/tex/texsis/base/TXSprns.tex" + "texmf-dist/tex/texsis/base/TXSrefs.tex" + "texmf-dist/tex/texsis/base/TXSruled.tex" + "texmf-dist/tex/texsis/base/TXSsects.tex" + "texmf-dist/tex/texsis/base/TXSsite.tex" + "texmf-dist/tex/texsis/base/TXSsymb.tex" + "texmf-dist/tex/texsis/base/TXStags.tex" + "texmf-dist/tex/texsis/base/TXStitle.tex" + "texmf-dist/tex/texsis/base/Tablebod.txs" + "texmf-dist/tex/texsis/base/WorldSci.txs" + "texmf-dist/tex/texsis/base/color.txs" + "texmf-dist/tex/texsis/base/nuclproc.txs" + "texmf-dist/tex/texsis/base/printfont.txs" + "texmf-dist/tex/texsis/base/spine.txs" + "texmf-dist/tex/texsis/base/texsis.tex" + "texmf-dist/tex/texsis/base/thesis.txs" + "texmf-dist/tex/texsis/base/twin.txs" + "texmf-dist/tex/texsis/config/texsis.ini")) + (catalogue-license . "lppl"))))) -(define sxml - '(*TOP* (entry (@ (id "foo")) - (name "foo") - (caption "Foomatic frobnication in LuaLaTeX") - (authorref (@ (id "rekado"))) - (license (@ (type "lppl1.3"))) - (version (@ (number "2.6a"))) - (description - (p "\n Foo is a package for LuaLaTeX. It provides an interface to frobnicate gimbals\n in a foomatic way with the LuaTeX engine.\n ") - (p "\n The package requires the bar and golly\n bundles for extremely special specialties.\n ")) - (ctan (@ (path "/macros/latex/contrib/foo") (file "true"))) - (texlive (@ (location "foo"))) - (keyval (@ (value "tests") (key "topic"))) - "\n null\n"))) - -(test-equal "fetch-sxml: returns SXML for valid XML" - sxml - (with-http-server `((200 ,xml)) - (parameterize ((current-http-proxy (%local-url))) - (fetch-sxml "foo")))) - -;; TODO: -(test-assert "sxml->package" +(test-assert "texlive->guix-package" ;; Replace network resources with sample data. (mock ((guix build svn) svn-fetch (lambda* (url revision directory #:key (svn-command "svn") (user-name #f) - (password #f)) + (password #f) + (recursive? #t)) (mkdir-p directory) (with-output-to-file (string-append directory "/foo") (lambda () (display "source"))))) - (let ((result (sxml->package sxml))) + (let ((result (texlive->guix-package "texsis" + #:package-database + (lambda _ %fake-tlpdb)))) (match result (('package - ('name "texlive-latex-foo") - ('version "2.6a") - ('source ('origin - ('method 'svn-fetch) - ('uri ('texlive-ref "latex" "foo")) - ('sha256 - ('base32 - (? string? hash))))) - ('build-system 'texlive-build-system) - ('arguments ('quote (#:tex-directory "latex/foo"))) - ('home-page "http://www.ctan.org/pkg/foo") - ('synopsis "Foomatic frobnication in LuaLaTeX") - ('description - "Foo is a package for LuaLaTeX. It provides an interface to \ -frobnicate gimbals in a foomatic way with the LuaTeX engine. The package \ -requires the bar and golly bundles for extremely special specialties.") - ('license 'lppl1.3+)) - #t) + ('inherit ('simple-texlive-package + "texlive-texsis" + ('list "bibtex/bst/texsis/" + "doc/man/man1/" + "doc/otherformats/texsis/base/" + "tex/texsis/base/" + "tex/texsis/config/") + ('base32 (? string? hash)) + #:trivial? #t)) + ('propagated-inputs + ('list 'texlive-cm + 'texlive-hyphen-base + 'texlive-knuth-lib + 'texlive-plain + 'texlive-tex)) + ('home-page "https://www.tug.org/texlive/") + ('synopsis "Plain TeX macros for Physicists") + ('description (? string? description)) + ('license 'lppl)) + #true) (_ (begin - (format #t "~s\n" result) + (format #t "~s~%" result) (pk 'fail result #f))))))) (test-end "texlive") diff --git a/tests/transformations.scm b/tests/transformations.scm index 09839dc1c5..8db85b4305 100644 --- a/tests/transformations.scm +++ b/tests/transformations.scm @@ -38,12 +38,14 @@ #:use-module (guix utils) #:use-module (guix git) #:use-module (guix upstream) + #:use-module (guix diagnostics) #:use-module (gnu packages) #:use-module (gnu packages base) #:use-module (gnu packages busybox) #:use-module (ice-9 match) #:use-module (srfi srfi-1) #:use-module (srfi srfi-26) + #:use-module (srfi srfi-34) #:use-module (srfi srfi-64)) @@ -465,6 +467,39 @@ `((with-latest . "foo"))))) (package-version (t p))))) +(test-equal "options->transformation, tune" + '(cpu-tuning . "superfast") + (let* ((p0 (dummy-package "p0")) + (p1 (dummy-package "p1" + (inputs `(("p0" ,p0))) + (properties '((tunable? . #t))))) + (p2 (dummy-package "p2" + (inputs `(("p1" ,p1))))) + (t (options->transformation '((tune . "superfast")))) + (p3 (t p2))) + (and (not (package-replacement p3)) + (match (package-inputs p3) + ((("p1" tuned)) + (match (package-inputs tuned) + ((("p0" p0)) + (and (not (package-replacement p0)) + (assq 'cpu-tuning + (package-properties + (package-replacement tuned))))))))))) + +(test-assert "options->transformations, tune, wrong micro-architecture" + (let ((p (dummy-package "tunable" + (properties '((tunable? . #t))))) + (t (options->transformation '((tune . "nonexistent-superfast"))))) + ;; Because GCC used by P's build system does not support + ;; '-march=nonexistent-superfast', we should see an error when lowering + ;; the tuned package. + (guard (c ((formatted-message? c) + (member "nonexistent-superfast" + (formatted-message-arguments c)))) + (package->bag (t p)) + #f))) + (test-equal "options->transformation + package->manifest-entry" '((transformations . ((without-tests . "foo")))) (let* ((p (dummy-package "foo")) diff --git a/tests/upstream.scm b/tests/upstream.scm index e431956960..9aacb77229 100644 --- a/tests/upstream.scm +++ b/tests/upstream.scm @@ -1,5 +1,6 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2016 Ludovic Courtès <[email protected]> +;;; Copyright © 2022 Ricardo Wurmus <[email protected]> ;;; ;;; This file is part of GNU Guix. ;;; @@ -17,9 +18,16 @@ ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. (define-module (test-upstream) + #:use-module (gnu packages base) + #:use-module (guix download) + #:use-module (guix packages) + #:use-module (guix build-system gnu) + #:use-module (guix import print) + #:use-module ((guix licenses) #:prefix license:) #:use-module (guix upstream) #:use-module (guix tests) - #:use-module (srfi srfi-64)) + #:use-module (srfi srfi-64) + #:use-module (ice-9 match)) (test-begin "upstream") @@ -46,4 +54,160 @@ (signature-urls '("ftp://example.org/foo-1.tar.xz.sig")))))) +(define test-package + (package + (name "test") + (version "2.10") + (source (origin + (method url-fetch) + (uri (string-append "mirror://gnu/hello/hello-" version + ".tar.gz")) + (sha256 + (base32 + "0ssi1wpaf7plaswqqjwigppsg5fyh99vdlb9kzl7c9lng89ndq1i")))) + (build-system gnu-build-system) + (inputs + `(("hello" ,hello))) + (native-inputs + `(("sed" ,sed) + ("tar" ,tar))) + (propagated-inputs + `(("grep" ,grep))) + (home-page "http://localhost") + (synopsis "test") + (description "test") + (license license:gpl3+))) + +(define test-package-sexp + '(package + (name "test") + (version "2.10") + (source (origin + (method url-fetch) + (uri (string-append "mirror://gnu/hello/hello-" version + ".tar.gz")) + (sha256 + (base32 + "0ssi1wpaf7plaswqqjwigppsg5fyh99vdlb9kzl7c9lng89ndq1i")))) + (build-system gnu-build-system) + (inputs + `(("hello" ,hello))) + (native-inputs + `(("sed" ,sed) + ("tar" ,tar))) + (propagated-inputs + `(("grep" ,grep))) + (home-page "http://localhost") + (synopsis "test") + (description "test") + (license license:gpl3+))) + +(test-equal "changed-inputs returns no changes" + '() + (changed-inputs test-package test-package-sexp)) + +(test-assert "changed-inputs returns changes to labelled input list" + (let ((changes (changed-inputs + (package + (inherit test-package) + (inputs `(("hello" ,hello) + ("sed" ,sed)))) + test-package-sexp))) + (match changes + ;; Exactly one change + (((? upstream-input-change? item)) + (and (equal? (upstream-input-change-type item) + 'regular) + (equal? (upstream-input-change-action item) + 'remove) + (string=? (upstream-input-change-name item) + "sed"))) + (else (pk else #false))))) + +(test-assert "changed-inputs returns changes to all labelled input lists" + (let ((changes (changed-inputs + (package + (inherit test-package) + (inputs '()) + (native-inputs '()) + (propagated-inputs '())) + test-package-sexp))) + (match changes + (((? upstream-input-change? items) ...) + (and (equal? (map upstream-input-change-type items) + '(regular native native propagated)) + (equal? (map upstream-input-change-action items) + '(add add add add)) + (equal? (map upstream-input-change-name items) + '("hello" "sed" "tar" "grep")))) + (else (pk else #false))))) + +(define test-new-package + (package + (inherit test-package) + (inputs + (list hello)) + (native-inputs + (list sed tar)) + (propagated-inputs + (list grep)))) + +(define test-new-package-sexp + '(package + (name "test") + (version "2.10") + (source (origin + (method url-fetch) + (uri (string-append "mirror://gnu/hello/hello-" version + ".tar.gz")) + (sha256 + (base32 + "0ssi1wpaf7plaswqqjwigppsg5fyh99vdlb9kzl7c9lng89ndq1i")))) + (build-system gnu-build-system) + (inputs + (list hello)) + (native-inputs + (list sed tar)) + (propagated-inputs + (list grep)) + (home-page "http://localhost") + (synopsis "test") + (description "test") + (license license:gpl3+))) + +(test-assert "changed-inputs returns changes to plain input list" + (let ((changes (changed-inputs + (package + (inherit test-new-package) + (inputs (list hello sed))) + test-new-package-sexp))) + (match changes + ;; Exactly one change + (((? upstream-input-change? item)) + (and (equal? (upstream-input-change-type item) + 'regular) + (equal? (upstream-input-change-action item) + 'remove) + (string=? (upstream-input-change-name item) + "sed"))) + (else (pk else #false))))) + +(test-assert "changed-inputs returns changes to all plain input lists" + (let ((changes (changed-inputs + (package + (inherit test-new-package) + (inputs '()) + (native-inputs '()) + (propagated-inputs '())) + test-new-package-sexp))) + (match changes + (((? upstream-input-change? items) ...) + (and (equal? (map upstream-input-change-type items) + '(regular native native propagated)) + (equal? (map upstream-input-change-action items) + '(add add add add)) + (equal? (map upstream-input-change-name items) + '("hello" "sed" "tar" "grep")))) + (else (pk else #false))))) + (test-end) diff --git a/tests/utils.scm b/tests/utils.scm index 7fcbb25552..648e91f242 100644 --- a/tests/utils.scm +++ b/tests/utils.scm @@ -3,6 +3,7 @@ ;;; Copyright © 2014 Eric Bavier <[email protected]> ;;; Copyright © 2016 Mathieu Lirzin <[email protected]> ;;; Copyright © 2021 Simon Tournier <[email protected]> +;;; Copyright © 2021 Maxime Devos <[email protected]> ;;; ;;; This file is part of GNU Guix. ;;; @@ -289,6 +290,45 @@ skip these tests." (string-closest "hello" '("kikoo" "helo" "hihihi" "halo")) (string-closest "hello" '("aaaaa" "12345" "hellohello" "h")))) +(test-equal "target-linux?" + '(#t #f #f #t) + (map target-linux? + '("i686-linux-gnu" "i686-w64-mingw32" + ;; Checking that "gnu" is present is not sufficient, + ;; as GNU/Hurd exists. + "i686-pc-gnu" + ;; Some targets have a suffix. + "arm-linux-gnueabihf"))) + +(test-equal "target-mingw?" + '(#f #f #t) + (map target-mingw? + '("i686-linux-gnu" "i686-pc-gnu" + "i686-w64-mingw32"))) + +(test-equal "target-x86-32?" + '(#f #f #f #t #t #t #t #f) + ;; These are (according to Wikipedia) two RISC architectures + ;; by Intel and presumably not compatible with the x86-32 series. + (map target-x86-32? + '("i860-gnu" "i960-gnu" + ;; This is a 16-bit architecture + "i286-gnu" + ;; These are part of the x86-32 series. + "i386-gnu" "i486-gnu" "i586-gnu" "i686-gnu" + ;; Maybe this one will exist some day, but not yet. + "i786-gnu"))) + +(test-equal "target-x86-64?" + '(#t #f #f #f) + (map target-x86-64? + `("x86_64-linux-gnu" "i386-linux-gnu" + ;; Just because it includes "64" doesn't make it 64-bit. + "aarch64-linux-gnu" + ;; Note that (expt 2 109) in decimal notation starts with 64. + ;; However, it isn't 32-bit. + ,(format #f "x86_~a-linux-gnu" (expt 2 109))))) + (test-end) (false-if-exception (delete-file temp-file)) |