aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/guix-register.sh29
-rw-r--r--tests/hash.scm59
-rw-r--r--tests/nar.scm103
-rw-r--r--tests/store.scm54
-rw-r--r--tests/utils.scm32
5 files changed, 272 insertions, 5 deletions
diff --git a/tests/guix-register.sh b/tests/guix-register.sh
index ca28fb0d95..ee633af4f9 100644
--- a/tests/guix-register.sh
+++ b/tests/guix-register.sh
@@ -1,5 +1,5 @@
# GNU Guix --- Functional package management for GNU
-# Copyright © 2013 Ludovic Courtès <ludo@gnu.org>
+# Copyright © 2013, 2014 Ludovic Courtès <ludo@gnu.org>
#
# This file is part of GNU Guix.
#
@@ -29,6 +29,33 @@ rm -rf "$new_store"
exit_hook=":"
trap "chmod -R +w $new_store ; rm -rf $new_store $closure ; \$exit_hook" EXIT
+#
+# Registering items in the current store---i.e., without '--prefix'.
+#
+
+new_file="$NIX_STORE_DIR/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-guix-register-$$"
+echo "Fake store file to test registration." > "$new_file"
+
+# Register the file with zero references and no deriver.
+guix-register <<EOF
+$new_file
+
+0
+EOF
+
+# Make sure it's valid, and delete it.
+guile -c "
+ (use-modules (guix store))
+ (define s (open-connection))
+ (exit (and (valid-path? s \"$new_file\")
+ (null? (references s \"$new_file\"))
+ (pair? (delete-paths s (list \"$new_file\")))))"
+
+
+#
+# Registering items in a new store, with '--prefix'.
+#
+
mkdir -p "$new_store/$storedir"
new_store_dir="`cd "$new_store/$storedir" ; pwd`"
new_store="`cd "$new_store" ; pwd`"
diff --git a/tests/hash.scm b/tests/hash.scm
index 27751023d3..9bcd69440b 100644
--- a/tests/hash.scm
+++ b/tests/hash.scm
@@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2013 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2013, 2014 Ludovic Courtès <ludo@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -37,6 +37,14 @@
(base16-string->bytevector
"b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9"))
+(define (supports-unbuffered-cbip?)
+ "Return #t if unbuffered custom binary input ports (CBIPs) are supported.
+In Guile <= 2.0.9, CBIPs were always fully buffered, so the
+'open-sha256-input-port' does not work there."
+ (false-if-exception
+ (setvbuf (make-custom-binary-input-port "foo" pk #f #f #f) _IONBF)))
+
+
(test-begin "hash")
(test-equal "sha256, empty"
@@ -68,6 +76,55 @@
(equal? (sha256 contents)
(call-with-input-file file port-sha256))))
+(test-skip (if (supports-unbuffered-cbip?) 0 4))
+
+(test-equal "open-sha256-input-port, empty"
+ `("" ,%empty-sha256)
+ (let-values (((port get)
+ (open-sha256-input-port (open-string-input-port ""))))
+ (let ((str (get-string-all port)))
+ (list str (get)))))
+
+(test-equal "open-sha256-input-port, hello"
+ `("hello world" ,%hello-sha256)
+ (let-values (((port get)
+ (open-sha256-input-port
+ (open-bytevector-input-port
+ (string->utf8 "hello world")))))
+ (let ((str (get-string-all port)))
+ (list str (get)))))
+
+(test-equal "open-sha256-input-port, hello, one two"
+ (list (string->utf8 "hel") (string->utf8 "lo")
+ (base16-string->bytevector ; echo -n hello | sha256sum
+ "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824")
+ " world")
+ (let-values (((port get)
+ (open-sha256-input-port
+ (open-bytevector-input-port (string->utf8 "hello world")))))
+ (let* ((one (get-bytevector-n port 3))
+ (two (get-bytevector-n port 2))
+ (hash (get))
+ (three (get-string-all port)))
+ (list one two hash three))))
+
+(test-equal "open-sha256-input-port, hello, read from wrapped port"
+ (list (string->utf8 "hello")
+ (base16-string->bytevector ; echo -n hello | sha256sum
+ "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824")
+ " world")
+ (let*-values (((wrapped)
+ (open-bytevector-input-port (string->utf8 "hello world")))
+ ((port get)
+ (open-sha256-input-port wrapped)))
+ (let* ((hello (get-bytevector-n port 5))
+ (hash (get))
+
+ ;; Now read from WRAPPED to make sure its current position is
+ ;; correct.
+ (world (get-string-all wrapped)))
+ (list hello hash world))))
+
(test-end)
diff --git a/tests/nar.scm b/tests/nar.scm
index 6493d76876..9f21f990c8 100644
--- a/tests/nar.scm
+++ b/tests/nar.scm
@@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2012, 2013 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2012, 2013, 2014 Ludovic Courtès <ludo@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -18,11 +18,17 @@
(define-module (test-nar)
#:use-module (guix nar)
+ #:use-module (guix store)
+ #:use-module ((guix hash) #:select (open-sha256-input-port))
#:use-module (rnrs bytevectors)
#:use-module (rnrs io ports)
+ #:use-module (srfi srfi-1)
#:use-module (srfi srfi-26)
+ #:use-module (srfi srfi-34)
+ #:use-module (srfi srfi-35)
#:use-module (srfi srfi-64)
#:use-module (ice-9 ftw)
+ #:use-module (ice-9 regex)
#:use-module (ice-9 match))
;; Test the (guix nar) module.
@@ -156,6 +162,24 @@
(string-append (dirname (search-path %load-path "pre-inst-env"))
"/test-nar-" (number->string (getpid))))
+;; XXX: Factorize.
+(define %seed
+ (seed->random-state (logxor (getpid) (car (gettimeofday)))))
+
+(define (random-text)
+ (number->string (random (expt 2 256) %seed) 16))
+
+(define-syntax-rule (let/ec k exp...)
+ ;; This one appeared in Guile 2.0.9, so provide a copy here.
+ (let ((tag (make-prompt-tag)))
+ (call-with-prompt tag
+ (lambda ()
+ (let ((k (lambda args
+ (apply abort-to-prompt tag args))))
+ exp...))
+ (lambda (_ . args)
+ (apply values args)))))
+
(test-begin "nar")
@@ -201,6 +225,83 @@
(lambda ()
(rmdir input)))))
+;; 'restore-file-set' depends on 'open-sha256-input-port', which in turn
+;; relies on a Guile 2.0.10+ feature.
+(test-skip (if (false-if-exception
+ (open-sha256-input-port (%make-void-port "r")))
+ 0
+ 3))
+
+(test-assert "restore-file-set (signed, valid)"
+ (with-store store
+ (let* ((texts (unfold (cut >= <> 10)
+ (lambda _ (random-text))
+ 1+
+ 0))
+ (files (map (cut add-text-to-store store "text" <>) texts))
+ (dump (call-with-bytevector-output-port
+ (cut export-paths store files <>))))
+ (delete-paths store files)
+ (and (every (negate file-exists?) files)
+ (let* ((source (open-bytevector-input-port dump))
+ (imported (restore-file-set source)))
+ (and (equal? imported files)
+ (every (lambda (file)
+ (and (file-exists? file)
+ (valid-path? store file)))
+ files)
+ (equal? texts
+ (map (lambda (file)
+ (call-with-input-file file
+ get-string-all))
+ files))))))))
+
+(test-assert "restore-file-set (missing signature)"
+ (let/ec return
+ (with-store store
+ (let* ((file (add-text-to-store store "foo" "Hello, world!"))
+ (dump (call-with-bytevector-output-port
+ (cute export-paths store (list file) <>
+ #:sign? #f))))
+ (delete-paths store (list file))
+ (and (not (file-exists? file))
+ (let ((source (open-bytevector-input-port dump)))
+ (guard (c ((nar-signature-error? c)
+ (let ((message (condition-message c))
+ (port (nar-error-port c)))
+ (return
+ (and (string-match "lacks.*signature" message)
+ (string=? file (nar-error-file c))
+ (eq? source port))))))
+ (restore-file-set source))
+ #f))))))
+
+(test-assert "restore-file-set (corrupt)"
+ (let/ec return
+ (with-store store
+ (let* ((file (add-text-to-store store "foo"
+ (random-text)))
+ (dump (call-with-bytevector-output-port
+ (cute export-paths store (list file) <>))))
+ (delete-paths store (list file))
+
+ ;; Flip a byte in the file contents.
+ (let* ((index 120)
+ (byte (bytevector-u8-ref dump index)))
+ (bytevector-u8-set! dump index (logxor #xff byte)))
+
+ (and (not (file-exists? file))
+ (let ((source (open-bytevector-input-port dump)))
+ (guard (c ((nar-invalid-hash-error? c)
+ (let ((message (condition-message c))
+ (port (nar-error-port c)))
+ (return
+ (and (string-contains message "hash")
+ (string=? file (nar-error-file c))
+ (eq? source port))))))
+ (restore-file-set source))
+ #f))))))
+
(test-end "nar")
diff --git a/tests/store.scm b/tests/store.scm
index 4bd739e7f6..a61d449fb4 100644
--- a/tests/store.scm
+++ b/tests/store.scm
@@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2012, 2013 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2012, 2013, 2014 Ludovic Courtès <ludo@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -162,6 +162,38 @@
(equal? (valid-derivers %store o)
(list (derivation-file-name d))))))
+(test-assert "topologically-sorted, one item"
+ (let* ((a (add-text-to-store %store "a" "a"))
+ (b (add-text-to-store %store "b" "b" (list a)))
+ (c (add-text-to-store %store "c" "c" (list b)))
+ (d (add-text-to-store %store "d" "d" (list c)))
+ (s (topologically-sorted %store (list d))))
+ (equal? s (list a b c d))))
+
+(test-assert "topologically-sorted, several items"
+ (let* ((a (add-text-to-store %store "a" "a"))
+ (b (add-text-to-store %store "b" "b" (list a)))
+ (c (add-text-to-store %store "c" "c" (list b)))
+ (d (add-text-to-store %store "d" "d" (list c)))
+ (s1 (topologically-sorted %store (list d a c b)))
+ (s2 (topologically-sorted %store (list b d c a b d))))
+ (equal? s1 s2 (list a b c d))))
+
+(test-assert "topologically-sorted, more difficult"
+ (let* ((a (add-text-to-store %store "a" "a"))
+ (b (add-text-to-store %store "b" "b" (list a)))
+ (c (add-text-to-store %store "c" "c" (list b)))
+ (d (add-text-to-store %store "d" "d" (list c)))
+ (w (add-text-to-store %store "w" "w"))
+ (x (add-text-to-store %store "x" "x" (list w)))
+ (y (add-text-to-store %store "y" "y" (list x d)))
+ (s1 (topologically-sorted %store (list y)))
+ (s2 (topologically-sorted %store (list c y)))
+ (s3 (topologically-sorted %store (cons y (references %store y)))))
+ (and (equal? s1 (list w x a b c d y))
+ (equal? s2 (list a b c w x d y))
+ (lset= string=? s1 s3))))
+
(test-assert "log-file, derivation"
(let* ((b (add-text-to-store %store "build" "echo $foo > $out" '()))
(s (add-to-store %store "bash" #t "sha256"
@@ -389,6 +421,26 @@ Deriver: ~a~%"
(pk 'corrupt-imported imported)
#f)))))
+(test-assert "register-path"
+ (let ((file (string-append (%store-prefix) "/" (make-string 32 #\f)
+ "-fake")))
+ (when (valid-path? %store file)
+ (delete-paths %store (list file)))
+ (false-if-exception (delete-file file))
+
+ (let ((ref (add-text-to-store %store "ref-of-fake" (random-text)))
+ (drv (string-append file ".drv")))
+ (call-with-output-file file
+ (cut display "This is a fake store item.\n" <>))
+ (register-path file
+ #:references (list ref)
+ #:deriver drv)
+
+ (and (valid-path? %store file)
+ (equal? (references %store file) (list ref))
+ (null? (valid-derivers %store file))
+ (null? (referrers %store file))))))
+
(test-end "store")
diff --git a/tests/utils.scm b/tests/utils.scm
index 017d9170fa..b5706aa792 100644
--- a/tests/utils.scm
+++ b/tests/utils.scm
@@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2012, 2013 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2012, 2013, 2014 Ludovic Courtès <ludo@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -139,6 +139,36 @@
(append pids1 pids2)))
(equal? (get-bytevector-all decompressed) data)))))
+(test-equal "fcntl-flock"
+ 0 ; the child's exit status
+ (let ((file (open-input-file (search-path %load-path "guix.scm"))))
+ (fcntl-flock file 'read-lock)
+ (match (primitive-fork)
+ (0
+ (dynamic-wind
+ (const #t)
+ (lambda ()
+ ;; Taking a read lock should be OK.
+ (fcntl-flock file 'read-lock)
+ (fcntl-flock file 'unlock)
+
+ (catch 'flock-error
+ (lambda ()
+ ;; Taking an exclusive lock should raise an exception.
+ (fcntl-flock file 'write-lock))
+ (lambda args
+ (primitive-exit 0)))
+ (primitive-exit 1))
+ (lambda ()
+ (primitive-exit 2))))
+ (pid
+ (match (waitpid pid)
+ ((_ . status)
+ (let ((result (status:exit-val status)))
+ (fcntl-flock file 'unlock)
+ (close-port file)
+ result)))))))
+
;; This is actually in (guix store).
(test-equal "store-path-package-name"
"bash-4.2-p24"