test-stat-time: avoid more spurious failures
authorEric Blake <ebb9@byu.net>
Sat, 10 Oct 2009 14:04:41 +0000 (08:04 -0600)
committerEric Blake <ebb9@byu.net>
Sat, 10 Oct 2009 14:21:18 +0000 (08:21 -0600)
On xfs, although timestamps can have a full nanosecond resolution,
successive file actions appear to be quantized to approximately
10 millisecond windows.  Running with just 1 ms delays could
cause two actions to fall in the same window, leading to sporadic
failures on a fast enough machine.  Slow down to prevent this.

On ext2, timestamps only have 1 second resolution, but if the
first timestamp was made at 1.95 and the second at 2.10, then
the two files appear 1 second apart, and the shorter delay was
used, causing spurious failures.  Require that the observable
difference lie within the same second, using a second try if
necessary, to prevent this.

* tests/test-stat-time.c (nap): Wait for 15ms rather than 2ms, for
xfs; and avoid race if the two timestamps cross quantization edge.

Signed-off-by: Eric Blake <ebb9@byu.net>
ChangeLog
tests/test-stat-time.c

index 042d7e2..379780e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2009-10-10  Eric Blake  <ebb9@byu.net>
 
+       test-stat-time: avoid more spurious failures
+       * tests/test-stat-time.c (nap): Wait for 15ms rather than 2ms, for
+       xfs; and avoid race if the two timestamps cross quantization edge.
+
        relocatable: prefer 'file system' over 'filesystem'
        * m4/relocatable-lib.m4 (gl_RELOCATABLE_NOP): Use AS_HELP_STRING.
        (gl_RELOCATABLE_LIBRARY_BODY): Fix spelling.
index 3759024..da52851 100644 (file)
@@ -104,19 +104,31 @@ nap (void)
   static long delay;
   if (!delay)
     {
-      /* Initialize only once, by sleeping for 1 millisecond.  If that
-         was enough to observe a difference, then we are set;
-         otherwise fall back to 2 seconds.  */
+      /* Initialize only once, by sleeping for 15 milliseconds (needed
+         since xfs has a quantization of about 10 milliseconds, even
+         though it has a granularity of 1 nanosecond).  If the seconds
+         differ, repeat the test one more time (in case we crossed a
+         quantization boundary on a file system with 1 second
+         resolution).  If we can't observe a difference in only the
+         nanoseconds, then fall back to 2 seconds.  */
       struct stat st1;
       struct stat st2;
       ASSERT (stat ("t-stt-stamp1", &st1) == 0);
       ASSERT (unlink ("t-stt-stamp1") == 0);
-      usleep (delay = 1000);
+      usleep (delay = 15000);
       create_file ("t-stt-stamp1");
       ASSERT (stat ("t-stt-stamp1", &st2) == 0);
-      if (! (st1.st_mtime < st2.st_mtime
-             || (st1.st_mtime == st2.st_mtime
-                 && get_stat_mtime_ns (&st1) < get_stat_mtime_ns (&st2))))
+      if (st1.st_mtime != st2.st_mtime)
+        {
+          /* Seconds differ, give it one more shot.  */
+          st1 = st2;
+          ASSERT (unlink ("t-stt-stamp1") == 0);
+          usleep (delay);
+          create_file ("t-stt-stamp1");
+          ASSERT (stat ("t-stt-stamp1", &st2) == 0);
+        }
+      if (! (st1.st_mtime == st2.st_mtime
+             && get_stat_mtime_ns (&st1) < get_stat_mtime_ns (&st2)))
         delay = 2000000;
     }
   usleep (delay);