;;; file-notify-tests.el --- Tests of file notifications
-;; Copyright (C) 2013 Free Software Foundation, Inc.
+;; Copyright (C) 2013-2015 Free Software Foundation, Inc.
;; Author: Michael Albinus <michael.albinus@gmx.de>
;;; Commentary:
-;; Some of the tests are intended to run over remote files. Set
-;; `file-notify-test-remote-temporary-file-directory' to a suitable
-;; value. It must NOT require an interactive password prompt, when
-;; running the tests in batch mode.
+;; Some of the tests require access to a remote host files. Since
+;; this could be problematic, a mock-up connection method "mock" is
+;; used. Emulating a remote connection, it simply calls "sh -i".
+;; Tramp's file name handlers still run, so this test is sufficient
+;; except for connection establishing.
-;; If you want to skip tests for remote files, set this variable to
-;; `null-device'.
+;; If you want to test a real Tramp connection, set
+;; $REMOTE_TEMPORARY_FILE_DIRECTORY to a suitable value in order to
+;; overwrite the default value. If you want to skip tests accessing a
+;; remote host, set this environment variable to "/dev/null" or
+;; whatever is appropriate on your system.
+
+;; A whole test run can be performed calling the command `file-notify-test-all'.
;;; Code:
(require 'ert)
(require 'filenotify)
+(require 'tramp)
;; There is no default value on w32 systems, which could work out of the box.
(defconst file-notify-test-remote-temporary-file-directory
- (if (eq system-type 'windows-nt) null-device "/ssh::/tmp")
+ (cond
+ ((getenv "REMOTE_TEMPORARY_FILE_DIRECTORY"))
+ ((eq system-type 'windows-nt) null-device)
+ (t (add-to-list
+ 'tramp-methods
+ '("mock"
+ (tramp-login-program "sh")
+ (tramp-login-args (("-i")))
+ (tramp-remote-shell "/bin/sh")
+ (tramp-remote-shell-args ("-c"))
+ (tramp-connection-timeout 10)))
+ (format "/mock::%s" temporary-file-directory)))
"Temporary directory for Tramp tests.")
(defvar file-notify--test-tmpfile nil)
(defvar file-notify--test-results nil)
(defvar file-notify--test-event nil)
-(require 'tramp)
-(setq tramp-verbose 0
+(setq password-cache-expiry nil
+ tramp-verbose 0
tramp-message-show-message nil)
-(when noninteractive (defalias 'tramp-read-passwd 'ignore))
+
;; This shall happen on hydra only.
(when (getenv "NIX_STORE")
(add-to-list 'tramp-remote-path 'tramp-own-remote-path))
This is needed for local `temporary-file-directory' only, in the
remote case we return always `t'."
(or file-notify--library
- (not (file-remote-p temporary-file-directory))))
+ (file-remote-p temporary-file-directory)))
(defvar file-notify--test-remote-enabled-checked nil
"Cached result of `file-notify--test-remote-enabled'.
file-notify-test-remote-temporary-file-directory)
(ert-test (ert-get-test ',test)))
(skip-unless (file-notify--test-remote-enabled))
- ;; The local test could have passed, skipped, or quit. All of
- ;; these results should not prevent us to run the remote test.
- ;; That's why we skip only for failed local tests.
- (skip-unless
- (not (ert-test-failed-p (ert-test-most-recent-result ert-test))))
+ (tramp-cleanup-connection
+ (tramp-dissect-file-name temporary-file-directory) nil 'keep-password)
(funcall (ert-test-body ert-test)))))
(ert-deftest file-notify-test00-availability ()
(expand-file-name
(make-temp-name "file-notify-test") temporary-file-directory))
+(defmacro file-notify--wait-for-events (timeout until)
+ "Wait for file notification events until form UNTIL is true.
+TIMEOUT is the maximum time to wait for, in seconds."
+ `(with-timeout (,timeout (ignore))
+ (while (null ,until)
+ (read-event nil nil 0.1))))
+
(ert-deftest file-notify-test02-events ()
"Check file creation/removal notifications."
(skip-unless (file-notify--test-local-enabled))
(write-region
"any text" nil file-notify--test-tmpfile nil 'no-message)
(delete-file file-notify--test-tmpfile)
+ (sleep-for 0.1)
;; Check copy and rename.
(write-region
(copy-file file-notify--test-tmpfile file-notify--test-tmpfile1)
(delete-file file-notify--test-tmpfile)
(delete-file file-notify--test-tmpfile1)
+ (sleep-for 0.1)
(write-region
"any text" nil file-notify--test-tmpfile nil 'no-message)
(rename-file file-notify--test-tmpfile file-notify--test-tmpfile1)
- (delete-file file-notify--test-tmpfile1))
+ (delete-file file-notify--test-tmpfile1)
+ (sleep-for 0.1))
;; Wait for events, and exit.
- (sit-for 5 'nodisplay)
+ (file-notify--wait-for-events 5 file-notify--test-results)
(file-notify-rm-watch desc)
(ignore-errors (delete-file file-notify--test-tmpfile))
(ignore-errors (delete-file file-notify--test-tmpfile1))))
+ (should file-notify--test-results)
(dolist (result file-notify--test-results)
;(message "%s" (ert-test-result-messages result))
(when (ert-test-failed-p result)
(file-notify--deftest-remote file-notify-test02-events
"Check file creation/removal notifications for remote files.")
-;; autorevert runs only in interactive mode.
(defvar auto-revert-remote-files)
-(setq auto-revert-remote-files t)
+(defvar auto-revert-stop-on-user-input)
+(setq auto-revert-remote-files t
+ auto-revert-stop-on-user-input nil)
(require 'autorevert)
(ert-deftest file-notify-test03-autorevert ()
"Check autorevert via file notification.
This test is skipped in batch mode."
(skip-unless (file-notify--test-local-enabled))
- (skip-unless (not noninteractive))
;; `auto-revert-buffers' runs every 5". And we must wait, until the
;; file has been reverted.
- (let ((timeout 10)
- buf)
+ (let* ((remote (file-remote-p temporary-file-directory))
+ (timeout (if remote 60 10))
+ buf)
(unwind-protect
(progn
(setq file-notify--test-tmpfile (file-notify--test-make-temp-name))
;; `auto-revert-buffers' runs every 5".
(with-timeout (timeout (ignore))
(while (null auto-revert-notify-watch-descriptor)
- (sit-for 0.1 'nodisplay)))
+ (sleep-for 1)))
;; Check, that file notification has been used.
(should auto-revert-mode)
;; Modify file. We wait for a second, in order to
;; have another timestamp.
- (sit-for 1)
+ (sleep-for 1)
(shell-command
(format "echo -n 'another text' >%s"
(or (file-remote-p file-notify--test-tmpfile 'localname)
;; Check, that the buffer has been reverted.
(with-current-buffer (get-buffer-create "*Messages*")
- (with-timeout (timeout (ignore))
- (while
- (null (string-match
- (format "Reverting buffer `%s'." (buffer-name buf))
- (buffer-string)))
- (sit-for 0.1 'nodisplay))))
- (should (string-equal (buffer-string) "another text"))))
+ (file-notify--wait-for-events
+ timeout
+ (string-match (format "Reverting buffer `%s'." (buffer-name buf))
+ (buffer-string))))
+ (should (string-match "another text" (buffer-string)))))
;; Exit.
(ignore-errors (kill-buffer buf))