aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Albinus2015-11-25 15:00:06 +0100
committerMichael Albinus2015-11-25 15:07:12 +0100
commitbec57a486a2a40d7c770dab72a34cf6a4d17a5d0 (patch)
treeab824a9c680a488764c8a7bcb975c2b3015c9d5a
parent0247489fed0f70b2abf960de48bc4432381a581b (diff)
downloademacs-bec57a486a2a40d7c770dab72a34cf6a4d17a5d0.tar.gz
emacs-bec57a486a2a40d7c770dab72a34cf6a4d17a5d0.zip
Some final fixes in file notification before merging with master
* lisp/filenotify.el (file-notify--rm-descriptor): Remove WHAT arg. (file-notify-callback): Improve check for `stopped' event. Call `file-notify-rm-watch' rather than `file-notify--rm-descriptor'. (file-notify-add-watch): In case FILE is not a directory, call the file monitor for the kqueue backend. Otherwise, call the directory monitor for the upper directory. * src/inotify.c (inotifyevent_to_event): Extract file name from watch_object if the event doesn't provide it. (Finotify_add_watch): Add file name to watch_object. * test/automated/file-notify-tests.el (file-notify--test-timeout): Use different timeouts for different libraries. (file-notify--test-with-events): Suppress lock files. Flush outstanding events before running the body. (file-notify-test02-events, file-notify-test04-file-validity): Do not skip cygwin tests. Add additional test for file creation. Adapt expected result for different backends. (file-notify-test03-autorevert): Some of the tests don't work for w32notify. (file-notify-test06-many-events): Rename into both directions.
-rw-r--r--lisp/filenotify.el36
-rw-r--r--src/inotify.c9
-rw-r--r--test/automated/file-notify-tests.el308
3 files changed, 239 insertions, 114 deletions
diff --git a/lisp/filenotify.el b/lisp/filenotify.el
index 0d7a2b914c6..b6c1f686fe1 100644
--- a/lisp/filenotify.el
+++ b/lisp/filenotify.el
@@ -49,17 +49,16 @@ handler. The value in the hash table is a list
49Several values for a given DIR happen only for `inotify', when 49Several values for a given DIR happen only for `inotify', when
50different files from the same directory are watched.") 50different files from the same directory are watched.")
51 51
52(defun file-notify--rm-descriptor (descriptor &optional what) 52(defun file-notify--rm-descriptor (descriptor)
53 "Remove DESCRIPTOR from `file-notify-descriptors'. 53 "Remove DESCRIPTOR from `file-notify-descriptors'.
54DESCRIPTOR should be an object returned by `file-notify-add-watch'. 54DESCRIPTOR should be an object returned by `file-notify-add-watch'.
55If it is registered in `file-notify-descriptors', a stopped event is sent. 55If it is registered in `file-notify-descriptors', a stopped event is sent."
56WHAT is a file or directory name to be removed, needed just for `inotify'."
57 (let* ((desc (if (consp descriptor) (car descriptor) descriptor)) 56 (let* ((desc (if (consp descriptor) (car descriptor) descriptor))
58 (file (if (consp descriptor) (cdr descriptor))) 57 (file (if (consp descriptor) (cdr descriptor)))
59 (registered (gethash desc file-notify-descriptors)) 58 (registered (gethash desc file-notify-descriptors))
60 (dir (car registered))) 59 (dir (car registered)))
61 60
62 (when (and (consp registered) (or (null what) (string-equal dir what))) 61 (when (consp registered)
63 ;; Send `stopped' event. 62 ;; Send `stopped' event.
64 (dolist (entry (cdr registered)) 63 (dolist (entry (cdr registered))
65 (funcall (cdr entry) 64 (funcall (cdr entry)
@@ -236,7 +235,6 @@ EVENT is the cadr of the event in `file-notify-handle-event'
236 (setq pending-event nil)) 235 (setq pending-event nil))
237 236
238 ;; Check for stopped. 237 ;; Check for stopped.
239 ;;(message "file-notify-callback %S %S %S" file file1 registered)
240 (setq 238 (setq
241 stopped 239 stopped
242 (or 240 (or
@@ -244,10 +242,13 @@ EVENT is the cadr of the event in `file-notify-handle-event'
244 (and 242 (and
245 (memq action '(deleted renamed)) 243 (memq action '(deleted renamed))
246 (= (length (cdr registered)) 1) 244 (= (length (cdr registered)) 1)
247 (string-equal 245 (or
248 (file-name-nondirectory file) 246 (string-equal
249 (or (file-name-nondirectory (car registered)) 247 (file-name-nondirectory file)
250 (car (cadr registered))))))) 248 (file-name-nondirectory (car registered)))
249 (string-equal
250 (file-name-nondirectory file)
251 (car (cadr registered)))))))
251 252
252 ;; Apply callback. 253 ;; Apply callback.
253 (when (and action 254 (when (and action
@@ -266,6 +267,9 @@ EVENT is the cadr of the event in `file-notify-handle-event'
266 (and (stringp file1) 267 (and (stringp file1)
267 (string-equal 268 (string-equal
268 (nth 0 entry) (file-name-nondirectory file1))))) 269 (nth 0 entry) (file-name-nondirectory file1)))))
270 ;;(message
271 ;;"file-notify-callback %S %S %S %S %S"
272 ;;(file-notify--descriptor desc file) action file file1 registered)
269 (if file1 273 (if file1
270 (funcall 274 (funcall
271 callback 275 callback
@@ -276,8 +280,7 @@ EVENT is the cadr of the event in `file-notify-handle-event'
276 280
277 ;; Modify `file-notify-descriptors'. 281 ;; Modify `file-notify-descriptors'.
278 (when stopped 282 (when stopped
279 (file-notify--rm-descriptor 283 (file-notify-rm-watch (file-notify--descriptor desc file))))))
280 (file-notify--descriptor desc file) file)))))
281 284
282;; `kqueue', `gfilenotify' and `w32notify' return a unique descriptor 285;; `kqueue', `gfilenotify' and `w32notify' return a unique descriptor
283;; for every `file-notify-add-watch', while `inotify' returns a unique 286;; for every `file-notify-add-watch', while `inotify' returns a unique
@@ -342,7 +345,12 @@ FILE is the name of the file whose event is being reported."
342 ;; A file name handler could exist even if there is no local 345 ;; A file name handler could exist even if there is no local
343 ;; file notification support. 346 ;; file notification support.
344 (setq desc (funcall 347 (setq desc (funcall
345 handler 'file-notify-add-watch file flags callback)) 348 handler 'file-notify-add-watch
349 ;; kqueue does not report file changes in
350 ;; directory monitor. So we must watch the file
351 ;; itself.
352 (if (eq file-notify--library 'kqueue) file dir)
353 flags callback))
346 354
347 ;; Check, whether Emacs has been compiled with file notification 355 ;; Check, whether Emacs has been compiled with file notification
348 ;; support. 356 ;; support.
@@ -379,7 +387,9 @@ FILE is the name of the file whose event is being reported."
379 l-flags))) 387 l-flags)))
380 388
381 ;; Call low-level function. 389 ;; Call low-level function.
382 (setq desc (funcall func file l-flags 'file-notify-callback))) 390 (setq desc (funcall
391 func (if (eq file-notify--library 'kqueue) file dir)
392 l-flags 'file-notify-callback)))
383 393
384 ;; Modify `file-notify-descriptors'. 394 ;; Modify `file-notify-descriptors'.
385 (setq file (unless (file-directory-p file) (file-name-nondirectory file)) 395 (setq file (unless (file-directory-p file) (file-name-nondirectory file))
diff --git a/src/inotify.c b/src/inotify.c
index d1a80bbad1b..6577ee28cd1 100644
--- a/src/inotify.c
+++ b/src/inotify.c
@@ -46,8 +46,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
46static int inotifyfd = -1; 46static int inotifyfd = -1;
47 47
48/* Assoc list of files being watched. 48/* Assoc list of files being watched.
49 Format: 49 Format: (watch-descriptor name callback)
50 (watch-descriptor . callback)
51 */ 50 */
52static Lisp_Object watch_list; 51static Lisp_Object watch_list;
53 52
@@ -106,12 +105,14 @@ inotifyevent_to_event (Lisp_Object watch_object, struct inotify_event const *ev)
106 name = make_unibyte_string (ev->name, min (len, ev->len)); 105 name = make_unibyte_string (ev->name, min (len, ev->len));
107 name = DECODE_FILE (name); 106 name = DECODE_FILE (name);
108 } 107 }
108 else
109 name = XCAR (XCDR (watch_object));
109 110
110 return list2 (list4 (make_watch_descriptor (ev->wd), 111 return list2 (list4 (make_watch_descriptor (ev->wd),
111 mask_to_aspects (ev->mask), 112 mask_to_aspects (ev->mask),
112 name, 113 name,
113 make_number (ev->cookie)), 114 make_number (ev->cookie)),
114 XCDR (watch_object)); 115 Fnth (make_number (2), watch_object));
115} 116}
116 117
117/* This callback is called when the FD is available for read. The inotify 118/* This callback is called when the FD is available for read. The inotify
@@ -325,7 +326,7 @@ is managed internally and there is no corresponding inotify_init. Use
325 watch_list = Fdelete (watch_object, watch_list); 326 watch_list = Fdelete (watch_object, watch_list);
326 327
327 /* Store watch object in watch list. */ 328 /* Store watch object in watch list. */
328 watch_object = Fcons (watch_descriptor, callback); 329 watch_object = list3 (watch_descriptor, encoded_file_name, callback);
329 watch_list = Fcons (watch_object, watch_list); 330 watch_list = Fcons (watch_object, watch_list);
330 331
331 return watch_descriptor; 332 return watch_descriptor;
diff --git a/test/automated/file-notify-tests.el b/test/automated/file-notify-tests.el
index 7bacddd8855..b665dddb631 100644
--- a/test/automated/file-notify-tests.el
+++ b/test/automated/file-notify-tests.el
@@ -65,7 +65,11 @@
65 65
66(defun file-notify--test-timeout () 66(defun file-notify--test-timeout ()
67 "Timeout to wait for arriving events, in seconds." 67 "Timeout to wait for arriving events, in seconds."
68 (if (file-remote-p temporary-file-directory) 6 3)) 68 (cond
69 ((file-remote-p temporary-file-directory) 6)
70 ((string-equal (file-notify--test-library) "w32notify") 20)
71 ((eq system-type 'cygwin) 10)
72 (t 3)))
69 73
70(defun file-notify--test-cleanup () 74(defun file-notify--test-cleanup ()
71 "Cleanup after a test." 75 "Cleanup after a test."
@@ -262,7 +266,7 @@ and the event to `file-notify--test-events'."
262 (let* ((file-notify--test-event event) 266 (let* ((file-notify--test-event event)
263 (result 267 (result
264 (ert-run-test (make-ert-test :body 'file-notify--test-event-test)))) 268 (ert-run-test (make-ert-test :body 'file-notify--test-event-test))))
265 ;; Do not add temporary files, this would confuse the checks. 269 ;; Do not add lock files, this would confuse the checks.
266 (unless (string-match 270 (unless (string-match
267 (regexp-quote ".#") 271 (regexp-quote ".#")
268 (file-notify--event-file-name file-notify--test-event)) 272 (file-notify--event-file-name file-notify--test-event))
@@ -289,9 +293,14 @@ TIMEOUT is the maximum time to wait for, in seconds."
289Don't wait longer than timeout seconds for the events to be delivered." 293Don't wait longer than timeout seconds for the events to be delivered."
290 (declare (indent 1)) 294 (declare (indent 1))
291 (let ((outer (make-symbol "outer"))) 295 (let ((outer (make-symbol "outer")))
292 `(let ((,outer file-notify--test-events)) 296 `(let ((,outer file-notify--test-events)
297 create-lockfiles)
293 (setq file-notify--test-expected-events 298 (setq file-notify--test-expected-events
294 (append file-notify--test-expected-events ,events)) 299 (append file-notify--test-expected-events ,events))
300 ;; Flush pending events.
301 (file-notify--wait-for-events
302 (file-notify--test-timeout)
303 (input-pending-p))
295 (let (file-notify--test-events) 304 (let (file-notify--test-events)
296 ,@body 305 ,@body
297 (file-notify--wait-for-events 306 (file-notify--wait-for-events
@@ -305,11 +314,34 @@ Don't wait longer than timeout seconds for the events to be delivered."
305(ert-deftest file-notify-test02-events () 314(ert-deftest file-notify-test02-events ()
306 "Check file creation/change/removal notifications." 315 "Check file creation/change/removal notifications."
307 (skip-unless (file-notify--test-local-enabled)) 316 (skip-unless (file-notify--test-local-enabled))
308 ;; Under cygwin there are so bad timings that it doesn't make sense to test.
309 (skip-unless (not (eq system-type 'cygwin)))
310 317
311 (unwind-protect 318 (unwind-protect
312 (progn 319 (progn
320 ;; Check file creation, change and deletion. It doesn't work
321 ;; for cygwin and kqueue, because we don't use an implicit
322 ;; directory monitor (kqueue), or the timings are too bad (cygwin).
323 (unless (or (eq system-type 'cygwin)
324 (string-equal (file-notify--test-library) "kqueue"))
325 (setq file-notify--test-tmpfile (file-notify--test-make-temp-name))
326 (should
327 (setq file-notify--test-desc
328 (file-notify-add-watch
329 file-notify--test-tmpfile
330 '(change) 'file-notify--test-event-handler)))
331 (file-notify--test-with-events
332 (cond
333 ;; cygwin recognizes only `deleted' and `stopped' events.
334 ((eq system-type 'cygwin)
335 '(deleted stopped))
336 (t '(created changed deleted stopped)))
337 (write-region
338 "another text" nil file-notify--test-tmpfile nil 'no-message)
339 (read-event nil nil 0.1)
340 (delete-file file-notify--test-tmpfile))
341 ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it.
342 (let (file-notify--test-events)
343 (file-notify-rm-watch file-notify--test-desc)))
344
313 ;; Check file change and deletion. 345 ;; Check file change and deletion.
314 (setq file-notify--test-tmpfile (file-notify--test-make-temp-name)) 346 (setq file-notify--test-tmpfile (file-notify--test-make-temp-name))
315 (write-region "any text" nil file-notify--test-tmpfile nil 'no-message) 347 (write-region "any text" nil file-notify--test-tmpfile nil 'no-message)
@@ -318,9 +350,23 @@ Don't wait longer than timeout seconds for the events to be delivered."
318 (file-notify-add-watch 350 (file-notify-add-watch
319 file-notify--test-tmpfile 351 file-notify--test-tmpfile
320 '(change) 'file-notify--test-event-handler))) 352 '(change) 'file-notify--test-event-handler)))
321 (file-notify--test-with-events '(changed deleted) 353 (file-notify--test-with-events
354 (cond
355 ;; cygwin recognizes only `deleted' and `stopped' events.
356 ((eq system-type 'cygwin)
357 '(deleted stopped))
358 ;; inotify, kqueueg and gfilenotify raise just one
359 ;; `changed' event, the other backends show us two of
360 ;; them.
361 ((or (string-equal "inotify" (file-notify--test-library))
362 (string-equal "kqueue" (file-notify--test-library))
363 (string-equal "gfilenotify" (file-notify--test-library)))
364 '(changed deleted stopped))
365 (t '(changed changed deleted stopped)))
366 (read-event nil nil 0.1)
322 (write-region 367 (write-region
323 "another text" nil file-notify--test-tmpfile nil 'no-message) 368 "another text" nil file-notify--test-tmpfile nil 'no-message)
369 (read-event nil nil 0.1)
324 (delete-file file-notify--test-tmpfile)) 370 (delete-file file-notify--test-tmpfile))
325 ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it. 371 ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it.
326 (let (file-notify--test-events) 372 (let (file-notify--test-events)
@@ -328,29 +374,37 @@ Don't wait longer than timeout seconds for the events to be delivered."
328 374
329 ;; Check file creation, change and deletion when watching a 375 ;; Check file creation, change and deletion when watching a
330 ;; directory. There must be a `stopped' event when deleting 376 ;; directory. There must be a `stopped' event when deleting
331 ;; the directory. It doesn't work for w32notify. 377 ;; the directory.
332 (unless (string-equal (file-notify--test-library) "w32notify") 378 (let ((temporary-file-directory
333 (let ((temporary-file-directory 379 (make-temp-file "file-notify-test-parent" t)))
334 (make-temp-file "file-notify-test-parent" t))) 380 (should
335 (should 381 (setq file-notify--test-tmpfile (file-notify--test-make-temp-name)
336 (setq file-notify--test-tmpfile (file-notify--test-make-temp-name) 382 file-notify--test-desc
337 file-notify--test-desc 383 (file-notify-add-watch
338 (file-notify-add-watch 384 temporary-file-directory
339 temporary-file-directory 385 '(change) 'file-notify--test-event-handler)))
340 '(change) 'file-notify--test-event-handler))) 386 (file-notify--test-with-events
341 (file-notify--test-with-events 387 (cond
342 ;; There are two `deleted' events, for the file and 388 ;; w32notify does raise a `stopped' event when a
343 ;; for the directory. Except for kqueue. 389 ;; watched directory is deleted.
344 (if (string-equal (file-notify--test-library) "kqueue") 390 ((string-equal (file-notify--test-library) "w32notify")
345 '(created changed deleted stopped) 391 '(created changed deleted))
346 '(created changed deleted deleted stopped)) 392 ;; cygwin recognizes only `deleted' and `stopped' events.
347 (write-region 393 ((eq system-type 'cygwin)
348 "any text" nil file-notify--test-tmpfile nil 'no-message) 394 '(deleted stopped))
349 (read-event nil nil 0.1) 395 ;; There are two `deleted' events, for the file and for
350 (delete-directory temporary-file-directory 'recursive)) 396 ;; the directory. Except for kqueue.
351 ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it. 397 ((string-equal (file-notify--test-library) "kqueue")
352 (let (file-notify--test-events) 398 '(created changed deleted stopped))
353 (file-notify-rm-watch file-notify--test-desc)))) 399 (t '(created changed deleted deleted stopped)))
400 (read-event nil nil 0.1)
401 (write-region
402 "any text" nil file-notify--test-tmpfile nil 'no-message)
403 (read-event nil nil 0.1)
404 (delete-directory temporary-file-directory 'recursive))
405 ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it.
406 (let (file-notify--test-events)
407 (file-notify-rm-watch file-notify--test-desc)))
354 408
355 ;; Check copy of files inside a directory. 409 ;; Check copy of files inside a directory.
356 (let ((temporary-file-directory 410 (let ((temporary-file-directory
@@ -363,11 +417,22 @@ Don't wait longer than timeout seconds for the events to be delivered."
363 temporary-file-directory 417 temporary-file-directory
364 '(change) 'file-notify--test-event-handler))) 418 '(change) 'file-notify--test-event-handler)))
365 (file-notify--test-with-events 419 (file-notify--test-with-events
366 ;; w32notify does not distinguish between `changed' and 420 (cond
367 ;; `attribute-changed'. 421 ;; w32notify does not distinguish between `changed' and
368 (if (string-equal (file-notify--test-library) "w32notify") 422 ;; `attribute-changed'.
369 '(created changed changed deleted) 423 ((string-equal (file-notify--test-library) "w32notify")
424 '(created changed created changed changed changed changed
425 deleted deleted))
426 ;; cygwin recognizes only `deleted' and `stopped' events.
427 ((eq system-type 'cygwin)
428 '(deleted stopped))
429 ;; There are three `deleted' events, for two files and
430 ;; for the directory. Except for kqueue.
431 ((string-equal (file-notify--test-library) "kqueue")
370 '(created changed created changed deleted stopped)) 432 '(created changed created changed deleted stopped))
433 (t '(created changed created changed
434 deleted deleted deleted stopped)))
435 (read-event nil nil 0.1)
371 (write-region 436 (write-region
372 "any text" nil file-notify--test-tmpfile nil 'no-message) 437 "any text" nil file-notify--test-tmpfile nil 'no-message)
373 (read-event nil nil 0.1) 438 (read-event nil nil 0.1)
@@ -393,7 +458,21 @@ Don't wait longer than timeout seconds for the events to be delivered."
393 (file-notify-add-watch 458 (file-notify-add-watch
394 temporary-file-directory 459 temporary-file-directory
395 '(change) 'file-notify--test-event-handler))) 460 '(change) 'file-notify--test-event-handler)))
396 (file-notify--test-with-events '(created changed renamed) 461 (file-notify--test-with-events
462 (cond
463 ;; w32notify does not distinguish between `changed' and
464 ;; `attribute-changed'.
465 ((string-equal (file-notify--test-library) "w32notify")
466 '(created changed renamed deleted))
467 ;; cygwin recognizes only `deleted' and `stopped' events.
468 ((eq system-type 'cygwin)
469 '(deleted stopped))
470 ;; There are two `deleted' events, for the file and for
471 ;; the directory. Except for kqueue.
472 ((string-equal (file-notify--test-library) "kqueue")
473 '(created changed renamed deleted stopped))
474 (t '(created changed renamed deleted deleted stopped)))
475 (read-event nil nil 0.1)
397 (write-region 476 (write-region
398 "any text" nil file-notify--test-tmpfile nil 'no-message) 477 "any text" nil file-notify--test-tmpfile nil 'no-message)
399 (read-event nil nil 0.1) 478 (read-event nil nil 0.1)
@@ -405,30 +484,37 @@ Don't wait longer than timeout seconds for the events to be delivered."
405 (let (file-notify--test-events) 484 (let (file-notify--test-events)
406 (file-notify-rm-watch file-notify--test-desc))) 485 (file-notify-rm-watch file-notify--test-desc)))
407 486
408 ;; Check attribute change. It doesn't work for kqueue and w32notify. 487 ;; Check attribute change. Does not work for cygwin.
409 (unless (or (string-equal (file-notify--test-library) "kqueue") 488 (unless (eq system-type 'cygwin)
410 (string-equal (file-notify--test-library) "w32notify")) 489 (setq file-notify--test-tmpfile (file-notify--test-make-temp-name))
490 (write-region
491 "any text" nil file-notify--test-tmpfile nil 'no-message)
411 (should 492 (should
412 (setq file-notify--test-desc 493 (setq file-notify--test-desc
413 (file-notify-add-watch 494 (file-notify-add-watch
414 file-notify--test-tmpfile 495 file-notify--test-tmpfile
415 '(attribute-change) 'file-notify--test-event-handler))) 496 '(attribute-change) 'file-notify--test-event-handler)))
416 (file-notify--test-with-events 497 (file-notify--test-with-events
417 (if (file-remote-p temporary-file-directory) 498 (cond
418 ;; In the remote case, `write-region' raises also an 499 ;; w32notify does not distinguish between `changed' and
419 ;; `attribute-changed' event. 500 ;; `attribute-changed'.
420 '(attribute-changed attribute-changed attribute-changed) 501 ((string-equal (file-notify--test-library) "w32notify")
421 '(attribute-changed attribute-changed)) 502 '(changed changed changed changed))
422 ;; We must use short delays between the operations. 503 ;; For kqueue and in the remote case, `write-region'
423 ;; Otherwise, not all events arrive us in the remote case. 504 ;; raises also an `attribute-changed' event.
424 (write-region 505 ((or (string-equal (file-notify--test-library) "kqueue")
425 "any text" nil file-notify--test-tmpfile nil 'no-message) 506 (file-remote-p temporary-file-directory))
426 (read-event nil nil 0.1) 507 '(attribute-changed attribute-changed attribute-changed))
427 (set-file-modes file-notify--test-tmpfile 000) 508 (t '(attribute-changed attribute-changed)))
428 (read-event nil nil 0.1) 509 (read-event nil nil 0.1)
429 (set-file-times file-notify--test-tmpfile '(0 0)) 510 (write-region
430 (read-event nil nil 0.1) 511 "any text" nil file-notify--test-tmpfile nil 'no-message)
431 (delete-file file-notify--test-tmpfile)) 512 (read-event nil nil 0.1)
513 (set-file-modes file-notify--test-tmpfile 000)
514 (read-event nil nil 0.1)
515 (set-file-times file-notify--test-tmpfile '(0 0))
516 (read-event nil nil 0.1)
517 (delete-file file-notify--test-tmpfile))
432 ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it. 518 ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it.
433 (let (file-notify--test-events) 519 (let (file-notify--test-events)
434 (file-notify-rm-watch file-notify--test-desc))) 520 (file-notify-rm-watch file-notify--test-desc)))
@@ -504,28 +590,31 @@ Don't wait longer than timeout seconds for the events to be delivered."
504 (should (string-match "another text" (buffer-string))) 590 (should (string-match "another text" (buffer-string)))
505 591
506 ;; Stop file notification. Autorevert shall still work via polling. 592 ;; Stop file notification. Autorevert shall still work via polling.
507 (file-notify-rm-watch auto-revert-notify-watch-descriptor) 593 ;; It doesn't work for `w32notify'.
508 (file-notify--wait-for-events 594 (unless (string-equal (file-notify--test-library) "w32notify")
509 timeout (null auto-revert-use-notify)) 595 (file-notify-rm-watch auto-revert-notify-watch-descriptor)
510 (should-not auto-revert-use-notify)
511 (should-not auto-revert-notify-watch-descriptor)
512
513 ;; Modify file. We wait for two seconds, in order to have
514 ;; another timestamp. One second seems to be too short.
515 (with-current-buffer (get-buffer-create "*Messages*")
516 (narrow-to-region (point-max) (point-max)))
517 (sleep-for 2)
518 (write-region
519 "foo bla" nil file-notify--test-tmpfile nil 'no-message)
520
521 ;; Check, that the buffer has been reverted.
522 (with-current-buffer (get-buffer-create "*Messages*")
523 (file-notify--wait-for-events 596 (file-notify--wait-for-events
524 timeout 597 timeout (null auto-revert-use-notify))
525 (string-match 598 (should-not auto-revert-use-notify)
526 (format-message "Reverting buffer `%s'." (buffer-name buf)) 599 (should-not auto-revert-notify-watch-descriptor)
527 (buffer-string)))) 600
528 (should (string-match "foo bla" (buffer-string))))) 601 ;; Modify file. We wait for two seconds, in order to
602 ;; have another timestamp. One second seems to be too
603 ;; short.
604 (with-current-buffer (get-buffer-create "*Messages*")
605 (narrow-to-region (point-max) (point-max)))
606 (sleep-for 2)
607 (write-region
608 "foo bla" nil file-notify--test-tmpfile nil 'no-message)
609
610 ;; Check, that the buffer has been reverted.
611 (with-current-buffer (get-buffer-create "*Messages*")
612 (file-notify--wait-for-events
613 timeout
614 (string-match
615 (format-message "Reverting buffer `%s'." (buffer-name buf))
616 (buffer-string))))
617 (should (string-match "foo bla" (buffer-string))))))
529 618
530 ;; Cleanup. 619 ;; Cleanup.
531 (with-current-buffer "*Messages*" (widen)) 620 (with-current-buffer "*Messages*" (widen))
@@ -538,8 +627,6 @@ Don't wait longer than timeout seconds for the events to be delivered."
538(ert-deftest file-notify-test04-file-validity () 627(ert-deftest file-notify-test04-file-validity ()
539 "Check `file-notify-valid-p' for files." 628 "Check `file-notify-valid-p' for files."
540 (skip-unless (file-notify--test-local-enabled)) 629 (skip-unless (file-notify--test-local-enabled))
541 ;; Under cygwin there are so bad timings that it doesn't make sense to test.
542 (skip-unless (not (eq system-type 'cygwin)))
543 630
544 (unwind-protect 631 (unwind-protect
545 (progn 632 (progn
@@ -569,7 +656,20 @@ Don't wait longer than timeout seconds for the events to be delivered."
569 (file-notify-add-watch 656 (file-notify-add-watch
570 file-notify--test-tmpfile 657 file-notify--test-tmpfile
571 '(change) #'file-notify--test-event-handler))) 658 '(change) #'file-notify--test-event-handler)))
572 (file-notify--test-with-events '(changed deleted) 659 (file-notify--test-with-events
660 (cond
661 ;; cygwin recognizes only `deleted' and `stopped' events.
662 ((eq system-type 'cygwin)
663 '(deleted stopped))
664 ;; inotify, kqueueg and gfilenotify raise just one
665 ;; `changed' event, the other backends show us two of
666 ;; them.
667 ((or (string-equal "inotify" (file-notify--test-library))
668 (string-equal "kqueue" (file-notify--test-library))
669 (string-equal "gfilenotify" (file-notify--test-library)))
670 '(changed deleted stopped))
671 (t '(changed changed deleted stopped)))
672 (read-event nil nil 0.1)
573 (should (file-notify-valid-p file-notify--test-desc)) 673 (should (file-notify-valid-p file-notify--test-desc))
574 (write-region 674 (write-region
575 "another text" nil file-notify--test-tmpfile nil 'no-message) 675 "another text" nil file-notify--test-tmpfile nil 'no-message)
@@ -583,10 +683,10 @@ Don't wait longer than timeout seconds for the events to be delivered."
583 (file-notify--test-cleanup)) 683 (file-notify--test-cleanup))
584 684
585 (unwind-protect 685 (unwind-protect
586 ;; The batch-mode operation of w32notify is fragile (there's no 686 ;; w32notify does not send a `stopped' event when deleting a
587 ;; input threads to send the message to). 687 ;; directory. The test does not work, therefore.
588 (unless (string-equal (file-notify--test-library) "w32notify") 688 (unless (string-equal (file-notify--test-library) "w32notify")
589 (let ((temporary-file-directory 689 (let ((temporary-file-directory
590 (make-temp-file "file-notify-test-parent" t))) 690 (make-temp-file "file-notify-test-parent" t)))
591 (should 691 (should
592 (setq file-notify--test-tmpfile (file-notify--test-make-temp-name) 692 (setq file-notify--test-tmpfile (file-notify--test-make-temp-name)
@@ -594,20 +694,25 @@ Don't wait longer than timeout seconds for the events to be delivered."
594 (file-notify-add-watch 694 (file-notify-add-watch
595 temporary-file-directory 695 temporary-file-directory
596 '(change) #'file-notify--test-event-handler))) 696 '(change) #'file-notify--test-event-handler)))
597 (file-notify--test-with-events 697 (file-notify--test-with-events
598 ;; There are two `deleted' events, for the file and for 698 (cond
599 ;; the directory. Except for kqueue. 699 ;; cygwin recognizes only `deleted' and `stopped' events.
600 (if (string-equal (file-notify--test-library) "kqueue") 700 ((eq system-type 'cygwin)
601 '(created changed deleted stopped) 701 '(deleted stopped))
602 '(created changed deleted deleted stopped)) 702 ;; There are two `deleted' events, for the file and for
603 (should (file-notify-valid-p file-notify--test-desc)) 703 ;; the directory. Except for kqueue.
604 (write-region 704 ((string-equal (file-notify--test-library) "kqueue")
605 "any text" nil file-notify--test-tmpfile nil 'no-message) 705 '(created changed deleted stopped))
606 (read-event nil nil 0.1) 706 (t '(created changed deleted deleted stopped)))
707 (should (file-notify-valid-p file-notify--test-desc))
708 (read-event nil nil 0.1)
709 (write-region
710 "any text" nil file-notify--test-tmpfile nil 'no-message)
711 (read-event nil nil 0.1)
607 (delete-directory temporary-file-directory t)) 712 (delete-directory temporary-file-directory t))
608 ;; After deleting the parent directory, the descriptor must 713 ;; After deleting the parent directory, the descriptor must
609 ;; not be valid anymore. 714 ;; not be valid anymore.
610 (should-not (file-notify-valid-p file-notify--test-desc)))) 715 (should-not (file-notify-valid-p file-notify--test-desc))))
611 716
612 ;; Cleanup. 717 ;; Cleanup.
613 (file-notify--test-cleanup))) 718 (file-notify--test-cleanup)))
@@ -659,7 +764,7 @@ Don't wait longer than timeout seconds for the events to be delivered."
659 ;; valid anymore. 764 ;; valid anymore.
660 (delete-directory file-notify--test-tmpfile t) 765 (delete-directory file-notify--test-tmpfile t)
661 (file-notify--wait-for-events 766 (file-notify--wait-for-events
662 (file-notify--test-timeout) 767 (file-notify--test-timeout)
663 (not (file-notify-valid-p file-notify--test-desc))) 768 (not (file-notify-valid-p file-notify--test-desc)))
664 (should-not (file-notify-valid-p file-notify--test-desc))) 769 (should-not (file-notify-valid-p file-notify--test-desc)))
665 770
@@ -672,8 +777,9 @@ Don't wait longer than timeout seconds for the events to be delivered."
672(ert-deftest file-notify-test06-many-events () 777(ert-deftest file-notify-test06-many-events ()
673 "Check that events are not dropped." 778 "Check that events are not dropped."
674 (skip-unless (file-notify--test-local-enabled)) 779 (skip-unless (file-notify--test-local-enabled))
675 ;; Under cygwin there are so bad timings that it doesn't make sense to test. 780 ;; Under cygwin events arrive in random order. Impossible to define a test.
676 (skip-unless (not (eq system-type 'cygwin))) 781 (skip-unless (not (eq system-type 'cygwin)))
782
677 (setq file-notify--test-tmpfile (file-notify--test-make-temp-name)) 783 (setq file-notify--test-tmpfile (file-notify--test-make-temp-name))
678 (make-directory file-notify--test-tmpfile) 784 (make-directory file-notify--test-tmpfile)
679 (should 785 (should
@@ -699,10 +805,18 @@ Don't wait longer than timeout seconds for the events to be delivered."
699 (let ((source-file-list source-file-list) 805 (let ((source-file-list source-file-list)
700 (target-file-list target-file-list)) 806 (target-file-list target-file-list))
701 (while (and source-file-list target-file-list) 807 (while (and source-file-list target-file-list)
808 (read-event nil nil 0.1)
702 (write-region "" nil (pop source-file-list) nil 'no-message) 809 (write-region "" nil (pop source-file-list) nil 'no-message)
703 (read-event nil nil 0.1) 810 (read-event nil nil 0.1)
704 (write-region "" nil (pop target-file-list) nil 'no-message)))) 811 (write-region "" nil (pop target-file-list) nil 'no-message))))
705 (file-notify--test-with-events (make-list n 'renamed) 812 (file-notify--test-with-events
813 (cond
814 ;; w32notify fires both `deleted' and `renamed' events.
815 ((string-equal (file-notify--test-library) "w32notify")
816 (let (r)
817 (dotimes (i n r)
818 (setq r (append '(deleted renamed) r)))))
819 (t (make-list n 'renamed)))
706 (let ((source-file-list source-file-list) 820 (let ((source-file-list source-file-list)
707 (target-file-list target-file-list)) 821 (target-file-list target-file-list))
708 (while (and source-file-list target-file-list) 822 (while (and source-file-list target-file-list)
@@ -725,7 +839,7 @@ Don't wait longer than timeout seconds for the events to be delivered."
725;; TODO: 839;; TODO:
726 840
727;; * For w32notify, no stopped events arrive when a directory is removed. 841;; * For w32notify, no stopped events arrive when a directory is removed.
728;; * Try to handle arriving events under cygwin reliably. 842;; * Check, why cygwin recognizes only `deleted' and `stopped' events.
729 843
730(provide 'file-notify-tests) 844(provide 'file-notify-tests)
731;;; file-notify-tests.el ends here 845;;; file-notify-tests.el ends here