unistr/u*-chr, unistr/u*-strchr: Fix link errors and warnings.
[gnulib.git] / tests / test-futimens.h
index 0335845..97c7acd 100644 (file)
@@ -1,9 +1,9 @@
 /* Test of file timestamp modification functions.
 /* Test of file timestamp modification functions.
-   Copyright (C) 2009 Free Software Foundation, Inc.
+   Copyright (C) 2009, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
-/* This file assumes that BASE and ASSERT are already defined.  */
+#include "test-utimens-common.h"
 
 
-#ifndef GL_TEST_UTIMENS
-# define GL_TEST_UTIMENS
-
-#include <fcntl.h>
-#include <errno.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "stat-time.h"
-#include "timespec.h"
-#include "utimecmp.h"
-
-enum {
-  BILLION = 1000 * 1000 * 1000,
-
-  Y2K = 946684800, /* Jan 1, 2000, in seconds since epoch.  */
-
-  /* Bogus positive and negative tv_nsec values closest to valid
-     range, but without colliding with UTIME_NOW or UTIME_OMIT.  */
-  UTIME_BOGUS_POS = BILLION + ((UTIME_NOW == BILLION || UTIME_OMIT == BILLION)
-                               ? (1 + (UTIME_NOW == BILLION + 1)
-                                  + (UTIME_OMIT == BILLION + 1))
-                               : 0),
-  UTIME_BOGUS_NEG = -1 - ((UTIME_NOW == -1 || UTIME_OMIT == -1)
-                          ? (1 + (UTIME_NOW == -2) + (UTIME_OMIT == -2))
-                          : 0)
-};
-
-#endif /* GL_TEST_UTIMENS */
-
-/* This function is designed to test both gl_futimens(a,NULL,b) and
-   futimens(a,b).  FUNC is the function to test.  If PRINT, warn
-   before skipping tests with status 77.  */
+/* This file is designed to test both gl_futimens(a,NULL,b) and
+   futimens(a,b).  FUNC is the function to test.  Assumes that BASE
+   and ASSERT are already defined.  If PRINT, warn before skipping
+   tests with status 77.  */
 static int
 test_futimens (int (*func) (int, struct timespec const *),
                bool print)
 static int
 test_futimens (int (*func) (int, struct timespec const *),
                bool print)
@@ -60,6 +31,8 @@ test_futimens (int (*func) (int, struct timespec const *),
   ASSERT (0 <= fd);
 
   /* Sanity check.  */
   ASSERT (0 <= fd);
 
   /* Sanity check.  */
+  ASSERT (fstat (fd, &st1) == 0);
+  nap ();
   errno = 0;
   result = func (fd, NULL);
   if (result == -1 && errno == ENOSYS)
   errno = 0;
   result = func (fd, NULL);
   if (result == -1 && errno == ENOSYS)
@@ -73,7 +46,32 @@ test_futimens (int (*func) (int, struct timespec const *),
       return 77;
     }
   ASSERT (!result);
       return 77;
     }
   ASSERT (!result);
-  ASSERT (fstat (fd, &st1) == 0);
+  ASSERT (fstat (fd, &st2) == 0);
+  /* If utimens truncates to less resolution than the file system
+     supports, then time can appear to go backwards between now and a
+     follow-up utimens with UTIME_NOW or a NULL timespec.  Use
+     UTIMECMP_TRUNCATE_SOURCE to compensate, with st1 as the
+     source.  */
+  ASSERT (0 <= utimecmp (BASE "file", &st2, &st1, UTIMECMP_TRUNCATE_SOURCE));
+  if (check_ctime)
+    ASSERT (st1.st_ctime < st2.st_ctime
+            || (st1.st_ctime == st2.st_ctime
+                && get_stat_ctime_ns (&st1) < get_stat_ctime_ns (&st2)));
+  {
+    /* On some NFS systems, the 'now' timestamp of creat or a NULL
+       timespec is determined by the server, but the 'now' timestamp
+       determined by gettime() (as is done when using UTIME_NOW) is
+       determined by the client; since the two machines are not
+       necessarily on the same clock, this is another case where time
+       can appear to go backwards.  The rest of this test cares about
+       client time, so manually use gettime() to set both times.  */
+    struct timespec ts[2];
+    gettime (&ts[0]);
+    ts[1] = ts[0];
+    ASSERT (func (fd, ts) == 0);
+    ASSERT (fstat (fd, &st1) == 0);
+    nap ();
+  }
 
   /* Invalid arguments.  */
   errno = 0;
 
   /* Invalid arguments.  */
   errno = 0;
@@ -107,17 +105,40 @@ test_futimens (int (*func) (int, struct timespec const *),
     ASSERT (st2.st_mtime == Y2K);
     ASSERT (0 <= get_stat_mtime_ns (&st2));
     ASSERT (get_stat_mtime_ns (&st2) < BILLION);
     ASSERT (st2.st_mtime == Y2K);
     ASSERT (0 <= get_stat_mtime_ns (&st2));
     ASSERT (get_stat_mtime_ns (&st2) < BILLION);
+    if (check_ctime)
+      ASSERT (st1.st_ctime < st2.st_ctime
+              || (st1.st_ctime == st2.st_ctime
+                  && get_stat_ctime_ns (&st1) < get_stat_ctime_ns (&st2)));
   }
 
   /* Play with UTIME_OMIT, UTIME_NOW.  */
   {
   }
 
   /* Play with UTIME_OMIT, UTIME_NOW.  */
   {
+    struct stat st3;
     struct timespec ts[2] = { { BILLION, UTIME_OMIT }, { 0, UTIME_NOW } };
     struct timespec ts[2] = { { BILLION, UTIME_OMIT }, { 0, UTIME_NOW } };
+    nap ();
+    ASSERT (func (fd, ts) == 0);
+    ASSERT (fstat (fd, &st3) == 0);
+    ASSERT (st3.st_atime == Y2K);
+    ASSERT (0 <= get_stat_atime_ns (&st3));
+    ASSERT (get_stat_atime_ns (&st3) <= BILLION / 2);
+    ASSERT (utimecmp (BASE "file", &st1, &st3, 0) <= 0);
+    if (check_ctime)
+      ASSERT (st2.st_ctime < st3.st_ctime
+              || (st2.st_ctime == st3.st_ctime
+                  && get_stat_ctime_ns (&st2) < get_stat_ctime_ns (&st3)));
+    nap ();
+    ts[0].tv_nsec = 0;
+    ts[1].tv_nsec = UTIME_OMIT;
     ASSERT (func (fd, ts) == 0);
     ASSERT (fstat (fd, &st2) == 0);
     ASSERT (func (fd, ts) == 0);
     ASSERT (fstat (fd, &st2) == 0);
-    ASSERT (st2.st_atime == Y2K);
-    ASSERT (0 <= get_stat_atime_ns (&st2));
-    ASSERT (get_stat_atime_ns (&st2) <= BILLION / 2);
-    ASSERT (utimecmp (BASE "file", &st1, &st2, 0) <= 0);
+    ASSERT (st2.st_atime == BILLION);
+    ASSERT (get_stat_atime_ns (&st2) == 0);
+    ASSERT (st3.st_mtime == st2.st_mtime);
+    ASSERT (get_stat_mtime_ns (&st3) == get_stat_mtime_ns (&st2));
+    if (check_ctime)
+      ASSERT (st3.st_ctime < st2.st_ctime
+              || (st3.st_ctime == st2.st_ctime
+                  && get_stat_ctime_ns (&st3) < get_stat_ctime_ns (&st2)));
   }
 
   /* Cleanup.  */
   }
 
   /* Cleanup.  */