+(test-assert "write-file #:select? + restore-file"
+ (let ((input (string-append %test-dir ".input")))
+ (mkdir input)
+ (dynamic-wind
+ (const #t)
+ (lambda ()
+ (with-file-tree input
+ (directory "root"
+ ((directory "a" (("x") ("y") ("z")))
+ ("b") ("c") ("d" -> "b")))
+ (let* ((output %test-dir)
+ (nar (string-append output ".nar")))
+ (dynamic-wind
+ (lambda () #t)
+ (lambda ()
+ (call-with-output-file nar
+ (lambda (port)
+ (write-file input port
+ #:select?
+ (lambda (file stat)
+ (and (not (string=? (basename file)
+ "a"))
+ (not (eq? (stat:type stat)
+ 'symlink)))))))
+ (call-with-input-file nar
+ (cut restore-file <> output))
+
+ ;; Make sure "a" and "d" have been filtered out.
+ (and (not (file-exists? (string-append output "/root/a")))
+ (file=? (string-append output "/root/b")
+ (string-append input "/root/b"))
+ (file=? (string-append output "/root/c")
+ (string-append input "/root/c"))
+ (not (file-exists? (string-append output "/root/d")))))
+ (lambda ()
+ (false-if-exception (delete-file nar))
+ (false-if-exception (rm-rf output)))))))
+ (lambda ()
+ (rmdir input)))))
+
+(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)))))