From bff8e70b16bf68e74178f692ba9a48e83b7afe85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20B=C3=A9rat?= Date: Thu, 16 Oct 2025 10:30:01 +0200 Subject: [PATCH] Add tests of time, gettimeofday, clock_gettime (RHEL-119386) Resolves: RHEL-119386 --- glibc-RHEL-119386-1.patch | 70 +++++++ glibc-RHEL-119386-2.patch | 428 ++++++++++++++++++++++++++++++++++++++ glibc-RHEL-119386-3.patch | 24 +++ 3 files changed, 522 insertions(+) create mode 100644 glibc-RHEL-119386-1.patch create mode 100644 glibc-RHEL-119386-2.patch create mode 100644 glibc-RHEL-119386-3.patch diff --git a/glibc-RHEL-119386-1.patch b/glibc-RHEL-119386-1.patch new file mode 100644 index 0000000..359be3f --- /dev/null +++ b/glibc-RHEL-119386-1.patch @@ -0,0 +1,70 @@ +commit 255df9299f544ad9e027e0c8d6b65b0635c59f8c +Author: Samuel Dobron +Date: Thu Jul 11 05:31:11 2024 +0200 + + time/Makefile: Split and sort tests + + Reviewed-by: Adhemerval Zanella + +diff --git a/time/Makefile b/time/Makefile +index 5b541fb9d3be1c28..059d85c151401587 100644 +--- a/time/Makefile ++++ b/time/Makefile +@@ -42,15 +42,48 @@ routines := offtime asctime clock ctime ctime_r difftime \ + + aux := era alt_digit lc-time-cleanup + +-tests := test_time clocktest tst-posixtz tst-strptime tst_wcsftime \ +- tst-getdate tst-mktime tst-mktime2 tst-ftime_l tst-strftime \ +- tst-mktime3 tst-strptime2 bug-asctime bug-asctime_r bug-mktime1 \ +- tst-strptime3 bug-getdate1 tst-strptime-whitespace tst-ftime \ +- tst-tzname tst-y2039 bug-mktime4 tst-strftime2 tst-strftime3 \ +- tst-clock tst-clock2 tst-clock_nanosleep tst-cpuclock1 \ +- tst-adjtime tst-ctime tst-difftime tst-mktime4 tst-clock_settime \ +- tst-settimeofday tst-itimer tst-gmtime tst-timegm \ +- tst-timespec_get tst-timespec_getres tst-strftime4 ++tests := \ ++ bug-asctime \ ++ bug-asctime_r \ ++ bug-getdate1 \ ++ bug-mktime1 \ ++ bug-mktime4 \ ++ clocktest \ ++ test_time \ ++ tst-adjtime \ ++ tst-clock \ ++ tst-clock2 \ ++ tst-clock_nanosleep \ ++ tst-clock_settime \ ++ tst-cpuclock1 \ ++ tst-ctime \ ++ tst-difftime \ ++ tst-ftime \ ++ tst-ftime_l \ ++ tst-getdate \ ++ tst-gmtime \ ++ tst-itimer \ ++ tst-mktime \ ++ tst-mktime2 \ ++ tst-mktime3 \ ++ tst-mktime4 \ ++ tst-posixtz \ ++ tst-settimeofday \ ++ tst-strftime \ ++ tst-strftime2 \ ++ tst-strftime3 \ ++ tst-strftime4 \ ++ tst-strptime \ ++ tst-strptime-whitespace \ ++ tst-strptime2 \ ++ tst-strptime3 \ ++ tst-timegm \ ++ tst-timespec_get \ ++ tst-timespec_getres \ ++ tst-tzname \ ++ tst-y2039 \ ++ tst_wcsftime \ ++ # tests + + tests-time64 := \ + tst-adjtime-time64 \ diff --git a/glibc-RHEL-119386-2.patch b/glibc-RHEL-119386-2.patch new file mode 100644 index 0000000..6c39662 --- /dev/null +++ b/glibc-RHEL-119386-2.patch @@ -0,0 +1,428 @@ +commit e5ea9aef5468404eecc8c990e6852315b7d1a0e3 +Author: Joseph Myers +Date: Wed Oct 30 16:48:38 2024 +0000 + + Add tests of time, gettimeofday, clock_gettime + + There are no tests specifically focused on the functions time, + gettimeofday and clock_gettime, although there are some incidental + uses in tests of other functions. Add tests specifically for these + three functions. + + Tested for x86_64 and x86. + +diff --git a/time/Makefile b/time/Makefile +index 059d85c151401587..b57963c1c6443770 100644 +--- a/time/Makefile ++++ b/time/Makefile +@@ -53,6 +53,7 @@ tests := \ + tst-adjtime \ + tst-clock \ + tst-clock2 \ ++ tst-clock_gettime \ + tst-clock_nanosleep \ + tst-clock_settime \ + tst-cpuclock1 \ +@@ -61,6 +62,7 @@ tests := \ + tst-ftime \ + tst-ftime_l \ + tst-getdate \ ++ tst-gettimeofday \ + tst-gmtime \ + tst-itimer \ + tst-mktime \ +@@ -77,6 +79,7 @@ tests := \ + tst-strptime-whitespace \ + tst-strptime2 \ + tst-strptime3 \ ++ tst-time \ + tst-timegm \ + tst-timespec_get \ + tst-timespec_getres \ +@@ -89,16 +92,19 @@ tests-time64 := \ + tst-adjtime-time64 \ + tst-clock-time64 \ + tst-clock2-time64 \ ++ tst-clock_gettime-time64 \ + tst-clock_nanosleep-time64 \ + tst-clock_settime-time64 \ + tst-cpuclock1-time64 \ + tst-ctime-time64 \ + tst-difftime-time64 \ ++ tst-gettimeofday-time64 \ + tst-gmtime-time64 \ + tst-itimer-time64 \ + tst-mktime4-time64 \ + tst-settimeofday-time64 \ + tst-strftime4-time64 \ ++ tst-time-time64 \ + tst-timegm-time64 \ + tst-timespec_get-time64 \ + tst-timespec_getres-time64 \ +diff --git a/time/tst-clock_gettime-time64.c b/time/tst-clock_gettime-time64.c +new file mode 100644 +index 0000000000000000..5b215d11f8a0a424 +--- /dev/null ++++ b/time/tst-clock_gettime-time64.c +@@ -0,0 +1 @@ ++#include "tst-clock_gettime.c" +diff --git a/time/tst-clock_gettime.c b/time/tst-clock_gettime.c +new file mode 100644 +index 0000000000000000..51f24c0be2084a91 +--- /dev/null ++++ b/time/tst-clock_gettime.c +@@ -0,0 +1,184 @@ ++/* Test clock_gettime function. ++ Copyright (C) 2024 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++/* Compare two struct timespec values, returning a value -1, 0 or 1. */ ++ ++int ++compare_timespec (const struct timespec *tv1, const struct timespec *tv2) ++{ ++ if (tv1->tv_sec < tv2->tv_sec) ++ return -1; ++ if (tv1->tv_sec > tv2->tv_sec) ++ return 1; ++ if (tv1->tv_nsec < tv2->tv_nsec) ++ return -1; ++ if (tv1->tv_nsec > tv2->tv_nsec) ++ return 1; ++ return 0; ++} ++ ++struct test_clockid ++{ ++ clockid_t clockid; ++ const char *name; ++ bool is_cputime; ++ bool fail_ok; ++}; ++ ++#define CLOCK(clockid) { clockid, # clockid, false, false } ++#define CLOCK_CPU(clockid) { clockid, # clockid, true, false } ++#define CLOCK_FAIL_OK(clockid) { clockid, # clockid, false, true } ++ ++static const struct test_clockid clocks[] = ++ { ++ CLOCK (CLOCK_REALTIME), ++#ifdef CLOCK_MONOTONIC ++ CLOCK (CLOCK_MONOTONIC), ++#endif ++#ifdef CLOCK_PROCESS_CPUTIME_ID ++ CLOCK_CPU (CLOCK_PROCESS_CPUTIME_ID), ++#endif ++#ifdef CLOCK_THREAD_CPUTIME_ID ++ CLOCK_CPU (CLOCK_THREAD_CPUTIME_ID), ++#endif ++#ifdef CLOCK_MONOTONIC_RAW ++ CLOCK (CLOCK_MONOTONIC_RAW), ++#endif ++#ifdef CLOCK_REALTIME_COARSE ++ CLOCK (CLOCK_REALTIME_COARSE), ++#endif ++#ifdef CLOCK_MONOTONIC_COARSE ++ CLOCK (CLOCK_MONOTONIC_COARSE), ++#endif ++#ifdef CLOCK_BOOTTIME ++ CLOCK (CLOCK_BOOTTIME), ++#endif ++#ifdef CLOCK_REALTIME_ALARM ++ CLOCK_FAIL_OK (CLOCK_REALTIME_ALARM), ++#endif ++#ifdef CLOCK_BOOTTIME_ALARM ++ CLOCK_FAIL_OK (CLOCK_BOOTTIME_ALARM), ++#endif ++#ifdef CLOCK_TAI ++ CLOCK (CLOCK_TAI), ++#endif ++ }; ++ ++ ++volatile int sigalrm_received; ++ ++void ++handle_sigalrm (int sig) ++{ ++ sigalrm_received = 1; ++} ++ ++int ++do_test (void) ++{ ++ /* Verify that the calls to clock_gettime succeed, that the time does ++ not decrease, and that time returns a truncated (not rounded) ++ version of the time. */ ++ for (size_t i = 0; i < sizeof clocks / sizeof clocks[0]; i++) ++ { ++ printf ("testing %s\n", clocks[i].name); ++ struct timespec ts1, ts2, ts3; ++ int ret; ++ time_t t1; ++ t1 = time (NULL); ++ TEST_VERIFY_EXIT (t1 != (time_t) -1); ++ ret = clock_gettime (clocks[i].clockid, &ts1); ++ if (clocks[i].fail_ok && ret == -1) ++ { ++ printf ("failed (OK for this clock): %m\n"); ++ continue; ++ } ++ TEST_VERIFY_EXIT (ret == 0); ++ if (clocks[i].clockid == CLOCK_REALTIME) ++ TEST_VERIFY (t1 <= ts1.tv_sec); ++ TEST_VERIFY (ts1.tv_nsec >= 0); ++ TEST_VERIFY (ts1.tv_nsec < 1000000000); ++ ret = clock_gettime (clocks[i].clockid, &ts2); ++ TEST_VERIFY_EXIT (ret == 0); ++ TEST_VERIFY (compare_timespec (&ts1, &ts2) <= 0); ++ TEST_VERIFY (ts2.tv_nsec >= 0); ++ TEST_VERIFY (ts2.tv_nsec < 1000000000); ++ /* Also verify that after sleeping, the time returned has ++ increased. Repeat several times to verify that each time, ++ the time from the time function is truncated not rounded. ++ For CPU time clocks, the time spent spinning on the CPU, and ++ so whether we end in the later half of a second, is not ++ predictable; thus, only test once for those clocks. */ ++ const struct timespec duration = { .tv_nsec = 100000000 }; ++ for (int j = 0; j < 5; j++) ++ { ++ if (clocks[i].is_cputime) ++ { ++ timer_t timer; ++ ret = timer_create (CLOCK_PROCESS_CPUTIME_ID, NULL, &timer); ++ TEST_VERIFY_EXIT (ret == 0); ++ sigalrm_received = 0; ++ xsignal (SIGALRM, handle_sigalrm); ++ struct itimerspec t = ++ { .it_value = ++ { ++ .tv_sec = 0, ++ .tv_nsec = 200000000 ++ } ++ }; ++ ret = timer_settime (timer, 0, &t, NULL); ++ TEST_VERIFY_EXIT (ret == 0); ++ while (sigalrm_received == 0) ++ ; ++ xsignal (SIGALRM, SIG_DFL); ++ ret = timer_delete (timer); ++ TEST_VERIFY_EXIT (ret == 0); ++ } ++ else ++ { ++ ret = nanosleep (&duration, NULL); ++ TEST_VERIFY_EXIT (ret == 0); ++ } ++ t1 = time (NULL); ++ TEST_VERIFY_EXIT (t1 != (time_t) -1); ++ ret = clock_gettime (clocks[i].clockid, &ts3); ++ TEST_VERIFY_EXIT (ret == 0); ++ TEST_VERIFY (compare_timespec (&ts2, &ts3) < 0); ++ if (clocks[i].clockid == CLOCK_REALTIME) ++ TEST_VERIFY (t1 <= ts3.tv_sec); ++ TEST_VERIFY (ts3.tv_nsec >= 0); ++ TEST_VERIFY (ts3.tv_nsec < 1000000000); ++ ts2 = ts3; ++ if (clocks[i].is_cputime) ++ break; ++ } ++ } ++ return 0; ++} ++ ++#define TIMEOUT 60 ++ ++#include +diff --git a/time/tst-gettimeofday-time64.c b/time/tst-gettimeofday-time64.c +new file mode 100644 +index 0000000000000000..6c08761ef995ce7c +--- /dev/null ++++ b/time/tst-gettimeofday-time64.c +@@ -0,0 +1 @@ ++#include "tst-gettimeofday.c" +diff --git a/time/tst-gettimeofday.c b/time/tst-gettimeofday.c +new file mode 100644 +index 0000000000000000..978ae28587d486f2 +--- /dev/null ++++ b/time/tst-gettimeofday.c +@@ -0,0 +1,93 @@ ++/* Test gettimeofday function. ++ Copyright (C) 2024 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#include ++#include ++ ++/* Compare two struct timeval values, returning a value -1, 0 or 1. */ ++ ++int ++compare_timeval (const struct timeval *tv1, const struct timeval *tv2) ++{ ++ if (tv1->tv_sec < tv2->tv_sec) ++ return -1; ++ if (tv1->tv_sec > tv2->tv_sec) ++ return 1; ++ if (tv1->tv_usec < tv2->tv_usec) ++ return -1; ++ if (tv1->tv_usec > tv2->tv_usec) ++ return 1; ++ return 0; ++} ++ ++int ++do_test (void) ++{ ++ struct timeval tv1, tv2, tv3; ++ int ret; ++ time_t t1; ++ /* Verify that the calls to gettimeofday succeed, that the time does ++ not decrease, and that time returns a truncated (not rounded) ++ version of the time. */ ++ t1 = time (NULL); ++ TEST_VERIFY_EXIT (t1 != (time_t) -1); ++ ret = gettimeofday (&tv1, NULL); ++ TEST_VERIFY_EXIT (ret == 0); ++ TEST_VERIFY (t1 <= tv1.tv_sec); ++ TEST_VERIFY (tv1.tv_usec >= 0); ++ TEST_VERIFY (tv1.tv_usec < 1000000); ++ ret = gettimeofday (&tv2, NULL); ++ TEST_VERIFY_EXIT (ret == 0); ++ TEST_VERIFY (compare_timeval (&tv1, &tv2) <= 0); ++ TEST_VERIFY (tv2.tv_usec >= 0); ++ TEST_VERIFY (tv2.tv_usec < 1000000); ++ /* Also verify that after sleeping, the time returned has increased. ++ Repeat several times to verify that each time, the time from the ++ time function is truncated not rounded. */ ++ const struct timespec duration = { .tv_nsec = 100000000 }; ++ for (int i = 0; i < 10; i++) ++ { ++ ret = nanosleep (&duration, NULL); ++ TEST_VERIFY_EXIT (ret == 0); ++ t1 = time (NULL); ++ TEST_VERIFY_EXIT (t1 != (time_t) -1); ++ ret = gettimeofday (&tv3, NULL); ++ TEST_VERIFY_EXIT (ret == 0); ++ TEST_VERIFY (compare_timeval (&tv2, &tv3) < 0); ++ TEST_VERIFY (t1 <= tv3.tv_sec); ++ TEST_VERIFY (tv3.tv_usec >= 0); ++ TEST_VERIFY (tv3.tv_usec < 1000000); ++ tv2 = tv3; ++ } ++ /* Also test with the obsolete tz argument not being NULL. */ ++ struct timezone tz = { 0 }; ++ t1 = time (NULL); ++ TEST_VERIFY_EXIT (t1 != (time_t) -1); ++ ret = gettimeofday (&tv3, &tz); ++ TEST_VERIFY_EXIT (ret == 0); ++ TEST_VERIFY (t1 <= tv3.tv_sec); ++ TEST_VERIFY (compare_timeval (&tv2, &tv3) <= 0); ++ TEST_VERIFY (tv3.tv_usec >= 0); ++ TEST_VERIFY (tv3.tv_usec < 1000000); ++ return 0; ++} ++ ++#include +diff --git a/time/tst-time-time64.c b/time/tst-time-time64.c +new file mode 100644 +index 0000000000000000..30e8d3c86ef973cc +--- /dev/null ++++ b/time/tst-time-time64.c +@@ -0,0 +1 @@ ++#include "tst-time.c" +diff --git a/time/tst-time.c b/time/tst-time.c +new file mode 100644 +index 0000000000000000..7f24bed3530e1c1e +--- /dev/null ++++ b/time/tst-time.c +@@ -0,0 +1,51 @@ ++/* Test time function. ++ Copyright (C) 2024 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#include ++#include ++ ++int ++do_test (void) ++{ ++ time_t t1, t2, t3, t4, t5, t6; ++ /* Verify that the calls to time succeed, that the value returned ++ directly equals that returned through the pointer passed, and ++ that the time does not decrease. */ ++ t1 = time (&t2); ++ TEST_VERIFY_EXIT (t1 != (time_t) -1); ++ TEST_VERIFY (t1 == t2); ++ t3 = time (NULL); ++ TEST_VERIFY_EXIT (t3 != (time_t) -1); ++ TEST_VERIFY (t3 >= t1); ++ /* Also verify that after sleeping, the time returned has ++ increased. */ ++ sleep (2); ++ t4 = time (&t5); ++ TEST_VERIFY_EXIT (t4 != (time_t) -1); ++ TEST_VERIFY (t4 == t5); ++ TEST_VERIFY (t4 > t3); ++ t6 = time (NULL); ++ TEST_VERIFY_EXIT (t6 != (time_t) -1); ++ TEST_VERIFY (t6 >= t4); ++ return 0; ++} ++ ++#include diff --git a/glibc-RHEL-119386-3.patch b/glibc-RHEL-119386-3.patch new file mode 100644 index 0000000..a7f3320 --- /dev/null +++ b/glibc-RHEL-119386-3.patch @@ -0,0 +1,24 @@ +commit 9c0903fb7388f645d23b26160ed3669a116189fe +Author: Joseph Myers +Date: Thu Oct 31 17:43:52 2024 +0000 + + Link tst-clock_gettime with $(librt) + + This is needed to avoid link failures for the timer_* functions on + Hurd. + + Tested with build-many-glibcs.py for i686-gnu. + +diff --git a/time/Makefile b/time/Makefile +index b57963c1c6443770..77a6ded3a5028746 100644 +--- a/time/Makefile ++++ b/time/Makefile +@@ -126,6 +126,8 @@ $(objpfx)tst-strftime2.out: $(gen-locales) + $(objpfx)tst-strftime3.out: $(gen-locales) + endif + ++$(objpfx)tst-clock_gettime: $(librt) ++$(objpfx)tst-clock_gettime-time64: $(librt) + $(objpfx)tst-clock_nanosleep: $(librt) + $(objpfx)tst-clock_nanosleep-time64: $(librt) +