123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268 |
- ;;;; filesys.test --- test file system functions -*- scheme -*-
- ;;;;
- ;;;; Copyright (C) 2004, 2006, 2013, 2019, 2021 Free Software Foundation, Inc.
- ;;;;
- ;;;; This library is free software; you can redistribute it and/or
- ;;;; modify it under the terms of the GNU Lesser General Public
- ;;;; License as published by the Free Software Foundation; either
- ;;;; version 3 of the License, or (at your option) any later version.
- ;;;;
- ;;;; This library 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
- ;;;; Lesser General Public License for more details.
- ;;;;
- ;;;; You should have received a copy of the GNU Lesser General Public
- ;;;; License along with this library; if not, write to the Free Software
- ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- (define-module (test-suite test-filesys)
- #:use-module (test-suite lib)
- #:use-module (test-suite guile-test)
- #:use-module (ice-9 threads)
- #:use-module (ice-9 match)
- #:use-module (rnrs io ports)
- #:use-module (rnrs bytevectors))
- (define (test-file)
- (data-file-name "filesys-test.tmp"))
- (define (test-symlink)
- (data-file-name "filesys-test-link.tmp"))
- ;;;
- ;;; copy-file
- ;;;
- (with-test-prefix "copy-file"
- ;; return next prospective file descriptor number
- (define (next-fd)
- (let ((fd (dup 0)))
- (close fd)
- fd))
- ;; in guile 1.6.4 and earlier, copy-file didn't close the input fd when
- ;; the output could not be opened
- (pass-if "fd leak when dest unwritable"
- (let ((old-next (next-fd)))
- (false-if-exception (copy-file "/dev/null" "no/such/dir/foo"))
- (= old-next (next-fd)))))
- ;;;
- ;;; lstat
- ;;;
- (with-test-prefix "lstat"
- (pass-if "normal file"
- (call-with-output-file (test-file)
- (lambda (port)
- (display "hello" port)))
- (eqv? 5 (stat:size (lstat (test-file)))))
- (call-with-output-file (test-file)
- (lambda (port)
- (display "hello" port)))
- (false-if-exception (delete-file (test-symlink)))
- (if (not (false-if-exception
- (begin (symlink (test-file) (test-symlink)) #t)))
- (display "cannot create symlink, lstat test skipped\n")
- (pass-if "symlink"
- ;; not much to test, except that it works
- (->bool (lstat (test-symlink))))))
- ;;;
- ;;; opendir and friends
- ;;;
- (with-test-prefix "opendir"
- (with-test-prefix "root directory"
- (let ((d (opendir "/")))
- (pass-if "not empty"
- (string? (readdir d)))
- (pass-if "all entries are strings"
- (let more ()
- (let ((f (readdir d)))
- (cond ((string? f)
- (more))
- ((eof-object? f)
- #t)
- (else
- #f)))))
- (closedir d))))
- ;;;
- ;;; stat
- ;;;
- (with-test-prefix "stat"
- (with-test-prefix "filename"
- (pass-if "size"
- (call-with-output-file (test-file)
- (lambda (port)
- (display "hello" port)))
- (eqv? 5 (stat:size (stat (test-file))))))
- (with-test-prefix "file descriptor"
- (pass-if "size"
- (call-with-output-file (test-file)
- (lambda (port)
- (display "hello" port)))
- (let* ((fd (open-fdes (test-file) O_RDONLY))
- (st (stat fd)))
- (close-fdes fd)
- (eqv? 5 (stat:size st)))))
- (with-test-prefix "port"
- (pass-if "size"
- (call-with-output-file (test-file)
- (lambda (port)
- (display "hello" port)))
- (let* ((port (open-file (test-file) "r+"))
- (st (stat port)))
- (close-port port)
- (eqv? 5 (stat:size st))))))
- (with-test-prefix "sendfile"
- (let* ((file (search-path %load-path "ice-9/boot-9.scm"))
- (len (stat:size (stat file)))
- (ref (call-with-input-file file get-bytevector-all)))
- (pass-if-equal "file" (cons len ref)
- (let* ((result (call-with-input-file file
- (lambda (input)
- (call-with-output-file (test-file)
- (lambda (output)
- (sendfile output input len 0))))))
- (out (call-with-input-file (test-file) get-bytevector-all)))
- (cons result out)))
- (pass-if-equal "file with offset"
- (cons (- len 777) (call-with-input-file file
- (lambda (input)
- (seek input 777 SEEK_SET)
- (get-bytevector-all input))))
- (let* ((result (call-with-input-file file
- (lambda (input)
- (call-with-output-file (test-file)
- (lambda (output)
- (sendfile output input (- len 777) 777))))))
- (out (call-with-input-file (test-file) get-bytevector-all)))
- (cons result out)))
- (pass-if-equal "file with offset past the end"
- (cons (- len 777) (call-with-input-file file
- (lambda (input)
- (seek input 777 SEEK_SET)
- (get-bytevector-all input))))
- (let* ((result (call-with-input-file file
- (lambda (input)
- (call-with-output-file (test-file)
- (lambda (output)
- (sendfile output input len 777))))))
- (out (call-with-input-file (test-file) get-bytevector-all)))
- (cons result out)))
- (pass-if-equal "file with offset near the end"
- (cons 77 (call-with-input-file file
- (lambda (input)
- (seek input (- len 77) SEEK_SET)
- (get-bytevector-all input))))
- (let* ((result (call-with-input-file file
- (lambda (input)
- (call-with-output-file (test-file)
- (lambda (output)
- (sendfile output input len (- len 77)))))))
- (out (call-with-input-file (test-file) get-bytevector-all)))
- (cons result out)))
- (pass-if-equal "pipe" (cons len ref)
- (if (provided? 'threads)
- (let* ((in+out (pipe))
- (child (call-with-new-thread
- (lambda ()
- (call-with-input-file file
- (lambda (input)
- (let ((result (sendfile (cdr in+out)
- (fileno input)
- len 0)))
- (close-port (cdr in+out))
- result)))))))
- (let ((out (get-bytevector-all (car in+out))))
- (close-port (car in+out))
- (cons (join-thread child) out)))
- (throw 'unresolved)))
- (pass-if-equal "pipe with offset"
- (cons (- len 777) (call-with-input-file file
- (lambda (input)
- (seek input 777 SEEK_SET)
- (get-bytevector-all input))))
- (if (provided? 'threads)
- (let* ((in+out (pipe))
- (child (call-with-new-thread
- (lambda ()
- (call-with-input-file file
- (lambda (input)
- (let ((result (sendfile (cdr in+out)
- (fileno input)
- (- len 777)
- 777)))
- (close-port (cdr in+out))
- result)))))))
- (let ((out (get-bytevector-all (car in+out))))
- (close-port (car in+out))
- (cons (join-thread child) out)))
- (throw 'unresolved)))))
- (with-test-prefix "basename"
- (pass-if-equal "/" "/" (basename "/"))
- (pass-if-equal "//" "/" (basename "//"))
- (pass-if-equal "a/b/c" "c" (basename "a/b/c")))
- (delete-file (test-file))
- (when (file-exists? (test-symlink))
- (delete-file (test-symlink)))
- (with-test-prefix "mkdtemp"
- (pass-if-exception "number arg" exception:wrong-type-arg
- (if (not (defined? 'mkdtemp))
- (throw 'unresolved)
- (mkdtemp 123)))
- (pass-if "template prefix is preserved"
- (if (not (defined? 'mkdtemp))
- (throw 'unresolved)
- (let* ((template "T-XXXXXX")
- (name (mkdtemp template)))
- (false-if-exception (rmdir name))
- (and
- (string? name)
- (string-contains name "T-")
- (= (string-length name) 8)))))
- (pass-if-exception "invalid template" exception:system-error
- (if (not (defined? 'mkdtemp))
- (throw 'unresolved)
- (mkdtemp "T-AAAAAA")))
- (pass-if "directory created"
- (if (not (defined? 'mkdtemp))
- (throw 'unresolved)
- (let* ((template "T-XXXXXX")
- (name (mkdtemp template)))
- (let* ((_stat (stat name))
- (result (eqv? 'directory (stat:type _stat))))
- (false-if-exception (rmdir name))
- result)))))
|