filesys.test 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. ;;;; filesys.test --- test file system functions -*- scheme -*-
  2. ;;;;
  3. ;;;; Copyright (C) 2004, 2006, 2013, 2019, 2021 Free Software Foundation, Inc.
  4. ;;;;
  5. ;;;; This library is free software; you can redistribute it and/or
  6. ;;;; modify it under the terms of the GNU Lesser General Public
  7. ;;;; License as published by the Free Software Foundation; either
  8. ;;;; version 3 of the License, or (at your option) any later version.
  9. ;;;;
  10. ;;;; This library is distributed in the hope that it will be useful,
  11. ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. ;;;; Lesser General Public License for more details.
  14. ;;;;
  15. ;;;; You should have received a copy of the GNU Lesser General Public
  16. ;;;; License along with this library; if not, write to the Free Software
  17. ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  18. (define-module (test-suite test-filesys)
  19. #:use-module (test-suite lib)
  20. #:use-module (test-suite guile-test)
  21. #:use-module (ice-9 threads)
  22. #:use-module (ice-9 match)
  23. #:use-module (rnrs io ports)
  24. #:use-module (rnrs bytevectors))
  25. (define (test-file)
  26. (data-file-name "filesys-test.tmp"))
  27. (define (test-symlink)
  28. (data-file-name "filesys-test-link.tmp"))
  29. ;;;
  30. ;;; copy-file
  31. ;;;
  32. (with-test-prefix "copy-file"
  33. ;; return next prospective file descriptor number
  34. (define (next-fd)
  35. (let ((fd (dup 0)))
  36. (close fd)
  37. fd))
  38. ;; in guile 1.6.4 and earlier, copy-file didn't close the input fd when
  39. ;; the output could not be opened
  40. (pass-if "fd leak when dest unwritable"
  41. (let ((old-next (next-fd)))
  42. (false-if-exception (copy-file "/dev/null" "no/such/dir/foo"))
  43. (= old-next (next-fd)))))
  44. ;;;
  45. ;;; lstat
  46. ;;;
  47. (with-test-prefix "lstat"
  48. (pass-if "normal file"
  49. (call-with-output-file (test-file)
  50. (lambda (port)
  51. (display "hello" port)))
  52. (eqv? 5 (stat:size (lstat (test-file)))))
  53. (call-with-output-file (test-file)
  54. (lambda (port)
  55. (display "hello" port)))
  56. (false-if-exception (delete-file (test-symlink)))
  57. (if (not (false-if-exception
  58. (begin (symlink (test-file) (test-symlink)) #t)))
  59. (display "cannot create symlink, lstat test skipped\n")
  60. (pass-if "symlink"
  61. ;; not much to test, except that it works
  62. (->bool (lstat (test-symlink))))))
  63. ;;;
  64. ;;; opendir and friends
  65. ;;;
  66. (with-test-prefix "opendir"
  67. (with-test-prefix "root directory"
  68. (let ((d (opendir "/")))
  69. (pass-if "not empty"
  70. (string? (readdir d)))
  71. (pass-if "all entries are strings"
  72. (let more ()
  73. (let ((f (readdir d)))
  74. (cond ((string? f)
  75. (more))
  76. ((eof-object? f)
  77. #t)
  78. (else
  79. #f)))))
  80. (closedir d))))
  81. ;;;
  82. ;;; stat
  83. ;;;
  84. (with-test-prefix "stat"
  85. (with-test-prefix "filename"
  86. (pass-if "size"
  87. (call-with-output-file (test-file)
  88. (lambda (port)
  89. (display "hello" port)))
  90. (eqv? 5 (stat:size (stat (test-file))))))
  91. (with-test-prefix "file descriptor"
  92. (pass-if "size"
  93. (call-with-output-file (test-file)
  94. (lambda (port)
  95. (display "hello" port)))
  96. (let* ((fd (open-fdes (test-file) O_RDONLY))
  97. (st (stat fd)))
  98. (close-fdes fd)
  99. (eqv? 5 (stat:size st)))))
  100. (with-test-prefix "port"
  101. (pass-if "size"
  102. (call-with-output-file (test-file)
  103. (lambda (port)
  104. (display "hello" port)))
  105. (let* ((port (open-file (test-file) "r+"))
  106. (st (stat port)))
  107. (close-port port)
  108. (eqv? 5 (stat:size st))))))
  109. (with-test-prefix "sendfile"
  110. (let* ((file (search-path %load-path "ice-9/boot-9.scm"))
  111. (len (stat:size (stat file)))
  112. (ref (call-with-input-file file get-bytevector-all)))
  113. (pass-if-equal "file" (cons len ref)
  114. (let* ((result (call-with-input-file file
  115. (lambda (input)
  116. (call-with-output-file (test-file)
  117. (lambda (output)
  118. (sendfile output input len 0))))))
  119. (out (call-with-input-file (test-file) get-bytevector-all)))
  120. (cons result out)))
  121. (pass-if-equal "file with offset"
  122. (cons (- len 777) (call-with-input-file file
  123. (lambda (input)
  124. (seek input 777 SEEK_SET)
  125. (get-bytevector-all input))))
  126. (let* ((result (call-with-input-file file
  127. (lambda (input)
  128. (call-with-output-file (test-file)
  129. (lambda (output)
  130. (sendfile output input (- len 777) 777))))))
  131. (out (call-with-input-file (test-file) get-bytevector-all)))
  132. (cons result out)))
  133. (pass-if-equal "file with offset past the end"
  134. (cons (- len 777) (call-with-input-file file
  135. (lambda (input)
  136. (seek input 777 SEEK_SET)
  137. (get-bytevector-all input))))
  138. (let* ((result (call-with-input-file file
  139. (lambda (input)
  140. (call-with-output-file (test-file)
  141. (lambda (output)
  142. (sendfile output input len 777))))))
  143. (out (call-with-input-file (test-file) get-bytevector-all)))
  144. (cons result out)))
  145. (pass-if-equal "file with offset near the end"
  146. (cons 77 (call-with-input-file file
  147. (lambda (input)
  148. (seek input (- len 77) SEEK_SET)
  149. (get-bytevector-all input))))
  150. (let* ((result (call-with-input-file file
  151. (lambda (input)
  152. (call-with-output-file (test-file)
  153. (lambda (output)
  154. (sendfile output input len (- len 77)))))))
  155. (out (call-with-input-file (test-file) get-bytevector-all)))
  156. (cons result out)))
  157. (pass-if-equal "pipe" (cons len ref)
  158. (if (provided? 'threads)
  159. (let* ((in+out (pipe))
  160. (child (call-with-new-thread
  161. (lambda ()
  162. (call-with-input-file file
  163. (lambda (input)
  164. (let ((result (sendfile (cdr in+out)
  165. (fileno input)
  166. len 0)))
  167. (close-port (cdr in+out))
  168. result)))))))
  169. (let ((out (get-bytevector-all (car in+out))))
  170. (close-port (car in+out))
  171. (cons (join-thread child) out)))
  172. (throw 'unresolved)))
  173. (pass-if-equal "pipe with offset"
  174. (cons (- len 777) (call-with-input-file file
  175. (lambda (input)
  176. (seek input 777 SEEK_SET)
  177. (get-bytevector-all input))))
  178. (if (provided? 'threads)
  179. (let* ((in+out (pipe))
  180. (child (call-with-new-thread
  181. (lambda ()
  182. (call-with-input-file file
  183. (lambda (input)
  184. (let ((result (sendfile (cdr in+out)
  185. (fileno input)
  186. (- len 777)
  187. 777)))
  188. (close-port (cdr in+out))
  189. result)))))))
  190. (let ((out (get-bytevector-all (car in+out))))
  191. (close-port (car in+out))
  192. (cons (join-thread child) out)))
  193. (throw 'unresolved)))))
  194. (with-test-prefix "basename"
  195. (pass-if-equal "/" "/" (basename "/"))
  196. (pass-if-equal "//" "/" (basename "//"))
  197. (pass-if-equal "a/b/c" "c" (basename "a/b/c")))
  198. (delete-file (test-file))
  199. (when (file-exists? (test-symlink))
  200. (delete-file (test-symlink)))
  201. (with-test-prefix "mkdtemp"
  202. (pass-if-exception "number arg" exception:wrong-type-arg
  203. (if (not (defined? 'mkdtemp))
  204. (throw 'unresolved)
  205. (mkdtemp 123)))
  206. (pass-if "template prefix is preserved"
  207. (if (not (defined? 'mkdtemp))
  208. (throw 'unresolved)
  209. (let* ((template "T-XXXXXX")
  210. (name (mkdtemp template)))
  211. (false-if-exception (rmdir name))
  212. (and
  213. (string? name)
  214. (string-contains name "T-")
  215. (= (string-length name) 8)))))
  216. (pass-if-exception "invalid template" exception:system-error
  217. (if (not (defined? 'mkdtemp))
  218. (throw 'unresolved)
  219. (mkdtemp "T-AAAAAA")))
  220. (pass-if "directory created"
  221. (if (not (defined? 'mkdtemp))
  222. (throw 'unresolved)
  223. (let* ((template "T-XXXXXX")
  224. (name (mkdtemp template)))
  225. (let* ((_stat (stat name))
  226. (result (eqv? 'directory (stat:type _stat))))
  227. (false-if-exception (rmdir name))
  228. result)))))