aboutsummaryrefslogtreecommitdiffstats
path: root/tests/time_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/time_test.cpp')
-rw-r--r--tests/time_test.cpp100
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));
+}