From b9cacf044902df441dc7cbd9a21f36833dc40a30 Mon Sep 17 00:00:00 2001 From: Michael Albinus Date: Thu, 29 Dec 2016 19:48:17 +0100 Subject: [PATCH] Improve filenotify-tests.el * src/inotify.c (Finotify_valid_p): * src/kqueue.c (Fkqueue_valid_p): * src/w32notify.c (Fw32notify_valid_p): * src/gfilenotify.c (Fgfile_valid_p): Fix typo in docstring. (Fgfile_monitor_name): New defun. (syms_of_gfilenotify): Declare Sgfile_monitor_name. * test/lisp/filenotify-tests.el (file-notify--test-read-event): New defun, derived from `file-notify--test-read-event-timeout'. Replace all calls of `read-event' by this. (file-notify--test-timeout): Fix docstring. (file-notify--test-monitor): New defun. (file-notify--deftest-remote): Do not bind `file-notify--test-read-event-timeout' anymore. (file-notify-test00-availability): Print also monitor, if existent. (file-notify--test-with-events): Add an additional `file-notify--test-read-event' call, in order to get it work after `file-notify-add-watch'. Remove special timeout for cygwin. (file-notify-test02-events): Make a better check for cygwin. (file-notify-test06-many-events): Improve event list for cygwin. (file-notify-test08-watched-file-in-watched-dir): Add cygwin case. --- src/gfilenotify.c | 23 +++++++- src/inotify.c | 2 +- src/kqueue.c | 2 +- src/w32notify.c | 2 +- test/lisp/filenotify-tests.el | 103 ++++++++++++++++++++-------------- 5 files changed, 87 insertions(+), 45 deletions(-) diff --git a/src/gfilenotify.c b/src/gfilenotify.c index 30d0753f7e7..1ad989a0d95 100644 --- a/src/gfilenotify.c +++ b/src/gfilenotify.c @@ -258,7 +258,7 @@ WATCH-DESCRIPTOR should be an object returned by `gfile-add-watch'. */) } DEFUN ("gfile-valid-p", Fgfile_valid_p, Sgfile_valid_p, 1, 1, 0, - doc: /* "Check a watch specified by its WATCH-DESCRIPTOR. + doc: /* Check a watch specified by its WATCH-DESCRIPTOR. WATCH-DESCRIPTOR should be an object returned by `gfile-add-watch'. @@ -278,6 +278,26 @@ invalid. */) } } +DEFUN ("gfile-monitor-name", Fgfile_monitor_name, Sgfile_monitor_name, 1, 1, 0, + doc: /* Return the internal monitor name for WATCH-DESCRIPTOR. + +The result is a string, either "GInotifyFileMonitor", +"GKqueueFileMonitor", or "GPollFileMonitor". + +WATCH-DESCRIPTOR should be an object returned by `gfile-add-watch'. +If WATCH-DESCRIPTOR is not valid, nil is returned. */) + (Lisp_Object watch_descriptor) +{ + if (NILP (Fgfile_valid_p (watch_descriptor))) + return Qnil; + else + { + Lisp_Object watch_object = Fassoc (watch_descriptor, watch_list); + GFileMonitor *monitor = XINTPTR (watch_descriptor); + return build_string (G_OBJECT_TYPE_NAME (monitor)); + } +} + void globals_of_gfilenotify (void) @@ -294,6 +314,7 @@ syms_of_gfilenotify (void) defsubr (&Sgfile_add_watch); defsubr (&Sgfile_rm_watch); defsubr (&Sgfile_valid_p); + defsubr (&Sgfile_monitor_name); /* Filter objects. */ DEFSYM (Qchange, "change"); diff --git a/src/inotify.c b/src/inotify.c index 38c8df5a29a..cacc6dca147 100644 --- a/src/inotify.c +++ b/src/inotify.c @@ -364,7 +364,7 @@ See inotify_rm_watch(2) for more information. } DEFUN ("inotify-valid-p", Finotify_valid_p, Sinotify_valid_p, 1, 1, 0, - doc: /* "Check a watch specified by its WATCH-DESCRIPTOR. + doc: /* Check a watch specified by its WATCH-DESCRIPTOR. WATCH-DESCRIPTOR should be an object returned by `inotify-add-watch'. diff --git a/src/kqueue.c b/src/kqueue.c index d1d0a612044..8ebd132fdc3 100644 --- a/src/kqueue.c +++ b/src/kqueue.c @@ -491,7 +491,7 @@ WATCH-DESCRIPTOR should be an object returned by `kqueue-add-watch'. */) } DEFUN ("kqueue-valid-p", Fkqueue_valid_p, Skqueue_valid_p, 1, 1, 0, - doc: /* "Check a watch specified by its WATCH-DESCRIPTOR. + doc: /* Check a watch specified by its WATCH-DESCRIPTOR. WATCH-DESCRIPTOR should be an object returned by `kqueue-add-watch'. diff --git a/src/w32notify.c b/src/w32notify.c index 32a03f70a66..e23e2b8740c 100644 --- a/src/w32notify.c +++ b/src/w32notify.c @@ -670,7 +670,7 @@ w32_get_watch_object (void *desc) } DEFUN ("w32notify-valid-p", Fw32notify_valid_p, Sw32notify_valid_p, 1, 1, 0, - doc: /* "Check a watch specified by its WATCH-DESCRIPTOR for validity. + doc: /* Check a watch specified by its WATCH-DESCRIPTOR for validity. WATCH-DESCRIPTOR should be an object returned by `w32notify-add-watch'. diff --git a/test/lisp/filenotify-tests.el b/test/lisp/filenotify-tests.el index 1ed764fb976..e2bcc6b0f7e 100644 --- a/test/lisp/filenotify-tests.el +++ b/test/lisp/filenotify-tests.el @@ -64,16 +64,22 @@ (defvar file-notify--test-event nil) (defvar file-notify--test-events nil) -(defconst file-notify--test-read-event-timeout - (cond - ;; Some events take several seconds to arrive on cygwin. - ((eq system-type 'cygwin) 7) - (t 0.01)) - "Timeout for `read-event' calls. -It is different for local and remote file notification libraries.") +(defun file-notify--test-read-event () + "Read one event. +There are different timeouts for local and remote file notification libraries." + (read-event + nil nil + (cond + ;; gio/gpollfilemonitor.c declares POLL_TIME_SECS 5. So we must + ;; wait at least this time. + ((and (string-equal (file-notify--test-library) "gfilenotify") + (string-equal (file-notify--test-monitor) "GPollFileMonitor")) + 7) + ((file-remote-p temporary-file-directory) 0.1) + (t 0.01)))) (defun file-notify--test-timeout () - "Timeout to wait for arriving events, in seconds." + "Timeout to wait for arriving a bunch of events, in seconds." (cond ((file-remote-p temporary-file-directory) 6) ((string-equal (file-notify--test-library) "w32notify") 4) @@ -85,7 +91,7 @@ It is different for local and remote file notification libraries.") TIMEOUT is the maximum time to wait for, in seconds." `(with-timeout (,timeout (ignore)) (while (null ,until) - (read-event nil nil file-notify--test-read-event-timeout)))) + (file-notify--test-read-event)))) (defun file-notify--test-no-descriptors () "Check that `file-notify-descriptors' is an empty hash table. @@ -197,6 +203,15 @@ remote host, or nil." "<[[:digit:]]+>\\'" "" (process-name (cdr file-notify--test-remote-enabled-checked)))))) +(defun file-notify--test-monitor () + "The used monitor for the test, as a string. +This returns only for the local case and gfilenotify; otherwise it is nil. +`file-notify--test-desc' must be a valid watch descriptor." + (and file-notify--test-desc + (null (file-remote-p temporary-file-directory)) + (functionp 'gfile-monitor-name) + (gfile-monitor-name file-notify--test-desc))) + (defmacro file-notify--deftest-remote (test docstring) "Define ert `TEST-remote' for remote files." (declare (indent 1)) @@ -205,7 +220,6 @@ remote host, or nil." :tags '(:expensive-test) (let* ((temporary-file-directory file-notify-test-remote-temporary-file-directory) - (file-notify--test-read-event-timeout 0.1) (ert-test (ert-get-test ',test))) (skip-unless (file-notify--test-remote-enabled)) (tramp-cleanup-connection @@ -224,6 +238,8 @@ remote host, or nil." (setq file-notify--test-desc (file-notify-add-watch temporary-file-directory '(change) #'ignore))) + (when (file-notify--test-monitor) + (message "Monitor: `%s'" (file-notify--test-monitor))) (file-notify-rm-watch file-notify--test-desc) ;; The environment shall be cleaned up. @@ -387,15 +403,12 @@ delivered." events))) create-lockfiles) ;; Flush pending events. + (file-notify--test-read-event) (file-notify--wait-for-events (file-notify--test-timeout) (not (input-pending-p))) (setq file-notify--test-events nil file-notify--test-results nil) - ;; cygwin needs a delay between setting a watch and beginning - ;; file activity, or else the first event is not sent. - (if (eq system-type 'cygwin) - (sleep-for 1)) ,@body (file-notify--wait-for-events ;; More events need more time. Use some fudge factor. @@ -434,7 +447,7 @@ delivered." (t '(created changed deleted stopped))) (write-region "another text" nil file-notify--test-tmpfile nil 'no-message) - (read-event nil nil file-notify--test-read-event-timeout) + (file-notify--test-read-event) (delete-file file-notify--test-tmpfile)) (file-notify-rm-watch file-notify--test-desc)) @@ -452,7 +465,7 @@ delivered." (changed changed deleted stopped)) (write-region "another text" nil file-notify--test-tmpfile nil 'no-message) - (read-event nil nil file-notify--test-read-event-timeout) + (file-notify--test-read-event) (delete-file file-notify--test-tmpfile)) (file-notify-rm-watch file-notify--test-desc) @@ -483,7 +496,7 @@ delivered." (t '(created changed deleted deleted stopped))) (write-region "any text" nil file-notify--test-tmpfile nil 'no-message) - (read-event nil nil file-notify--test-read-event-timeout) + (file-notify--test-read-event) (delete-directory temporary-file-directory 'recursive)) (file-notify-rm-watch file-notify--test-desc)) @@ -516,14 +529,14 @@ delivered." deleted deleted deleted stopped))) (write-region "any text" nil file-notify--test-tmpfile nil 'no-message) - (read-event nil nil file-notify--test-read-event-timeout) + (file-notify--test-read-event) (copy-file file-notify--test-tmpfile file-notify--test-tmpfile1) ;; The next two events shall not be visible. - (read-event nil nil file-notify--test-read-event-timeout) + (file-notify--test-read-event) (set-file-modes file-notify--test-tmpfile 000) - (read-event nil nil file-notify--test-read-event-timeout) + (file-notify--test-read-event) (set-file-times file-notify--test-tmpfile '(0 0)) - (read-event nil nil file-notify--test-read-event-timeout) + (file-notify--test-read-event) (delete-directory temporary-file-directory 'recursive)) (file-notify-rm-watch file-notify--test-desc)) @@ -554,15 +567,16 @@ delivered." (t '(created changed renamed deleted deleted stopped))) (write-region "any text" nil file-notify--test-tmpfile nil 'no-message) - (read-event nil nil file-notify--test-read-event-timeout) + (file-notify--test-read-event) (rename-file file-notify--test-tmpfile file-notify--test-tmpfile1) ;; After the rename, we won't get events anymore. - (read-event nil nil file-notify--test-read-event-timeout) + (file-notify--test-read-event) (delete-directory temporary-file-directory 'recursive)) (file-notify-rm-watch file-notify--test-desc)) ;; Check attribute change. Does not work for cygwin. - (unless (eq system-type 'cygwin) + (unless (and (eq system-type 'cygwin) + (not (file-remote-p temporary-file-directory))) (setq file-notify--test-tmpfile (file-notify--test-make-temp-name)) (write-region "any text" nil file-notify--test-tmpfile nil 'no-message) @@ -588,11 +602,11 @@ delivered." (t '(attribute-changed attribute-changed))) (write-region "any text" nil file-notify--test-tmpfile nil 'no-message) - (read-event nil nil file-notify--test-read-event-timeout) + (file-notify--test-read-event) (set-file-modes file-notify--test-tmpfile 000) - (read-event nil nil file-notify--test-read-event-timeout) + (file-notify--test-read-event) (set-file-times file-notify--test-tmpfile '(0 0)) - (read-event nil nil file-notify--test-read-event-timeout) + (file-notify--test-read-event) (delete-file file-notify--test-tmpfile)) (file-notify-rm-watch file-notify--test-desc)) @@ -736,7 +750,7 @@ delivered." (changed changed deleted stopped)) (write-region "another text" nil file-notify--test-tmpfile nil 'no-message) - (read-event nil nil file-notify--test-read-event-timeout) + (file-notify--test-read-event) (delete-file file-notify--test-tmpfile)) ;; After deleting the file, the descriptor is not valid anymore. (should-not (file-notify-valid-p file-notify--test-desc)) @@ -774,7 +788,7 @@ delivered." (t '(created changed deleted deleted stopped))) (write-region "any text" nil file-notify--test-tmpfile nil 'no-message) - (read-event nil nil file-notify--test-read-event-timeout) + (file-notify--test-read-event) (delete-directory temporary-file-directory t)) ;; After deleting the parent directory, the descriptor must ;; not be valid anymore. @@ -876,9 +890,9 @@ delivered." (let ((source-file-list source-file-list) (target-file-list target-file-list)) (while (and source-file-list target-file-list) - (read-event nil nil file-notify--test-read-event-timeout) + (file-notify--test-read-event) (write-region "" nil (pop source-file-list) nil 'no-message) - (read-event nil nil file-notify--test-read-event-timeout) + (file-notify--test-read-event) (write-region "" nil (pop target-file-list) nil 'no-message)))) (file-notify--test-with-events (cond @@ -890,19 +904,19 @@ delivered." ;; cygwin fires `changed' and `deleted' events, sometimes ;; in random order. ((eq system-type 'cygwin) - (let ((r '(:random))) - (dotimes (_i n r) - (setq r (append r '(changed deleted)))))) + (let (r) + (dotimes (_i n (cons :random r)) + (setq r (append '(changed deleted) r))))) (t (make-list n 'renamed))) (let ((source-file-list source-file-list) (target-file-list target-file-list)) (while (and source-file-list target-file-list) - (read-event nil nil file-notify--test-read-event-timeout) + (file-notify--test-read-event) (rename-file (pop source-file-list) (pop target-file-list) t)))) (file-notify--test-with-events (make-list n 'deleted) (dolist (file target-file-list) - (read-event nil nil file-notify--test-read-event-timeout) - (delete-file file) file-notify--test-read-event-timeout)) + (file-notify--test-read-event) + (delete-file file))) (delete-directory file-notify--test-tmpfile) ;; The environment shall be cleaned up. @@ -1040,6 +1054,12 @@ the file watch." (file-notify--test-with-events ;; There could be one or two `changed' events. (list + ;; cygwin. + (append + '(:random) + (make-list (/ n 2) 'changed) + (make-list (/ n 2) 'created) + (make-list (/ n 2) 'changed)) (append '(:random) ;; Directory monitor and file monitor. @@ -1059,7 +1079,7 @@ the file watch." (make-list (/ n 2) 'created) (make-list (/ n 2) 'changed))) (dotimes (i n) - (read-event nil nil file-notify--test-read-event-timeout) + (file-notify--test-read-event) (if (zerop (mod i 2)) (write-region "any text" nil file-notify--test-tmpfile1 t 'no-message) @@ -1081,9 +1101,10 @@ the file watch." ;; Now we delete the directory. (file-notify--test-with-events (cond - ;; In kqueue, just one `deleted' event for the directory - ;; is received. - ((string-equal (file-notify--test-library) "kqueue") + ;; In kqueue and for cygwin, just one `deleted' event for + ;; the directory is received. + ((or (eq system-type 'cygwin) + (string-equal (file-notify--test-library) "kqueue")) '(deleted stopped)) (t (append ;; The directory monitor raises a `deleted' event for -- 2.39.2