[PATCH v2 4/5] psx13: Added tests for utimensat() and futimens()
Ryan Long
ryan.long at oarcorp.com
Thu May 6 19:50:48 UTC 2021
Improved tests for utime() and utimes() and update license.
Close #4399
---
testsuites/psxtests/psx13/main.c | 5 +-
testsuites/psxtests/psx13/test.c | 517 +++++++++++++++++++++++++++++++++++++--
2 files changed, 498 insertions(+), 24 deletions(-)
diff --git a/testsuites/psxtests/psx13/main.c b/testsuites/psxtests/psx13/main.c
index f9e7907..7a560f9 100644
--- a/testsuites/psxtests/psx13/main.c
+++ b/testsuites/psxtests/psx13/main.c
@@ -1,5 +1,3 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-
/**
* @file
*
@@ -8,8 +6,7 @@
*/
/*
- * COPYRIGHT (c) 1989-2009, 2021.
- * On-Line Applications Research Corporation (OAR).
+ * COPYRIGHT (C) 1989, 2021 On-Line Applications Research Corporation (OAR).
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/testsuites/psxtests/psx13/test.c b/testsuites/psxtests/psx13/test.c
index e98b03a..cc929ef 100644
--- a/testsuites/psxtests/psx13/test.c
+++ b/testsuites/psxtests/psx13/test.c
@@ -1,5 +1,3 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-
/**
* @file
*
@@ -17,12 +15,13 @@
* - umask()
* - utime()
* - utimes()
+ * - utimensat()
+ * - futimens()
* - sync()
*/
/*
- * COPYRIGHT (c) 1989-2009, 2021.
- * On-Line Applications Research Corporation (OAR).
+ * COPYRIGHT (C) 1989, 2021 On-Line Applications Research Corporation (OAR).
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -210,8 +209,7 @@ static void Dup2Test( void )
}
/**
- * @brief Exercises fdatasync(). Does NOT test the functionality of the
- * underlying fdatasync entry in the IMFS op table.
+ * @brief Exercises fdatasync().
*/
static void FDataSyncTest( void )
{
@@ -259,60 +257,537 @@ static void UMaskTest( void )
}
/**
- * @brief Exercises utime(). Does not test the functionality of the
- * underlying utime entry in the IMFS op table.
+ * @brief Exercises utime().
*/
static void UTimeTest( void )
{
int rv;
struct utimbuf time;
+ struct timespec current_time;
struct stat fstat;
- /* First, an invalid filename. */
+ /* ENOENT test case */
+
+ /* Case: Pass an invalid filename. */
rv = utime( "!This is an =invalid p at thname!!! :)", NULL );
rtems_test_assert( rv == -1 );
rtems_test_assert( errno == ENOENT );
- /* Now, the success test. */
+ /* EACCES test case */
+
+ /* Case: Change user ID to someone besides root */
+ rv = seteuid( 1 );
+ rtems_test_assert( rv == 0 );
+
+ rv = utime( "testfile1.tst", NULL );
+ rtems_test_assert( rv == -1 );
+ rtems_test_assert( errno == EACCES );
+
+ rv = seteuid( 0 );
+ rtems_test_assert( rv == 0 );
+
+ /* EINVAL test cases */
+
+ /* Case: Invalid access time */
+ time.actime = -1;
+ time.modtime = 54321;
+
+ rv = utime( "testfile1.tst", &time );
+ rtems_test_assert( rv == -1 );
+ rtems_test_assert( errno == EINVAL );
+
+ /* Case: Invalid modified time */
+ time.actime = 12345;
+ time.modtime = -1;
+
+ rv = utime( "testfile1.tst", &time );
+ rtems_test_assert( rv == -1 );
+ rtems_test_assert( errno == EINVAL );
+
+ /* Successful test cases */
+
+ /* Case: Test without times argument */
+ clock_gettime( CLOCK_REALTIME, ¤t_time );
+
+ rv = utime( "testfile1.tst", NULL );
+ rtems_test_assert( rv == 0 );
+
+ rv = stat( "testfile1.tst", &fstat );
+ rtems_test_assert( rv == 0 );
+ rtems_test_assert( current_time.tv_sec <= fstat.st_atim.tv_sec );
+ rtems_test_assert( current_time.tv_sec <= fstat.st_mtim.tv_sec );
+
+ /* Case: time is filled with valid values */
time.actime = 12345;
time.modtime = 54321;
rv = utime( "testfile1.tst", &time );
rtems_test_assert( rv == 0 );
- /* But, did it set the time? */
+ /* Check that it actually changed the time */
rv = stat( "testfile1.tst", &fstat );
rtems_test_assert( rv == 0 );
rtems_test_assert( fstat.st_atime == 12345 );
rtems_test_assert( fstat.st_mtime == 54321 );
-
- rv = utime( "testfile1.tst", NULL );
- rtems_test_assert( rv == 0 );
}
/**
- * @brief Exercises utimes(). Does NOT test the functionality of the
- * underlying utime entry in the IMFS op table.
+ * @brief Exercises utimes().
*/
static void UTimesTest( void )
{
int rv;
struct timeval time[2];
+ struct timespec current_time;
struct stat fstat;
- /* First, an invalid filename. */
+ /* ENOENT test case */
+
+ /* Case: First, an invalid filename. */
rv = utimes( "!This is an =invalid p at thname!!! : )", NULL);
rtems_test_assert( rv == -1 );
rtems_test_assert( errno == ENOENT );
- /* Now, the success test. */
+ /* EACCES test case */
+
+ /* Change the user ID of the process to someone besides root */
+ rv = seteuid( 1 );
+ rtems_test_assert( rv == 0 );
+
+ rv = utimes( "testfile1.tst", NULL );
+ rtems_test_assert( rv == -1 );
+ rtems_test_assert( errno == EACCES );
+
+ rv = seteuid( 0 );
+ rtems_test_assert( rv == 0 );
+
+ /* EINVAL test cases */
+
+ /* Case: Negative access time tv_sec value */
+ time[0].tv_sec = -1;
+ time[0].tv_usec = 12345;
+ time[1].tv_sec = 54321;
+ time[1].tv_usec = 54321;
+
+ rv = utimes( "testfile1.tst", time );
+ rtems_test_assert( rv == -1 );
+ rtems_test_assert( errno == EINVAL );
+
+ /* Case: Negative modified time second value */
+ time[0].tv_sec = 12345;
+ time[1].tv_sec = -1;
+
+ rv = utimes( "testfile1.tst", time );
+ rtems_test_assert( rv == -1 );
+ rtems_test_assert( errno == EINVAL );
+
+ /* Case: Negative access time microsecond value */
+ time[1].tv_sec = 54321;
+ time[0].tv_usec = -1;
+
+ rv = utimes( "testfile1.tst", time );
+ rtems_test_assert( rv == -1 );
+ rtems_test_assert( errno == EINVAL );
+
+ /* Case: Negative modified time microsecond value */
+ time[0].tv_usec = 12345;
+ time[1].tv_usec = -1;
+
+ rv = utimes( "testfile1.tst", time );
+ rtems_test_assert( rv == -1 );
+ rtems_test_assert( errno == EINVAL );
+
+ /* Case: Access time microsecond value too large */
+ time[0].tv_usec = 1000000;
+ time[1].tv_usec = 54321;
+
+ rv = utimes( "testfile1.tst", time );
+ rtems_test_assert( rv == -1 );
+ rtems_test_assert( errno == EINVAL );
+
+ /* Case: Modified time microsecond value too large */
+ time[1].tv_usec = 1000000;
+ time[0].tv_usec = 12345;
+
+ rv = utimes( "testfile1.tst", time );
+ rtems_test_assert( rv == -1 );
+ rtems_test_assert( errno == EINVAL );
+
+ /* Successful test cases */
+
+ /* Case: Test without times argument */
+ clock_gettime( CLOCK_REALTIME, ¤t_time );
+
+ rv = utimes( "testfile1.tst", NULL );
+ rtems_test_assert( rv == 0 );
+
+ rv = stat( "testfile1.tst", &fstat );
+ rtems_test_assert( rv == 0 );
+ rtems_test_assert( current_time.tv_sec <= fstat.st_atim.tv_sec );
+ rtems_test_assert( current_time.tv_sec <= fstat.st_mtim.tv_sec );
+
+ /* Case: time is filled with valid values */
+ time[0].tv_sec = 12345;
+ time[0].tv_usec = 12345;
+ time[1].tv_sec = 54321;
+ time[1].tv_usec = 54321;
+
+ rv = utimes( "testfile1.tst", time );
+ rtems_test_assert( rv == 0 );
+
+ /* Check that it actually changed the time */
+ rv = stat( "testfile1.tst", &fstat );
+ rtems_test_assert( rv == 0 );
+ rtems_test_assert( fstat.st_atime == 12345 );
+ rtems_test_assert( fstat.st_mtime == 54321 );
+}
+
+/**
+ * @brief Exercises utimensat().
+ */
+static void UTimensatTest( void )
+{
+ int rv;
+ struct timespec time[2];
+ struct timespec current_time;
+ struct stat fstat;
+
+ /* ENOSYS test cases */
+
+ /* Case: Pass an unsupported file descriptor */
+ rv = utimensat(
+ 0,
+ "!This is an =invalid p at thname!!! : )",
+ NULL,
+ 0
+ );
+ rtems_test_assert( rv == -1 );
+ rtems_test_assert( errno == ENOSYS );
+
+ /* Case: Pass unsupported flag */
+ rv = utimensat(
+ AT_FDCWD,
+ "!This is an =invalid p at thname!!! : )",
+ NULL,
+ 1
+ );
+ rtems_test_assert( rv == -1 );
+ rtems_test_assert( errno == ENOSYS );
+
+ /* ENOENT test case */
+
+ /* Use an invalid filename. */
+ rv = utimensat(
+ AT_FDCWD,
+ "!This is an =invalid p at thname!!! : )",
+ NULL,
+ 0
+ );
+ rtems_test_assert( rv == -1 );
+ rtems_test_assert( errno == ENOENT );
+
+ rv = stat( "testfile1.tst", &fstat );
+ rtems_test_assert( rv == 0 );
+
+ /* EACCES test Cases */
+
+ /* Case: When times is NULL and the user has insufficient privileges */
+
+ /* Change the user ID of the process to someone besides root */
+ rv = seteuid( 1 );
+ rtems_test_assert( rv == 0 );
+
+ rv = utimensat( AT_FDCWD, "testfile1.tst", NULL, 0 );
+ rtems_test_assert( rv == -1 );
+ rtems_test_assert( errno == EACCES );
+
+ rv = seteuid( 0 );
+ rtems_test_assert( rv == 0 );
+
+ /* Case: File is read-only and time's tv_nsec members are UTIME_NOW */
+
+ /* Change file to be read-only */
+ rv = chmod( "testfile1.tst", 06444 );
+ rtems_test_assert( rv == 0 );
+
+ time[0].tv_sec = 0;
+ time[0].tv_nsec = UTIME_NOW;
+ time[1].tv_sec = 0;
+ time[1].tv_nsec = UTIME_NOW;
+
+ rv = utimensat( AT_FDCWD, "testfile1.tst", time, 0 );
+ rtems_test_assert( rv == -1 );
+ rtems_test_assert( errno == EACCES );
+
+ rv = chmod( "testfile1.tst", fstat.st_mode );
+ rtems_test_assert( rv == 0 );
+
+ /* EINVAL test cases */
+
+ /* Case: Negative access time second value */
+ time[0].tv_sec = -12345;
+ time[0].tv_nsec = 12345;
+ time[1].tv_sec = 54321;
+ time[1].tv_nsec = 54321;
+
+ rv = utimensat( AT_FDCWD, "testfile1.tst", time, 0 );
+ rtems_test_assert( rv == -1 );
+ rtems_test_assert( errno == EINVAL );
+
+ /* Case: Negative modified time second value */
+ time[0].tv_sec = 12345;
+ time[1].tv_sec = -54321;
+
+ rv = utimensat( AT_FDCWD, "testfile1.tst", time, 0 );
+ rtems_test_assert( rv == -1 );
+ rtems_test_assert( errno == EINVAL );
+
+ /* Case: Negative access time nanosecond value */
+ time[1].tv_sec = 54321;
+ time[0].tv_nsec = -12345;
+
+ rv = utimensat( AT_FDCWD, "testfile1.tst", time, 0 );
+ rtems_test_assert( rv == -1 );
+ rtems_test_assert( errno == EINVAL );
+
+ /* Case: Negative modified time nanosecond value */
+ time[0].tv_nsec = 12345;
+ time[1].tv_nsec = -54321;
+
+ rv = utimensat( AT_FDCWD, "testfile1.tst", time, 0 );
+ rtems_test_assert( rv == -1 );
+ rtems_test_assert( errno == EINVAL );
+
+ /* Case: Access time nanosecond value too large */
+ time[0].tv_nsec = 1000000000;
+ time[1].tv_nsec = 54321;
+
+ rv = utimensat( AT_FDCWD, "testfile1.tst", time, 0 );
+ rtems_test_assert( rv == -1 );
+ rtems_test_assert( errno == EINVAL );
+
+ /* Case: Modified time nanosecond value too large */
+ time[1].tv_nsec = 1000000000;
+ time[0].tv_nsec = 12345;
+
+ rv = utimensat( AT_FDCWD, "testfile1.tst", time, 0 );
+ rtems_test_assert( rv == -1 );
+ rtems_test_assert( errno == EINVAL );
+
+ /* Successful test cases */
+
+ /* Case: Test without times argument */
+ clock_gettime( CLOCK_REALTIME, ¤t_time );
+
+ rv = utimensat( AT_FDCWD, "testfile1.tst", NULL, 0 );
+ rtems_test_assert( rv == 0 );
+
+ rv = stat( "testfile1.tst", &fstat );
+ rtems_test_assert( rv == 0 );
+ rtems_test_assert( current_time.tv_sec <= fstat.st_atim.tv_sec );
+ rtems_test_assert( current_time.tv_sec <= fstat.st_mtim.tv_sec );
+
+ /* Case: Running with access time nanosecond field equal to UTIME_NOW */
+ time[0].tv_sec = 12345;
+ time[0].tv_nsec = UTIME_NOW;
+ time[1].tv_sec = 54321;
+ time[1].tv_nsec = 54321;
+
+ rv = utimensat( AT_FDCWD, "testfile1.tst", time, 0 );
+ rtems_test_assert( rv == 0 );
+
+ rv = stat( "testfile1.tst", &fstat );
+ rtems_test_assert( rv == 0 );
+ rtems_test_assert( current_time.tv_sec <= fstat.st_atim.tv_sec );
+ rtems_test_assert( fstat.st_mtime == 54321 );
+
+ /* Case: Running with modified time nanosecond field equal to UTIME_NOW */
+ time[0].tv_sec = 12345;
+ time[0].tv_nsec = 12345;
+ time[1].tv_sec = 54321;
+ time[1].tv_nsec = UTIME_NOW;
+
+ rv = utimensat( AT_FDCWD, "testfile1.tst", time, 0 );
+ rtems_test_assert( rv == 0 );
+
+ rv = stat( "testfile1.tst", &fstat );
+ rtems_test_assert( rv == 0 );
+ rtems_test_assert( fstat.st_atime == 12345 );
+ rtems_test_assert( current_time.tv_sec <= fstat.st_mtim.tv_sec );
+
+ /* Case: Normal run */
+ time[0].tv_sec = 12345;
+ time[0].tv_nsec = 12345;
+ time[1].tv_sec = 54321;
+ time[1].tv_nsec = 54321;
+
+ rv = utimensat( AT_FDCWD, "testfile1.tst", time, 0 );
+ rtems_test_assert( rv == 0 );
+
+ /* Check that it actually changed the time */
+ rv = stat( "testfile1.tst", &fstat );
+ rtems_test_assert( rv == 0 );
+ rtems_test_assert( fstat.st_atime == 12345 );
+ rtems_test_assert( fstat.st_mtime == 54321 );
+}
+
+/**
+ * @brief Exercises futimens().
+ */
+static void FutimensTest( void )
+{
+ int rv;
+ int fd;
+ struct timespec time[2];
+ struct timespec current_time;
+ struct stat fstat;
+
+ /* EBADF test case */
+
+ /* Case: Pass an invalid file descriptor */
+ rv = futimens( -1, time );
+ rtems_test_assert( rv == -1 );
+ rtems_test_assert( errno == EBADF );
+
+ fd = open( "testfile1.tst", O_RDWR );
+ rtems_test_assert( fd != -1 );
+
+ /* EACCES test cases */
+
+ /* Case: When times is NULL and the user has insufficient privileges */
+
+ /* Change the user ID of the process to someone besides root */
+ rv = seteuid( 1 );
+ rtems_test_assert( rv == 0 );
+
+ rv = futimens( fd, NULL );
+ rtems_test_assert( rv == -1 );
+ rtems_test_assert( errno == EACCES );
+
+ rv = seteuid( 0 );
+ rtems_test_assert( rv == 0 );
+
+ /* Case: File is read-only and time's tv_nsec members are UTIME_NOW */
+
+ /* Change file to be read-only */
+ rv = chmod( "testfile1.tst", 06444 );
+ rtems_test_assert( rv == 0 );
+
+ time[0].tv_sec = 0;
+ time[0].tv_nsec = UTIME_NOW;
+ time[1].tv_sec = 0;
+ time[1].tv_nsec = UTIME_NOW;
+
+ rv = futimens( fd, time );
+ rtems_test_assert( rv == -1 );
+ rtems_test_assert( errno == EACCES );
+
+ rv = chmod( "testfile1.tst", fstat.st_mode );
+ rtems_test_assert( rv == 0 );
+
+ /* EINVAL test cases */
+
+ /* Case: Negative access time second value */
+ time[0].tv_sec = -12345;
+ time[0].tv_nsec = 12345;
+ time[1].tv_sec = 54321;
+ time[1].tv_nsec = 54321;
+
+ rv = futimens( fd, time );
+ rtems_test_assert( rv == -1 );
+ rtems_test_assert( errno == EINVAL );
+
+ /* Case: Negative modified time second value */
+ time[0].tv_sec = 12345;
+ time[1].tv_sec = -54321;
+
+ rv = futimens( fd, time );
+ rtems_test_assert( rv == -1 );
+ rtems_test_assert( errno == EINVAL );
+
+ /* Case: Negative access time nanosecond value */
+ time[1].tv_sec = 54321;
+ time[0].tv_nsec = -12345;
+
+ rv = futimens( fd, time );
+ rtems_test_assert( rv == -1 );
+ rtems_test_assert( errno == EINVAL );
+
+ /* Case: Negative modified time nanosecond value */
+ time[0].tv_nsec = 12345;
+ time[1].tv_nsec = -54321;
+
+ rv = futimens( fd, time );
+ rtems_test_assert( rv == -1 );
+ rtems_test_assert( errno == EINVAL );
+
+ /* Case: Access time nanosecond value too large */
+ time[0].tv_nsec = 1000000000;
+ time[1].tv_nsec = 54321;
+
+ rv = futimens( fd, time );
+ rtems_test_assert( rv == -1 );
+ rtems_test_assert( errno == EINVAL );
+
+ /* Case: Modified time nanosecond value too large */
+ time[1].tv_nsec = 1000000000;
+ time[0].tv_nsec = 12345;
+
+ rv = futimens( fd, time );
+ rtems_test_assert( rv == -1 );
+ rtems_test_assert( errno == EINVAL );
+
+ /* Successful test cases */
+
+ /* Case: Test without times argument */
+ clock_gettime( CLOCK_REALTIME, ¤t_time );
+
+ rv = futimens( fd, NULL );
+ rtems_test_assert( rv == 0 );
+
+ rv = stat( "testfile1.tst", &fstat );
+ rtems_test_assert( rv == 0 );
+ rtems_test_assert( current_time.tv_sec <= fstat.st_atim.tv_sec );
+ rtems_test_assert( current_time.tv_sec <= fstat.st_mtim.tv_sec );
+
+/* Case: Running with access time nanosecond field equal to UTIME_NOW */
+ time[0].tv_sec = 12345;
+ time[0].tv_nsec = UTIME_NOW;
+ time[1].tv_sec = 54321;
+ time[1].tv_nsec = 54321;
+
+ rv = futimens( fd, time );
+ rtems_test_assert( rv == 0 );
+
+ rv = stat( "testfile1.tst", &fstat );
+ rtems_test_assert( rv == 0 );
+ rtems_test_assert( current_time.tv_sec <= fstat.st_atim.tv_sec );
+ rtems_test_assert( fstat.st_mtime == 54321 );
+
+ /* Case: Running with modified time nanosecond field equal to UTIME_NOW */
+ time[0].tv_sec = 12345;
+ time[0].tv_nsec = 12345;
+ time[1].tv_sec = 54321;
+ time[1].tv_nsec = UTIME_NOW;
+
+ rv = futimens( fd, time );
+ rtems_test_assert( rv == 0 );
+
+ rv = stat( "testfile1.tst", &fstat );
+ rtems_test_assert( rv == 0 );
+ rtems_test_assert( fstat.st_atime == 12345 );
+ rtems_test_assert( current_time.tv_sec <= fstat.st_mtim.tv_sec );
+
+ /* Case: Normal run */
time[0].tv_sec = 12345;
+ time[0].tv_nsec = 12345;
time[1].tv_sec = 54321;
+ time[1].tv_nsec = 54321;
- rv = utimes( "testfile1.tst", (struct timeval *)&time );
+ rv = futimens( fd, time );
rtems_test_assert( rv == 0 );
- /* But, did it set the time? */
+ /* Check that it actually changed the time */
rv = stat( "testfile1.tst", &fstat );
rtems_test_assert( rv == 0 );
rtems_test_assert( fstat.st_atime == 12345 );
@@ -443,6 +918,8 @@ int test_main( void )
UMaskTest();
UTimeTest();
UTimesTest();
+ UTimensatTest();
+ FutimensTest();
FSyncTest();
PathConfTest();
FPathConfTest();
--
1.8.3.1
More information about the devel
mailing list