Merge branch 'master' into staging
[jackhill/guix/guix.git] / tests / nar.scm
index d610ea5..bfc71c6 100644 (file)
@@ -1,5 +1,5 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Courtès <ludo@gnu.org>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -25,6 +25,8 @@
                 #:select (open-sha256-port open-sha256-input-port))
   #:use-module ((guix packages)
                 #:select (base32))
+  #:use-module ((guix build utils)
+                #:select (find-files))
   #:use-module (rnrs bytevectors)
   #:use-module (rnrs io ports)
   #:use-module (srfi srfi-1)
       (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-eq "restore-file with non-UTF8 locale"     ;<https://bugs.gnu.org/33603>
+  'encoding-error
+  (let* ((file   (search-path %load-path "guix.scm"))
+         (output (string-append %test-dir "/output"))
+         (locale (setlocale LC_ALL "C")))
+    (dynamic-wind
+      (lambda () #t)
+      (lambda ()
+        (define-values (port get-bytevector)
+          (open-bytevector-output-port))
+
+        (write-file-tree "root" port
+                         #:file-type+size
+                         (match-lambda
+                           ("root"   (values 'directory 0))
+                           ("root/λ" (values 'regular 0)))
+                         #:file-port (const (%make-void-port "r"))
+                         #:symlink-target (const #f)
+                         #:directory-entries (const '("λ")))
+        (close-port port)
+
+        (mkdir %test-dir)
+        (catch 'encoding-error
+          (lambda ()
+            ;; This show throw to 'encoding-error.
+            (restore-file (open-bytevector-input-port (get-bytevector))
+                          output)
+            (scandir output))
+          (lambda args
+            'encoding-error)))
+      (lambda ()
+        (false-if-exception (rm-rf %test-dir))
+        (setlocale LC_ALL locale)))))
 
 (test-assert "restore-file-set (signed, valid)"
   (with-store store
                           (map (lambda (file)
                                  (call-with-input-file file
                                    get-string-all))
-                               files))))))))
+                               files))
+                  (every canonical-file? files)))))))
+
+(test-assert "restore-file-set with directories (signed, valid)"
+  ;; <https://bugs.gnu.org/33361> describes a bug whereby directories
+  ;; containing files subject to deduplication were not canonicalized--i.e.,
+  ;; their mtime and permissions were not reset.  Ensure that this bug is
+  ;; gone.
+  (with-store store
+    (let* ((text1 (random-text))
+           (text2 (random-text))
+           (tree  `("tree" directory
+                    ("a" regular (data ,text1))
+                    ("b" directory
+                     ("c" regular (data ,text2))
+                     ("d" regular (data ,text1))))) ;duplicate
+           (file  (add-file-tree-to-store store tree))
+           (dump  (call-with-bytevector-output-port
+                   (cute export-paths store (list file) <>))))
+      (delete-paths store (list file))
+      (and (not (file-exists? file))
+           (let* ((source   (open-bytevector-input-port dump))
+                  (imported (restore-file-set source)))
+             (and (equal? imported (list file))
+                  (file-exists? file)
+                  (valid-path? store file)
+                  (string=? text1
+                            (call-with-input-file (string-append file "/a")
+                              get-string-all))
+                  (string=? text2
+                            (call-with-input-file
+                                (string-append file "/b/c")
+                              get-string-all))
+                  (= (stat:ino (stat (string-append file "/a"))) ;deduplication
+                     (stat:ino (stat (string-append file "/b/d"))))
+                  (every canonical-file?
+                         (find-files file #:directories? #t))))))))
 
 (test-assert "restore-file-set (missing signature)"
   (let/ec return