Hash :
4d8f2295
Author :
Date :
2009-10-12T10:42:35
test-stat-time, test-utimens: improve portability
ext4 on an alpha system has a quantization of about 10 ms but
a resolution of 1ns; utimecmp does not know about quantization,
so tests were failing when comparing timestamps that fall
within the same quantization window. Add strategic usleeps
throughout to minimize this issue, whether or not we later
improve utimecmp to account for quantization.
Windows (and hence cygwin) is documented as having a default
clock quantization of 15.25 milliseconds (although it can be
reduced to 1 millisecond); file timestamps are quantized to this
boundary even though more accurate timing can be obtained.
However, this means that 15 milliseconds is too short for any
test that wants to guarantee crossing a file timestamp boundary.
Cygwin, however, still has bugs where clock_gettime can lag
behind file timestamps, which is not fixed by this patch.
Solaris 9 with NFS exposed the same problem for futimes that was
previously fixed for utimes on Solaris 8, where futimens(f,NULL)
uses a different time source than futimes(,{,UTIME_NOW}).
* tests/test-stat-time.c (nap): Lengthen delay to 20ms, for
ext4 on alpha, and for cygwin.
* tests/test-utimens-common.h: New file.
(nap): Factor delays into single function.
* tests/test-lutimens.h (test_lutimens): Use new header.
* tests/test-futimens.h (test_futimens): Likewise.
* tests/test-utimens.h (test_utimens): Likewise. Also, force NFS
timestamps to occur from same machine, as was done previously for
test_utimens.
* modules/utimens-tests (Files): Ship new file.
* modules/futimens-tests (Files): Likewise.
Reported in part by Jim Meyering.
Signed-off-by: Eric Blake <ebb9@byu.net>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
/* Test of file timestamp modification functions.
Copyright (C) 2009 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
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
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 defines some prerequisites useful to utime-related tests. */
#ifndef GL_TEST_UTIMENS_COMMON
# define GL_TEST_UTIMENS_COMMON
#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)
};
/* Sleep long enough to cross a timestamp quantization boundary on
most known systems with subsecond timestamp resolution. For
example, ext4 has a quantization of 10 milliseconds, but a
resolution of 1 nanosecond. Likewise, NTFS has a quantization as
slow as 15.25 milliseconds, but a resolution of 100 nanoseconds.
This is necessary on systems where creat or utimens with NULL
rounds down to the quantization boundary, but where gettime and
hence utimensat can inject timestamps between quantization
boundaries. By ensuring we cross a boundary, we are less likely to
confuse utimecmp for two times that would round to the same
quantization boundary but are distinct based on resolution. */
static void
nap (void)
{
/* Systems that lack usleep also lack subsecond timestamps. Our
usage of utimecmp allows equality, so we don't need to sleep. */
#if HAVE_USLEEP
usleep (20 * 1000); /* 20 milliseconds. */
#endif
}
#endif /* GL_TEST_UTIMENS_COMMON */