diff options
Diffstat (limited to 'tests/time_test.cpp')
-rw-r--r-- | tests/time_test.cpp | 100 |
1 files changed, 87 insertions, 13 deletions
diff --git a/tests/time_test.cpp b/tests/time_test.cpp index 42c20d3b8..90de8d804 100644 --- a/tests/time_test.cpp +++ b/tests/time_test.cpp @@ -17,17 +17,19 @@ #include <time.h> #include <errno.h> -#include <features.h> #include <gtest/gtest.h> #include <pthread.h> #include <signal.h> -#include <stdatomic.h> #include <sys/syscall.h> #include <sys/types.h> #include <sys/wait.h> +#include <unistd.h> +#include <atomic> #include "ScopedSignalHandler.h" +#include "private/bionic_constants.h" + TEST(time, gmtime) { time_t t = 0; tm* broken_down = gmtime(&t); @@ -71,6 +73,30 @@ TEST(time, gmtime_no_stack_overflow_14313703) { ASSERT_EQ(0, pthread_join(t, &result)); } +TEST(time, mktime_empty_TZ) { + // tzcode used to have a bug where it didn't reinitialize some internal state. + + // Choose a time where DST is set. + struct tm t; + memset(&t, 0, sizeof(tm)); + t.tm_year = 1980 - 1900; + t.tm_mon = 6; + t.tm_mday = 2; + + setenv("TZ", "America/Los_Angeles", 1); + tzset(); + ASSERT_EQ(static_cast<time_t>(331372800U), mktime(&t)); + + memset(&t, 0, sizeof(tm)); + t.tm_year = 1980 - 1900; + t.tm_mon = 6; + t.tm_mday = 2; + + setenv("TZ", "", 1); // Implies UTC. + tzset(); + ASSERT_EQ(static_cast<time_t>(331344000U), mktime(&t)); +} + TEST(time, mktime_10310929) { struct tm t; memset(&t, 0, sizeof(tm)); @@ -205,7 +231,7 @@ TEST(time, timer_create_SIGEV_SIGNAL) { struct Counter { private: - atomic_int value; + std::atomic<int> value; timer_t timer_id; sigevent_t se; bool timer_valid; @@ -217,14 +243,13 @@ struct Counter { } public: - Counter(void (*fn)(sigval_t)) : value(ATOMIC_VAR_INIT(0)), timer_valid(false) { + Counter(void (*fn)(sigval_t)) : value(0), timer_valid(false) { memset(&se, 0, sizeof(se)); se.sigev_notify = SIGEV_THREAD; se.sigev_notify_function = fn; se.sigev_value.sival_ptr = this; Create(); } - void DeleteTimer() { ASSERT_TRUE(timer_valid); ASSERT_EQ(0, timer_delete(timer_id)); @@ -237,8 +262,8 @@ struct Counter { } } - int Value() { - return atomic_load(&value); + int Value() const { + return value; } void SetTime(time_t value_s, time_t value_ns, time_t interval_s, time_t interval_ns) { @@ -246,21 +271,21 @@ struct Counter { } bool ValueUpdated() { - int current_value = atomic_load(&value); + int current_value = value; time_t start = time(NULL); - while (current_value == atomic_load(&value) && (time(NULL) - start) < 5) { + while (current_value == value && (time(NULL) - start) < 5) { } - return current_value != atomic_load(&value); + return current_value != value; } static void CountNotifyFunction(sigval_t value) { Counter* cd = reinterpret_cast<Counter*>(value.sival_ptr); - atomic_fetch_add(&cd->value, 1); + ++cd->value; } static void CountAndDisarmNotifyFunction(sigval_t value) { Counter* cd = reinterpret_cast<Counter*>(value.sival_ptr); - atomic_fetch_add(&cd->value, 1); + ++cd->value; // Setting the initial expiration time to 0 disarms the timer. cd->SetTime(0, 0, 1, 0); @@ -462,10 +487,59 @@ TEST(time, clock_gettime) { ts2.tv_nsec -= ts1.tv_nsec; if (ts2.tv_nsec < 0) { --ts2.tv_sec; - ts2.tv_nsec += 1000000000; + ts2.tv_nsec += NS_PER_S; } // Should be less than (a very generous, to try to avoid flakiness) 1000000ns. ASSERT_EQ(0, ts2.tv_sec); ASSERT_LT(ts2.tv_nsec, 1000000); } + +TEST(time, clock) { + // clock(3) is hard to test, but a 1s sleep should cost less than 1ms. + clock_t t0 = clock(); + sleep(1); + clock_t t1 = clock(); + ASSERT_LT(t1 - t0, CLOCKS_PER_SEC / 1000); +} + +pid_t GetInvalidPid() { + FILE* fp = fopen("/proc/sys/kernel/pid_max", "r"); + long pid_max; + fscanf(fp, "%ld", &pid_max); + pid_t invalid_pid = static_cast<pid_t>(pid_max + 1); + fclose(fp); + return invalid_pid; +} + +TEST(time, clock_getcpuclockid) { + // For current process. + clockid_t clockid; + ASSERT_EQ(0, clock_getcpuclockid(getpid(), &clockid)); + + timespec ts; + ASSERT_EQ(0, clock_gettime(clockid, &ts)); + + // For parent process. + ASSERT_EQ(0, clock_getcpuclockid(getppid(), &clockid)); + ASSERT_EQ(0, clock_gettime(clockid, &ts)); + + // For invalid process. + // We can't use -1 for invalid pid here, because clock_getcpuclockid() can't detect it. + errno = 0; + ASSERT_EQ(ESRCH, clock_getcpuclockid(GetInvalidPid(), &clockid)); + ASSERT_EQ(0, errno); +} + +TEST(time, clock_settime) { + errno = 0; + timespec ts; + ASSERT_EQ(-1, clock_settime(-1, &ts)); + ASSERT_EQ(EINVAL, errno); +} + +TEST(time, clock_nanosleep) { + timespec in; + timespec out; + ASSERT_EQ(EINVAL, clock_nanosleep(-1, 0, &in, &out)); +} |