]> git.eshelyaron.com Git - emacs.git/commitdiff
Improve tests for gio file notifications
authorMichael Albinus <michael.albinus@gmx.de>
Wed, 9 Dec 2020 13:49:58 +0000 (14:49 +0100)
committerMichael Albinus <michael.albinus@gmx.de>
Wed, 9 Dec 2020 13:49:58 +0000 (14:49 +0100)
* .gitlab-ci.yml (test-filenotify-gio): Call "make -k".

* lisp/net/tramp-gvfs.el (tramp-gvfs-handle-file-notify-add-watch):
Set connection property "gio-file-monitor".

* lisp/net/tramp-sh.el (tramp-get-remote-gio-file-monitor): New defun.
(tramp-sh-handle-file-notify-add-watch): Use it.

* test/lisp/filenotify-tests.el (file-notify--test-read-event): Simplify.
(file-notify--test-monitor): Handle also remote "gio monitor".
(file-notify-test03-events, file-notify-test04-autorevert)
(file-notify-test05-file-validity, file-notify-test08-backup)
(file-notify-test09-watched-file-in-watched-dir):
Handle GKqueueFileMonitor.

.gitlab-ci.yml
lisp/net/tramp-gvfs.el
lisp/net/tramp-sh.el
test/lisp/filenotify-tests.el

index f4e08d59dd07905e7821f0808f086ea174346a7b..bab2573c883eee3b7958e6cc805913e2a17ca0ce 100644 (file)
@@ -91,7 +91,7 @@ test-filenotify-gio:
     - ./autogen.sh autoconf
     - ./configure --without-makeinfo --with-file-notification=gfile
     - make bootstrap
-    - make -C test autorevert-tests filenotify-tests
+    - make -k -C test autorevert-tests filenotify-tests
 
 test-gnustep:
   stage: test
index c2028c4908cc48b92194b8745a66a532e2e59c71..1722c53be055ed672f4d7c2b35127558b692c136 100644 (file)
@@ -1434,6 +1434,9 @@ If FILE-SYSTEM is non-nil, return file system attributes."
        (unless (process-live-p p)
          (tramp-error
           p 'file-notify-error "Monitoring not supported for `%s'" file-name))
+       ;; Set "gio-file-monitor" property.  We believe, that "gio
+       ;; monitor" uses polling when applied for mounted files.
+       (tramp-set-connection-property p "gio-file-monitor" 'GPollFileMonitor)
        p))))
 
 (defun tramp-gvfs-monitor-process-filter (proc string)
index 79a7feae46954ac28eb51f76765298b9a480df80..98537a100f3d1bd9fc72b16257ccb3188e20812b 100644 (file)
@@ -3834,6 +3834,10 @@ Fall back to normal file name handler if no Tramp handler exists."
        (unless (process-live-p p)
          (tramp-error
           p 'file-notify-error "Monitoring not supported for `%s'" file-name))
+       ;; Set "gio-file-monitor" property if needed.
+       (when (string-equal (file-name-nondirectory command) "gio")
+         (tramp-set-connection-property
+          p "gio-file-monitor" (tramp-get-remote-gio-file-monitor v)))
        p))))
 
 (defun tramp-sh-gio-monitor-process-filter (proc string)
@@ -5753,6 +5757,30 @@ This command is returned only if `delete-by-moving-to-trash' is non-nil."
     (tramp-message vec 5 "Finding a suitable `gio-monitor' command")
     (tramp-find-executable vec "gio" (tramp-get-remote-path vec) t t)))
 
