blob: c685e9478c1bd34e184e5e18ef84f9b4548643c9 [file] [log] [blame]
Elliott Hughese0175ca2013-03-14 14:38:08 -07001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Elliott Hughes4b558f52014-03-04 15:58:02 -080017#include <time.h>
18
19#include <errno.h>
Elliott Hughese0175ca2013-03-14 14:38:08 -070020#include <gtest/gtest.h>
Elliott Hughes329103d2014-04-25 16:55:04 -070021#include <pthread.h>
Elliott Hughes4b558f52014-03-04 15:58:02 -080022#include <signal.h>
Elliott Hughes625993d2014-07-15 16:53:13 -070023#include <sys/syscall.h>
Brian Carlstrombe1d91d2014-03-08 15:05:26 -080024#include <sys/types.h>
25#include <sys/wait.h>
Yabin Cuid5c65272014-11-26 14:04:26 -080026#include <unistd.h>
Yabin Cui95f1ee22015-01-13 19:53:15 -080027#include <atomic>
Elliott Hughese0175ca2013-03-14 14:38:08 -070028
Elliott Hughes4b558f52014-03-04 15:58:02 -080029#include "ScopedSignalHandler.h"
Elliott Hughese0175ca2013-03-14 14:38:08 -070030
Elliott Hughes04303f52014-09-18 16:11:59 -070031#include "private/bionic_constants.h"
32
Elliott Hughesee178bf2013-07-12 11:25:20 -070033TEST(time, gmtime) {
34 time_t t = 0;
35 tm* broken_down = gmtime(&t);
36 ASSERT_TRUE(broken_down != NULL);
37 ASSERT_EQ(0, broken_down->tm_sec);
38 ASSERT_EQ(0, broken_down->tm_min);
39 ASSERT_EQ(0, broken_down->tm_hour);
40 ASSERT_EQ(1, broken_down->tm_mday);
41 ASSERT_EQ(0, broken_down->tm_mon);
42 ASSERT_EQ(1970, broken_down->tm_year + 1900);
43}
Elliott Hughes7843d442013-08-22 11:37:32 -070044
Elliott Hughes329103d2014-04-25 16:55:04 -070045static void* gmtime_no_stack_overflow_14313703_fn(void*) {
46 const char* original_tz = getenv("TZ");
47 // Ensure we'll actually have to enter tzload by using a time zone that doesn't exist.
48 setenv("TZ", "gmtime_stack_overflow_14313703", 1);
49 tzset();
50 if (original_tz != NULL) {
51 setenv("TZ", original_tz, 1);
52 }
53 tzset();
54 return NULL;
55}
56
57TEST(time, gmtime_no_stack_overflow_14313703) {
58 // Is it safe to call tzload on a thread with a small stack?
59 // http://b/14313703
60 // https://code.google.com/p/android/issues/detail?id=61130
61 pthread_attr_t attributes;
62 ASSERT_EQ(0, pthread_attr_init(&attributes));
63#if defined(__BIONIC__)
64 ASSERT_EQ(0, pthread_attr_setstacksize(&attributes, PTHREAD_STACK_MIN));
65#else
66 // PTHREAD_STACK_MIN not currently in the host GCC sysroot.
67 ASSERT_EQ(0, pthread_attr_setstacksize(&attributes, 4 * getpagesize()));
68#endif
69
70 pthread_t t;
71 ASSERT_EQ(0, pthread_create(&t, &attributes, gmtime_no_stack_overflow_14313703_fn, NULL));
72 void* result;
73 ASSERT_EQ(0, pthread_join(t, &result));
74}
75
Satoru Takeuchi154e2022014-05-27 17:04:04 +090076TEST(time, mktime_empty_TZ) {
77 // tzcode used to have a bug where it didn't reinitialize some internal state.
78
79 // Choose a time where DST is set.
80 struct tm t;
81 memset(&t, 0, sizeof(tm));
82 t.tm_year = 1980 - 1900;
83 t.tm_mon = 6;
84 t.tm_mday = 2;
85
86 setenv("TZ", "America/Los_Angeles", 1);
87 tzset();
88 ASSERT_EQ(static_cast<time_t>(331372800U), mktime(&t));
89
90 memset(&t, 0, sizeof(tm));
91 t.tm_year = 1980 - 1900;
92 t.tm_mon = 6;
93 t.tm_mday = 2;
94
95 setenv("TZ", "", 1); // Implies UTC.
96 tzset();
97 ASSERT_EQ(static_cast<time_t>(331344000U), mktime(&t));
98}
99
Elliott Hughes7843d442013-08-22 11:37:32 -0700100TEST(time, mktime_10310929) {
101 struct tm t;
102 memset(&t, 0, sizeof(tm));
103 t.tm_year = 200;
104 t.tm_mon = 2;
105 t.tm_mday = 10;
106
Elliott Hughes0c401522013-10-18 16:21:54 -0700107#if !defined(__LP64__)
108 // 32-bit bionic stupidly had a signed 32-bit time_t.
Elliott Hughes7843d442013-08-22 11:37:32 -0700109 ASSERT_EQ(-1, mktime(&t));
Elliott Hughes0c401522013-10-18 16:21:54 -0700110#else
111 // Everyone else should be using a signed 64-bit time_t.
112 ASSERT_GE(sizeof(time_t) * 8, 64U);
113
114 setenv("TZ", "America/Los_Angeles", 1);
115 tzset();
116 ASSERT_EQ(static_cast<time_t>(4108348800U), mktime(&t));
Elliott Hughes0c401522013-10-18 16:21:54 -0700117
118 setenv("TZ", "UTC", 1);
119 tzset();
120 ASSERT_EQ(static_cast<time_t>(4108320000U), mktime(&t));
Elliott Hughes7843d442013-08-22 11:37:32 -0700121#endif
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800122}
Elliott Hughes4b558f52014-03-04 15:58:02 -0800123
Elliott Hughes3e3409a2014-03-10 18:19:03 -0700124TEST(time, strftime) {
125 setenv("TZ", "UTC", 1);
126
127 struct tm t;
128 memset(&t, 0, sizeof(tm));
129 t.tm_year = 200;
130 t.tm_mon = 2;
131 t.tm_mday = 10;
132
133 char buf[64];
134
135 // Seconds since the epoch.
136#if defined(__BIONIC__) || defined(__LP64__) // Not 32-bit glibc.
137 EXPECT_EQ(10U, strftime(buf, sizeof(buf), "%s", &t));
138 EXPECT_STREQ("4108320000", buf);
139#endif
140
141 // Date and time as text.
142 EXPECT_EQ(24U, strftime(buf, sizeof(buf), "%c", &t));
143 EXPECT_STREQ("Sun Mar 10 00:00:00 2100", buf);
144}
145
146TEST(time, strptime) {
147 setenv("TZ", "UTC", 1);
148
149 struct tm t;
150 char buf[64];
151
152 memset(&t, 0, sizeof(t));
153 strptime("11:14", "%R", &t);
154 strftime(buf, sizeof(buf), "%H:%M", &t);
155 EXPECT_STREQ("11:14", buf);
156
157 memset(&t, 0, sizeof(t));
158 strptime("09:41:53", "%T", &t);
159 strftime(buf, sizeof(buf), "%H:%M:%S", &t);
160 EXPECT_STREQ("09:41:53", buf);
161}
162
Elliott Hughes4b558f52014-03-04 15:58:02 -0800163void SetTime(timer_t t, time_t value_s, time_t value_ns, time_t interval_s, time_t interval_ns) {
164 itimerspec ts;
165 ts.it_value.tv_sec = value_s;
166 ts.it_value.tv_nsec = value_ns;
167 ts.it_interval.tv_sec = interval_s;
168 ts.it_interval.tv_nsec = interval_ns;
Yabin Cuid1ade7c2015-06-18 17:01:11 -0700169 ASSERT_EQ(0, timer_settime(t, 0, &ts, NULL));
Elliott Hughes4b558f52014-03-04 15:58:02 -0800170}
171
172static void NoOpNotifyFunction(sigval_t) {
173}
174
175TEST(time, timer_create) {
176 sigevent_t se;
177 memset(&se, 0, sizeof(se));
178 se.sigev_notify = SIGEV_THREAD;
179 se.sigev_notify_function = NoOpNotifyFunction;
180 timer_t timer_id;
181 ASSERT_EQ(0, timer_create(CLOCK_MONOTONIC, &se, &timer_id));
182
183 int pid = fork();
184 ASSERT_NE(-1, pid) << strerror(errno);
185
186 if (pid == 0) {
187 // Timers are not inherited by the child.
188 ASSERT_EQ(-1, timer_delete(timer_id));
189 ASSERT_EQ(EINVAL, errno);
190 _exit(0);
191 }
192
193 int status;
194 ASSERT_EQ(pid, waitpid(pid, &status, 0));
195 ASSERT_TRUE(WIFEXITED(status));
196 ASSERT_EQ(0, WEXITSTATUS(status));
197
198 ASSERT_EQ(0, timer_delete(timer_id));
199}
200
Yabin Cui95f1ee22015-01-13 19:53:15 -0800201static int timer_create_SIGEV_SIGNAL_signal_handler_invocation_count;
Elliott Hughes4b558f52014-03-04 15:58:02 -0800202static void timer_create_SIGEV_SIGNAL_signal_handler(int signal_number) {
203 ++timer_create_SIGEV_SIGNAL_signal_handler_invocation_count;
204 ASSERT_EQ(SIGUSR1, signal_number);
205}
206
207TEST(time, timer_create_SIGEV_SIGNAL) {
208 sigevent_t se;
209 memset(&se, 0, sizeof(se));
210 se.sigev_notify = SIGEV_SIGNAL;
211 se.sigev_signo = SIGUSR1;
212
213 timer_t timer_id;
214 ASSERT_EQ(0, timer_create(CLOCK_MONOTONIC, &se, &timer_id));
215
Yabin Cui95f1ee22015-01-13 19:53:15 -0800216 timer_create_SIGEV_SIGNAL_signal_handler_invocation_count = 0;
Elliott Hughes4b558f52014-03-04 15:58:02 -0800217 ScopedSignalHandler ssh(SIGUSR1, timer_create_SIGEV_SIGNAL_signal_handler);
218
219 ASSERT_EQ(0, timer_create_SIGEV_SIGNAL_signal_handler_invocation_count);
220
221 itimerspec ts;
222 ts.it_value.tv_sec = 0;
223 ts.it_value.tv_nsec = 1;
224 ts.it_interval.tv_sec = 0;
225 ts.it_interval.tv_nsec = 0;
Yabin Cuid1ade7c2015-06-18 17:01:11 -0700226 ASSERT_EQ(0, timer_settime(timer_id, 0, &ts, NULL));
Elliott Hughes4b558f52014-03-04 15:58:02 -0800227
228 usleep(500000);
229 ASSERT_EQ(1, timer_create_SIGEV_SIGNAL_signal_handler_invocation_count);
230}
231
232struct Counter {
Yabin Cui95f1ee22015-01-13 19:53:15 -0800233 private:
234 std::atomic<int> value;
Elliott Hughes4b558f52014-03-04 15:58:02 -0800235 timer_t timer_id;
236 sigevent_t se;
Christopher Ferris62d84b12014-10-20 19:09:19 -0700237 bool timer_valid;
Elliott Hughes4b558f52014-03-04 15:58:02 -0800238
Elliott Hughes4b558f52014-03-04 15:58:02 -0800239 void Create() {
Christopher Ferris62d84b12014-10-20 19:09:19 -0700240 ASSERT_FALSE(timer_valid);
Elliott Hughes4b558f52014-03-04 15:58:02 -0800241 ASSERT_EQ(0, timer_create(CLOCK_REALTIME, &se, &timer_id));
Christopher Ferris62d84b12014-10-20 19:09:19 -0700242 timer_valid = true;
243 }
244
Yabin Cui95f1ee22015-01-13 19:53:15 -0800245 public:
246 Counter(void (*fn)(sigval_t)) : value(0), timer_valid(false) {
247 memset(&se, 0, sizeof(se));
248 se.sigev_notify = SIGEV_THREAD;
249 se.sigev_notify_function = fn;
250 se.sigev_value.sival_ptr = this;
251 Create();
252 }
Christopher Ferris62d84b12014-10-20 19:09:19 -0700253 void DeleteTimer() {
254 ASSERT_TRUE(timer_valid);
255 ASSERT_EQ(0, timer_delete(timer_id));
256 timer_valid = false;
Elliott Hughes4b558f52014-03-04 15:58:02 -0800257 }
258
259 ~Counter() {
Christopher Ferris62d84b12014-10-20 19:09:19 -0700260 if (timer_valid) {
261 DeleteTimer();
Elliott Hughes4b558f52014-03-04 15:58:02 -0800262 }
263 }
264
Yabin Cui95f1ee22015-01-13 19:53:15 -0800265 int Value() const {
266 return value;
267 }
268
Christopher Ferris62d84b12014-10-20 19:09:19 -0700269 void SetTime(time_t value_s, time_t value_ns, time_t interval_s, time_t interval_ns) {
270 ::SetTime(timer_id, value_s, value_ns, interval_s, interval_ns);
271 }
272
273 bool ValueUpdated() {
Yabin Cui95f1ee22015-01-13 19:53:15 -0800274 int current_value = value;
Christopher Ferris62d84b12014-10-20 19:09:19 -0700275 time_t start = time(NULL);
276 while (current_value == value && (time(NULL) - start) < 5) {
277 }
278 return current_value != value;
279 }
280
Elliott Hughes4b558f52014-03-04 15:58:02 -0800281 static void CountNotifyFunction(sigval_t value) {
282 Counter* cd = reinterpret_cast<Counter*>(value.sival_ptr);
283 ++cd->value;
284 }
285
286 static void CountAndDisarmNotifyFunction(sigval_t value) {
287 Counter* cd = reinterpret_cast<Counter*>(value.sival_ptr);
288 ++cd->value;
289
290 // Setting the initial expiration time to 0 disarms the timer.
Christopher Ferris62d84b12014-10-20 19:09:19 -0700291 cd->SetTime(0, 0, 1, 0);
Elliott Hughes4b558f52014-03-04 15:58:02 -0800292 }
293};
294
295TEST(time, timer_settime_0) {
296 Counter counter(Counter::CountAndDisarmNotifyFunction);
Yabin Cui95f1ee22015-01-13 19:53:15 -0800297 ASSERT_EQ(0, counter.Value());
Elliott Hughes4b558f52014-03-04 15:58:02 -0800298
Yabin Cuibf572d92015-08-11 11:23:16 -0700299 counter.SetTime(0, 500000000, 1, 0);
300 sleep(1);
Elliott Hughes4b558f52014-03-04 15:58:02 -0800301
302 // The count should just be 1 because we disarmed the timer the first time it fired.
Yabin Cui95f1ee22015-01-13 19:53:15 -0800303 ASSERT_EQ(1, counter.Value());
Elliott Hughes4b558f52014-03-04 15:58:02 -0800304}
305
306TEST(time, timer_settime_repeats) {
307 Counter counter(Counter::CountNotifyFunction);
Yabin Cui95f1ee22015-01-13 19:53:15 -0800308 ASSERT_EQ(0, counter.Value());
Elliott Hughes4b558f52014-03-04 15:58:02 -0800309
Christopher Ferris62d84b12014-10-20 19:09:19 -0700310 counter.SetTime(0, 1, 0, 10);
311 ASSERT_TRUE(counter.ValueUpdated());
312 ASSERT_TRUE(counter.ValueUpdated());
313 ASSERT_TRUE(counter.ValueUpdated());
Yabin Cui95f1ee22015-01-13 19:53:15 -0800314 counter.DeleteTimer();
315 // Add a sleep as other threads may be calling the callback function when the timer is deleted.
316 usleep(500000);
Elliott Hughes4b558f52014-03-04 15:58:02 -0800317}
318
Yabin Cui95f1ee22015-01-13 19:53:15 -0800319static int timer_create_NULL_signal_handler_invocation_count;
Elliott Hughes4b558f52014-03-04 15:58:02 -0800320static void timer_create_NULL_signal_handler(int signal_number) {
321 ++timer_create_NULL_signal_handler_invocation_count;
322 ASSERT_EQ(SIGALRM, signal_number);
323}
324
325TEST(time, timer_create_NULL) {
326 // A NULL sigevent* is equivalent to asking for SIGEV_SIGNAL for SIGALRM.
327 timer_t timer_id;
328 ASSERT_EQ(0, timer_create(CLOCK_MONOTONIC, NULL, &timer_id));
329
Yabin Cui95f1ee22015-01-13 19:53:15 -0800330 timer_create_NULL_signal_handler_invocation_count = 0;
Elliott Hughes4b558f52014-03-04 15:58:02 -0800331 ScopedSignalHandler ssh(SIGALRM, timer_create_NULL_signal_handler);
332
333 ASSERT_EQ(0, timer_create_NULL_signal_handler_invocation_count);
334
335 SetTime(timer_id, 0, 1, 0, 0);
336 usleep(500000);
337
338 ASSERT_EQ(1, timer_create_NULL_signal_handler_invocation_count);
339}
340
341TEST(time, timer_create_EINVAL) {
342 clockid_t invalid_clock = 16;
343
344 // A SIGEV_SIGNAL timer is easy; the kernel does all that.
345 timer_t timer_id;
346 ASSERT_EQ(-1, timer_create(invalid_clock, NULL, &timer_id));
347 ASSERT_EQ(EINVAL, errno);
348
349 // A SIGEV_THREAD timer is more interesting because we have stuff to clean up.
350 sigevent_t se;
351 memset(&se, 0, sizeof(se));
352 se.sigev_notify = SIGEV_THREAD;
353 se.sigev_notify_function = NoOpNotifyFunction;
354 ASSERT_EQ(-1, timer_create(invalid_clock, &se, &timer_id));
355 ASSERT_EQ(EINVAL, errno);
356}
357
358TEST(time, timer_delete_multiple) {
359 timer_t timer_id;
360 ASSERT_EQ(0, timer_create(CLOCK_MONOTONIC, NULL, &timer_id));
361 ASSERT_EQ(0, timer_delete(timer_id));
362 ASSERT_EQ(-1, timer_delete(timer_id));
363 ASSERT_EQ(EINVAL, errno);
364
365 sigevent_t se;
366 memset(&se, 0, sizeof(se));
367 se.sigev_notify = SIGEV_THREAD;
368 se.sigev_notify_function = NoOpNotifyFunction;
369 ASSERT_EQ(0, timer_create(CLOCK_MONOTONIC, &se, &timer_id));
370 ASSERT_EQ(0, timer_delete(timer_id));
371 ASSERT_EQ(-1, timer_delete(timer_id));
372 ASSERT_EQ(EINVAL, errno);
373}
374
375TEST(time, timer_create_multiple) {
376 Counter counter1(Counter::CountNotifyFunction);
Elliott Hughes4b558f52014-03-04 15:58:02 -0800377 Counter counter2(Counter::CountNotifyFunction);
Elliott Hughes4b558f52014-03-04 15:58:02 -0800378 Counter counter3(Counter::CountNotifyFunction);
Elliott Hughes4b558f52014-03-04 15:58:02 -0800379
Yabin Cui95f1ee22015-01-13 19:53:15 -0800380 ASSERT_EQ(0, counter1.Value());
381 ASSERT_EQ(0, counter2.Value());
382 ASSERT_EQ(0, counter3.Value());
Elliott Hughes4b558f52014-03-04 15:58:02 -0800383
Yabin Cui410c1ad2015-06-18 16:19:02 -0700384 counter2.SetTime(0, 500000000, 0, 0);
385 sleep(1);
Elliott Hughes4b558f52014-03-04 15:58:02 -0800386
Yabin Cui95f1ee22015-01-13 19:53:15 -0800387 EXPECT_EQ(0, counter1.Value());
388 EXPECT_EQ(1, counter2.Value());
389 EXPECT_EQ(0, counter3.Value());
390}
391
392// Test to verify that disarming a repeatable timer disables the callbacks.
393TEST(time, timer_disarm_terminates) {
394 Counter counter(Counter::CountNotifyFunction);
395 ASSERT_EQ(0, counter.Value());
396
397 counter.SetTime(0, 1, 0, 1);
398 ASSERT_TRUE(counter.ValueUpdated());
399 ASSERT_TRUE(counter.ValueUpdated());
400 ASSERT_TRUE(counter.ValueUpdated());
401
402 counter.SetTime(0, 0, 0, 0);
403 // Add a sleep as the kernel may have pending events when the timer is disarmed.
404 usleep(500000);
405 int value = counter.Value();
406 usleep(500000);
407
408 // Verify the counter has not been incremented.
409 ASSERT_EQ(value, counter.Value());
410}
411
412// Test to verify that deleting a repeatable timer disables the callbacks.
413TEST(time, timer_delete_terminates) {
414 Counter counter(Counter::CountNotifyFunction);
415 ASSERT_EQ(0, counter.Value());
416
417 counter.SetTime(0, 1, 0, 1);
418 ASSERT_TRUE(counter.ValueUpdated());
419 ASSERT_TRUE(counter.ValueUpdated());
420 ASSERT_TRUE(counter.ValueUpdated());
421
422 counter.DeleteTimer();
423 // Add a sleep as other threads may be calling the callback function when the timer is deleted.
424 usleep(500000);
425 int value = counter.Value();
426 usleep(500000);
427
428 // Verify the counter has not been incremented.
429 ASSERT_EQ(value, counter.Value());
Elliott Hughes4b558f52014-03-04 15:58:02 -0800430}
Christopher Ferris753ad772014-03-20 20:47:45 -0700431
432struct TimerDeleteData {
433 timer_t timer_id;
434 pthread_t thread_id;
435 volatile bool complete;
436};
437
438static void TimerDeleteCallback(sigval_t value) {
439 TimerDeleteData* tdd = reinterpret_cast<TimerDeleteData*>(value.sival_ptr);
440
441 tdd->thread_id = pthread_self();
442 timer_delete(tdd->timer_id);
443 tdd->complete = true;
444}
445
446TEST(time, timer_delete_from_timer_thread) {
447 TimerDeleteData tdd;
448 sigevent_t se;
449
450 memset(&se, 0, sizeof(se));
451 se.sigev_notify = SIGEV_THREAD;
452 se.sigev_notify_function = TimerDeleteCallback;
453 se.sigev_value.sival_ptr = &tdd;
454
455 tdd.complete = false;
456 ASSERT_EQ(0, timer_create(CLOCK_REALTIME, &se, &tdd.timer_id));
457
458 itimerspec ts;
Christopher Ferris3da136a2015-02-18 17:11:47 -0800459 ts.it_value.tv_sec = 1;
460 ts.it_value.tv_nsec = 0;
Christopher Ferris753ad772014-03-20 20:47:45 -0700461 ts.it_interval.tv_sec = 0;
462 ts.it_interval.tv_nsec = 0;
Christopher Ferris3da136a2015-02-18 17:11:47 -0800463 ASSERT_EQ(0, timer_settime(tdd.timer_id, 0, &ts, NULL));
Christopher Ferris753ad772014-03-20 20:47:45 -0700464
465 time_t cur_time = time(NULL);
466 while (!tdd.complete && (time(NULL) - cur_time) < 5);
467 ASSERT_TRUE(tdd.complete);
468
469#if defined(__BIONIC__)
470 // Since bionic timers are implemented by creating a thread to handle the
471 // callback, verify that the thread actually completes.
472 cur_time = time(NULL);
473 while (pthread_detach(tdd.thread_id) != ESRCH && (time(NULL) - cur_time) < 5);
474 ASSERT_EQ(ESRCH, pthread_detach(tdd.thread_id));
475#endif
476}
Elliott Hughes625993d2014-07-15 16:53:13 -0700477
478TEST(time, clock_gettime) {
479 // Try to ensure that our vdso clock_gettime is working.
480 timespec ts1;
481 ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &ts1));
482 timespec ts2;
483 ASSERT_EQ(0, syscall(__NR_clock_gettime, CLOCK_MONOTONIC, &ts2));
484
485 // What's the difference between the two?
486 ts2.tv_sec -= ts1.tv_sec;
487 ts2.tv_nsec -= ts1.tv_nsec;
488 if (ts2.tv_nsec < 0) {
489 --ts2.tv_sec;
Elliott Hughes04303f52014-09-18 16:11:59 -0700490 ts2.tv_nsec += NS_PER_S;
Elliott Hughes625993d2014-07-15 16:53:13 -0700491 }
492
493 // Should be less than (a very generous, to try to avoid flakiness) 1000000ns.
494 ASSERT_EQ(0, ts2.tv_sec);
495 ASSERT_LT(ts2.tv_nsec, 1000000);
496}
Alex Van Brunt8d0b2db2014-09-26 13:32:47 -0700497
498TEST(time, clock) {
Haruki Hasegawa18160252014-10-13 00:50:47 +0900499 // clock(3) is hard to test, but a 1s sleep should cost less than 1ms.
500 clock_t t0 = clock();
501 sleep(1);
502 clock_t t1 = clock();
503 ASSERT_LT(t1 - t0, CLOCKS_PER_SEC / 1000);
504}
505
Yabin Cuid5c65272014-11-26 14:04:26 -0800506pid_t GetInvalidPid() {
507 FILE* fp = fopen("/proc/sys/kernel/pid_max", "r");
508 long pid_max;
509 fscanf(fp, "%ld", &pid_max);
510 pid_t invalid_pid = static_cast<pid_t>(pid_max + 1);
511 fclose(fp);
512 return invalid_pid;
513}
514
515TEST(time, clock_getcpuclockid) {
516 // For current process.
517 clockid_t clockid;
518 ASSERT_EQ(0, clock_getcpuclockid(getpid(), &clockid));
519
520 timespec ts;
521 ASSERT_EQ(0, clock_gettime(clockid, &ts));
522
523 // For parent process.
524 ASSERT_EQ(0, clock_getcpuclockid(getppid(), &clockid));
525 ASSERT_EQ(0, clock_gettime(clockid, &ts));
526
527 // For invalid process.
528 // We can't use -1 for invalid pid here, because clock_getcpuclockid() can't detect it.
529 errno = 0;
530 ASSERT_EQ(ESRCH, clock_getcpuclockid(GetInvalidPid(), &clockid));
531 ASSERT_EQ(0, errno);
532}
533
Haruki Hasegawa18160252014-10-13 00:50:47 +0900534TEST(time, clock_settime) {
535 errno = 0;
536 timespec ts;
537 ASSERT_EQ(-1, clock_settime(-1, &ts));
538 ASSERT_EQ(EINVAL, errno);
539}
540
541TEST(time, clock_nanosleep) {
542 timespec in;
543 timespec out;
544 ASSERT_EQ(EINVAL, clock_nanosleep(-1, 0, &in, &out));
Alex Van Brunt8d0b2db2014-09-26 13:32:47 -0700545}