]> code.delx.au - gnu-emacs/commitdiff
Merge branch 'feature/standard-test-location'
authorPhillip Lord <phillip.lord@russet.org.uk>
Thu, 26 Nov 2015 21:11:29 +0000 (21:11 +0000)
committerPhillip Lord <phillip.lord@russet.org.uk>
Thu, 26 Nov 2015 21:11:29 +0000 (21:11 +0000)
1  2 
configure.ac
test/lisp/autorevert-tests.el
test/lisp/filenotify-tests.el

diff --combined configure.ac
index bae4fec72ece9c0b7321fb00269dc7f9ac98a466,2d832d03ed9eb574cca7b00d86651bdb12689ccd..0b7b4032482abcfd8e082696291c8e417373e7ba
@@@ -355,18 -355,17 +355,18 @@@ OPTION_DEFAULT_ON([gnutls],[don't use -
  OPTION_DEFAULT_ON([zlib],[don't compile with zlib decompression support])
  
  AC_ARG_WITH([file-notification],[AS_HELP_STRING([--with-file-notification=LIB],
 - [use a file notification library (LIB one of: yes, gfile, inotify, w32, no)])],
 + [use a file notification library (LIB one of: yes, inotify, kqueue, gfile, w32, no)])],
   [ case "${withval}" in
      y | ye | yes )    val=yes ;;
      n | no )          val=no  ;;
 -    g | gf | gfi | gfil | gfile )     val=gfile ;;
      i | in | ino | inot | inoti | inotif | inotify )  val=inotify ;;
 +    k | kq | kqu | kque | kqueu | kqueue )    val=kqueue ;;
 +    g | gf | gfi | gfil | gfile )     val=gfile ;;
      w | w3 | w32 )    val=w32 ;;
      * ) AC_MSG_ERROR(['--with-file-notification=$withval' is invalid;
 -this option's value should be 'yes', 'no', 'gfile', 'inotify' or 'w32'.
 +this option's value should be 'yes', 'no', 'inotify', 'kqeue', 'gfile' or 'w32'.
  'yes' is a synonym for 'w32' on MS-Windows, for 'no' on Nextstep,
 -otherwise for the first of 'inotify' or 'gfile' that is usable.])
 +otherwise for the first of 'inotify', 'kqueue' or 'gfile' that is usable.])
      ;;
     esac
     with_file_notification=$val
@@@ -2691,6 -2690,12 +2691,6 @@@ AC_SUBST(LIBGNUTLS_CFLAGS
  NOTIFY_OBJ=
  NOTIFY_SUMMARY=no
  
 -dnl FIXME?  Don't auto-detect on NS, but do allow someone to specify
 -dnl a particular library.  This doesn't make much sense?
 -if test "${HAVE_NS}" = yes && test ${with_file_notification} = yes; then
 -  with_file_notification=no
 -fi
 -
  dnl MS Windows native file monitor is available for mingw32 only.
  case $with_file_notification,$opsys in
    w32,cygwin)
@@@ -2721,41 -2726,16 +2721,41 @@@ case $with_file_notification,$NOTIFY_OB
      fi ;;
  esac
  
 +dnl kqueue is available on BSD-like systems.
 +case $with_file_notification,$NOTIFY_OBJ in
 +  kqueue,* | yes,)
 +    EMACS_CHECK_MODULES([KQUEUE], [libkqueue])
 +    if test "$HAVE_KQUEUE" = "yes"; then
 +       AC_DEFINE(HAVE_KQUEUE, 1, [Define to 1 to use kqueue.])
 +       CPPFLAGS="$CPPFLAGS -I/usr/include/kqueue"
 +       NOTIFY_CFLAGS=$KQUEUE_CFLAGS
 +       NOTIFY_LIBS=$KQUEUE_LIBS
 +       NOTIFY_OBJ=kqueue.o
 +       NOTIFY_SUMMARY="yes -lkqueue"
 +    else
 +       AC_SEARCH_LIBS(kqueue, [])
 +       if test "$ac_cv_search_kqueue" != no; then
 +         AC_DEFINE(HAVE_KQUEUE, 1, [Define to 1 to use kqueue.])
 +       NOTIFY_OBJ=kqueue.o
 +       NOTIFY_SUMMARY="yes (kqueue)"
 +       fi
 +    fi ;;
 +esac
 +
  dnl g_file_monitor exists since glib 2.18.  G_FILE_MONITOR_EVENT_MOVED
  dnl has been added in glib 2.24.  It has been tested under
  dnl GNU/Linux only.
  case $with_file_notification,$NOTIFY_OBJ in
    gfile,* | yes,)
 -    EMACS_CHECK_MODULES([GFILENOTIFY], [gio-2.0 >= 2.24])
 -    if test "$HAVE_GFILENOTIFY" = "yes"; then
 -       AC_DEFINE(HAVE_GFILENOTIFY, 1, [Define to 1 if using GFile.])
 -       NOTIFY_OBJ=gfilenotify.o
 -       NOTIFY_SUMMARY="yes -lgio (gfile)"
 +    if test "${HAVE_NS}" != yes; then
 +       EMACS_CHECK_MODULES([GFILENOTIFY], [gio-2.0 >= 2.24])
 +       if test "$HAVE_GFILENOTIFY" = "yes"; then
 +        AC_DEFINE(HAVE_GFILENOTIFY, 1, [Define to 1 if using GFile.])
 +        NOTIFY_CFLAGS=$GFILENOTIFY_CFLAGS
 +        NOTIFY_LIBS=$GFILENOTIFY_LIBS
 +        NOTIFY_OBJ=gfilenotify.o
 +        NOTIFY_SUMMARY="yes -lgio (gfile)"
 +       fi
      fi ;;
  esac
  