+(defun tramp-get-remote-gio-file-monitor (vec)
+  "Determine remote GFileMonitor."
+  (with-tramp-connection-property vec "gio-file-monitor"
+    (with-current-buffer (tramp-get-connection-buffer vec)
+      (tramp-message vec 5 "Finding the used GFileMonitor")
+      (when-let ((gio (tramp-get-remote-gio-monitor vec)))
+       ;; Search for the used FileMonitor.  There is no known way to
+       ;; get this information directly from gio, so we check for
+       ;; linked libraries of libgio.
+       (when (tramp-send-command-and-check vec (concat "ldd " gio))
+         (goto-char (point-min))
+         (when (re-search-forward "\\S-+/libgio\\S-+")
+           (when (tramp-send-command-and-check
+                  vec (concat "strings " (match-string 0)))
+             (goto-char (point-min))
+             (re-search-forward
+              (format
+               "^%s$"
+               (regexp-opt
+                '("GFamFileMonitor" "GFenFileMonitor"
+                  "GInotifyFileMonitor" "GKqueueFileMonitor")))
+              nil 'noerror)
+             (intern (match-string 0)))))))))
+
 (defun tramp-get-remote-gvfs-monitor-dir (vec)
   "Determine remote `gvfs-monitor-dir' command."
   (with-tramp-connection-property vec "gvfs-monitor-dir"
index 268c3185bc6762f29a8a1f7f36fd9dfcd71bd8cf..25017dd326103875d3eeccb9397f1053a8a82c29 100644 (file)
@@ -108,11 +108,8 @@ There are different timeouts for local and remote file notification libraries."
     ;; gio/gpollfilemonitor.c declares POLL_TIME_SECS 5.  So we must
     ;; wait at least this time in the GPollFileMonitor case.  A
     ;; similar timeout seems to be needed in the GFamFileMonitor case,
-    ;; at least on Cygwin.
-    ((and (string-equal (file-notify--test-library) "gfilenotify")
-          (memq (file-notify--test-monitor)
-                '(GFamFileMonitor GPollFileMonitor)))
-     7)
+    ;; at least on cygwin.
+    ((memq (file-notify--test-monitor) '(GFamFileMonitor GPollFileMonitor)) 7)
     ((string-equal (file-notify--test-library) "gvfs-monitor-dir.exe") 1)
     ((file-remote-p temporary-file-directory) 0.1)
     (t 0.01))))
@@ -264,13 +261,19 @@ This returns only for the local case and gfilenotify; otherwise it is nil.
   ;; We cache the result, because after `file-notify-rm-watch',
   ;; `gfile-monitor-name' does not return a proper result anymore.
   ;; But we still need this information.
-  (unless (file-remote-p temporary-file-directory)
-    (or (cdr (assq file-notify--test-desc file-notify--test-monitors))
-        (when (functionp 'gfile-monitor-name)
-          (add-to-list 'file-notify--test-monitors
-                       (cons file-notify--test-desc
-                             (gfile-monitor-name file-notify--test-desc)))
-          (cdr (assq file-notify--test-desc file-notify--test-monitors))))))
+  ;; So far, we know the monitors GFamFileMonitor, GFenFileMonitor,
+  ;; GInotifyFileMonitor, GKqueueFileMonitor and GPollFileMonitor.
+  (or (cdr (assq file-notify--test-desc file-notify--test-monitors))
+      (progn
+       (add-to-list
+        'file-notify--test-monitors
+        (cons file-notify--test-desc
+              (if (file-remote-p temporary-file-directory)
+                  (tramp-get-connection-property
+                   file-notify--test-desc "gio-file-monitor" nil)
+                (and (functionp 'gfile-monitor-name)
+                     (gfile-monitor-name file-notify--test-desc)))))
+       (cdr (assq file-notify--test-desc file-notify--test-monitors)))))
 
 (defmacro file-notify--deftest-remote (test docstring &optional unstable)
   "Define ert `TEST-remote' for remote files.
@@ -457,7 +460,7 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'."
 
   (unwind-protect
       ;; Check, that removing watch descriptors out of order do not
-      ;; harm.  This fails on Cygwin because of timing issues unless a
+      ;; harm.  This fails on cygwin because of timing issues unless a
       ;; long `sit-for' is added before the call to
       ;; `file-notify--test-read-event'.
       (unless (eq system-type 'cygwin)
@@ -631,13 +634,15 @@ delivered."
             (cond
              ;; gvfs-monitor-dir on cygwin does not detect the
              ;; `created' event reliably.
-            ((string-equal
-              (file-notify--test-library) "gvfs-monitor-dir.exe")
+            ((string-equal (file-notify--test-library) "gvfs-monitor-dir.exe")
              '((deleted stopped)
                (created deleted stopped)))
              ;; cygwin does not raise a `changed' event.
              ((eq system-type 'cygwin)
               '(created deleted stopped))
+            ;; GKqueueFileMonitor does not report the `changed' event.
+            ((equal (file-notify--test-monitor) 'GKqueueFileMonitor)
+             '(created deleted stopped))
              (t '(created changed deleted stopped)))
           (write-region
            "another text" nil file-notify--test-tmpfile nil 'no-message)
@@ -668,6 +673,9 @@ delivered."
             ((string-equal (file-notify--test-library) "gvfs-monitor-dir.exe")
              '((deleted stopped)
                (changed deleted stopped)))
+            ;; GKqueueFileMonitor does not report the `changed' event.
+            ((equal (file-notify--test-monitor) 'GKqueueFileMonitor)
+             '(deleted stopped))
             ;; There could be one or two `changed' events.
             (t '((changed deleted stopped)
                  (changed changed deleted stopped))))
@@ -718,6 +726,9 @@ delivered."
              '(created deleted stopped))
             ((string-equal (file-notify--test-library) "kqueue")
              '(created changed deleted stopped))
+            ;; GKqueueFileMonitor does not report the `changed' event.
+            ((equal (file-notify--test-monitor) 'GKqueueFileMonitor)
+             '(created deleted deleted stopped))
             (t '(created changed deleted deleted stopped)))
          (write-region
           "any text" nil file-notify--test-tmpfile nil 'no-message)
@@ -767,6 +778,9 @@ delivered."
              ;; directory are not detected.
              ((getenv "EMACS_EMBA_CI")
               '(created changed created changed deleted deleted))
+            ;; GKqueueFileMonitor does not report the `changed' event.
+            ((equal (file-notify--test-monitor) 'GKqueueFileMonitor)
+             '(created created deleted deleted deleted stopped))
             (t '(created changed created changed
                  deleted deleted deleted stopped)))
          (write-region
@@ -823,6 +837,9 @@ delivered."
              '(created created deleted deleted stopped))
             ((string-equal (file-notify--test-library) "kqueue")
              '(created changed renamed deleted stopped))
+            ;; GKqueueFileMonitor does not report the `changed' event.
+            ((equal (file-notify--test-monitor) 'GKqueueFileMonitor)
+             '(created renamed deleted deleted stopped))
             (t '(created changed renamed deleted deleted stopped)))
          (write-region
           "any text" nil file-notify--test-tmpfile nil 'no-message)
@@ -859,6 +876,8 @@ delivered."
             ((string-equal (file-notify--test-library) "w32notify")
              '((changed changed)
                (changed changed changed changed)))
+            ;; GKqueueFileMonitor does not report the `attribute-changed' event.
+            ((equal (file-notify--test-monitor) 'GKqueueFileMonitor) nil)
             ;; For kqueue and in the remote case, `write-region'
             ;; raises also an `attribute-changed' event.
             ((or (string-equal (file-notify--test-library) "kqueue")
@@ -925,6 +944,10 @@ delivered."
             ;; timeouts.
             (setq file-notify--test-desc auto-revert-notify-watch-descriptor)
 
+           ;; GKqueueFileMonitor does not report the `changed' event.
+           (skip-unless
+            (not (equal (file-notify--test-monitor) 'GKqueueFileMonitor)))
+
            ;; Check, that file notification has been used.
            (should auto-revert-mode)
            (should auto-revert-use-notify)
@@ -956,7 +979,7 @@ delivered."
 
            ;; Modify file.  We wait for two seconds, in order to
            ;; have another timestamp.  One second seems to be too
-            ;; short.  And Cygwin sporadically requires more than two.
+            ;; short.  And cygwin sporadically requires more than two.
             (ert-with-message-capture captured-messages
               (let ((inhibit-message t))
                 (sleep-for (if (eq system-type 'cygwin) 3 2))
@@ -1028,6 +1051,9 @@ delivered."
             ((string-equal (file-notify--test-library) "gvfs-monitor-dir.exe")
              '((deleted stopped)
                (changed deleted stopped)))
+            ;; GKqueueFileMonitor does not report the `changed' event.
+            ((equal (file-notify--test-monitor) 'GKqueueFileMonitor)
+             '(deleted stopped))
             ;; There could be one or two `changed' events.
             (t '((changed deleted stopped)
                  (changed changed deleted stopped))))
@@ -1077,6 +1103,9 @@ delivered."
                '(created deleted stopped))
               ((string-equal (file-notify--test-library) "kqueue")
                '(created changed deleted stopped))
+              ;; GKqueueFileMonitor does not report the `changed' event.
+              ((equal (file-notify--test-monitor) 'GKqueueFileMonitor)
+               '(created deleted deleted stopped))
               (t '(created changed deleted deleted stopped)))
            (write-region
             "any text" nil file-notify--test-tmpfile nil 'no-message)
@@ -1254,9 +1283,12 @@ delivered."
                '(change) #'file-notify--test-event-handler)))
         (should (file-notify-valid-p file-notify--test-desc))
         (file-notify--test-with-actions
-            ;; There could be one or two `changed' events.
-            '((changed)
-              (changed changed))
+           (cond
+            ;; GKqueueFileMonitor does not report the `changed' event.
+            ((equal (file-notify--test-monitor) 'GKqueueFileMonitor) nil)
+             ;; There could be one or two `changed' events.
+            (t '((changed)
+                 (changed changed))))
           ;; There shouldn't be any problem, because the file is kept.
           (with-temp-buffer
             (let ((buffer-file-name file-notify--test-tmpfile)
@@ -1294,6 +1326,9 @@ delivered."
              ;; On cygwin we only get the `changed' event.
              ((eq system-type 'cygwin)
               '(changed))
+            ;; GKqueueFileMonitor does not report the `changed' event.
+            ((equal (file-notify--test-monitor) 'GKqueueFileMonitor)
+             '(renamed created))
              (t '(renamed created changed)))
           ;; The file is renamed when creating a backup.  It shall
           ;; still be watched.
@@ -1391,7 +1426,12 @@ the file watch."
                 (make-list (/ n 2) 'changed)
                 ;; Just the directory monitor.
                 (make-list (/ n 2) 'created)
-                (make-list (/ n 2) 'changed)))
+                (make-list (/ n 2) 'changed))
+              (append
+                '(:random)
+               ;; Just the directory monitor.  GKqueueFileMonitor
+               ;; does not report the `changed' event.
+                (make-list (/ n 2) 'created)))
             (dotimes (i n)
               (file-notify--test-read-event)
               (if (zerop (mod i 2))