aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Albinus2016-02-07 19:30:01 +0100
committerMichael Albinus2016-02-07 19:30:01 +0100
commitd5a10aefee22cf1d092edad26c845e049ab8861c (patch)
tree14156a9156b1a3409cab4d24579b5f84892c7012
parent67fcd5addcd91169f79dc5d51d0a71eb2b486aed (diff)
downloademacs-d5a10aefee22cf1d092edad26c845e049ab8861c.tar.gz
emacs-d5a10aefee22cf1d092edad26c845e049ab8861c.zip
Fix Bug#22557
* lisp/filenotify.el (file-notify-callback): Do not send a `stopped' event in case of backup by renaming. (Bug#22557) * test/automated/Makefile.in: Use $(SELECTOR_EXPENSIVE) for all targets but check and check-maybe. * test/automated/file-notify-tests.el (file-notify--test-read-event-timeout): New defconst. (file-notify--deftest-remote, file-notify--wait-for-events) (file-notify-test02-events) (file-notify-test04-file-validity) (file-notify-test06-many-events): Use it. (file-notify--test-cleanup): Make it more robust. Delete also backup file. (file-notify-test07-backup): New test.
-rw-r--r--lisp/filenotify.el4
-rw-r--r--test/automated/Makefile.in8
-rw-r--r--test/automated/file-notify-tests.el140
3 files changed, 116 insertions, 36 deletions
diff --git a/lisp/filenotify.el b/lisp/filenotify.el
index faa801ee6e7..66e7fd7a315 100644
--- a/lisp/filenotify.el
+++ b/lisp/filenotify.el
@@ -242,10 +242,14 @@ EVENT is the cadr of the event in `file-notify-handle-event'
242 (and 242 (and
243 (memq action '(deleted renamed)) 243 (memq action '(deleted renamed))
244 (= (length (cdr registered)) 1) 244 (= (length (cdr registered)) 1)
245 ;; Not, when a file is backed up.
246 (not (and (stringp file1) (backup-file-name-p file1)))
245 (or 247 (or
248 ;; Watched file or directory is concerned.
246 (string-equal 249 (string-equal
247 (file-name-nondirectory file) 250 (file-name-nondirectory file)
248 (file-name-nondirectory (car registered))) 251 (file-name-nondirectory (car registered)))
252 ;; File inside a watched directory is concerned.
249 (string-equal 253 (string-equal
250 (file-name-nondirectory file) 254 (file-name-nondirectory file)
251 (car (cadr registered))))))) 255 (car (cadr registered)))))))
diff --git a/test/automated/Makefile.in b/test/automated/Makefile.in
index 2534a65a9a3..5074d515499 100644
--- a/test/automated/Makefile.in
+++ b/test/automated/Makefile.in
@@ -89,10 +89,14 @@ WRITE_LOG = > $@ 2>&1 || { stat=ERROR; cat $@; }; echo $$stat: $@
89## Beware: it approximates 'no-byte-compile', so watch out for false-positives! 89## Beware: it approximates 'no-byte-compile', so watch out for false-positives!
90SELECTOR_DEFAULT = (quote (not (tag :expensive-test))) 90SELECTOR_DEFAULT = (quote (not (tag :expensive-test)))
91SELECTOR_EXPENSIVE = nil 91SELECTOR_EXPENSIVE = nil
92ifndef SELECTOR 92ifdef SELECTOR
93SELECTOR_ACTUAL=$(SELECTOR)
94else ifeq ($(MAKECMDGOALS),check)
95SELECTOR_ACTUAL=$(SELECTOR_DEFAULT)
96else ifeq ($(MAKECMDGOALS),check-maybe)
93SELECTOR_ACTUAL=$(SELECTOR_DEFAULT) 97SELECTOR_ACTUAL=$(SELECTOR_DEFAULT)
94else 98else
95SELECTOR_ACTUAL=$(SELECTOR) 99SELECTOR_ACTUAL=$(SELECTOR_EXPENSIVE)
96endif 100endif
97 101
98 102
diff --git a/test/automated/file-notify-tests.el b/test/automated/file-notify-tests.el
index 5fc4ff8bf42..4261507f59f 100644
--- a/test/automated/file-notify-tests.el
+++ b/test/automated/file-notify-tests.el
@@ -62,6 +62,10 @@
62(defvar file-notify--test-event nil) 62(defvar file-notify--test-event nil)
63(defvar file-notify--test-events nil) 63(defvar file-notify--test-events nil)
64 64
65(defconst file-notify--test-read-event-timeout 0.02
66 "Timeout for `read-event' calls.
67It is different for local and remote file notification libraries.")
68
65(defun file-notify--test-timeout () 69(defun file-notify--test-timeout ()
66 "Timeout to wait for arriving events, in seconds." 70 "Timeout to wait for arriving events, in seconds."
67 (cond 71 (cond
@@ -74,19 +78,20 @@
74 "Cleanup after a test." 78 "Cleanup after a test."
75 (file-notify-rm-watch file-notify--test-desc) 79 (file-notify-rm-watch file-notify--test-desc)
76 80
77 (when (and file-notify--test-tmpfile 81 (ignore-errors
78 (file-exists-p file-notify--test-tmpfile)) 82 (delete-file (file-newest-backup file-notify--test-tmpfile)))
83 (ignore-errors
79 (if (file-directory-p file-notify--test-tmpfile) 84 (if (file-directory-p file-notify--test-tmpfile)
80 (delete-directory file-notify--test-tmpfile 'recursive) 85 (delete-directory file-notify--test-tmpfile 'recursive)
81 (delete-file file-notify--test-tmpfile))) 86 (delete-file file-notify--test-tmpfile)))
82 (when (and file-notify--test-tmpfile1 87 (ignore-errors
83 (file-exists-p file-notify--test-tmpfile1))
84 (if (file-directory-p file-notify--test-tmpfile1) 88 (if (file-directory-p file-notify--test-tmpfile1)
85 (delete-directory file-notify--test-tmpfile1 'recursive) 89 (delete-directory file-notify--test-tmpfile1 'recursive)
86 (delete-file file-notify--test-tmpfile1))) 90 (delete-file file-notify--test-tmpfile1)))
87 (when (file-remote-p temporary-file-directory) 91 (ignore-errors
88 (tramp-cleanup-connection 92 (when (file-remote-p temporary-file-directory)
89 (tramp-dissect-file-name temporary-file-directory) nil 'keep-password)) 93 (tramp-cleanup-connection
94 (tramp-dissect-file-name temporary-file-directory) nil 'keep-password)))
90 95
91 (setq file-notify--test-tmpfile nil 96 (setq file-notify--test-tmpfile nil
92 file-notify--test-tmpfile1 nil 97 file-notify--test-tmpfile1 nil
@@ -155,6 +160,7 @@ remote host, or nil."
155 :tags '(:expensive-test) 160 :tags '(:expensive-test)
156 (let* ((temporary-file-directory 161 (let* ((temporary-file-directory
157 file-notify-test-remote-temporary-file-directory) 162 file-notify-test-remote-temporary-file-directory)
163 (file-notify--test-read-event-timeout 0.1)
158 (ert-test (ert-get-test ',test))) 164 (ert-test (ert-get-test ',test)))
159 (skip-unless (file-notify--test-remote-enabled)) 165 (skip-unless (file-notify--test-remote-enabled))
160 (tramp-cleanup-connection 166 (tramp-cleanup-connection
@@ -285,7 +291,7 @@ and the event to `file-notify--test-events'."
285TIMEOUT is the maximum time to wait for, in seconds." 291TIMEOUT is the maximum time to wait for, in seconds."
286 `(with-timeout (,timeout (ignore)) 292 `(with-timeout (,timeout (ignore))
287 (while (null ,until) 293 (while (null ,until)
288 (read-event nil nil 0.1)))) 294 (read-event nil nil file-notify--test-read-event-timeout))))
289 295
290(defmacro file-notify--test-with-events (events &rest body) 296(defmacro file-notify--test-with-events (events &rest body)
291 "Run BODY collecting events and then compare with EVENTS. 297 "Run BODY collecting events and then compare with EVENTS.
@@ -342,7 +348,7 @@ longer than timeout seconds for the events to be delivered."
342 (t '(created changed deleted stopped))) 348 (t '(created changed deleted stopped)))
343 (write-region 349 (write-region
344 "another text" nil file-notify--test-tmpfile nil 'no-message) 350 "another text" nil file-notify--test-tmpfile nil 'no-message)
345 (read-event nil nil 0.1) 351 (read-event nil nil file-notify--test-read-event-timeout)
346 (delete-file file-notify--test-tmpfile)) 352 (delete-file file-notify--test-tmpfile))
347 ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it. 353 ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it.
348 (let (file-notify--test-events) 354 (let (file-notify--test-events)
@@ -371,10 +377,10 @@ longer than timeout seconds for the events to be delivered."
371 '((changed deleted stopped) 377 '((changed deleted stopped)
372 (changed changed deleted stopped))) 378 (changed changed deleted stopped)))
373 (t '(changed changed deleted stopped))) 379 (t '(changed changed deleted stopped)))
374 (read-event nil nil 0.1) 380 (read-event nil nil file-notify--test-read-event-timeout)
375 (write-region 381 (write-region
376 "another text" nil file-notify--test-tmpfile nil 'no-message) 382 "another text" nil file-notify--test-tmpfile nil 'no-message)
377 (read-event nil nil 0.1) 383 (read-event nil nil file-notify--test-read-event-timeout)
378 (delete-file file-notify--test-tmpfile)) 384 (delete-file file-notify--test-tmpfile))
379 ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it. 385 ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it.
380 (let (file-notify--test-events) 386 (let (file-notify--test-events)
@@ -405,10 +411,10 @@ longer than timeout seconds for the events to be delivered."
405 ((string-equal (file-notify--test-library) "kqueue") 411 ((string-equal (file-notify--test-library) "kqueue")
406 '(created changed deleted stopped)) 412 '(created changed deleted stopped))
407 (t '(created changed deleted deleted stopped))) 413 (t '(created changed deleted deleted stopped)))
408 (read-event nil nil 0.1) 414 (read-event nil nil file-notify--test-read-event-timeout)
409 (write-region 415 (write-region
410 "any text" nil file-notify--test-tmpfile nil 'no-message) 416 "any text" nil file-notify--test-tmpfile nil 'no-message)
411 (read-event nil nil 0.1) 417 (read-event nil nil file-notify--test-read-event-timeout)
412 (delete-directory temporary-file-directory 'recursive)) 418 (delete-directory temporary-file-directory 'recursive))
413 ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it. 419 ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it.
414 (let (file-notify--test-events) 420 (let (file-notify--test-events)
@@ -440,17 +446,17 @@ longer than timeout seconds for the events to be delivered."
440 '(created changed created changed deleted stopped)) 446 '(created changed created changed deleted stopped))
441 (t '(created changed created changed 447 (t '(created changed created changed
442 deleted deleted deleted stopped))) 448 deleted deleted deleted stopped)))
443 (read-event nil nil 0.1) 449 (read-event nil nil file-notify--test-read-event-timeout)
444 (write-region 450 (write-region
445 "any text" nil file-notify--test-tmpfile nil 'no-message) 451 "any text" nil file-notify--test-tmpfile nil 'no-message)
446 (read-event nil nil 0.1) 452 (read-event nil nil file-notify--test-read-event-timeout)
447 (copy-file file-notify--test-tmpfile file-notify--test-tmpfile1) 453 (copy-file file-notify--test-tmpfile file-notify--test-tmpfile1)
448 ;; The next two events shall not be visible. 454 ;; The next two events shall not be visible.
449 (read-event nil nil 0.1) 455 (read-event nil nil file-notify--test-read-event-timeout)
450 (set-file-modes file-notify--test-tmpfile 000) 456 (set-file-modes file-notify--test-tmpfile 000)
451 (read-event nil nil 0.1) 457 (read-event nil nil file-notify--test-read-event-timeout)
452 (set-file-times file-notify--test-tmpfile '(0 0)) 458 (set-file-times file-notify--test-tmpfile '(0 0))
453 (read-event nil nil 0.1) 459 (read-event nil nil file-notify--test-read-event-timeout)
454 (delete-directory temporary-file-directory 'recursive)) 460 (delete-directory temporary-file-directory 'recursive))
455 ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it. 461 ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it.
456 (let (file-notify--test-events) 462 (let (file-notify--test-events)
@@ -480,13 +486,13 @@ longer than timeout seconds for the events to be delivered."
480 ((string-equal (file-notify--test-library) "kqueue") 486 ((string-equal (file-notify--test-library) "kqueue")
481 '(created changed renamed deleted stopped)) 487 '(created changed renamed deleted stopped))
482 (t '(created changed renamed deleted deleted stopped))) 488 (t '(created changed renamed deleted deleted stopped)))
483 (read-event nil nil 0.1) 489 (read-event nil nil file-notify--test-read-event-timeout)
484 (write-region 490 (write-region
485 "any text" nil file-notify--test-tmpfile nil 'no-message) 491 "any text" nil file-notify--test-tmpfile nil 'no-message)
486 (read-event nil nil 0.1) 492 (read-event nil nil file-notify--test-read-event-timeout)
487 (rename-file file-notify--test-tmpfile file-notify--test-tmpfile1) 493 (rename-file file-notify--test-tmpfile file-notify--test-tmpfile1)
488 ;; After the rename, we won't get events anymore. 494 ;; After the rename, we won't get events anymore.
489 (read-event nil nil 0.1) 495 (read-event nil nil file-notify--test-read-event-timeout)
490 (delete-directory temporary-file-directory 'recursive)) 496 (delete-directory temporary-file-directory 'recursive))
491 ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it. 497 ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it.
492 (let (file-notify--test-events) 498 (let (file-notify--test-events)
@@ -514,14 +520,14 @@ longer than timeout seconds for the events to be delivered."
514 (file-remote-p temporary-file-directory)) 520 (file-remote-p temporary-file-directory))
515 '(attribute-changed attribute-changed attribute-changed)) 521 '(attribute-changed attribute-changed attribute-changed))
516 (t '(attribute-changed attribute-changed))) 522 (t '(attribute-changed attribute-changed)))
517 (read-event nil nil 0.1) 523 (read-event nil nil file-notify--test-read-event-timeout)
518 (write-region 524 (write-region
519 "any text" nil file-notify--test-tmpfile nil 'no-message) 525 "any text" nil file-notify--test-tmpfile nil 'no-message)
520 (read-event nil nil 0.1) 526 (read-event nil nil file-notify--test-read-event-timeout)
521 (set-file-modes file-notify--test-tmpfile 000) 527 (set-file-modes file-notify--test-tmpfile 000)
522 (read-event nil nil 0.1) 528 (read-event nil nil file-notify--test-read-event-timeout)
523 (set-file-times file-notify--test-tmpfile '(0 0)) 529 (set-file-times file-notify--test-tmpfile '(0 0))
524 (read-event nil nil 0.1) 530 (read-event nil nil file-notify--test-read-event-timeout)
525 (delete-file file-notify--test-tmpfile)) 531 (delete-file file-notify--test-tmpfile))
526 ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it. 532 ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it.
527 (let (file-notify--test-events) 533 (let (file-notify--test-events)
@@ -678,10 +684,10 @@ longer than timeout seconds for the events to be delivered."
678 (changed changed deleted stopped))) 684 (changed changed deleted stopped)))
679 (t '(changed changed deleted stopped))) 685 (t '(changed changed deleted stopped)))
680 (should (file-notify-valid-p file-notify--test-desc)) 686 (should (file-notify-valid-p file-notify--test-desc))
681 (read-event nil nil 0.1) 687 (read-event nil nil file-notify--test-read-event-timeout)
682 (write-region 688 (write-region
683 "another text" nil file-notify--test-tmpfile nil 'no-message) 689 "another text" nil file-notify--test-tmpfile nil 'no-message)
684 (read-event nil nil 0.1) 690 (read-event nil nil file-notify--test-read-event-timeout)
685 (delete-file file-notify--test-tmpfile)) 691 (delete-file file-notify--test-tmpfile))
686 ;; After deleting the file, the descriptor is not valid anymore. 692 ;; After deleting the file, the descriptor is not valid anymore.
687 (should-not (file-notify-valid-p file-notify--test-desc)) 693 (should-not (file-notify-valid-p file-notify--test-desc))
@@ -713,10 +719,10 @@ longer than timeout seconds for the events to be delivered."
713 '(created changed deleted stopped)) 719 '(created changed deleted stopped))
714 (t '(created changed deleted deleted stopped))) 720 (t '(created changed deleted deleted stopped)))
715 (should (file-notify-valid-p file-notify--test-desc)) 721 (should (file-notify-valid-p file-notify--test-desc))
716 (read-event nil nil 0.1) 722 (read-event nil nil file-notify--test-read-event-timeout)
717 (write-region 723 (write-region
718 "any text" nil file-notify--test-tmpfile nil 'no-message) 724 "any text" nil file-notify--test-tmpfile nil 'no-message)
719 (read-event nil nil 0.1) 725 (read-event nil nil file-notify--test-read-event-timeout)
720 (delete-directory temporary-file-directory t)) 726 (delete-directory temporary-file-directory t))
721 ;; After deleting the parent directory, the descriptor must 727 ;; After deleting the parent directory, the descriptor must
722 ;; not be valid anymore. 728 ;; not be valid anymore.
@@ -814,9 +820,9 @@ longer than timeout seconds for the events to be delivered."
814 (let ((source-file-list source-file-list) 820 (let ((source-file-list source-file-list)
815 (target-file-list target-file-list)) 821 (target-file-list target-file-list))
816 (while (and source-file-list target-file-list) 822 (while (and source-file-list target-file-list)
817 (read-event nil nil 0.1) 823 (read-event nil nil file-notify--test-read-event-timeout)
818 (write-region "" nil (pop source-file-list) nil 'no-message) 824 (write-region "" nil (pop source-file-list) nil 'no-message)
819 (read-event nil nil 0.1) 825 (read-event nil nil file-notify--test-read-event-timeout)
820 (write-region "" nil (pop target-file-list) nil 'no-message)))) 826 (write-region "" nil (pop target-file-list) nil 'no-message))))
821 (file-notify--test-with-events 827 (file-notify--test-with-events
822 (cond 828 (cond
@@ -829,16 +835,82 @@ longer than timeout seconds for the events to be delivered."
829 (let ((source-file-list source-file-list) 835 (let ((source-file-list source-file-list)
830 (target-file-list target-file-list)) 836 (target-file-list target-file-list))
831 (while (and source-file-list target-file-list) 837 (while (and source-file-list target-file-list)
832 (rename-file (pop source-file-list) (pop target-file-list) t) 838 (read-event nil nil file-notify--test-read-event-timeout)
833 (read-event nil nil 0.02)))) 839 (rename-file (pop source-file-list) (pop target-file-list) t))))
834 (file-notify--test-with-events (make-list n 'deleted) 840 (file-notify--test-with-events (make-list n 'deleted)
835 (dolist (file target-file-list) 841 (dolist (file target-file-list)
836 (prog1 (delete-file file) (read-event nil nil 0.02))))) 842 (read-event nil nil file-notify--test-read-event-timeout)
843 (delete-file file) file-notify--test-read-event-timeout)))
844
845 ;; Cleanup.
837 (file-notify--test-cleanup))) 846 (file-notify--test-cleanup)))
838 847
839(file-notify--deftest-remote file-notify-test06-many-events 848(file-notify--deftest-remote file-notify-test06-many-events
840 "Check that events are not dropped for remote directories.") 849 "Check that events are not dropped for remote directories.")
841 850
851(ert-deftest file-notify-test07-backup ()
852 "Check that backup keeps file supervision."
853 (skip-unless (file-notify--test-local-enabled))
854
855 (unwind-protect
856 (progn
857 (setq file-notify--test-tmpfile (file-notify--test-make-temp-name))
858 (write-region "any text" nil file-notify--test-tmpfile nil 'no-message)
859 (should
860 (setq file-notify--test-desc
861 (file-notify-add-watch
862 file-notify--test-tmpfile
863 '(change) #'file-notify--test-event-handler)))
864 (should (file-notify-valid-p file-notify--test-desc))
865 (file-notify--test-with-events '(changed)
866 ;; There shouldn't be any problem, because the file is kept.
867 (with-temp-buffer
868 (let ((buffer-file-name file-notify--test-tmpfile)
869 (make-backup-files t)
870 (backup-by-copying t)
871 (kept-new-versions 1)
872 (delete-old-versions t))
873 (insert "another text")
874 (save-buffer))))
875 ;; After saving the buffer, the descriptor is still valid.
876 (should (file-notify-valid-p file-notify--test-desc))
877 (delete-file file-notify--test-tmpfile))
878
879 ;; Cleanup.
880 (file-notify--test-cleanup))
881
882 (unwind-protect
883 (progn
884 (setq file-notify--test-tmpfile (file-notify--test-make-temp-name))
885 (write-region "any text" nil file-notify--test-tmpfile nil 'no-message)
886 (should
887 (setq file-notify--test-desc
888 (file-notify-add-watch
889 file-notify--test-tmpfile
890 '(change) #'file-notify--test-event-handler)))
891 (should (file-notify-valid-p file-notify--test-desc))
892 (file-notify--test-with-events '(renamed created changed)
893 ;; The file is renamed when creating a backup. It shall
894 ;; still be watched.
895 (with-temp-buffer
896 (let ((buffer-file-name file-notify--test-tmpfile)
897 (make-backup-files t)
898 (backup-by-copying nil)
899 (backup-by-copying-when-mismatch nil)
900 (kept-new-versions 1)
901 (delete-old-versions t))
902 (insert "another text")
903 (save-buffer))))
904 ;; After saving the buffer, the descriptor is still valid.
905 (should (file-notify-valid-p file-notify--test-desc))
906 (delete-file file-notify--test-tmpfile))
907
908 ;; Cleanup.
909 (file-notify--test-cleanup)))
910
911(file-notify--deftest-remote file-notify-test07-backup
912 "Check that backup keeps file supervision for remote files.")
913
842(defun file-notify-test-all (&optional interactive) 914(defun file-notify-test-all (&optional interactive)
843 "Run all tests for \\[file-notify]." 915 "Run all tests for \\[file-notify]."
844 (interactive "p") 916 (interactive "p")