@@@ -2767,9 -2747,9 +2767,9 @@@ esa
  if test -n "$NOTIFY_OBJ"; then
     AC_DEFINE(USE_FILE_NOTIFY, 1, [Define to 1 if using file notifications.])
  fi
 +AC_SUBST(NOTIFY_CFLAGS)
 +AC_SUBST(NOTIFY_LIBS)
  AC_SUBST(NOTIFY_OBJ)
 -AC_SUBST(GFILENOTIFY_CFLAGS)
 -AC_SUBST(GFILENOTIFY_LIBS)
  
  dnl Do not put whitespace before the #include statements below.
  dnl Older compilers (eg sunos4 cc) choke on it.
@@@ -4086,8 -4066,8 +4086,8 @@@ OLDCFLAGS="$CFLAGS
  OLDLIBS="$LIBS"
  CFLAGS="$CFLAGS $GTK_CFLAGS $RSVG_CFLAGS $DBUS_CFLAGS $SETTINGS_CFLAGS"
  LIBS="$LIBS $GTK_LIBS $RSVG_LIBS $DBUS_LIBS $SETTINGS_LIBS"
 -CFLAGS="$CFLAGS $GFILENOTIFY_CFLAGS $CAIRO_CFLAGS"
 -LIBS="$LIBS $GFILENOTIFY_LIBS $CAIRO_LIBS"
 +CFLAGS="$CFLAGS $NOTIFY_CFLAGS $CAIRO_CFLAGS"
 +LIBS="$LIBS $NOTIFY_LIBS $CAIRO_LIBS"
  AC_MSG_CHECKING([whether GLib is linked in])
  AC_LINK_IFELSE([AC_LANG_PROGRAM(
        [[#include <glib.h>
@@@ -4167,7 -4147,7 +4167,7 @@@ els
    SEPCHAR=':'
  fi
  AC_DEFINE_UNQUOTED(SEPCHAR, ['$SEPCHAR'], [Character that separates PATH elements.])
- dnl This is for MinGW, and is used in test/automated/Makefile.in.
+ dnl This is for MinGW, and is used in test/Makefile.in.
  dnl The MSYS Bash has heuristics for replacing ':' with ';' when it
  dnl decides that a command-line argument to be passed to a MinGW program
  dnl is a PATH-style list of directories.  But that heuristics plays it
@@@ -5318,13 -5298,13 +5318,13 @@@ AC_CONFIG_FILES([Makefile lib/Makefile 
         leim/Makefile nextstep/Makefile nt/Makefile])
  
  dnl test/ is not present in release tarfiles.
- opt_makefile=test/automated/Makefile
+ opt_makefile=test/Makefile
  
  if test -f "$srcdir/$opt_makefile.in"; then
    SUBDIR_MAKEFILES="$SUBDIR_MAKEFILES $opt_makefile"
    dnl Again, it's best not to use a variable.  Though you can add
    dnl ", [], [opt_makefile='$opt_makefile']" and it should work.
-   AC_CONFIG_FILES([test/automated/Makefile])
+   AC_CONFIG_FILES([test/Makefile])
  fi
  
  
index 6f186973ee75f7e34c34dd07d01efcec3389f073,2745f106087fd938e059427a7c88782ccb29690f..6f186973ee75f7e34c34dd07d01efcec3389f073
            ;; Strange, that `copy-directory' does not work as expected.
            ;; The following shell command is not portable on all
            ;; platforms, unfortunately.
 -          (shell-command (format "%s -f %s/* %s" cp tmpdir2 tmpdir1))
 +          (shell-command (format "%s %s/* %s" cp tmpdir2 tmpdir1))
  
            ;; Check, that the buffers have been reverted.
            (dolist (buf (list buf1 buf2))
index b665dddb6315a610c11c81e8d601871c085ac441,67e929a647728d2f3fbb73633131662d31846182..b665dddb6315a610c11c81e8d601871c085ac441
  
  (defun file-notify--test-timeout ()
    "Timeout to wait for arriving events, in seconds."
 -  (if (file-remote-p temporary-file-directory) 6 3))
 +  (cond
 +   ((file-remote-p temporary-file-directory) 6)
 +   ((string-equal (file-notify--test-library) "w32notify") 20)
 +   ((eq system-type 'cygwin) 10)
 +   (t 3)))
  
  (defun file-notify--test-cleanup ()
    "Cleanup after a test."
@@@ -137,18 -133,6 +137,18 @@@ being the result."
    ;; Return result.
    (cdr file-notify--test-remote-enabled-checked))
  
 +(defun file-notify--test-library ()
 +  "The used libray for the test, as string.
 +In the remote case, it is the process name which runs on the
 +remote host, or nil."
 +  (if (null (file-remote-p temporary-file-directory))
 +      (symbol-name file-notify--library)
 +    (and (consp file-notify--test-remote-enabled-checked)
 +       (processp (cdr file-notify--test-remote-enabled-checked))
 +       (replace-regexp-in-string
 +        "<[[:digit:]]+>\\'" ""
 +        (process-name (cdr file-notify--test-remote-enabled-checked))))))
 +
  (defmacro file-notify--deftest-remote (test docstring)
    "Define ert `TEST-remote' for remote files."
    (declare (indent 1))
    "Test availability of `file-notify'."
    (skip-unless (file-notify--test-local-enabled))
    ;; Report the native library which has been used.
 -  (if (null (file-remote-p temporary-file-directory))
 -      (message "Local library: `%s'" file-notify--library)
 -    (message "Remote command: `%s'"
 -             (replace-regexp-in-string
 -              "<[[:digit:]]+>\\'" ""
 -              (process-name (cdr file-notify--test-remote-enabled-checked)))))
 +  (message "Library: `%s'" (file-notify--test-library))
    (should
     (setq file-notify--test-desc
           (file-notify-add-watch temporary-file-directory '(change) 'ignore)))
           (file-notify-add-watch
            temporary-file-directory '(change attribute-change) 'ignore)))
    (file-notify-rm-watch file-notify--test-desc)
 -  ;; The file does not need to exist, just the upper directory.
 +  (write-region "any text" nil file-notify--test-tmpfile nil 'no-message)
    (should
     (setq file-notify--test-desc
           (file-notify-add-watch
            file-notify--test-tmpfile '(change attribute-change) 'ignore)))
    (file-notify-rm-watch file-notify--test-desc)
 +  (delete-file file-notify--test-tmpfile)
  
    ;; Check error handling.
    (should-error (file-notify-add-watch 1 2 3 4)
@@@ -247,17 -235,16 +247,17 @@@ is bound somewhere.
    (should
     (or (string-equal (file-notify--event-file-name file-notify--test-event)
                     file-notify--test-tmpfile)
 -       (string-equal (directory-file-name
 -                    (file-name-directory
 -                     (file-notify--event-file-name file-notify--test-event)))
 -                   file-notify--test-tmpfile)))
 +       (string-equal (file-notify--event-file-name file-notify--test-event)
 +                   file-notify--test-tmpfile1)
 +       (string-equal (file-notify--event-file-name file-notify--test-event)
 +                   temporary-file-directory)))
    ;; Check the second file name if exists.
    (when (eq (nth 1 file-notify--test-event) 'renamed)
      (should
 -     (string-equal
 -      (file-notify--event-file1-name file-notify--test-event)
 -      file-notify--test-tmpfile1))))
 +     (or (string-equal (file-notify--event-file1-name file-notify--test-event)
 +                     file-notify--test-tmpfile1)
 +       (string-equal (file-notify--event-file1-name file-notify--test-event)
 +                     temporary-file-directory)))))
  
  (defun file-notify--test-event-handler (event)
    "Run a test over FILE-NOTIFY--TEST-EVENT.
@@@ -266,7 -253,7 +266,7 @@@ and the event to `file-notify--test-eve
    (let* ((file-notify--test-event event)
           (result
            (ert-run-test (make-ert-test :body 'file-notify--test-event-test))))
 -    ;; Do not add temporary files, this would confuse the checks.
 +    ;; Do not add lock files, this would confuse the checks.
      (unless (string-match
             (regexp-quote ".#")
             (file-notify--event-file-name file-notify--test-event))
@@@ -293,19 -280,13 +293,19 @@@ TIMEOUT is the maximum time to wait for
  Don't wait longer than timeout seconds for the events to be delivered."
    (declare (indent 1))
    (let ((outer (make-symbol "outer")))
 -    `(let ((,outer file-notify--test-events))
 +    `(let ((,outer file-notify--test-events)
 +           create-lockfiles)
         (setq file-notify--test-expected-events
             (append file-notify--test-expected-events ,events))
 +       ;; Flush pending events.
 +       (file-notify--wait-for-events
 +        (file-notify--test-timeout)
 +        (input-pending-p))
         (let (file-notify--test-events)
           ,@body
           (file-notify--wait-for-events
 -          (file-notify--test-timeout)
 +          ;; More events need more time.  Use some fudge factor.
 +          (* (ceiling (length ,events) 100) (file-notify--test-timeout))
            (= (length ,events) (length file-notify--test-events)))
           (should (equal ,events (mapcar #'cadr file-notify--test-events)))
           (setq ,outer (append ,outer file-notify--test-events)))
  (ert-deftest file-notify-test02-events ()
    "Check file creation/change/removal notifications."
    (skip-unless (file-notify--test-local-enabled))
 -  ;; Under cygwin there are so bad timings that it doesn't make sense to test.
 -  (skip-unless (not (eq system-type 'cygwin)))
 -
 -  (setq file-notify--test-tmpfile (file-notify--test-make-temp-name)
 -      file-notify--test-tmpfile1 (file-notify--test-make-temp-name))
  
    (unwind-protect
        (progn
 -        ;; Check creation, change and deletion.
 -      (setq file-notify--test-desc
 -              (file-notify-add-watch
 -               file-notify--test-tmpfile
 -               '(change) 'file-notify--test-event-handler))
 -        (file-notify--test-with-events '(created changed deleted)
 +        ;; Check file creation, change and deletion.  It doesn't work
 +        ;; for cygwin and kqueue, because we don't use an implicit
 +        ;; directory monitor (kqueue), or the timings are too bad (cygwin).
 +        (unless (or (eq system-type 'cygwin)
 +                  (string-equal (file-notify--test-library) "kqueue"))
 +          (setq file-notify--test-tmpfile (file-notify--test-make-temp-name))
 +          (should
 +           (setq file-notify--test-desc
 +                 (file-notify-add-watch
 +                  file-notify--test-tmpfile
 +                  '(change) 'file-notify--test-event-handler)))
 +          (file-notify--test-with-events
 +              (cond
 +               ;; cygwin recognizes only `deleted' and `stopped' events.
 +               ((eq system-type 'cygwin)
 +                '(deleted stopped))
 +               (t '(created changed deleted stopped)))
 +            (write-region
 +             "another text" nil file-notify--test-tmpfile nil 'no-message)
 +            (read-event nil nil 0.1)
 +            (delete-file file-notify--test-tmpfile))
 +          ;; `file-notify-rm-watch' fires the `stopped' event.  Suppress it.
 +          (let (file-notify--test-events)
 +            (file-notify-rm-watch file-notify--test-desc)))
 +
 +        ;; Check file change and deletion.
 +      (setq file-notify--test-tmpfile (file-notify--test-make-temp-name))
 +        (write-region "any text" nil file-notify--test-tmpfile nil 'no-message)
 +      (should
 +       (setq file-notify--test-desc
 +             (file-notify-add-watch
 +              file-notify--test-tmpfile
 +              '(change) 'file-notify--test-event-handler)))
 +        (file-notify--test-with-events
 +          (cond
 +           ;; cygwin recognizes only `deleted' and `stopped' events.
 +           ((eq system-type 'cygwin)
 +            '(deleted stopped))
 +             ;; inotify, kqueueg and gfilenotify raise just one
 +             ;; `changed' event, the other backends show us two of
 +             ;; them.
 +             ((or (string-equal "inotify" (file-notify--test-library))
 +                  (string-equal "kqueue" (file-notify--test-library))
 +                  (string-equal "gfilenotify" (file-notify--test-library)))
 +            '(changed deleted stopped))
 +           (t '(changed changed deleted stopped)))
 +          (read-event nil nil 0.1)
            (write-region
 -           "any text" nil file-notify--test-tmpfile nil 'no-message)
 +           "another text" nil file-notify--test-tmpfile nil 'no-message)
 +          (read-event nil nil 0.1)
            (delete-file file-notify--test-tmpfile))
        ;; `file-notify-rm-watch' fires the `stopped' event.  Suppress it.
        (let (file-notify--test-events)
          (file-notify-rm-watch file-notify--test-desc))
  
 -        ;; Check creation, change and deletion.  There must be a
 -        ;; `stopped' event when deleting the directory.  It doesn't
 -        ;; work for w32notify.
 -        (unless (eq file-notify--library 'w32notify)
 -        (make-directory file-notify--test-tmpfile)
 -        (setq file-notify--test-desc
 -              (file-notify-add-watch
 -               file-notify--test-tmpfile
 -               '(change) 'file-notify--test-event-handler))
 +        ;; Check file creation, change and deletion when watching a
 +        ;; directory.  There must be a `stopped' event when deleting
 +        ;; the directory.
 +      (let ((temporary-file-directory
 +             (make-temp-file "file-notify-test-parent" t)))
 +        (should
 +         (setq file-notify--test-tmpfile (file-notify--test-make-temp-name)
 +               file-notify--test-desc
 +               (file-notify-add-watch
 +                temporary-file-directory
 +                '(change) 'file-notify--test-event-handler)))
          (file-notify--test-with-events
 -            ;; There are two `deleted' events, for the file and for
 -            ;; the directory.
 -            '(created changed deleted deleted stopped)
 +            (cond
 +             ;; w32notify does raise a `stopped' event when a
 +             ;; watched directory is deleted.
 +             ((string-equal (file-notify--test-library) "w32notify")
 +              '(created changed deleted))
 +             ;; cygwin recognizes only `deleted' and `stopped' events.
 +             ((eq system-type 'cygwin)
 +              '(deleted stopped))
 +             ;; There are two `deleted' events, for the file and for
 +             ;; the directory.  Except for kqueue.
 +             ((string-equal (file-notify--test-library) "kqueue")
 +              '(created changed deleted stopped))
 +             (t '(created changed deleted deleted stopped)))
 +          (read-event nil nil 0.1)
            (write-region
 -           "any text" nil (expand-file-name "foo" file-notify--test-tmpfile)
 -           nil 'no-message)
 -          (delete-directory file-notify--test-tmpfile 'recursive))
 +           "any text" nil file-notify--test-tmpfile nil 'no-message)
 +          (read-event nil nil 0.1)
 +          (delete-directory temporary-file-directory 'recursive))
          ;; `file-notify-rm-watch' fires the `stopped' event.  Suppress it.
          (let (file-notify--test-events)
            (file-notify-rm-watch file-notify--test-desc)))
  
 -        ;; Check copy.
 -        (setq file-notify--test-desc
 -              (file-notify-add-watch
 -               file-notify--test-tmpfile
 -               '(change) 'file-notify--test-event-handler))
 -        (should file-notify--test-desc)
 -        (file-notify--test-with-events
 -            ;; w32notify does not distinguish between `changed' and
 -            ;; `attribute-changed'.
 -            (if (eq file-notify--library 'w32notify)
 -                '(created changed changed deleted)
 -              '(created changed deleted))
 -          (write-region
 -           "any text" nil file-notify--test-tmpfile nil 'no-message)
 -          (copy-file file-notify--test-tmpfile file-notify--test-tmpfile1)
 -          ;; The next two events shall not be visible.
 -          (set-file-modes file-notify--test-tmpfile 000)
 -          (read-event nil nil 0.1) ; In order to distinguish the events.
 -          (set-file-times file-notify--test-tmpfile '(0 0))
 -          (delete-file file-notify--test-tmpfile)
 -          (delete-file file-notify--test-tmpfile1))
 -      ;; `file-notify-rm-watch' fires the `stopped' event.  Suppress it.
 -      (let (file-notify--test-events)
 -        (file-notify-rm-watch file-notify--test-desc))
 +        ;; Check copy of files inside a directory.
 +      (let ((temporary-file-directory
 +             (make-temp-file "file-notify-test-parent" t)))
 +        (should
 +         (setq file-notify--test-tmpfile (file-notify--test-make-temp-name)
 +               file-notify--test-tmpfile1 (file-notify--test-make-temp-name)
 +               file-notify--test-desc
 +               (file-notify-add-watch
 +                temporary-file-directory
 +                '(change) 'file-notify--test-event-handler)))
 +        (file-notify--test-with-events
 +            (cond
 +             ;; w32notify does not distinguish between `changed' and
 +             ;; `attribute-changed'.
 +             ((string-equal (file-notify--test-library) "w32notify")
 +              '(created changed created changed changed changed changed
 +                deleted deleted))
 +             ;; cygwin recognizes only `deleted' and `stopped' events.
 +             ((eq system-type 'cygwin)
 +              '(deleted stopped))
 +             ;; There are three `deleted' events, for two files and
 +             ;; for the directory.  Except for kqueue.
 +             ((string-equal (file-notify--test-library) "kqueue")
 +              '(created changed created changed deleted stopped))
 +             (t '(created changed created changed
 +                  deleted deleted deleted stopped)))
 +          (read-event nil nil 0.1)
 +          (write-region
 +           "any text" nil file-notify--test-tmpfile nil 'no-message)
 +          (read-event nil nil 0.1)
 +          (copy-file file-notify--test-tmpfile file-notify--test-tmpfile1)
 +          ;; The next two events shall not be visible.
 +          (read-event nil nil 0.1)
 +          (set-file-modes file-notify--test-tmpfile 000)
 +          (read-event nil nil 0.1)
 +          (set-file-times file-notify--test-tmpfile '(0 0))
 +          (read-event nil nil 0.1)
 +          (delete-directory temporary-file-directory 'recursive))
 +        ;; `file-notify-rm-watch' fires the `stopped' event.  Suppress it.
 +        (let (file-notify--test-events)
 +          (file-notify-rm-watch file-notify--test-desc)))
  
 -        ;; Check rename.
 -        (setq file-notify--test-desc
 -              (file-notify-add-watch
 -               file-notify--test-tmpfile
 -               '(change) 'file-notify--test-event-handler))
 -        (should file-notify--test-desc)
 -        (file-notify--test-with-events '(created changed renamed)
 -          (write-region
 -           "any text" nil file-notify--test-tmpfile nil 'no-message)
 -          (rename-file file-notify--test-tmpfile file-notify--test-tmpfile1)
 -          ;; After the rename, we won't get events anymore.
 -          (delete-file file-notify--test-tmpfile1))
 -      ;; `file-notify-rm-watch' fires the `stopped' event.  Suppress it.
 -      (let (file-notify--test-events)
 -        (file-notify-rm-watch file-notify--test-desc))
 +        ;; Check rename of files inside a directory.
 +      (let ((temporary-file-directory
 +             (make-temp-file "file-notify-test-parent" t)))
 +        (should
 +         (setq file-notify--test-tmpfile (file-notify--test-make-temp-name)
 +               file-notify--test-tmpfile1 (file-notify--test-make-temp-name)
 +               file-notify--test-desc
 +               (file-notify-add-watch
 +                temporary-file-directory
 +                '(change) 'file-notify--test-event-handler)))
 +        (file-notify--test-with-events
 +            (cond
 +             ;; w32notify does not distinguish between `changed' and
 +             ;; `attribute-changed'.
 +             ((string-equal (file-notify--test-library) "w32notify")
 +              '(created changed renamed deleted))
 +             ;; cygwin recognizes only `deleted' and `stopped' events.
 +             ((eq system-type 'cygwin)
 +              '(deleted stopped))
 +             ;; There are two `deleted' events, for the file and for
 +             ;; the directory.  Except for kqueue.
 +             ((string-equal (file-notify--test-library) "kqueue")
 +              '(created changed renamed deleted stopped))
 +             (t '(created changed renamed deleted deleted stopped)))
 +          (read-event nil nil 0.1)
 +          (write-region
 +           "any text" nil file-notify--test-tmpfile nil 'no-message)
 +          (read-event nil nil 0.1)
 +          (rename-file file-notify--test-tmpfile file-notify--test-tmpfile1)
 +          ;; After the rename, we won't get events anymore.
 +          (read-event nil nil 0.1)
 +          (delete-directory temporary-file-directory 'recursive))
 +        ;; `file-notify-rm-watch' fires the `stopped' event.  Suppress it.
 +        (let (file-notify--test-events)
 +          (file-notify-rm-watch file-notify--test-desc)))
  
 -        ;; Check attribute change.  It doesn't work for w32notify.
 -        (unless (eq file-notify--library 'w32notify)
 -          (setq file-notify--test-desc
 -                (file-notify-add-watch
 -                 file-notify--test-tmpfile
 -                 '(attribute-change) 'file-notify--test-event-handler))
 -          (file-notify--test-with-events
 -              (if (file-remote-p temporary-file-directory)
 -                  ;; In the remote case, `write-region' raises also an
 -                  ;; `attribute-changed' event.
 -                  '(attribute-changed attribute-changed attribute-changed)
 -                '(attribute-changed attribute-changed))
 -            ;; We must use short delays between the operations.
 -            ;; Otherwise, not all events arrive us in the remote case.
 -            (write-region
 -             "any text" nil file-notify--test-tmpfile nil 'no-message)
 -            (read-event nil nil 0.1)
 -            (set-file-modes file-notify--test-tmpfile 000)
 -            (read-event nil nil 0.1)
 -            (set-file-times file-notify--test-tmpfile '(0 0))
 -            (read-event nil nil 0.1)
 -            (delete-file file-notify--test-tmpfile))
 +        ;; Check attribute change.  Does not work for cygwin.
 +      (unless (eq system-type 'cygwin)
 +        (setq file-notify--test-tmpfile (file-notify--test-make-temp-name))
 +        (write-region
 +         "any text" nil file-notify--test-tmpfile nil 'no-message)
 +        (should
 +         (setq file-notify--test-desc
 +               (file-notify-add-watch
 +                file-notify--test-tmpfile
 +                '(attribute-change) 'file-notify--test-event-handler)))
 +        (file-notify--test-with-events
 +            (cond
 +             ;; w32notify does not distinguish between `changed' and
 +             ;; `attribute-changed'.
 +             ((string-equal (file-notify--test-library) "w32notify")
 +              '(changed changed changed changed))
 +             ;; For kqueue and in the remote case, `write-region'
 +             ;; raises also an `attribute-changed' event.
 +             ((or (string-equal (file-notify--test-library) "kqueue")
 +                  (file-remote-p temporary-file-directory))
 +              '(attribute-changed attribute-changed attribute-changed))
 +             (t '(attribute-changed attribute-changed)))
 +          (read-event nil nil 0.1)
 +          (write-region
 +           "any text" nil file-notify--test-tmpfile nil 'no-message)
 +          (read-event nil nil 0.1)
 +          (set-file-modes file-notify--test-tmpfile 000)
 +          (read-event nil nil 0.1)
 +          (set-file-times file-notify--test-tmpfile '(0 0))
 +          (read-event nil nil 0.1)
 +          (delete-file file-notify--test-tmpfile))
          ;; `file-notify-rm-watch' fires the `stopped' event.  Suppress it.
          (let (file-notify--test-events)
            (file-notify-rm-watch file-notify--test-desc)))
            (should (string-match "another text" (buffer-string)))
  
              ;; Stop file notification.  Autorevert shall still work via polling.
 -          (file-notify-rm-watch auto-revert-notify-watch-descriptor)
 -            (file-notify--wait-for-events
 -             timeout (null auto-revert-use-notify))
 -          (should-not auto-revert-use-notify)
 -          (should-not auto-revert-notify-watch-descriptor)
 -
 -          ;; Modify file.  We wait for two seconds, in order to have
 -          ;; another timestamp.  One second seems to be too short.
 -            (with-current-buffer (get-buffer-create "*Messages*")
 -              (narrow-to-region (point-max) (point-max)))
 -          (sleep-for 2)
 -            (write-region
 -             "foo bla" nil file-notify--test-tmpfile nil 'no-message)
 -
 -          ;; Check, that the buffer has been reverted.
 -          (with-current-buffer (get-buffer-create "*Messages*")
 +          ;; It doesn't work for `w32notify'.
 +          (unless (string-equal (file-notify--test-library) "w32notify")
 +            (file-notify-rm-watch auto-revert-notify-watch-descriptor)
              (file-notify--wait-for-events
 -             timeout
 -             (string-match
 -                (format-message "Reverting buffer `%s'." (buffer-name buf))
 -                (buffer-string))))
 -          (should (string-match "foo bla" (buffer-string)))))
 +             timeout (null auto-revert-use-notify))
 +            (should-not auto-revert-use-notify)
 +            (should-not auto-revert-notify-watch-descriptor)
 +
 +            ;; Modify file.  We wait for two seconds, in order to
 +            ;; have another timestamp.  One second seems to be too
 +            ;; short.
 +            (with-current-buffer (get-buffer-create "*Messages*")
 +              (narrow-to-region (point-max) (point-max)))
 +            (sleep-for 2)
 +            (write-region
 +             "foo bla" nil file-notify--test-tmpfile nil 'no-message)
 +
 +            ;; Check, that the buffer has been reverted.
 +            (with-current-buffer (get-buffer-create "*Messages*")
 +              (file-notify--wait-for-events
 +               timeout
 +               (string-match
 +                (format-message "Reverting buffer `%s'." (buffer-name buf))
 +                (buffer-string))))
 +            (should (string-match "foo bla" (buffer-string))))))
  
        ;; Cleanup.
        (with-current-buffer "*Messages*" (widen))
  (ert-deftest file-notify-test04-file-validity ()
    "Check `file-notify-valid-p' for files."
    (skip-unless (file-notify--test-local-enabled))
 -  ;; Under cygwin there are so bad timings that it doesn't make sense to test.
 -  (skip-unless (not (eq system-type 'cygwin)))
  
    (unwind-protect
        (progn
 -        (setq file-notify--test-tmpfile (file-notify--test-make-temp-name)
 -              file-notify--test-desc
 -              (file-notify-add-watch
 -               file-notify--test-tmpfile
 -               '(change) #'file-notify--test-event-handler))
 -        (file-notify--test-with-events '(created changed deleted)
 +        (setq file-notify--test-tmpfile (file-notify--test-make-temp-name))
 +      (write-region "any text" nil file-notify--test-tmpfile nil 'no-message)
 +      (should
 +       (setq file-notify--test-desc
 +             (file-notify-add-watch
 +              file-notify--test-tmpfile
 +              '(change) #'file-notify--test-event-handler)))
 +        (should (file-notify-valid-p file-notify--test-desc))
 +      ;; After calling `file-notify-rm-watch', the descriptor is not
 +      ;; valid anymore.
 +        (file-notify-rm-watch file-notify--test-desc)
 +        (should-not (file-notify-valid-p file-notify--test-desc))
 +      (delete-file file-notify--test-tmpfile))
 +
 +    ;; Cleanup.
 +    (file-notify--test-cleanup))
 +
 +  (unwind-protect
 +      (progn
 +        (setq file-notify--test-tmpfile (file-notify--test-make-temp-name))
 +      (write-region "any text" nil file-notify--test-tmpfile nil 'no-message)
 +      (should
 +       (setq file-notify--test-desc
 +             (file-notify-add-watch
 +              file-notify--test-tmpfile
 +              '(change) #'file-notify--test-event-handler)))
 +        (file-notify--test-with-events
 +            (cond
 +             ;; cygwin recognizes only `deleted' and `stopped' events.
 +           ((eq system-type 'cygwin)
 +            '(deleted stopped))
 +             ;; inotify, kqueueg and gfilenotify raise just one
 +             ;; `changed' event, the other backends show us two of
 +             ;; them.
 +             ((or (string-equal "inotify" (file-notify--test-library))
 +                  (string-equal "kqueue" (file-notify--test-library))
 +                  (string-equal "gfilenotify" (file-notify--test-library)))
 +            '(changed deleted stopped))
 +           (t '(changed changed deleted stopped)))
 +        (read-event nil nil 0.1)
            (should (file-notify-valid-p file-notify--test-desc))
            (write-region
 -           "any text" nil file-notify--test-tmpfile nil 'no-message)
 +           "another text" nil file-notify--test-tmpfile nil 'no-message)
 +        (read-event nil nil 0.1)
          (delete-file file-notify--test-tmpfile))
 -      ;; After deleting the file, the descriptor is still valid.
 -        (should (file-notify-valid-p file-notify--test-desc))
 -      ;; After removing the watch, the descriptor must not be valid
 -        ;; anymore.
 -        (file-notify-rm-watch file-notify--test-desc)
 -        (should-not (file-notify-valid-p file-notify--test-desc)))
 +      ;; After deleting the file, the descriptor is not valid anymore.
 +        (should-not (file-notify-valid-p file-notify--test-desc))
 +        (file-notify-rm-watch file-notify--test-desc))
  
      ;; Cleanup.
      (file-notify--test-cleanup))
  
    (unwind-protect
 -      ;; The batch-mode operation of w32notify is fragile (there's no
 -      ;; input threads to send the message to).
 -      ;(unless (and noninteractive (eq file-notify--library 'w32notify))
 -      (unless (eq file-notify--library 'w32notify)
 -        (let ((temporary-file-directory
 +      ;; w32notify does not send a `stopped' event when deleting a
 +      ;; directory.  The test does not work, therefore.
 +      (unless (string-equal (file-notify--test-library) "w32notify")
 +      (let ((temporary-file-directory
               (make-temp-file "file-notify-test-parent" t)))
 -          (setq file-notify--test-tmpfile (file-notify--test-make-temp-name)
 -                file-notify--test-desc
 -                (file-notify-add-watch
 -                 file-notify--test-tmpfile
 -                 '(change) #'file-notify--test-event-handler))
 -          (file-notify--test-with-events '(created changed deleted stopped)
 -            (should (file-notify-valid-p file-notify--test-desc))
 -            (write-region
 -             "any text" nil file-notify--test-tmpfile nil 'no-message)
 +        (should
 +         (setq file-notify--test-tmpfile (file-notify--test-make-temp-name)
 +               file-notify--test-desc
 +               (file-notify-add-watch
 +                temporary-file-directory
 +                '(change) #'file-notify--test-event-handler)))
 +        (file-notify--test-with-events
 +            (cond
 +             ;; cygwin recognizes only `deleted' and `stopped' events.
 +             ((eq system-type 'cygwin)
 +              '(deleted stopped))
 +             ;; There are two `deleted' events, for the file and for
 +             ;; the directory.  Except for kqueue.
 +             ((string-equal (file-notify--test-library) "kqueue")
 +              '(created changed deleted stopped))
 +             (t '(created changed deleted deleted stopped)))
 +          (should (file-notify-valid-p file-notify--test-desc))
 +          (read-event nil nil 0.1)
 +          (write-region
 +           "any text" nil file-notify--test-tmpfile nil 'no-message)
 +          (read-event nil nil 0.1)
            (delete-directory temporary-file-directory t))
 -          ;; After deleting the parent directory, the descriptor must
 -          ;; not be valid anymore.
 -          (should-not (file-notify-valid-p file-notify--test-desc))))
 +        ;; After deleting the parent directory, the descriptor must
 +        ;; not be valid anymore.
 +        (should-not (file-notify-valid-p file-notify--test-desc))))
  
      ;; Cleanup.
      (file-notify--test-cleanup)))
          (setq file-notify--test-tmpfile
              (file-name-as-directory (file-notify--test-make-temp-name)))
          (make-directory file-notify--test-tmpfile)
 -        (setq file-notify--test-desc
 -              (file-notify-add-watch
 -               file-notify--test-tmpfile
 -               '(change) #'file-notify--test-event-handler))
 +      (should
 +       (setq file-notify--test-desc
 +             (file-notify-add-watch
 +              file-notify--test-tmpfile
 +              '(change) #'file-notify--test-event-handler)))
          (should (file-notify-valid-p file-notify--test-desc))
          ;; After removing the watch, the descriptor must not be valid
          ;; anymore.
    (unwind-protect
        ;; The batch-mode operation of w32notify is fragile (there's no
        ;; input threads to send the message to).
 -      (unless (and noninteractive (eq file-notify--library 'w32notify))
 +      (unless (and noninteractive
 +                 (string-equal (file-notify--test-library) "w32notify"))
          (setq file-notify--test-tmpfile
              (file-name-as-directory (file-notify--test-make-temp-name)))
          (make-directory file-notify--test-tmpfile)
 -        (setq file-notify--test-desc
 -              (file-notify-add-watch
 -               file-notify--test-tmpfile
 -               '(change) #'file-notify--test-event-handler))
 +      (should
 +       (setq file-notify--test-desc
 +             (file-notify-add-watch
 +              file-notify--test-tmpfile
 +              '(change) #'file-notify--test-event-handler)))
          (should (file-notify-valid-p file-notify--test-desc))
          ;; After deleting the directory, the descriptor must not be
          ;; valid anymore.
          (delete-directory file-notify--test-tmpfile t)
          (file-notify--wait-for-events
 -         (file-notify--test-timeout)
 +       (file-notify--test-timeout)
         (not (file-notify-valid-p file-notify--test-desc)))
          (should-not (file-notify-valid-p file-notify--test-desc)))
  
  (file-notify--deftest-remote file-notify-test05-dir-validity
    "Check `file-notify-valid-p' via file notification for remote directories.")
  
 +(ert-deftest file-notify-test06-many-events ()
 +  "Check that events are not dropped."
 +  (skip-unless (file-notify--test-local-enabled))
 +  ;; Under cygwin events arrive in random order.  Impossible to define a test.
 +  (skip-unless (not (eq system-type 'cygwin)))
 +
 +  (setq file-notify--test-tmpfile (file-notify--test-make-temp-name))
 +  (make-directory file-notify--test-tmpfile)
 +  (should
 +   (setq file-notify--test-desc
 +       (file-notify-add-watch
 +        file-notify--test-tmpfile
 +        '(change) 'file-notify--test-event-handler)))
 +  (unwind-protect
 +      (let ((n 1000)
 +            source-file-list target-file-list
 +            (default-directory file-notify--test-tmpfile))
 +        (dotimes (i n)
 +        ;; It matters which direction we rename, at least for
 +        ;; kqueue.  This backend parses directories in alphabetic
 +        ;; order (x%d before y%d).  So we rename both directions.
 +        (if (zerop (mod i 2))
 +            (progn
 +              (push (expand-file-name (format "x%d" i)) source-file-list)
 +              (push (expand-file-name (format "y%d" i)) target-file-list))
 +          (push (expand-file-name (format "y%d" i)) source-file-list)
 +          (push (expand-file-name (format "x%d" i)) target-file-list)))
 +        (file-notify--test-with-events (make-list (+ n n) 'created)
 +          (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 0.1)
 +              (write-region "" nil (pop source-file-list) nil 'no-message)
 +              (read-event nil nil 0.1)
 +              (write-region "" nil (pop target-file-list) nil 'no-message))))
 +        (file-notify--test-with-events
 +          (cond
 +           ;; w32notify fires both `deleted' and `renamed' events.
 +           ((string-equal (file-notify--test-library) "w32notify")
 +            (let (r)
 +              (dotimes (i n r)
 +                (setq r (append '(deleted renamed) 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)
 +              (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)
 +            (delete-file file))))
 +    (file-notify--test-cleanup)))
 +
 +(file-notify--deftest-remote file-notify-test06-many-events
 +   "Check that events are not dropped for remote directories.")
 +
  (defun file-notify-test-all (&optional interactive)
    "Run all tests for \\[file-notify]."
    (interactive "p")
  ;; TODO:
  
  ;; * For w32notify, no stopped events arrive when a directory is removed.
 -;; * Try to handle arriving events under cygwin reliably.
 +;; * Check, why cygwin recognizes only `deleted' and `stopped' events.
  
  (provide 'file-notify-tests)
  ;;; file-notify-tests.el ends here