diff options
Diffstat (limited to 'test')
| -rw-r--r-- | test/lisp/filenotify-tests.el | 232 |
1 files changed, 175 insertions, 57 deletions
diff --git a/test/lisp/filenotify-tests.el b/test/lisp/filenotify-tests.el index a8521828c0e..a16de7fb058 100644 --- a/test/lisp/filenotify-tests.el +++ b/test/lisp/filenotify-tests.el | |||
| @@ -58,6 +58,8 @@ | |||
| 58 | (defvar file-notify--test-tmpfile nil) | 58 | (defvar file-notify--test-tmpfile nil) |
| 59 | (defvar file-notify--test-tmpfile1 nil) | 59 | (defvar file-notify--test-tmpfile1 nil) |
| 60 | (defvar file-notify--test-desc nil) | 60 | (defvar file-notify--test-desc nil) |
| 61 | (defvar file-notify--test-desc1 nil) | ||
| 62 | (defvar file-notify--test-desc2 nil) | ||
| 61 | (defvar file-notify--test-results nil) | 63 | (defvar file-notify--test-results nil) |
| 62 | (defvar file-notify--test-event nil) | 64 | (defvar file-notify--test-event nil) |
| 63 | (defvar file-notify--test-events nil) | 65 | (defvar file-notify--test-events nil) |
| @@ -77,6 +79,8 @@ It is different for local and remote file notification libraries.") | |||
| 77 | (defun file-notify--test-cleanup () | 79 | (defun file-notify--test-cleanup () |
| 78 | "Cleanup after a test." | 80 | "Cleanup after a test." |
| 79 | (file-notify-rm-watch file-notify--test-desc) | 81 | (file-notify-rm-watch file-notify--test-desc) |
| 82 | (file-notify-rm-watch file-notify--test-desc1) | ||
| 83 | (file-notify-rm-watch file-notify--test-desc2) | ||
| 80 | 84 | ||
| 81 | (ignore-errors | 85 | (ignore-errors |
| 82 | (delete-file (file-newest-backup file-notify--test-tmpfile))) | 86 | (delete-file (file-newest-backup file-notify--test-tmpfile))) |
| @@ -96,6 +100,8 @@ It is different for local and remote file notification libraries.") | |||
| 96 | (setq file-notify--test-tmpfile nil | 100 | (setq file-notify--test-tmpfile nil |
| 97 | file-notify--test-tmpfile1 nil | 101 | file-notify--test-tmpfile1 nil |
| 98 | file-notify--test-desc nil | 102 | file-notify--test-desc nil |
| 103 | file-notify--test-desc1 nil | ||
| 104 | file-notify--test-desc2 nil | ||
| 99 | file-notify--test-results nil | 105 | file-notify--test-results nil |
| 100 | file-notify--test-events nil) | 106 | file-notify--test-events nil) |
| 101 | (when file-notify--test-event | 107 | (when file-notify--test-event |
| @@ -250,19 +256,15 @@ is bound somewhere." | |||
| 250 | (should (equal (car file-notify--test-event) file-notify--test-desc)) | 256 | (should (equal (car file-notify--test-event) file-notify--test-desc)) |
| 251 | ;; Check the file name. | 257 | ;; Check the file name. |
| 252 | (should | 258 | (should |
| 253 | (or (string-equal (file-notify--event-file-name file-notify--test-event) | 259 | (string-prefix-p |
| 254 | file-notify--test-tmpfile) | 260 | (file-notify--event-watched-file file-notify--test-event) |
| 255 | (string-equal (file-notify--event-file-name file-notify--test-event) | 261 | (file-notify--event-file-name file-notify--test-event))) |
| 256 | file-notify--test-tmpfile1) | ||
| 257 | (string-equal (file-notify--event-file-name file-notify--test-event) | ||
| 258 | temporary-file-directory))) | ||
| 259 | ;; Check the second file name if exists. | 262 | ;; Check the second file name if exists. |
| 260 | (when (eq (nth 1 file-notify--test-event) 'renamed) | 263 | (when (eq (nth 1 file-notify--test-event) 'renamed) |
| 261 | (should | 264 | (should |
| 262 | (or (string-equal (file-notify--event-file1-name file-notify--test-event) | 265 | (string-prefix-p |
| 263 | file-notify--test-tmpfile1) | 266 | (file-notify--event-watched-file file-notify--test-event) |
| 264 | (string-equal (file-notify--event-file1-name file-notify--test-event) | 267 | (file-notify--event-file1-name file-notify--test-event))))) |
| 265 | temporary-file-directory))))) | ||
| 266 | 268 | ||
| 267 | (defun file-notify--test-event-handler (event) | 269 | (defun file-notify--test-event-handler (event) |
| 268 | "Run a test over FILE-NOTIFY--TEST-EVENT. | 270 | "Run a test over FILE-NOTIFY--TEST-EVENT. |
| @@ -275,7 +277,8 @@ and the event to `file-notify--test-events'." | |||
| 275 | (unless (string-match | 277 | (unless (string-match |
| 276 | (regexp-quote ".#") | 278 | (regexp-quote ".#") |
| 277 | (file-notify--event-file-name file-notify--test-event)) | 279 | (file-notify--event-file-name file-notify--test-event)) |
| 278 | ;;(message "file-notify--test-event-handler %S" file-notify--test-event) | 280 | ;;(message "file-notify--test-event-handler result: %s event: %S" |
| 281 | ;;(null (ert-test-failed-p result)) file-notify--test-event) | ||
| 279 | (setq file-notify--test-events | 282 | (setq file-notify--test-events |
| 280 | (append file-notify--test-events `(,file-notify--test-event)) | 283 | (append file-notify--test-events `(,file-notify--test-event)) |
| 281 | file-notify--test-results | 284 | file-notify--test-results |
| @@ -319,25 +322,28 @@ EVENTS is either a simple list of events, or a list of lists of | |||
| 319 | events, which represent different possible results. Don't wait | 322 | events, which represent different possible results. Don't wait |
| 320 | longer than timeout seconds for the events to be delivered." | 323 | longer than timeout seconds for the events to be delivered." |
| 321 | (declare (indent 1)) | 324 | (declare (indent 1)) |
| 322 | (let ((outer (make-symbol "outer"))) | 325 | `(let* ((events (if (consp (car ,events)) ,events (list ,events))) |
| 323 | `(let* ((,outer file-notify--test-events) | 326 | (max-length (apply 'max (mapcar 'length events))) |
| 324 | (events (if (consp (car ,events)) ,events (list ,events))) | 327 | create-lockfiles) |
| 325 | (max-length (apply 'max (mapcar 'length events))) | 328 | ;; Flush pending events. |
| 326 | create-lockfiles) | 329 | (file-notify--wait-for-events |
| 327 | ;; Flush pending events. | 330 | (file-notify--test-timeout) |
| 328 | (file-notify--wait-for-events | 331 | (input-pending-p)) |
| 329 | (file-notify--test-timeout) | 332 | (setq file-notify--test-events nil |
| 330 | (input-pending-p)) | 333 | file-notify--test-results nil) |
| 331 | (let (file-notify--test-events) | 334 | ,@body |
| 332 | ,@body | 335 | (file-notify--wait-for-events |
| 333 | (file-notify--wait-for-events | 336 | ;; More events need more time. Use some fudge factor. |
| 334 | ;; More events need more time. Use some fudge factor. | 337 | (* (ceiling max-length 100) (file-notify--test-timeout)) |
| 335 | (* (ceiling max-length 100) (file-notify--test-timeout)) | 338 | (= max-length (length file-notify--test-events))) |
| 336 | (= max-length (length file-notify--test-events))) | 339 | ;; Check the result sequence just to make sure that all events |
| 337 | ;; One of the possible results shall match. | 340 | ;; are as expected. |
| 338 | (should (file-notify--test-with-events-check events)) | 341 | (dolist (result file-notify--test-results) |
| 339 | (setq ,outer (append ,outer file-notify--test-events))) | 342 | (when (ert-test-failed-p result) |
| 340 | (setq file-notify--test-events ,outer)))) | 343 | (ert-fail |
| 344 | (cadr (ert-test-result-with-condition-condition result))))) | ||
| 345 | ;; One of the possible event sequences shall match. | ||
| 346 | (should (file-notify--test-with-events-check events)))) | ||
| 341 | 347 | ||
| 342 | (ert-deftest file-notify-test02-events () | 348 | (ert-deftest file-notify-test02-events () |
| 343 | "Check file creation/change/removal notifications." | 349 | "Check file creation/change/removal notifications." |
| @@ -366,9 +372,7 @@ longer than timeout seconds for the events to be delivered." | |||
| 366 | "another text" nil file-notify--test-tmpfile nil 'no-message) | 372 | "another text" nil file-notify--test-tmpfile nil 'no-message) |
| 367 | (read-event nil nil file-notify--test-read-event-timeout) | 373 | (read-event nil nil file-notify--test-read-event-timeout) |
| 368 | (delete-file file-notify--test-tmpfile)) | 374 | (delete-file file-notify--test-tmpfile)) |
| 369 | ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it. | 375 | (file-notify-rm-watch file-notify--test-desc)) |
| 370 | (let (file-notify--test-events) | ||
| 371 | (file-notify-rm-watch file-notify--test-desc))) | ||
| 372 | 376 | ||
| 373 | ;; Check file change and deletion. | 377 | ;; Check file change and deletion. |
| 374 | (setq file-notify--test-tmpfile (file-notify--test-make-temp-name)) | 378 | (setq file-notify--test-tmpfile (file-notify--test-make-temp-name)) |
| @@ -398,9 +402,7 @@ longer than timeout seconds for the events to be delivered." | |||
| 398 | "another text" nil file-notify--test-tmpfile nil 'no-message) | 402 | "another text" nil file-notify--test-tmpfile nil 'no-message) |
| 399 | (read-event nil nil file-notify--test-read-event-timeout) | 403 | (read-event nil nil file-notify--test-read-event-timeout) |
| 400 | (delete-file file-notify--test-tmpfile)) | 404 | (delete-file file-notify--test-tmpfile)) |
| 401 | ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it. | 405 | (file-notify-rm-watch file-notify--test-desc) |
| 402 | (let (file-notify--test-events) | ||
| 403 | (file-notify-rm-watch file-notify--test-desc)) | ||
| 404 | 406 | ||
| 405 | ;; Check file creation, change and deletion when watching a | 407 | ;; Check file creation, change and deletion when watching a |
| 406 | ;; directory. There must be a `stopped' event when deleting | 408 | ;; directory. There must be a `stopped' event when deleting |
| @@ -432,9 +434,7 @@ longer than timeout seconds for the events to be delivered." | |||
| 432 | "any text" nil file-notify--test-tmpfile nil 'no-message) | 434 | "any text" nil file-notify--test-tmpfile nil 'no-message) |
| 433 | (read-event nil nil file-notify--test-read-event-timeout) | 435 | (read-event nil nil file-notify--test-read-event-timeout) |
| 434 | (delete-directory temporary-file-directory 'recursive)) | 436 | (delete-directory temporary-file-directory 'recursive)) |
| 435 | ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it. | 437 | (file-notify-rm-watch file-notify--test-desc)) |
| 436 | (let (file-notify--test-events) | ||
| 437 | (file-notify-rm-watch file-notify--test-desc))) | ||
| 438 | 438 | ||
| 439 | ;; Check copy of files inside a directory. | 439 | ;; Check copy of files inside a directory. |
| 440 | (let ((temporary-file-directory | 440 | (let ((temporary-file-directory |
| @@ -474,9 +474,7 @@ longer than timeout seconds for the events to be delivered." | |||
| 474 | (set-file-times file-notify--test-tmpfile '(0 0)) | 474 | (set-file-times file-notify--test-tmpfile '(0 0)) |
| 475 | (read-event nil nil file-notify--test-read-event-timeout) | 475 | (read-event nil nil file-notify--test-read-event-timeout) |
| 476 | (delete-directory temporary-file-directory 'recursive)) | 476 | (delete-directory temporary-file-directory 'recursive)) |
| 477 | ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it. | 477 | (file-notify-rm-watch file-notify--test-desc)) |
| 478 | (let (file-notify--test-events) | ||
| 479 | (file-notify-rm-watch file-notify--test-desc))) | ||
| 480 | 478 | ||
| 481 | ;; Check rename of files inside a directory. | 479 | ;; Check rename of files inside a directory. |
| 482 | (let ((temporary-file-directory | 480 | (let ((temporary-file-directory |
| @@ -510,9 +508,7 @@ longer than timeout seconds for the events to be delivered." | |||
| 510 | ;; After the rename, we won't get events anymore. | 508 | ;; After the rename, we won't get events anymore. |
| 511 | (read-event nil nil file-notify--test-read-event-timeout) | 509 | (read-event nil nil file-notify--test-read-event-timeout) |
| 512 | (delete-directory temporary-file-directory 'recursive)) | 510 | (delete-directory temporary-file-directory 'recursive)) |
| 513 | ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it. | 511 | (file-notify-rm-watch file-notify--test-desc)) |
| 514 | (let (file-notify--test-events) | ||
| 515 | (file-notify-rm-watch file-notify--test-desc))) | ||
| 516 | 512 | ||
| 517 | ;; Check attribute change. Does not work for cygwin. | 513 | ;; Check attribute change. Does not work for cygwin. |
| 518 | (unless (eq system-type 'cygwin) | 514 | (unless (eq system-type 'cygwin) |
| @@ -545,17 +541,7 @@ longer than timeout seconds for the events to be delivered." | |||
| 545 | (set-file-times file-notify--test-tmpfile '(0 0)) | 541 | (set-file-times file-notify--test-tmpfile '(0 0)) |
| 546 | (read-event nil nil file-notify--test-read-event-timeout) | 542 | (read-event nil nil file-notify--test-read-event-timeout) |
| 547 | (delete-file file-notify--test-tmpfile)) | 543 | (delete-file file-notify--test-tmpfile)) |
| 548 | ;; `file-notify-rm-watch' fires the `stopped' event. Suppress it. | 544 | (file-notify-rm-watch file-notify--test-desc))) |
| 549 | (let (file-notify--test-events) | ||
| 550 | (file-notify-rm-watch file-notify--test-desc))) | ||
| 551 | |||
| 552 | ;; Check the global sequence again just to make sure that | ||
| 553 | ;; `file-notify--test-events' has been set correctly. | ||
| 554 | (should file-notify--test-results) | ||
| 555 | (dolist (result file-notify--test-results) | ||
| 556 | (when (ert-test-failed-p result) | ||
| 557 | (ert-fail | ||
| 558 | (cadr (ert-test-result-with-condition-condition result)))))) | ||
| 559 | 545 | ||
| 560 | ;; Cleanup. | 546 | ;; Cleanup. |
| 561 | (file-notify--test-cleanup))) | 547 | (file-notify--test-cleanup))) |
| @@ -825,7 +811,7 @@ longer than timeout seconds for the events to be delivered." | |||
| 825 | (dotimes (i n) | 811 | (dotimes (i n) |
| 826 | ;; It matters which direction we rename, at least for | 812 | ;; It matters which direction we rename, at least for |
| 827 | ;; kqueue. This backend parses directories in alphabetic | 813 | ;; kqueue. This backend parses directories in alphabetic |
| 828 | ;; order (x%d before y%d). So we rename both directions. | 814 | ;; order (x%d before y%d). So we rename into both directions. |
| 829 | (if (zerop (mod i 2)) | 815 | (if (zerop (mod i 2)) |
| 830 | (progn | 816 | (progn |
| 831 | (push (expand-file-name (format "x%d" i)) source-file-list) | 817 | (push (expand-file-name (format "x%d" i)) source-file-list) |
| @@ -885,6 +871,11 @@ longer than timeout seconds for the events to be delivered." | |||
| 885 | ((or (string-equal (file-notify--test-library) "w32notify") | 871 | ((or (string-equal (file-notify--test-library) "w32notify") |
| 886 | (file-remote-p temporary-file-directory)) | 872 | (file-remote-p temporary-file-directory)) |
| 887 | '(changed changed)) | 873 | '(changed changed)) |
| 874 | ;; gfilenotify raises one or two `changed' events | ||
| 875 | ;; randomly, no chance to test. So we accept both cases. | ||
| 876 | ((string-equal "gfilenotify" (file-notify--test-library)) | ||
| 877 | '((changed) | ||
| 878 | (changed changed))) | ||
| 888 | (t '(changed))) | 879 | (t '(changed))) |
| 889 | ;; There shouldn't be any problem, because the file is kept. | 880 | ;; There shouldn't be any problem, because the file is kept. |
| 890 | (with-temp-buffer | 881 | (with-temp-buffer |
| @@ -938,6 +929,133 @@ longer than timeout seconds for the events to be delivered." | |||
| 938 | (file-notify--deftest-remote file-notify-test07-backup | 929 | (file-notify--deftest-remote file-notify-test07-backup |
| 939 | "Check that backup keeps file notification for remote files.") | 930 | "Check that backup keeps file notification for remote files.") |
| 940 | 931 | ||
| 932 | (ert-deftest file-notify-test08-watched-file-in-watched-dir () | ||
| 933 | "Watches a directory and a file in that directory separately. | ||
| 934 | Checks that the callbacks are only called with events with | ||
| 935 | descriptors that were issued when registering the watches. This | ||
| 936 | test caters for the situation in bug#22736 where the callback for | ||
| 937 | the directory received events for the file with the descriptor of | ||
| 938 | the file watch." | ||
| 939 | :tags '(:expensive-test) | ||
| 940 | (skip-unless (file-notify--test-local-enabled)) | ||
| 941 | |||
| 942 | ;; A directory to be watched. | ||
| 943 | (should | ||
| 944 | (setq file-notify--test-tmpfile | ||
| 945 | (make-temp-file "file-notify-test-parent" t))) | ||
| 946 | ;; A file to be watched. | ||
| 947 | (should | ||
| 948 | (setq file-notify--test-tmpfile1 | ||
| 949 | (let ((temporary-file-directory file-notify--test-tmpfile)) | ||
| 950 | (file-notify--test-make-temp-name)))) | ||
| 951 | (write-region "any text" nil file-notify--test-tmpfile1 nil 'no-message) | ||
| 952 | (unwind-protect | ||
| 953 | (cl-flet (;; Directory monitor. | ||
| 954 | (dir-callback (event) | ||
| 955 | (let ((file-notify--test-desc file-notify--test-desc1)) | ||
| 956 | (file-notify--test-event-handler event))) | ||
| 957 | ;; File monitor. | ||
| 958 | (file-callback (event) | ||
| 959 | (let ((file-notify--test-desc file-notify--test-desc2)) | ||
| 960 | (file-notify--test-event-handler event)))) | ||
| 961 | (should | ||
| 962 | (setq file-notify--test-desc1 | ||
| 963 | (file-notify-add-watch | ||
| 964 | file-notify--test-tmpfile | ||
| 965 | '(change) #'dir-callback))) | ||
| 966 | (should | ||
| 967 | (setq file-notify--test-desc2 | ||
| 968 | (file-notify-add-watch | ||
| 969 | file-notify--test-tmpfile1 | ||
| 970 | '(change) #'file-callback))) | ||
| 971 | (should (file-notify-valid-p file-notify--test-desc1)) | ||
| 972 | (should (file-notify-valid-p file-notify--test-desc2)) | ||
| 973 | (should-not (equal file-notify--test-desc1 file-notify--test-desc2)) | ||
| 974 | ;; gfilenotify raises one or two `changed' events randomly in | ||
| 975 | ;; the file monitor, no chance to test. | ||
| 976 | (unless (string-equal "gfilenotify" (file-notify--test-library)) | ||
| 977 | (let ((n 100) events) | ||
| 978 | ;; Compute the expected events. | ||
| 979 | (dotimes (_i (/ n 2)) | ||
| 980 | (setq events | ||
| 981 | (append | ||
| 982 | (append | ||
| 983 | ;; Directory monitor and file monitor. | ||
| 984 | (cond | ||
| 985 | ;; In the remote case, there are two `changed' | ||
| 986 | ;; events. | ||
| 987 | ((file-remote-p temporary-file-directory) | ||
| 988 | '(changed changed changed changed)) | ||
| 989 | ;; The directory monitor in kqueue does not | ||
| 990 | ;; raise any `changed' event. Just the file | ||
| 991 | ;; monitor event is received. | ||
| 992 | ((string-equal (file-notify--test-library) "kqueue") | ||
| 993 | '(changed)) | ||
| 994 | ;; Otherwise, both monitors report the | ||
| 995 | ;; `changed' event. | ||
| 996 | (t '(changed changed))) | ||
| 997 | ;; Just the directory monitor. | ||
| 998 | (cond | ||
| 999 | ;; In kqueue, there is an additional `changed' | ||
| 1000 | ;; event. Why? | ||
| 1001 | ((string-equal (file-notify--test-library) "kqueue") | ||
| 1002 | '(changed created changed)) | ||
| 1003 | (t '(created changed)))) | ||
| 1004 | events))) | ||
| 1005 | |||
| 1006 | ;; Run the test. | ||
| 1007 | (file-notify--test-with-events events | ||
| 1008 | (dotimes (i n) | ||
| 1009 | (read-event nil nil file-notify--test-read-event-timeout) | ||
| 1010 | (if (zerop (mod i 2)) | ||
| 1011 | (write-region | ||
| 1012 | "any text" nil file-notify--test-tmpfile1 t 'no-message) | ||
| 1013 | (let ((temporary-file-directory file-notify--test-tmpfile)) | ||
| 1014 | (write-region | ||
| 1015 | "any text" nil | ||
| 1016 | (file-notify--test-make-temp-name) nil 'no-message))))))) | ||
| 1017 | |||
| 1018 | ;; If we delete the file, the directory monitor shall still be | ||
| 1019 | ;; active. We receive the `deleted' event from both the | ||
| 1020 | ;; directory and the file monitor. The `stopped' event is | ||
| 1021 | ;; from the file monitor. It's undecided in which order the | ||
| 1022 | ;; the directory and the file monitor are triggered. | ||
| 1023 | (file-notify--test-with-events | ||
| 1024 | '((deleted deleted stopped) | ||
| 1025 | (deleted stopped deleted)) | ||
| 1026 | (delete-file file-notify--test-tmpfile1)) | ||
| 1027 | (should (file-notify-valid-p file-notify--test-desc1)) | ||
| 1028 | (should-not (file-notify-valid-p file-notify--test-desc2)) | ||
| 1029 | |||
| 1030 | ;; Now we delete the directory. | ||
| 1031 | (file-notify--test-with-events | ||
| 1032 | (cond | ||
| 1033 | ;; In kqueue, just one `deleted' event for the directory | ||
| 1034 | ;; is received. | ||
| 1035 | ((string-equal (file-notify--test-library) "kqueue") | ||
| 1036 | '(deleted stopped)) | ||
| 1037 | (t (append | ||
| 1038 | ;; The directory monitor raises a `deleted' event for | ||
| 1039 | ;; every file contained in the directory, we must | ||
| 1040 | ;; count them. | ||
| 1041 | (make-list | ||
| 1042 | (length | ||
| 1043 | (directory-files | ||
| 1044 | file-notify--test-tmpfile nil | ||
| 1045 | directory-files-no-dot-files-regexp 'nosort)) | ||
| 1046 | 'deleted) | ||
| 1047 | ;; The events of the directory itself. | ||
| 1048 | '(deleted stopped)))) | ||
| 1049 | (delete-directory file-notify--test-tmpfile 'recursive)) | ||
| 1050 | (should-not (file-notify-valid-p file-notify--test-desc1)) | ||
| 1051 | (should-not (file-notify-valid-p file-notify--test-desc2))) | ||
| 1052 | |||
| 1053 | ;; Cleanup. | ||
| 1054 | (file-notify--test-cleanup))) | ||
| 1055 | |||
| 1056 | (file-notify--deftest-remote file-notify-test08-watched-file-in-watched-dir | ||
| 1057 | "Check `file-notify-test08-watched-file-in-watched-dir' for remote files.") | ||
| 1058 | |||
| 941 | (defun file-notify-test-all (&optional interactive) | 1059 | (defun file-notify-test-all (&optional interactive) |
| 942 | "Run all tests for \\[file-notify]." | 1060 | "Run all tests for \\[file-notify]." |
| 943 | (interactive "p") | 1061 | (interactive "p") |