1 ;;; file-notify-tests.el --- Tests of file notifications
3 ;; Copyright (C) 2013 Free Software Foundation, Inc.
5 ;; Author: Michael Albinus <michael.albinus@gmx.de>
7 ;; This program is free software: you can redistribute it and/or
8 ;; modify it under the terms of the GNU General Public License as
9 ;; published by the Free Software Foundation, either version 3 of the
10 ;; License, or (at your option) any later version.
12 ;; This program is distributed in the hope that it will be useful, but
13 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 ;; General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with this program. If not, see `http://www.gnu.org/licenses/'.
22 ;; Some of the tests are intended to run over remote files. Set
23 ;; `file-notify-test-remote-temporary-file-directory' to a suitable
24 ;; value. It must NOT require an interactive password prompt, when
25 ;; running the tests in batch mode.
27 ;; If you want to skip tests for remote files, set this variable to
35 ;; There is no default value on w32 systems, which could work out of the box.
36 (defconst file-notify-test-remote-temporary-file-directory
37 (if (eq system-type
'windows-nt
) null-device
"/ssh::/tmp")
38 "Temporary directory for Tramp tests.")
40 (defvar file-notify--test-tmpfile nil
)
41 (defvar file-notify--test-tmpfile1 nil
)
42 (defvar file-notify--test-results nil
)
43 (defvar file-notify--test-event nil
)
48 tramp-message-show-message nil
)
49 (when noninteractive
(defalias 'tramp-read-passwd
'ignore
))
51 ;; We do not want to try and fail `file-notify-add-watch'.
52 (defconst file-notify--test-local-enabled file-notify--library
53 "Whether local file notification is enabled.")
55 ;; We need also a check on the remote side, w/o adding a file monitor.
56 (defun file-notify--test-remote-enabled ()
57 "Whether remote file notification is enabled."
59 (and (file-remote-p file-notify-test-remote-temporary-file-directory
)
60 (file-directory-p file-notify-test-remote-temporary-file-directory
)
61 (file-writable-p file-notify-test-remote-temporary-file-directory
)
62 ;; Extracted from tramp-sh-handle-file-notify-add-watch.
63 ;; Even though the "remote" system is just ssh@localhost,
64 ;; the PATH might not be the same as the "local" PATH.
65 ;; Eg this seems to be the case on hydra.nixos.org.
66 ;; Without this, tests fail with:
67 ;; "No file notification program found on /ssh:localhost:"
68 ;; Try to fix PATH instead?
69 (with-parsed-tramp-file-name
70 file-notify-test-remote-temporary-file-directory nil
71 (or (tramp-get-remote-gvfs-monitor-dir v
)
72 (tramp-get-remote-inotifywait v
))))))
74 (defmacro file-notify--deftest-remote
(test docstring
)
75 "Define ert `TEST-remote' for remote files."
76 `(when (and (file-notify--test-remote-enabled) (ert-get-test ',test
))
78 (ert-deftest ,(intern (concat (symbol-name test
) "-remote")) ()
80 (let* ((temporary-file-directory
81 file-notify-test-remote-temporary-file-directory
)
82 (ert-test (ert-get-test ',test
))
83 (most-recent-result (ert-test-most-recent-result ert-test
))
89 (ert-run-test ert-test
)
92 (when (ert-test-failed-p result
)
94 (cadr (ert-test-result-with-condition-condition result
)))))
95 ;; Reset status of TEST.
96 (setf (ert-test-most-recent-result ert-test
) most-recent-result
))))))
98 (ert-deftest file-notify-test00-availability
()
99 "Test availability of `file-notify'."
101 ;; Check, that different valid parameters are accepted.
102 (should (setq desc
(file-notify-add-watch
103 temporary-file-directory
'(change) 'ignore
)))
104 (file-notify-rm-watch desc
)))
106 (file-notify--deftest-remote file-notify-test00-availability
107 "Test availability of `file-notify' for remote files.")
109 (when file-notify--test-local-enabled
111 (ert-deftest file-notify-test01-add-watch
()
112 "Check `file-notify-add-watch'."
114 ;; Check, that different valid parameters are accepted.
115 (should (setq desc
(file-notify-add-watch
116 temporary-file-directory
'(change) 'ignore
)))
117 (file-notify-rm-watch desc
)
118 (should (setq desc
(file-notify-add-watch
119 temporary-file-directory
120 '(attribute-change) 'ignore
)))
121 (file-notify-rm-watch desc
)
122 (should (setq desc
(file-notify-add-watch
123 temporary-file-directory
124 '(change attribute-change
) 'ignore
)))
125 (file-notify-rm-watch desc
)
127 ;; Check error handling.
128 (should-error (file-notify-add-watch 1 2 3 4)
129 :type
'wrong-number-of-arguments
)
131 (equal (should-error (file-notify-add-watch 1 2 3))
132 '(wrong-type-argument 1)))
134 (equal (should-error (file-notify-add-watch
135 temporary-file-directory
2 3))
136 '(wrong-type-argument 2)))
138 (equal (should-error (file-notify-add-watch
139 temporary-file-directory
'(change) 3))
140 '(wrong-type-argument 3)))))
142 (file-notify--deftest-remote file-notify-test01-add-watch
143 "Check `file-notify-add-watch' for remote files.")
144 ) ;; file-notify--test-local-enabled
146 (defun file-notify--test-event-test ()
147 "Ert test function to be called by `file-notify--test-event-handler'.
148 We cannot pass arguments, so we assume that `file-notify--test-event'
150 ;(message "Event %S" file-notify--test-event)
151 ;; Check the file name.
153 (string-equal (file-notify--event-file-name file-notify--test-event
)
154 file-notify--test-tmpfile
))
155 ;; Check the second file name if exists.
156 (when (eq (nth 1 file-notify--test-event
) 'renamed
)
159 (file-notify--event-file1-name file-notify--test-event
)
160 file-notify--test-tmpfile1
))))
162 (defun file-notify--test-event-handler (file-notify--test-event)
163 "Run a test over FILE-NOTIFY--TEST-EVENT.
164 Save the result in `file-notify--test-results', for later analysis."
166 (ert-run-test (make-ert-test :body
'file-notify--test-event-test
))))
167 (setq file-notify--test-results
168 (append file-notify--test-results
`(,result
)))))
170 (defun file-notify--test-make-temp-name ()
171 "Create a temporary file name for test."
173 (make-temp-name "file-notify-test") temporary-file-directory
))
175 (when file-notify--test-local-enabled
177 (ert-deftest file-notify-test02-events
()
178 "Check file creation/removal notifications."
182 (setq file-notify--test-results nil
183 file-notify--test-tmpfile
(file-notify--test-make-temp-name)
184 file-notify--test-tmpfile1
(file-notify--test-make-temp-name)
186 (file-notify-add-watch
187 file-notify--test-tmpfile
188 '(change) 'file-notify--test-event-handler
))
190 ;; Check creation and removal.
191 (write-region "any text" nil file-notify--test-tmpfile
)
192 (delete-file file-notify--test-tmpfile
)
194 ;; Check copy and rename.
195 (write-region "any text" nil file-notify--test-tmpfile
)
196 (copy-file file-notify--test-tmpfile file-notify--test-tmpfile1
)
197 (delete-file file-notify--test-tmpfile
)
198 (delete-file file-notify--test-tmpfile1
)
200 (write-region "any text" nil file-notify--test-tmpfile
)
201 (rename-file file-notify--test-tmpfile file-notify--test-tmpfile1
)
202 (delete-file file-notify--test-tmpfile1
))
204 ;; Wait for events, and exit.
205 (sit-for 5 'nodisplay
)
206 (file-notify-rm-watch desc
)
207 (ignore-errors (delete-file file-notify--test-tmpfile
))
208 (ignore-errors (delete-file file-notify--test-tmpfile1
))))
210 (dolist (result file-notify--test-results
)
211 ;(message "%s" (ert-test-result-messages result))
212 (when (ert-test-failed-p result
)
213 (ert-fail (cadr (ert-test-result-with-condition-condition result
))))))
215 (file-notify--deftest-remote file-notify-test02-events
216 "Check file creation/removal notifications for remote files.")
217 ) ;; file-notify--test-local-enabled
219 ;; autorevert runs only in interactive mode.
220 (defvar auto-revert-remote-files
)
221 (setq auto-revert-remote-files t
)
222 (require 'autorevert
)
223 (when (and file-notify--test-local-enabled
(null noninteractive
))
225 (ert-deftest file-notify-test03-autorevert
()
226 "Check autorevert via file notification.
227 This test is skipped in batch mode."
228 ;; `auto-revert-buffers' runs every 5". And we must wait, until
229 ;; the file has been reverted.
234 (setq file-notify--test-tmpfile
(file-notify--test-make-temp-name))
236 (write-region "any text" nil file-notify--test-tmpfile
)
237 (setq buf
(find-file-noselect file-notify--test-tmpfile
))
238 (with-current-buffer buf
239 (should (string-equal (buffer-string) "any text"))
242 ;; `auto-revert-buffers' runs every 5".
243 (with-timeout (timeout (ignore))
244 (while (null auto-revert-notify-watch-descriptor
)
245 (sit-for 0.1 'nodisplay
)))
247 ;; Check, that file notification has been used.
248 (should auto-revert-mode
)
249 (should auto-revert-use-notify
)
250 (should auto-revert-notify-watch-descriptor
)
252 ;; Modify file. We wait for a second, in order to
253 ;; have another timestamp.
256 (format "echo -n 'another text' >%s"
257 (or (file-remote-p file-notify--test-tmpfile
'localname
)
258 file-notify--test-tmpfile
)))
260 ;; Check, that the buffer has been reverted.
261 (with-current-buffer (get-buffer-create "*Messages*")
262 (with-timeout (timeout (ignore))
265 (format "Reverting buffer `%s'." (buffer-name buf
))
267 (sit-for 0.1 'nodisplay
))))
268 (should (string-equal (buffer-string) "another text"))))
271 (ignore-errors (kill-buffer buf
))
272 (ignore-errors (delete-file file-notify--test-tmpfile
)))))
274 (file-notify--deftest-remote file-notify-test03-autorevert
275 "Check autorevert via file notification for remote files.
276 This test is skipped in batch mode.")
277 ) ;; (and file-notify--test-local-enabled (null noninteractive))
279 (defun file-notify-test-all (&optional interactive
)
280 "Run all tests for \\[file-notify]."
282 (when file-notify--test-local-enabled
284 (ert-run-tests-interactively "^file-notify-")
285 (ert-run-tests-batch "^file-notify-"))))
287 (provide 'file-notify-tests
)
288 ;;; file-notify-tests.el ends here