diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/challenge.scm | 6 | ||||
-rw-r--r-- | tests/channels.scm | 47 | ||||
-rw-r--r-- | tests/derivations.scm | 65 | ||||
-rw-r--r-- | tests/ed25519bis.key | 10 | ||||
-rw-r--r-- | tests/ed25519bis.sec | 10 | ||||
-rw-r--r-- | tests/file-systems.scm | 64 | ||||
-rw-r--r-- | tests/gexp.scm | 17 | ||||
-rw-r--r-- | tests/git-authenticate.scm | 356 | ||||
-rw-r--r-- | tests/git.scm | 45 | ||||
-rw-r--r-- | tests/graph.scm | 6 | ||||
-rw-r--r-- | tests/guix-hash.sh | 7 | ||||
-rw-r--r-- | tests/guix-package-net.sh | 12 | ||||
-rw-r--r-- | tests/guix-system.sh | 7 | ||||
-rw-r--r-- | tests/lint.scm | 30 | ||||
-rw-r--r-- | tests/packages.scm | 86 | ||||
-rw-r--r-- | tests/store.scm | 20 | ||||
-rw-r--r-- | tests/syscalls.scm | 20 |
17 files changed, 753 insertions, 55 deletions
diff --git a/tests/challenge.scm b/tests/challenge.scm index bb5633a3eb..9c6d6e0d58 100644 --- a/tests/challenge.scm +++ b/tests/challenge.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2015, 2017, 2019 Ludovic Courtès <ludo@gnu.org> +;;; Copyright © 2015, 2017, 2019, 2020 Ludovic Courtès <ludo@gnu.org> ;;; ;;; This file is part of GNU Guix. ;;; @@ -19,7 +19,7 @@ (define-module (test-challenge) #:use-module (guix tests) #:use-module (guix tests http) - #:use-module (gcrypt hash) + #:use-module ((gcrypt hash) #:prefix gcrypt:) #:use-module (guix store) #:use-module (guix monads) #:use-module (guix derivations) @@ -135,7 +135,7 @@ (mlet* %store-monad ((drv (gexp->derivation "something" #~(list #$output #$text))) (out -> (derivation->output-path drv)) - (hash -> (sha256 #vu8()))) + (hash -> (gcrypt:sha256 #vu8()))) (with-derivation-narinfo* drv (sha256 => hash) (>>= (compare-contents (list out) (%test-substitute-urls)) (match-lambda diff --git a/tests/channels.scm b/tests/channels.scm index 910088ba15..3b141428c8 100644 --- a/tests/channels.scm +++ b/tests/channels.scm @@ -37,6 +37,7 @@ #:use-module (srfi srfi-34) #:use-module (srfi srfi-35) #:use-module (srfi srfi-64) + #:use-module (ice-9 control) #:use-module (ice-9 match)) (test-begin "channels") @@ -136,11 +137,11 @@ (url "test"))) (test-dir (channel-instance-checkout instance--simple))) (mock ((guix git) update-cached-checkout - (lambda* (url #:key ref) + (lambda* (url #:key ref starting-commit) (match url - ("test" (values test-dir "caf3cabba9e")) + ("test" (values test-dir "caf3cabba9e" #f)) (_ (values (channel-instance-checkout instance--no-deps) - "abcde1234"))))) + "abcde1234" #f))))) (with-store store (let ((instances (latest-channel-instances store (list channel)))) (and (eq? 2 (length instances)) @@ -155,11 +156,11 @@ (url "test"))) (test-dir (channel-instance-checkout instance--with-dupes))) (mock ((guix git) update-cached-checkout - (lambda* (url #:key ref) + (lambda* (url #:key ref starting-commit) (match url - ("test" (values test-dir "caf3cabba9e")) + ("test" (values test-dir "caf3cabba9e" #f)) (_ (values (channel-instance-checkout instance--no-deps) - "abcde1234"))))) + "abcde1234" #f))))) (with-store store (let ((instances (latest-channel-instances store (list channel)))) (and (= 2 (length instances)) @@ -178,6 +179,40 @@ "abc1234"))) instances))))))) +(unless (which (git-command)) (test-skip 1)) +(test-equal "latest-channel-instances #:validate-pull" + 'descendant + + ;; Make sure the #:validate-pull procedure receives the right values. + (let/ec return + (with-temporary-git-repository directory + '((add "a.txt" "A") + (commit "first commit") + (add "b.scm" "#t") + (commit "second commit")) + (with-repository directory repository + (let* ((commit1 (find-commit repository "first")) + (commit2 (find-commit repository "second")) + (spec (channel (url (string-append "file://" directory)) + (name 'foo))) + (new (channel (inherit spec) + (commit (oid->string (commit-id commit2))))) + (old (channel (inherit spec) + (commit (oid->string (commit-id commit1)))))) + (define (validate-pull channel current instance relation) + (return (and (eq? channel old) + (string=? (oid->string (commit-id commit2)) + current) + (string=? (oid->string (commit-id commit1)) + (channel-instance-commit instance)) + relation))) + + (with-store store + ;; Attempt a downgrade from NEW to OLD. + (latest-channel-instances store (list old) + #:current-channels (list new) + #:validate-pull validate-pull))))))) + (test-assert "channel-instances->manifest" ;; Compute the manifest for a graph of instances and make sure we get a ;; derivation graph that mirrors the instance graph. This test also ensures diff --git a/tests/derivations.scm b/tests/derivations.scm index ef6cec6c76..9f1104a887 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 Ludovic Courtès <ludo@gnu.org> +;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Ludovic Courtès <ludo@gnu.org> ;;; ;;; This file is part of GNU Guix. ;;; @@ -23,7 +23,7 @@ #:use-module (guix grafts) #:use-module (guix store) #:use-module (guix utils) - #:use-module (gcrypt hash) + #:use-module ((gcrypt hash) #:prefix gcrypt:) #:use-module (guix base32) #:use-module (guix tests) #:use-module (guix tests http) @@ -215,7 +215,7 @@ #:env-vars `(("url" . ,(object->string (%local-url)))) #:hash-algo 'sha256 - #:hash (sha256 (string->utf8 text))))) + #:hash (gcrypt:sha256 (string->utf8 text))))) (and (build-derivations %store (list drv)) (string=? (call-with-input-file (derivation->output-path drv) get-string-all) @@ -230,7 +230,7 @@ #:env-vars `(("url" . ,(object->string (%local-url)))) #:hash-algo 'sha256 - #:hash (sha256 (random-bytevector 100))))) ;wrong + #:hash (gcrypt:sha256 (random-bytevector 100))))) ;wrong (guard (c ((store-protocol-error? c) (string-contains (store-protocol-error-message c) "failed"))) (build-derivations %store (list drv)) @@ -245,7 +245,7 @@ #:env-vars `(("url" . ,(object->string (%local-url)))) #:hash-algo 'sha256 - #:hash (sha256 (random-bytevector 100))))) + #:hash (gcrypt:sha256 (random-bytevector 100))))) (guard (c ((store-protocol-error? c) (string-contains (store-protocol-error-message (pk c)) "failed"))) (build-derivations %store (list drv)) @@ -273,7 +273,7 @@ #:env-vars `(("url" . ,(object->string (%local-url)))) #:hash-algo 'sha256 - #:hash (sha256 (string->utf8 text))))) + #:hash (gcrypt:sha256 (string->utf8 text))))) (and (with-http-server `((200 ,text)) (build-derivations %store (list drv))) (with-http-server `((200 ,text)) @@ -317,34 +317,43 @@ (test-assert "fixed-output-derivation?" (let* ((builder (add-text-to-store %store "my-fixed-builder.sh" "echo -n hello > $out" '())) - (hash (sha256 (string->utf8 "hello"))) + (hash (gcrypt:sha256 (string->utf8 "hello"))) (drv (derivation %store "fixed" %bash `(,builder) #:sources (list builder) #:hash hash #:hash-algo 'sha256))) (fixed-output-derivation? drv))) -(test-assert "fixed-output derivation" - (let* ((builder (add-text-to-store %store "my-fixed-builder.sh" - "echo -n hello > $out" '())) - (hash (sha256 (string->utf8 "hello"))) - (drv (derivation %store "fixed" - %bash `(,builder) - #:sources `(,builder) ;optional - #:hash hash #:hash-algo 'sha256)) - (succeeded? (build-derivations %store (list drv)))) - (and succeeded? - (let ((p (derivation->output-path drv))) - (and (equal? (string->utf8 "hello") - (call-with-input-file p get-bytevector-all)) - (bytevector? (query-path-hash %store p))))))) +(test-equal "fixed-output derivation" + '(sha1 sha256 sha512) + (map (lambda (hash-algorithm) + (let* ((builder (add-text-to-store %store "my-fixed-builder.sh" + "echo -n hello > $out" '())) + (sha256 (gcrypt:sha256 (string->utf8 "hello"))) + (hash (gcrypt:bytevector-hash + (string->utf8 "hello") + (gcrypt:lookup-hash-algorithm hash-algorithm))) + (drv (derivation %store + (string-append + "fixed-" (symbol->string hash-algorithm)) + %bash `(,builder) + #:sources `(,builder) ;optional + #:hash hash + #:hash-algo hash-algorithm))) + (build-derivations %store (list drv)) + (let ((p (derivation->output-path drv))) + (and (bytevector=? (string->utf8 "hello") + (call-with-input-file p get-bytevector-all)) + (bytevector? (query-path-hash %store p)) + hash-algorithm)))) + '(sha1 sha256 sha512))) (test-assert "fixed-output derivation: output paths are equal" (let* ((builder1 (add-text-to-store %store "fixed-builder1.sh" "echo -n hello > $out" '())) (builder2 (add-text-to-store %store "fixed-builder2.sh" "echo hey; echo -n hello > $out" '())) - (hash (sha256 (string->utf8 "hello"))) + (hash (gcrypt:sha256 (string->utf8 "hello"))) (drv1 (derivation %store "fixed" %bash `(,builder1) #:hash hash #:hash-algo 'sha256)) @@ -359,7 +368,7 @@ (test-assert "fixed-output derivation, recursive" (let* ((builder (add-text-to-store %store "my-fixed-builder.sh" "echo -n hello > $out" '())) - (hash (sha256 (string->utf8 "hello"))) + (hash (gcrypt:sha256 (string->utf8 "hello"))) (drv (derivation %store "fixed-rec" %bash `(,builder) #:sources (list builder) @@ -381,7 +390,7 @@ "echo -n hello > $out" '())) (builder2 (add-text-to-store %store "fixed-builder2.sh" "echo hey; echo -n hello > $out" '())) - (hash (sha256 (string->utf8 "hello"))) + (hash (gcrypt:sha256 (string->utf8 "hello"))) (fixed1 (derivation %store "fixed" %bash `(,builder1) #:hash hash #:hash-algo 'sha256)) @@ -418,7 +427,7 @@ "echo -n hello > $out" '())) (builder2 (add-text-to-store %store "fixed-builder2.sh" "echo hey; echo -n hello > $out" '())) - (hash (sha256 (string->utf8 "hello"))) + (hash (gcrypt:sha256 (string->utf8 "hello"))) (fixed1 (derivation %store "fixed" %bash `(,builder1) #:hash hash #:hash-algo 'sha256)) @@ -671,7 +680,7 @@ (let* ((value (getenv "GUIX_STATE_DIRECTORY")) (drv (derivation %store "leaked-env-vars" %bash '("-c" "echo -n $GUIX_STATE_DIRECTORY > $out") - #:hash (sha256 (string->utf8 value)) + #:hash (gcrypt:sha256 (string->utf8 value)) #:hash-algo 'sha256 #:sources (list %bash) #:leaked-env-vars '("GUIX_STATE_DIRECTORY")))) @@ -1097,7 +1106,7 @@ (builder2 '(call-with-output-file (pk 'difference-here! %output) (lambda (p) (write "hello" p)))) - (hash (sha256 (string->utf8 "hello"))) + (hash (gcrypt:sha256 (string->utf8 "hello"))) (input1 (build-expression->derivation %store "fixed" builder1 #:hash hash #:hash-algo 'sha256)) @@ -1118,7 +1127,7 @@ (builder2 '(call-with-output-file (pk 'difference-here! %output) (lambda (p) (write "hello" p)))) - (hash (sha256 (string->utf8 "hello"))) + (hash (gcrypt:sha256 (string->utf8 "hello"))) (input1 (build-expression->derivation %store "fixed" builder1 #:hash hash #:hash-algo 'sha256)) diff --git a/tests/ed25519bis.key b/tests/ed25519bis.key new file mode 100644 index 0000000000..f5329105d5 --- /dev/null +++ b/tests/ed25519bis.key @@ -0,0 +1,10 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mDMEXtVsNhYJKwYBBAHaRw8BAQdAnLsYdh3BpeK1xDguJE80XW2/MSmqeeP6pbQw +8jAw0OG0IkNoYXJsaWUgR3VpeCA8Y2hhcmxpZUBleGFtcGxlLm9yZz6IlgQTFggA +PhYhBKBDaY1jer75FlruS4IkDtyrgNqDBQJe1Ww2AhsDBQkDwmcABQsJCAcCBhUK +CQgLAgQWAgMBAh4BAheAAAoJEIIkDtyrgNqDM6cA/idDdoxo9SU+witdTXt24APH +yRzHbX9Iyh4dZNIek9JwAP9E0BwSvDHB4LY9z4RWf2hJp3dm/yZ/jEpK+w4BGN4J +Ag== +=JIU0 +-----END PGP PUBLIC KEY BLOCK----- diff --git a/tests/ed25519bis.sec b/tests/ed25519bis.sec new file mode 100644 index 0000000000..059765f557 --- /dev/null +++ b/tests/ed25519bis.sec @@ -0,0 +1,10 @@ +-----BEGIN PGP PRIVATE KEY BLOCK----- + +lFgEXtVsNhYJKwYBBAHaRw8BAQdAnLsYdh3BpeK1xDguJE80XW2/MSmqeeP6pbQw +8jAw0OEAAP9lsLf3tk0OH1X4By4flYSz4PBFo40EwS4t6xx76poUphCEtCJDaGFy +bGllIEd1aXggPGNoYXJsaWVAZXhhbXBsZS5vcmc+iJYEExYIAD4WIQSgQ2mNY3q+ ++RZa7kuCJA7cq4DagwUCXtVsNgIbAwUJA8JnAAULCQgHAgYVCgkICwIEFgIDAQIe +AQIXgAAKCRCCJA7cq4DagzOnAP4nQ3aMaPUlPsIrXU17duADx8kcx21/SMoeHWTS +HpPScAD/RNAcErwxweC2Pc+EVn9oSad3Zv8mf4xKSvsOARjeCQI= +=gUik +-----END PGP PRIVATE KEY BLOCK----- diff --git a/tests/file-systems.scm b/tests/file-systems.scm index 4c28d0ebc5..7f7c373884 100644 --- a/tests/file-systems.scm +++ b/tests/file-systems.scm @@ -1,5 +1,6 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2015, 2017 Ludovic Courtès <ludo@gnu.org> +;;; Copyright © 2020 Maxim Cournoyer <maxim.cournoyer@gmail.com> ;;; ;;; This file is part of GNU Guix. ;;; @@ -64,4 +65,67 @@ (_ #f)) (source-module-closure '((gnu system file-systems))))) +(test-equal "file-system-options->alist" + '("autodefrag" ("subvol" . "home") ("compress" . "lzo")) + (file-system-options->alist "autodefrag,subvol=home,compress=lzo")) + +(test-equal "file-system-options->alist (#f)" + '() + (file-system-options->alist #f)) + +(test-equal "alist->file-system-options" + "autodefrag,subvol=root,compress=lzo" + (alist->file-system-options '("autodefrag" + ("subvol" . "root") + ("compress" . "lzo")))) + +(test-equal "alist->file-system-options (null)" + #f + (alist->file-system-options '())) + + +;;; +;;; Btrfs related. +;;; + +(define %btrfs-root-subvolume + (file-system + (device (file-system-label "btrfs-pool")) + (mount-point "/") + (type "btrfs") + (options "subvol=rootfs,compress=zstd"))) + +(define %btrfs-store-subvolid + (file-system + (device (file-system-label "btrfs-pool")) + (mount-point "/gnu/store") + (type "btrfs") + (options "subvolid=10,compress=zstd") + (dependencies (list %btrfs-root-subvolume)))) + +(define %btrfs-store-subvolume + (file-system + (device (file-system-label "btrfs-pool")) + (mount-point "/gnu/store") + (type "btrfs") + (options "subvol=/some/nested/file/name") + (dependencies (list %btrfs-root-subvolume)))) + +(test-assert "btrfs-subvolume? (subvol)" + (btrfs-subvolume? %btrfs-root-subvolume)) + +(test-assert "btrfs-subvolume? (subvolid)" + (btrfs-subvolume? %btrfs-store-subvolid)) + +(test-equal "btrfs-store-subvolume-file-name" + "/some/nested/file/name" + (parameterize ((%store-prefix "/gnu/store")) + (btrfs-store-subvolume-file-name (list %btrfs-root-subvolume + %btrfs-store-subvolume)))) + +(test-error "btrfs-store-subvolume-file-name (subvolid)" + (parameterize ((%store-prefix "/gnu/store")) + (btrfs-store-subvolume-file-name (list %btrfs-root-subvolume + %btrfs-store-subvolid)))) + (test-end) diff --git a/tests/gexp.scm b/tests/gexp.scm index e073a7b816..1beeb67c21 100644 --- a/tests/gexp.scm +++ b/tests/gexp.scm @@ -78,7 +78,8 @@ (mkdir-p out) (call-with-output-file (string-append out "/hg2g.scm") (lambda (port) - (write '(define-module (hg2g) + (define defmod 'define-module) ;fool Geiser + (write `(,defmod (hg2g) #:export (the-answer)) port) (write '(define the-answer 42) port))))))))) @@ -284,6 +285,20 @@ (((thing "out")) (eq? thing file)))))) +(test-assert "file-append, raw store item" + (let* ((obj (plain-file "example.txt" "Hello!")) + (a (file-append obj "/a")) + (b (file-append a "/b")) + (c (file-append b "/c")) + (exp #~(list #$c)) + (item (run-with-store %store (lower-object obj))) + (lexp (run-with-store %store (lower-gexp exp)))) + (and (equal? (lowered-gexp-sexp lexp) + `(list ,(string-append item "/a/b/c"))) + (equal? (lowered-gexp-sources lexp) + (list item)) + (null? (lowered-gexp-inputs lexp))))) + (test-assertm "with-parameters for %current-system" (mlet* %store-monad ((system -> (match (%current-system) ("aarch64-linux" "x86_64-linux") diff --git a/tests/git-authenticate.scm b/tests/git-authenticate.scm new file mode 100644 index 0000000000..97990acaea --- /dev/null +++ b/tests/git-authenticate.scm @@ -0,0 +1,356 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2020 Ludovic Courtès <ludo@gnu.org> +;;; +;;; 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-git-authenticate) + #:use-module (git) + #:use-module (guix git) + #:use-module (guix git-authenticate) + #:use-module (guix openpgp) + #:use-module (guix tests git) + #:use-module (guix tests gnupg) + #:use-module (guix build utils) + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-34) + #:use-module (srfi srfi-64) + #:use-module (rnrs bytevectors) + #:use-module (rnrs io ports)) + +;; Test the (guix git-authenticate) tools. + +(define %ed25519-public-key-file + (search-path %load-path "tests/ed25519.key")) +(define %ed25519-secret-key-file + (search-path %load-path "tests/ed25519.sec")) +(define %ed25519bis-public-key-file + (search-path %load-path "tests/ed25519bis.key")) +(define %ed25519bis-secret-key-file + (search-path %load-path "tests/ed25519bis.sec")) + +(define (read-openpgp-packet file) + (get-openpgp-packet + (open-bytevector-input-port + (call-with-input-file file read-radix-64)))) + +(define key-fingerprint + (compose openpgp-format-fingerprint + openpgp-public-key-fingerprint + read-openpgp-packet)) + +(define (key-id file) + (define id + (openpgp-public-key-id (read-openpgp-packet))) + + (string-pad (number->string id 16) 16 #\0)) + +(define (gpg+git-available?) + (and (which (git-command)) + (which (gpg-command)) (which (gpgconf-command)))) + + +(test-begin "git-authenticate") + +(unless (which (git-command)) (test-skip 1)) +(test-assert "unsigned commits" + (with-temporary-git-repository directory + '((add "a.txt" "A") + (commit "first commit") + (add "b.txt" "B") + (commit "second commit")) + (with-repository directory repository + (let ((commit1 (find-commit repository "first")) + (commit2 (find-commit repository "second"))) + (guard (c ((unsigned-commit-error? c) + (oid=? (git-authentication-error-commit c) + (commit-id commit1)))) + (authenticate-commits repository (list commit1 commit2) + #:keyring-reference "master") + 'failed))))) + +(unless (which (git-command)) (test-skip 1)) +(test-assert "signed commits, SHA1 signature" + (with-fresh-gnupg-setup (list %ed25519-public-key-file + %ed25519-secret-key-file) + ;; Force use of SHA1 for signatures. + (call-with-output-file (string-append (getenv "GNUPGHOME") "/gpg.conf") + (lambda (port) + (display "digest-algo sha1" port))) + + (with-temporary-git-repository directory + `((add "a.txt" "A") + (add "signer.key" ,(call-with-input-file %ed25519-public-key-file + get-string-all)) + (add ".guix-authorizations" + ,(object->string + `(authorizations (version 0) + ((,(key-fingerprint %ed25519-public-key-file) + (name "Charlie")))))) + (commit "first commit" + (signer ,(key-fingerprint %ed25519-public-key-file)))) + (with-repository directory repository + (let ((commit (find-commit repository "first"))) + (guard (c ((unsigned-commit-error? c) + (oid=? (git-authentication-error-commit c) + (commit-id commit)))) + (authenticate-commits repository (list commit) + #:keyring-reference "master") + 'failed)))))) + +(unless (gpg+git-available?) (test-skip 1)) +(test-assert "signed commits, default authorizations" + (with-fresh-gnupg-setup (list %ed25519-public-key-file + %ed25519-secret-key-file) + (with-temporary-git-repository directory + `((add "signer.key" ,(call-with-input-file %ed25519-public-key-file + get-string-all)) + (commit "zeroth commit") + (add "a.txt" "A") + (commit "first commit" + (signer ,(key-fingerprint %ed25519-public-key-file))) + (add "b.txt" "B") + (commit "second commit" + (signer ,(key-fingerprint %ed25519-public-key-file)))) + (with-repository directory repository + (let ((commit1 (find-commit repository "first")) + (commit2 (find-commit repository "second"))) + (authenticate-commits repository (list commit1 commit2) + #:default-authorizations + (list (openpgp-public-key-fingerprint + (read-openpgp-packet + %ed25519-public-key-file))) + #:keyring-reference "master")))))) + +(unless (gpg+git-available?) (test-skip 1)) +(test-assert "signed commits, .guix-authorizations" + (with-fresh-gnupg-setup (list %ed25519-public-key-file + %ed25519-secret-key-file) + (with-temporary-git-repository directory + `((add "signer.key" ,(call-with-input-file %ed25519-public-key-file + get-string-all)) + (add ".guix-authorizations" + ,(object->string + `(authorizations (version 0) + ((,(key-fingerprint + %ed25519-public-key-file) + (name "Charlie")))))) + (commit "zeroth commit") + (add "a.txt" "A") + (commit "first commit" + (signer ,(key-fingerprint %ed25519-public-key-file))) + (add ".guix-authorizations" + ,(object->string `(authorizations (version 0) ()))) ;empty + (commit "second commit" + (signer ,(key-fingerprint %ed25519-public-key-file))) + (add "b.txt" "B") + (commit "third commit" + (signer ,(key-fingerprint %ed25519-public-key-file)))) + (with-repository directory repository + (let ((commit1 (find-commit repository "first")) + (commit2 (find-commit repository "second")) + (commit3 (find-commit repository "third"))) + ;; COMMIT1 and COMMIT2 are fine. + (and (authenticate-commits repository (list commit1 commit2) + #:keyring-reference "master") + + ;; COMMIT3 is signed by an unauthorized key according to its + ;; parent's '.guix-authorizations' file. + (guard (c ((unauthorized-commit-error? c) + (and (oid=? (git-authentication-error-commit c) + (commit-id commit3)) + (bytevector=? + (openpgp-public-key-fingerprint + (unauthorized-commit-error-signing-key c)) + (openpgp-public-key-fingerprint + (read-openpgp-packet + %ed25519-public-key-file)))))) + (authenticate-commits repository + (list commit1 commit2 commit3) + #:keyring-reference "master") + 'failed))))))) + +(unless (gpg+git-available?) (test-skip 1)) +(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) + (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 + get-string-all)) + (add ".guix-authorizations" + ,(object->string + `(authorizations (version 0) + ((,(key-fingerprint + %ed25519-public-key-file) + (name "Alice")))))) + (commit "zeroth commit") + (add "a.txt" "A") + (commit "first commit" + (signer ,(key-fingerprint %ed25519-public-key-file))) + (branch "devel") + (checkout "devel") + (add "devel/1.txt" "1") + (commit "first devel commit" + (signer ,(key-fingerprint %ed25519bis-public-key-file))) + (checkout "master") + (add "b.txt" "B") + (commit "second commit" + (signer ,(key-fingerprint %ed25519-public-key-file))) + (merge "devel" "merge" + (signer ,(key-fingerprint %ed25519-public-key-file)))) + (with-repository directory repository + (let ((master1 (find-commit repository "first commit")) + (master2 (find-commit repository "second commit")) + (devel1 (find-commit repository "first devel commit")) + (merge (find-commit repository "merge"))) + (define (correct? c commit) + (and (oid=? (git-authentication-error-commit c) + (commit-id commit)) + (bytevector=? + (openpgp-public-key-fingerprint + (unauthorized-commit-error-signing-key c)) + (openpgp-public-key-fingerprint + (read-openpgp-packet %ed25519bis-public-key-file))))) + + (and (authenticate-commits repository (list master1 master2) + #:keyring-reference "master") + + ;; DEVEL1 is signed by an unauthorized key according to its + ;; parent's '.guix-authorizations' file. + (guard (c ((unauthorized-commit-error? c) + (correct? c devel1))) + (authenticate-commits repository + (list master1 devel1) + #:keyring-reference "master") + #f) + + ;; MERGE is authorized but one of its ancestors is not. + (guard (c ((unauthorized-commit-error? c) + (correct? c devel1))) + (authenticate-commits repository + (list master1 master2 + devel1 merge) + #:keyring-reference "master") + #f))))))) + +(unless (gpg+git-available?) (test-skip 1)) +(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) + (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 + get-string-all)) + (add ".guix-authorizations" + ,(object->string + `(authorizations (version 0) + ((,(key-fingerprint + %ed25519-public-key-file) + (name "Alice")))))) + (commit "zeroth commit") + (add "a.txt" "A") + (commit "first commit" + (signer ,(key-fingerprint %ed25519-public-key-file))) + (branch "devel") + (checkout "devel") + (add ".guix-authorizations" + ,(object->string ;add the second signer + `(authorizations (version 0) + ((,(key-fingerprint + %ed25519-public-key-file) + (name "Alice")) + (,(key-fingerprint + %ed25519bis-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))) + (checkout "master") + (add "b.txt" "B") + (commit "second commit" + (signer ,(key-fingerprint %ed25519-public-key-file))) + (merge "devel" "merge" + (signer ,(key-fingerprint %ed25519-public-key-file))) + ;; After the merge, the second signer is authorized. + (add "c.txt" "C") + (commit "third commit" + (signer ,(key-fingerprint %ed25519bis-public-key-file)))) + (with-repository directory repository + (let ((master1 (find-commit repository "first commit")) + (master2 (find-commit repository "second commit")) + (devel1 (find-commit repository "first devel commit")) + (devel2 (find-commit repository "second devel commit")) + (merge (find-commit repository "merge")) + (master3 (find-commit repository "third commit"))) + (authenticate-commits repository + (list master1 master2 devel1 devel2 + merge master3) + #:keyring-reference "master")))))) + +(unless (gpg+git-available?) (test-skip 1)) +(test-assert "signed commits, .guix-authorizations removed" + (with-fresh-gnupg-setup (list %ed25519-public-key-file + %ed25519-secret-key-file) + (with-temporary-git-repository directory + `((add "signer.key" ,(call-with-input-file %ed25519-public-key-file + get-string-all)) + (add ".guix-authorizations" + ,(object->string + `(authorizations (version 0) + ((,(key-fingerprint + %ed25519-public-key-file) + (name "Charlie")))))) + (commit "zeroth commit") + (add "a.txt" "A") + (commit "first commit" + (signer ,(key-fingerprint %ed25519-public-key-file))) + (remove ".guix-authorizations") + (commit "second commit" + (signer ,(key-fingerprint %ed25519-public-key-file))) + (add "b.txt" "B") + (commit "third commit" + (signer ,(key-fingerprint %ed25519-public-key-file)))) + (with-repository directory repository + (let ((commit1 (find-commit repository "first")) + (commit2 (find-commit repository "second")) + (commit3 (find-commit repository "third"))) + ;; COMMIT1 and COMMIT2 are fine. + (and (authenticate-commits repository (list commit1 commit2) + #:keyring-reference "master") + + ;; COMMIT3 is rejected because COMMIT2 removes + ;; '.guix-authorizations'. + (guard (c ((unauthorized-commit-error? c) + (oid=? (git-authentication-error-commit c) + (commit-id commit2)))) + (authenticate-commits repository + (list commit1 commit2 commit3) + #:keyring-reference "master") + 'failed))))))) + +(test-end "git-authenticate") + diff --git a/tests/git.scm b/tests/git.scm index 052f8a79c4..aa4f03ca62 100644 --- a/tests/git.scm +++ b/tests/git.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2019 Ludovic Courtès <ludo@gnu.org> +;;; Copyright © 2019, 2020 Ludovic Courtès <ludo@gnu.org> ;;; ;;; This file is part of GNU Guix. ;;; @@ -119,7 +119,46 @@ (list commit3 commit4)) (lset= eq? (commit-difference commit4 commit1 (list commit3)) (list commit4)) - (lset= eq? (commit-difference commit4 commit1 (list commit5)) - (list commit2 commit3 commit4))))))) + (null? (commit-difference commit4 commit1 (list commit5)))))))) + +(unless (which (git-command)) (test-skip 1)) +(test-equal "commit-relation" + '(self ;master3 master3 + ancestor ;master1 master3 + descendant ;master3 master1 + unrelated ;master2 branch1 + unrelated ;branch1 master2 + ancestor ;branch1 merge + descendant ;merge branch1 + ancestor ;master1 merge + descendant) ;merge master1 + (with-temporary-git-repository directory + '((add "a.txt" "A") + (commit "first commit") + (branch "hack") + (checkout "hack") + (add "1.txt" "1") + (commit "branch commit") + (checkout "master") + (add "b.txt" "B") + (commit "second commit") + (add "c.txt" "C") + (commit "third commit") + (merge "hack" "merge")) + (with-repository directory repository + (let ((master1 (find-commit repository "first")) + (master2 (find-commit repository "second")) + (master3 (find-commit repository "third")) + (branch1 (find-commit repository "branch")) + (merge (find-commit repository "merge"))) + (list (commit-relation master3 master3) + (commit-relation master1 master3) + (commit-relation master3 master1) + (commit-relation master2 branch1) + (commit-relation branch1 master2) + (commit-relation branch1 merge) + (commit-relation merge branch1) + (commit-relation master1 merge) + (commit-relation merge master1)))))) (test-end "git") diff --git a/tests/graph.scm b/tests/graph.scm index 136260c7d1..0663d13b49 100644 --- a/tests/graph.scm +++ b/tests/graph.scm @@ -162,7 +162,11 @@ edges." (let-values (((backend nodes+edges) (make-recording-backend))) (let* ((m (lambda* (uri hash-type hash name #:key system) (text-file "foo-1.2.3.tar.gz" "This is a fake!"))) - (o (origin (method m) (uri "the-uri") (sha256 #vu8(0 1 2)))) + (o (origin + (method m) (uri "the-uri") + (sha256 + (base32 + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")))) (p (dummy-package "p" (source o)))) (run-with-store %store (export-graph (list p) 'port diff --git a/tests/guix-hash.sh b/tests/guix-hash.sh index 190c9e7f8a..3538b9aeda 100644 --- a/tests/guix-hash.sh +++ b/tests/guix-hash.sh @@ -1,5 +1,5 @@ # GNU Guix --- Functional package management for GNU -# Copyright © 2013, 2014, 2016 Ludovic Courtès <ludo@gnu.org> +# Copyright © 2013, 2014, 2016, 2020 Ludovic Courtès <ludo@gnu.org> # Copyright © 2016 Jan Nieuwenhuizen <janneke@gnu.org> # # This file is part of GNU Guix. @@ -31,6 +31,11 @@ test `echo -n | guix hash -` = 0mdqa9w1p6cmli6976v4wi0sw9r4p5prkj7lzfd1877wk11c9 test `guix hash -f nix-base32 /dev/null` = 0mdqa9w1p6cmli6976v4wi0sw9r4p5prkj7lzfd1877wk11c9c73 test `guix hash -f hex /dev/null` = e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 test `guix hash -f base32 /dev/null` = 4oymiquy7qobjgx36tejs35zeqt24qpemsnzgtfeswmrw6csxbkq +test `guix hash -H sha512 -f hex /dev/null` = cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e +test `guix hash -H sha1 -f base64 /dev/null` = "2jmj7l5rSw0yVb/vlWAYkK/YBwk=" + +if guix hash -H abcd1234 /dev/null; +then false; else true; fi mkdir "$tmpdir" echo -n executable > "$tmpdir/exe" diff --git a/tests/guix-package-net.sh b/tests/guix-package-net.sh index 48a94865e1..3876701fa2 100644 --- a/tests/guix-package-net.sh +++ b/tests/guix-package-net.sh @@ -1,6 +1,7 @@ # GNU Guix --- Functional package management for GNU # Copyright © 2012, 2013, 2014, 2015, 2017, 2019 Ludovic Courtès <ludo@gnu.org> # Copyright © 2013 Nikita Karetnikov <nikita@karetnikov.org> +# Copyright © 2020 Simon Tournier <zimon.toutoune@gmail.com> # # This file is part of GNU Guix. # @@ -78,6 +79,17 @@ esac test "`guix package -p "$profile" -I 'g.*e' | cut -f1`" = "guile-bootstrap" +guix package --bootstrap -p "$profile_alt" -i gcc-bootstrap +installed="`guix package -p "$profile" -p "$profile_alt" -I | cut -f1 | xargs echo | sort`" +case "x$installed" in + "gcc-bootstrap guile-bootstrap make-boot0") + true;; + "*") + false;; +esac +test "`guix package -p "$profile_alt" -p "$profile" -I | wc -l`" = "3" +rm "$profile_alt" + # List generations. test "`guix package -p "$profile" -l | cut -f1 | grep guile | head -n1`" \ = " guile-bootstrap" diff --git a/tests/guix-system.sh b/tests/guix-system.sh index 3a831cba1d..0e22686a34 100644 --- a/tests/guix-system.sh +++ b/tests/guix-system.sh @@ -307,7 +307,12 @@ guix system search anonym network | grep "^name: tor" # Verify that the examples can be built. for example in gnu/system/examples/*.tmpl; do - guix system -n disk-image "$example" + if echo "$example" | grep hurd; then + target="--target=i586-pc-gnu" + else + target= + fi + guix system -n disk-image $target "$example" done # Verify that the disk image types can be built. diff --git a/tests/lint.scm b/tests/lint.scm index 4ce45b4a70..9d3c349fc5 100644 --- a/tests/lint.scm +++ b/tests/lint.scm @@ -353,6 +353,36 @@ (((and (? lint-warning?) first-warning) others ...) (lint-warning-message first-warning)))) +(test-equal "profile-collisions: no warnings" + '() + (check-profile-collisions (dummy-package "x"))) + +(test-equal "profile-collisions: propagated inputs collide" + "propagated inputs p0@1 and p0@2 collide" + (let* ((p0 (dummy-package "p0" (version "1"))) + (p0* (dummy-package "p0" (version "2"))) + (p1 (dummy-package "p1" (propagated-inputs `(("p0" ,p0))))) + (p2 (dummy-package "p2" (propagated-inputs `(("p1" ,p1))))) + (p3 (dummy-package "p3" (propagated-inputs `(("p0" ,p0*))))) + (p4 (dummy-package "p4" (propagated-inputs + `(("p2" ,p2) ("p3", p3)))))) + (single-lint-warning-message + (check-profile-collisions p4)))) + +(test-assert "profile-collisions: propagated inputs collide, store items" + (string-match-or-error + "propagated inputs /[[:graph:]]+-p0-1 and /[[:graph:]]+-p0-1 collide" + (let* ((p0 (dummy-package "p0" (version "1"))) + (p0* (dummy-package "p0" (version "1") + (inputs `(("x" ,(dummy-package "x")))))) + (p1 (dummy-package "p1" (propagated-inputs `(("p0" ,p0))))) + (p2 (dummy-package "p2" (propagated-inputs `(("p1" ,p1))))) + (p3 (dummy-package "p3" (propagated-inputs `(("p0" ,p0*))))) + (p4 (dummy-package "p4" (propagated-inputs + `(("p2" ,p2) ("p3", p3)))))) + (single-lint-warning-message + (check-profile-collisions p4))))) + (test-equal "license: invalid license" "invalid license field" (single-lint-warning-message diff --git a/tests/packages.scm b/tests/packages.scm index c528d2080c..c7b6f669b5 100644 --- a/tests/packages.scm +++ b/tests/packages.scm @@ -29,7 +29,7 @@ #:renamer (lambda (name) (cond ((eq? name 'location) 'make-location) (else name)))) - #:use-module (gcrypt hash) + #:use-module ((gcrypt hash) #:prefix gcrypt:) #:use-module (guix derivations) #:use-module (guix packages) #:use-module (guix grafts) @@ -51,6 +51,7 @@ #:use-module (srfi srfi-34) #:use-module (srfi srfi-35) #:use-module (srfi srfi-64) + #:use-module (rnrs bytevectors) #:use-module (rnrs io ports) #:use-module (ice-9 vlist) #:use-module (ice-9 regex) @@ -497,6 +498,32 @@ (search-path %load-path "guix/base32.scm") get-bytevector-all))))) +(test-equal "package-source-derivation, origin, sha512" + "hello" + (let* ((bash (search-bootstrap-binary "bash" (%current-system))) + (builder (add-text-to-store %store "my-fixed-builder.sh" + "echo -n hello > $out" '())) + (method (lambda* (url hash-algo hash #:optional name + #:rest rest) + (and (eq? hash-algo 'sha512) + (raw-derivation name bash (list builder) + #:sources (list builder) + #:hash hash + #:hash-algo hash-algo)))) + (source (origin + (method method) + (uri "unused://") + (file-name "origin-sha512") + (hash (content-hash + (gcrypt:bytevector-hash (string->utf8 "hello") + (gcrypt:lookup-hash-algorithm + 'sha512)) + sha512)))) + (drv (package-source-derivation %store source)) + (output (derivation->output-path drv))) + (build-derivations %store (list drv)) + (call-with-input-file output get-string-all))) + (unless (network-reachable?) (test-skip 1)) (test-equal "package-source-derivation, snippet" "OK" @@ -873,6 +900,30 @@ (replacement #f)))) (replacement (package-derivation %store new))))))) +(test-assert "package-grafts, dependency on several outputs" + ;; Make sure we get one graft per output; see <https://bugs.gnu.org/41796>. + (letrec* ((p0 (dummy-package "p0" + (version "1.0") + (replacement p0*) + (arguments '(#:implicit-inputs? #f)) + (outputs '("out" "lib")))) + (p0* (package (inherit p0) (version "1.1"))) + (p1 (dummy-package "p1" + (arguments '(#:implicit-inputs? #f)) + (inputs `(("p0" ,p0) + ("p0:lib" ,p0 "lib")))))) + (lset= equal? (pk (package-grafts %store p1)) + (list (graft + (origin (package-derivation %store p0)) + (origin-output "out") + (replacement (package-derivation %store p0*)) + (replacement-output "out")) + (graft + (origin (package-derivation %store p0)) + (origin-output "lib") + (replacement (package-derivation %store p0*)) + (replacement-output "lib")))))) + (test-assert "replacement also grafted" ;; We build a DAG as below, where dotted arrows represent replacements and ;; solid arrows represent dependencies: @@ -979,6 +1030,39 @@ (assoc-ref (bag-build-inputs bag) "libc") (assoc-ref (bag-build-inputs bag) "coreutils")))) +(test-assert "package->bag, sensitivity to %current-target-system" + ;; https://bugs.gnu.org/41713 + (let* ((lower (lambda* (name #:key system target inputs native-inputs + #:allow-other-keys) + (and (not target) + (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)))))))) + (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))))) + (do-not-build (lambda (continue store lst . _) lst))) + (equal? (with-build-handler do-not-build + (parameterize ((%current-target-system "powerpc64le-linux-gnu") + (%graft? #t)) + (package-cross-derivation %store pkg + (%current-target-system) + #:graft? #t))) + (with-build-handler do-not-build + (package-cross-derivation %store + (package (inherit pkg)) + "powerpc64le-linux-gnu" + #:graft? #t))))) + (test-equal "package->bag, cross-compilation" `(,(%current-system) "foo86-hurd" (,(package-source gnu-make)) diff --git a/tests/store.scm b/tests/store.scm index 0af099c1ad..06f7939657 100644 --- a/tests/store.scm +++ b/tests/store.scm @@ -22,7 +22,7 @@ #:use-module (guix store) #:use-module (guix utils) #:use-module (guix monads) - #:use-module (gcrypt hash) + #:use-module ((gcrypt hash) #:prefix gcrypt:) #:use-module (guix base32) #:use-module (guix packages) #:use-module (guix derivations) @@ -115,6 +115,18 @@ (passwd:name (getpwuid (getuid))))))) (list (stat:uid s) (stat:perms s)))) +(test-equal "add-to-store" + '("sha1" "sha256" "sha512") + (let* ((file (search-path %load-path "guix.scm")) + (content (call-with-input-file file get-bytevector-all))) + (map (lambda (hash-algo) + (let ((file (add-to-store %store "guix.scm" #f hash-algo file))) + (and (direct-store-path? file) + (bytevector=? (call-with-input-file file get-bytevector-all) + content) + hash-algo))) + '("sha1" "sha256" "sha512")))) + (test-equal "add-data-to-store" #vu8(1 2 3 4 5) (call-with-input-file (add-data-to-store %store "data" #vu8(1 2 3 4 5)) @@ -309,7 +321,7 @@ #:env-vars `(("t2" . ,t2)))) (o (derivation->output-path d))) (with-derivation-narinfo d - (sha256 => (sha256 (string->utf8 t2))) + (sha256 => (gcrypt:sha256 (string->utf8 t2))) (references => (list t2)) (equal? (references/substitutes s (list o t3 t2 t1)) @@ -928,7 +940,7 @@ (foldm %store-monad (lambda (item result) (define ref-hash - (let-values (((port get) (open-sha256-port))) + (let-values (((port get) (gcrypt:open-sha256-port))) (write-file item port) (close-port port) (get))) @@ -1132,7 +1144,7 @@ (info (query-path-info %store item))) (and (equal? (path-info-references info) (list ref)) (equal? (path-info-hash info) - (sha256 + (gcrypt:sha256 (string->utf8 (call-with-output-string (cut write-file item <>)))))))) diff --git a/tests/syscalls.scm b/tests/syscalls.scm index 3823de7c1e..6acaa0b131 100644 --- a/tests/syscalls.scm +++ b/tests/syscalls.scm @@ -1,6 +1,8 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2014, 2015, 2016, 2017, 2018, 2019, 2020 Ludovic Courtès <ludo@gnu.org> ;;; Copyright © 2015 David Thompson <davet@gnu.org> +;;; Copyright © 2020 Simon South <simon@simonsouth.net> +;;; Copyright © 2020 Mathieu Othacehe <m.othacehe@gmail.com> ;;; ;;; This file is part of GNU Guix. ;;; @@ -73,21 +75,21 @@ ;; Note: 'utimensat' does not change 'ctime'. (list (stat:mtime st) (stat:atime st))))) -(test-assert "swapon, ENOENT/EPERM" +(test-assert "swapon, ENOSYS/ENOENT/EPERM" (catch 'system-error (lambda () (swapon "/does-not-exist") #f) (lambda args - (memv (system-error-errno args) (list EPERM ENOENT))))) + (memv (system-error-errno args) (list EPERM ENOENT ENOSYS))))) -(test-assert "swapoff, ENOENT/EINVAL/EPERM" +(test-assert "swapoff, ENOSYS/ENOENT/EINVAL/EPERM" (catch 'system-error (lambda () (swapoff "/does-not-exist") #f) (lambda args - (memv (system-error-errno args) (list EPERM EINVAL ENOENT))))) + (memv (system-error-errno args) (list EPERM EINVAL ENOENT ENOSYS))))) (test-assert "mkdtemp!" (let* ((tmp (or (getenv "TMPDIR") "/tmp")) @@ -275,8 +277,14 @@ (let ((key "user.translator") (value "/hurd/pfinet\0") (file (open-file temp-file "w0"))) - (setxattr temp-file key value) - (string=? (getxattr temp-file key) value))) + (catch 'system-error + (lambda () + (setxattr temp-file key value) + (string=? (getxattr temp-file key) value)) + (lambda args + ;; Accept ENOTSUP, if the file-system does not support extended user + ;; attributes. + (memv (system-error-errno args) (list ENOTSUP)))))) (false-if-exception (delete-file temp-file)) (test-equal "fcntl-flock wait" |