1 /*
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
17 #include <time.h>
18
19 #include <errno.h>
20 #include <gtest/gtest.h>
21 #include <pthread.h>
22 #include <signal.h>
23 #include <sys/syscall.h>
24 #include <sys/types.h>
25 #include <sys/wait.h>
26 #include <unistd.h>
27
28 #include <atomic>
29 #include <chrono>
30
31 #include "SignalUtils.h"
32 #include "utils.h"
33
34 using namespace std::chrono_literals;
35
TEST(time,time)36 TEST(time, time) {
37 // Acquire time
38 time_t p1, t1 = time(&p1);
39 // valid?
40 ASSERT_NE(static_cast<time_t>(0), t1);
41 ASSERT_NE(static_cast<time_t>(-1), t1);
42 ASSERT_EQ(p1, t1);
43
44 // Acquire time one+ second later
45 usleep(1010000);
46 time_t p2, t2 = time(&p2);
47 // valid?
48 ASSERT_NE(static_cast<time_t>(0), t2);
49 ASSERT_NE(static_cast<time_t>(-1), t2);
50 ASSERT_EQ(p2, t2);
51
52 // Expect time progression
53 ASSERT_LT(p1, p2);
54 ASSERT_LE(t2 - t1, static_cast<time_t>(2));
55
56 // Expect nullptr call to produce same results
57 ASSERT_LE(t2, time(nullptr));
58 ASSERT_LE(time(nullptr) - t2, static_cast<time_t>(1));
59 }
60
TEST(time,gmtime)61 TEST(time, gmtime) {
62 time_t t = 0;
63 tm* broken_down = gmtime(&t);
64 ASSERT_TRUE(broken_down != nullptr);
65 ASSERT_EQ(0, broken_down->tm_sec);
66 ASSERT_EQ(0, broken_down->tm_min);
67 ASSERT_EQ(0, broken_down->tm_hour);
68 ASSERT_EQ(1, broken_down->tm_mday);
69 ASSERT_EQ(0, broken_down->tm_mon);
70 ASSERT_EQ(1970, broken_down->tm_year + 1900);
71 }
72
TEST(time,gmtime_r)73 TEST(time, gmtime_r) {
74 struct tm tm = {};
75 time_t t = 0;
76 struct tm* broken_down = gmtime_r(&t, &tm);
77 ASSERT_EQ(broken_down, &tm);
78 ASSERT_EQ(0, broken_down->tm_sec);
79 ASSERT_EQ(0, broken_down->tm_min);
80 ASSERT_EQ(0, broken_down->tm_hour);
81 ASSERT_EQ(1, broken_down->tm_mday);
82 ASSERT_EQ(0, broken_down->tm_mon);
83 ASSERT_EQ(1970, broken_down->tm_year + 1900);
84 }
85
gmtime_no_stack_overflow_14313703_fn(void *)86 static void* gmtime_no_stack_overflow_14313703_fn(void*) {
87 const char* original_tz = getenv("TZ");
88 // Ensure we'll actually have to enter tzload by using a time zone that doesn't exist.
89 setenv("TZ", "gmtime_stack_overflow_14313703", 1);
90 tzset();
91 if (original_tz != nullptr) {
92 setenv("TZ", original_tz, 1);
93 }
94 tzset();
95 return nullptr;
96 }
97
TEST(time,gmtime_no_stack_overflow_14313703)98 TEST(time, gmtime_no_stack_overflow_14313703) {
99 // Is it safe to call tzload on a thread with a small stack?
100 // http://b/14313703
101 // https://code.google.com/p/android/issues/detail?id=61130
102 pthread_attr_t a;
103 ASSERT_EQ(0, pthread_attr_init(&a));
104 ASSERT_EQ(0, pthread_attr_setstacksize(&a, PTHREAD_STACK_MIN));
105
106 pthread_t t;
107 ASSERT_EQ(0, pthread_create(&t, &a, gmtime_no_stack_overflow_14313703_fn, nullptr));
108 ASSERT_EQ(0, pthread_join(t, nullptr));
109 }
110
TEST(time,mktime_empty_TZ)111 TEST(time, mktime_empty_TZ) {
112 // tzcode used to have a bug where it didn't reinitialize some internal state.
113
114 // Choose a time where DST is set.
115 struct tm t;
116 memset(&t, 0, sizeof(tm));
117 t.tm_year = 1980 - 1900;
118 t.tm_mon = 6;
119 t.tm_mday = 2;
120
121 setenv("TZ", "America/Los_Angeles", 1);
122 tzset();
123 ASSERT_EQ(static_cast<time_t>(331372800U), mktime(&t));
124
125 memset(&t, 0, sizeof(tm));
126 t.tm_year = 1980 - 1900;
127 t.tm_mon = 6;
128 t.tm_mday = 2;
129
130 setenv("TZ", "", 1); // Implies UTC.
131 tzset();
132 ASSERT_EQ(static_cast<time_t>(331344000U), mktime(&t));
133 }
134
TEST(time,mktime_10310929)135 TEST(time, mktime_10310929) {
136 struct tm t;
137 memset(&t, 0, sizeof(tm));
138 t.tm_year = 200;
139 t.tm_mon = 2;
140 t.tm_mday = 10;
141
142 #if !defined(__LP64__)
143 // 32-bit bionic has a signed 32-bit time_t.
144 ASSERT_EQ(-1, mktime(&t));
145 ASSERT_EQ(EOVERFLOW, errno);
146 #else
147 // Everyone else should be using a signed 64-bit time_t.
148 ASSERT_GE(sizeof(time_t) * 8, 64U);
149
150 setenv("TZ", "America/Los_Angeles", 1);
151 tzset();
152 errno = 0;
153 ASSERT_EQ(static_cast<time_t>(4108348800U), mktime(&t));
154 ASSERT_EQ(0, errno);
155
156 setenv("TZ", "UTC", 1);
157 tzset();
158 errno = 0;
159 ASSERT_EQ(static_cast<time_t>(4108320000U), mktime(&t));
160 ASSERT_EQ(0, errno);
161 #endif
162 }
163
TEST(time,mktime_EOVERFLOW)164 TEST(time, mktime_EOVERFLOW) {
165 struct tm t;
166 memset(&t, 0, sizeof(tm));
167
168 // LP32 year range is 1901-2038, so this year is guaranteed not to overflow.
169 t.tm_year = 2016 - 1900;
170
171 t.tm_mon = 2;
172 t.tm_mday = 10;
173
174 errno = 0;
175 ASSERT_NE(static_cast<time_t>(-1), mktime(&t));
176 ASSERT_EQ(0, errno);
177
178 // This will overflow for LP32 or LP64.
179 t.tm_year = INT_MAX;
180
181 errno = 0;
182 ASSERT_EQ(static_cast<time_t>(-1), mktime(&t));
183 ASSERT_EQ(EOVERFLOW, errno);
184 }
185
TEST(time,strftime)186 TEST(time, strftime) {
187 setenv("TZ", "UTC", 1);
188
189 struct tm t;
190 memset(&t, 0, sizeof(tm));
191 t.tm_year = 200;
192 t.tm_mon = 2;
193 t.tm_mday = 10;
194
195 char buf[64];
196
197 // Seconds since the epoch.
198 #if defined(__BIONIC__) || defined(__LP64__) // Not 32-bit glibc.
199 EXPECT_EQ(10U, strftime(buf, sizeof(buf), "%s", &t));
200 EXPECT_STREQ("4108320000", buf);
201 #endif
202
203 // Date and time as text.
204 EXPECT_EQ(24U, strftime(buf, sizeof(buf), "%c", &t));
205 EXPECT_STREQ("Sun Mar 10 00:00:00 2100", buf);
206 }
207
TEST(time,strftime_null_tm_zone)208 TEST(time, strftime_null_tm_zone) {
209 // Netflix on Nexus Player wouldn't start (http://b/25170306).
210 struct tm t;
211 memset(&t, 0, sizeof(tm));
212
213 char buf[64];
214
215 setenv("TZ", "America/Los_Angeles", 1);
216 tzset();
217
218 t.tm_isdst = 0; // "0 if Daylight Savings Time is not in effect".
219 EXPECT_EQ(5U, strftime(buf, sizeof(buf), "<%Z>", &t));
220 EXPECT_STREQ("<PST>", buf);
221
222 #if defined(__BIONIC__) // glibc 2.19 only copes with tm_isdst being 0 and 1.
223 t.tm_isdst = 2; // "positive if Daylight Savings Time is in effect"
224 EXPECT_EQ(5U, strftime(buf, sizeof(buf), "<%Z>", &t));
225 EXPECT_STREQ("<PDT>", buf);
226
227 t.tm_isdst = -123; // "and negative if the information is not available".
228 EXPECT_EQ(2U, strftime(buf, sizeof(buf), "<%Z>", &t));
229 EXPECT_STREQ("<>", buf);
230 #endif
231
232 setenv("TZ", "UTC", 1);
233 tzset();
234
235 t.tm_isdst = 0;
236 EXPECT_EQ(5U, strftime(buf, sizeof(buf), "<%Z>", &t));
237 EXPECT_STREQ("<UTC>", buf);
238
239 #if defined(__BIONIC__) // glibc 2.19 thinks UTC DST is "UTC".
240 t.tm_isdst = 1; // UTC has no DST.
241 EXPECT_EQ(2U, strftime(buf, sizeof(buf), "<%Z>", &t));
242 EXPECT_STREQ("<>", buf);
243 #endif
244 }
245
TEST(time,strftime_l)246 TEST(time, strftime_l) {
247 locale_t cloc = newlocale(LC_ALL, "C.UTF-8", nullptr);
248 locale_t old_locale = uselocale(cloc);
249
250 setenv("TZ", "UTC", 1);
251
252 struct tm t;
253 memset(&t, 0, sizeof(tm));
254 t.tm_year = 200;
255 t.tm_mon = 2;
256 t.tm_mday = 10;
257
258 // Date and time as text.
259 char buf[64];
260 EXPECT_EQ(24U, strftime_l(buf, sizeof(buf), "%c", &t, cloc));
261 EXPECT_STREQ("Sun Mar 10 00:00:00 2100", buf);
262
263 uselocale(old_locale);
264 freelocale(cloc);
265 }
266
TEST(time,strptime)267 TEST(time, strptime) {
268 setenv("TZ", "UTC", 1);
269
270 struct tm t;
271 char buf[64];
272
273 memset(&t, 0, sizeof(t));
274 strptime("11:14", "%R", &t);
275 strftime(buf, sizeof(buf), "%H:%M", &t);
276 EXPECT_STREQ("11:14", buf);
277
278 memset(&t, 0, sizeof(t));
279 strptime("09:41:53", "%T", &t);
280 strftime(buf, sizeof(buf), "%H:%M:%S", &t);
281 EXPECT_STREQ("09:41:53", buf);
282 }
283
TEST(time,strptime_l)284 TEST(time, strptime_l) {
285 setenv("TZ", "UTC", 1);
286
287 struct tm t;
288 char buf[64];
289
290 memset(&t, 0, sizeof(t));
291 strptime_l("11:14", "%R", &t, LC_GLOBAL_LOCALE);
292 strftime_l(buf, sizeof(buf), "%H:%M", &t, LC_GLOBAL_LOCALE);
293 EXPECT_STREQ("11:14", buf);
294
295 memset(&t, 0, sizeof(t));
296 strptime_l("09:41:53", "%T", &t, LC_GLOBAL_LOCALE);
297 strftime_l(buf, sizeof(buf), "%H:%M:%S", &t, LC_GLOBAL_LOCALE);
298 EXPECT_STREQ("09:41:53", buf);
299 }
300
TEST(time,strptime_F)301 TEST(time, strptime_F) {
302 setenv("TZ", "UTC", 1);
303
304 struct tm tm = {};
305 ASSERT_EQ('\0', *strptime("2019-03-26", "%F", &tm));
306 EXPECT_EQ(119, tm.tm_year);
307 EXPECT_EQ(2, tm.tm_mon);
308 EXPECT_EQ(26, tm.tm_mday);
309 }
310
TEST(time,strptime_P_p)311 TEST(time, strptime_P_p) {
312 setenv("TZ", "UTC", 1);
313
314 // For parsing, %P and %p are the same: case doesn't matter.
315
316 struct tm tm = {.tm_hour = 12};
317 ASSERT_EQ('\0', *strptime("AM", "%p", &tm));
318 EXPECT_EQ(0, tm.tm_hour);
319
320 tm = {.tm_hour = 12};
321 ASSERT_EQ('\0', *strptime("am", "%p", &tm));
322 EXPECT_EQ(0, tm.tm_hour);
323
324 tm = {.tm_hour = 12};
325 ASSERT_EQ('\0', *strptime("AM", "%P", &tm));
326 EXPECT_EQ(0, tm.tm_hour);
327
328 tm = {.tm_hour = 12};
329 ASSERT_EQ('\0', *strptime("am", "%P", &tm));
330 EXPECT_EQ(0, tm.tm_hour);
331 }
332
TEST(time,strptime_u)333 TEST(time, strptime_u) {
334 setenv("TZ", "UTC", 1);
335
336 struct tm tm = {};
337 ASSERT_EQ('\0', *strptime("2", "%u", &tm));
338 EXPECT_EQ(2, tm.tm_wday);
339 }
340
TEST(time,strptime_v)341 TEST(time, strptime_v) {
342 setenv("TZ", "UTC", 1);
343
344 struct tm tm = {};
345 ASSERT_EQ('\0', *strptime("26-Mar-1980", "%v", &tm));
346 EXPECT_EQ(80, tm.tm_year);
347 EXPECT_EQ(2, tm.tm_mon);
348 EXPECT_EQ(26, tm.tm_mday);
349 }
350
TEST(time,strptime_V_G_g)351 TEST(time, strptime_V_G_g) {
352 setenv("TZ", "UTC", 1);
353
354 // %V (ISO-8601 week number), %G (year of week number, without century), and
355 // %g (year of week number) have no effect when parsed, and are supported
356 // solely so that it's possible for strptime(3) to parse everything that
357 // strftime(3) can output.
358 struct tm tm = {};
359 ASSERT_EQ('\0', *strptime("1 2 3", "%V %G %g", &tm));
360 struct tm zero = {};
361 EXPECT_TRUE(memcmp(&tm, &zero, sizeof(tm)) == 0);
362 }
363
TEST(time,strptime_Z)364 TEST(time, strptime_Z) {
365 #if defined(__BIONIC__)
366 // glibc doesn't handle %Z at all.
367 // The BSDs only handle hard-coded "GMT" and "UTC", plus whatever two strings
368 // are in the global `tzname` (which correspond to the current $TZ).
369 struct tm tm;
370 setenv("TZ", "Europe/Berlin", 1);
371
372 // "GMT" always works.
373 tm = {};
374 ASSERT_EQ('\0', *strptime("GMT", "%Z", &tm));
375 EXPECT_STREQ("GMT", tm.tm_zone);
376 EXPECT_EQ(0, tm.tm_isdst);
377 EXPECT_EQ(0, tm.tm_gmtoff);
378
379 // As does "UTC".
380 tm = {};
381 ASSERT_EQ('\0', *strptime("UTC", "%Z", &tm));
382 EXPECT_STREQ("UTC", tm.tm_zone);
383 EXPECT_EQ(0, tm.tm_isdst);
384 EXPECT_EQ(0, tm.tm_gmtoff);
385
386 // Europe/Berlin is known as "CET" when there's no DST.
387 tm = {};
388 ASSERT_EQ('\0', *strptime("CET", "%Z", &tm));
389 EXPECT_STREQ("CET", tm.tm_zone);
390 EXPECT_EQ(0, tm.tm_isdst);
391 EXPECT_EQ(3600, tm.tm_gmtoff);
392
393 // Europe/Berlin is known as "CEST" when there's no DST.
394 tm = {};
395 ASSERT_EQ('\0', *strptime("CEST", "%Z", &tm));
396 EXPECT_STREQ("CEST", tm.tm_zone);
397 EXPECT_EQ(1, tm.tm_isdst);
398 EXPECT_EQ(3600, tm.tm_gmtoff);
399
400 // And as long as we're in Europe/Berlin, those are the only time zone
401 // abbreviations that are recognized.
402 tm = {};
403 ASSERT_TRUE(strptime("PDT", "%Z", &tm) == nullptr);
404 #endif
405 }
406
TEST(time,strptime_z)407 TEST(time, strptime_z) {
408 struct tm tm;
409 setenv("TZ", "Europe/Berlin", 1);
410
411 // "UT" is what RFC822 called UTC.
412 tm = {};
413 ASSERT_EQ('\0', *strptime("UT", "%z", &tm));
414 EXPECT_STREQ("UTC", tm.tm_zone);
415 EXPECT_EQ(0, tm.tm_isdst);
416 EXPECT_EQ(0, tm.tm_gmtoff);
417 // "GMT" is RFC822's other name for UTC.
418 tm = {};
419 ASSERT_EQ('\0', *strptime("GMT", "%z", &tm));
420 EXPECT_STREQ("UTC", tm.tm_zone);
421 EXPECT_EQ(0, tm.tm_isdst);
422 EXPECT_EQ(0, tm.tm_gmtoff);
423
424 // "Z" ("Zulu") is a synonym for UTC.
425 tm = {};
426 ASSERT_EQ('\0', *strptime("Z", "%z", &tm));
427 EXPECT_STREQ("UTC", tm.tm_zone);
428 EXPECT_EQ(0, tm.tm_isdst);
429 EXPECT_EQ(0, tm.tm_gmtoff);
430
431 // "PST"/"PDT" and the other common US zone abbreviations are all supported.
432 tm = {};
433 ASSERT_EQ('\0', *strptime("PST", "%z", &tm));
434 EXPECT_STREQ("PST", tm.tm_zone);
435 EXPECT_EQ(0, tm.tm_isdst);
436 EXPECT_EQ(-28800, tm.tm_gmtoff);
437 tm = {};
438 ASSERT_EQ('\0', *strptime("PDT", "%z", &tm));
439 EXPECT_STREQ("PDT", tm.tm_zone);
440 EXPECT_EQ(1, tm.tm_isdst);
441 EXPECT_EQ(-25200, tm.tm_gmtoff);
442
443 // +-hh
444 tm = {};
445 ASSERT_EQ('\0', *strptime("+01", "%z", &tm));
446 EXPECT_EQ(3600, tm.tm_gmtoff);
447 EXPECT_TRUE(tm.tm_zone == nullptr);
448 EXPECT_EQ(0, tm.tm_isdst);
449 // +-hhmm
450 tm = {};
451 ASSERT_EQ('\0', *strptime("+0130", "%z", &tm));
452 EXPECT_EQ(5400, tm.tm_gmtoff);
453 EXPECT_TRUE(tm.tm_zone == nullptr);
454 EXPECT_EQ(0, tm.tm_isdst);
455 // +-hh:mm
456 tm = {};
457 ASSERT_EQ('\0', *strptime("+01:30", "%z", &tm));
458 EXPECT_EQ(5400, tm.tm_gmtoff);
459 EXPECT_TRUE(tm.tm_zone == nullptr);
460 EXPECT_EQ(0, tm.tm_isdst);
461 }
462
SetTime(timer_t t,time_t value_s,time_t value_ns,time_t interval_s,time_t interval_ns)463 void SetTime(timer_t t, time_t value_s, time_t value_ns, time_t interval_s, time_t interval_ns) {
464 itimerspec ts;
465 ts.it_value.tv_sec = value_s;
466 ts.it_value.tv_nsec = value_ns;
467 ts.it_interval.tv_sec = interval_s;
468 ts.it_interval.tv_nsec = interval_ns;
469 ASSERT_EQ(0, timer_settime(t, 0, &ts, nullptr));
470 }
471
NoOpNotifyFunction(sigval_t)472 static void NoOpNotifyFunction(sigval_t) {
473 }
474
TEST(time,timer_create)475 TEST(time, timer_create) {
476 sigevent_t se;
477 memset(&se, 0, sizeof(se));
478 se.sigev_notify = SIGEV_THREAD;
479 se.sigev_notify_function = NoOpNotifyFunction;
480 timer_t timer_id;
481 ASSERT_EQ(0, timer_create(CLOCK_MONOTONIC, &se, &timer_id));
482
483 pid_t pid = fork();
484 ASSERT_NE(-1, pid) << strerror(errno);
485
486 if (pid == 0) {
487 // Timers are not inherited by the child.
488 ASSERT_EQ(-1, timer_delete(timer_id));
489 ASSERT_EQ(EINVAL, errno);
490 _exit(0);
491 }
492
493 AssertChildExited(pid, 0);
494
495 ASSERT_EQ(0, timer_delete(timer_id));
496 }
497
498 static int timer_create_SIGEV_SIGNAL_signal_handler_invocation_count;
timer_create_SIGEV_SIGNAL_signal_handler(int signal_number)499 static void timer_create_SIGEV_SIGNAL_signal_handler(int signal_number) {
500 ++timer_create_SIGEV_SIGNAL_signal_handler_invocation_count;
501 ASSERT_EQ(SIGUSR1, signal_number);
502 }
503
TEST(time,timer_create_SIGEV_SIGNAL)504 TEST(time, timer_create_SIGEV_SIGNAL) {
505 sigevent_t se;
506 memset(&se, 0, sizeof(se));
507 se.sigev_notify = SIGEV_SIGNAL;
508 se.sigev_signo = SIGUSR1;
509
510 timer_t timer_id;
511 ASSERT_EQ(0, timer_create(CLOCK_MONOTONIC, &se, &timer_id));
512
513 timer_create_SIGEV_SIGNAL_signal_handler_invocation_count = 0;
514 ScopedSignalHandler ssh(SIGUSR1, timer_create_SIGEV_SIGNAL_signal_handler);
515
516 ASSERT_EQ(0, timer_create_SIGEV_SIGNAL_signal_handler_invocation_count);
517
518 itimerspec ts;
519 ts.it_value.tv_sec = 0;
520 ts.it_value.tv_nsec = 1;
521 ts.it_interval.tv_sec = 0;
522 ts.it_interval.tv_nsec = 0;
523 ASSERT_EQ(0, timer_settime(timer_id, 0, &ts, nullptr));
524
525 usleep(500000);
526 ASSERT_EQ(1, timer_create_SIGEV_SIGNAL_signal_handler_invocation_count);
527 }
528
529 struct Counter {
530 private:
531 std::atomic<int> value;
532 timer_t timer_id;
533 sigevent_t se;
534 bool timer_valid;
535
CreateCounter536 void Create() {
537 ASSERT_FALSE(timer_valid);
538 ASSERT_EQ(0, timer_create(CLOCK_REALTIME, &se, &timer_id));
539 timer_valid = true;
540 }
541
542 public:
CounterCounter543 explicit Counter(void (*fn)(sigval_t)) : value(0), timer_valid(false) {
544 memset(&se, 0, sizeof(se));
545 se.sigev_notify = SIGEV_THREAD;
546 se.sigev_notify_function = fn;
547 se.sigev_value.sival_ptr = this;
548 Create();
549 }
DeleteTimerCounter550 void DeleteTimer() {
551 ASSERT_TRUE(timer_valid);
552 ASSERT_EQ(0, timer_delete(timer_id));
553 timer_valid = false;
554 }
555
~CounterCounter556 ~Counter() {
557 if (timer_valid) {
558 DeleteTimer();
559 }
560 }
561
ValueCounter562 int Value() const {
563 return value;
564 }
565
SetTimeCounter566 void SetTime(time_t value_s, time_t value_ns, time_t interval_s, time_t interval_ns) {
567 ::SetTime(timer_id, value_s, value_ns, interval_s, interval_ns);
568 }
569
ValueUpdatedCounter570 bool ValueUpdated() {
571 int current_value = value;
572 time_t start = time(nullptr);
573 while (current_value == value && (time(nullptr) - start) < 5) {
574 }
575 return current_value != value;
576 }
577
CountNotifyFunctionCounter578 static void CountNotifyFunction(sigval_t value) {
579 Counter* cd = reinterpret_cast<Counter*>(value.sival_ptr);
580 ++cd->value;
581 }
582
CountAndDisarmNotifyFunctionCounter583 static void CountAndDisarmNotifyFunction(sigval_t value) {
584 Counter* cd = reinterpret_cast<Counter*>(value.sival_ptr);
585 ++cd->value;
586
587 // Setting the initial expiration time to 0 disarms the timer.
588 cd->SetTime(0, 0, 1, 0);
589 }
590 };
591
TEST(time,timer_settime_0)592 TEST(time, timer_settime_0) {
593 Counter counter(Counter::CountAndDisarmNotifyFunction);
594 ASSERT_EQ(0, counter.Value());
595
596 counter.SetTime(0, 500000000, 1, 0);
597 sleep(1);
598
599 // The count should just be 1 because we disarmed the timer the first time it fired.
600 ASSERT_EQ(1, counter.Value());
601 }
602
TEST(time,timer_settime_repeats)603 TEST(time, timer_settime_repeats) {
604 Counter counter(Counter::CountNotifyFunction);
605 ASSERT_EQ(0, counter.Value());
606
607 counter.SetTime(0, 1, 0, 10);
608 ASSERT_TRUE(counter.ValueUpdated());
609 ASSERT_TRUE(counter.ValueUpdated());
610 ASSERT_TRUE(counter.ValueUpdated());
611 counter.DeleteTimer();
612 // Add a sleep as other threads may be calling the callback function when the timer is deleted.
613 usleep(500000);
614 }
615
616 static int timer_create_NULL_signal_handler_invocation_count;
timer_create_NULL_signal_handler(int signal_number)617 static void timer_create_NULL_signal_handler(int signal_number) {
618 ++timer_create_NULL_signal_handler_invocation_count;
619 ASSERT_EQ(SIGALRM, signal_number);
620 }
621
TEST(time,timer_create_NULL)622 TEST(time, timer_create_NULL) {
623 // A NULL sigevent* is equivalent to asking for SIGEV_SIGNAL for SIGALRM.
624 timer_t timer_id;
625 ASSERT_EQ(0, timer_create(CLOCK_MONOTONIC, nullptr, &timer_id));
626
627 timer_create_NULL_signal_handler_invocation_count = 0;
628 ScopedSignalHandler ssh(SIGALRM, timer_create_NULL_signal_handler);
629
630 ASSERT_EQ(0, timer_create_NULL_signal_handler_invocation_count);
631
632 SetTime(timer_id, 0, 1, 0, 0);
633 usleep(500000);
634
635 ASSERT_EQ(1, timer_create_NULL_signal_handler_invocation_count);
636 }
637
TEST(time,timer_create_EINVAL)638 TEST(time, timer_create_EINVAL) {
639 clockid_t invalid_clock = 16;
640
641 // A SIGEV_SIGNAL timer is easy; the kernel does all that.
642 timer_t timer_id;
643 ASSERT_EQ(-1, timer_create(invalid_clock, nullptr, &timer_id));
644 ASSERT_EQ(EINVAL, errno);
645
646 // A SIGEV_THREAD timer is more interesting because we have stuff to clean up.
647 sigevent_t se;
648 memset(&se, 0, sizeof(se));
649 se.sigev_notify = SIGEV_THREAD;
650 se.sigev_notify_function = NoOpNotifyFunction;
651 ASSERT_EQ(-1, timer_create(invalid_clock, &se, &timer_id));
652 ASSERT_EQ(EINVAL, errno);
653 }
654
TEST(time,timer_create_multiple)655 TEST(time, timer_create_multiple) {
656 Counter counter1(Counter::CountNotifyFunction);
657 Counter counter2(Counter::CountNotifyFunction);
658 Counter counter3(Counter::CountNotifyFunction);
659
660 ASSERT_EQ(0, counter1.Value());
661 ASSERT_EQ(0, counter2.Value());
662 ASSERT_EQ(0, counter3.Value());
663
664 counter2.SetTime(0, 500000000, 0, 0);
665 sleep(1);
666
667 EXPECT_EQ(0, counter1.Value());
668 EXPECT_EQ(1, counter2.Value());
669 EXPECT_EQ(0, counter3.Value());
670 }
671
672 // Test to verify that disarming a repeatable timer disables the callbacks.
TEST(time,timer_disarm_terminates)673 TEST(time, timer_disarm_terminates) {
674 Counter counter(Counter::CountNotifyFunction);
675 ASSERT_EQ(0, counter.Value());
676
677 counter.SetTime(0, 1, 0, 1);
678 ASSERT_TRUE(counter.ValueUpdated());
679 ASSERT_TRUE(counter.ValueUpdated());
680 ASSERT_TRUE(counter.ValueUpdated());
681
682 counter.SetTime(0, 0, 0, 0);
683 // Add a sleep as the kernel may have pending events when the timer is disarmed.
684 usleep(500000);
685 int value = counter.Value();
686 usleep(500000);
687
688 // Verify the counter has not been incremented.
689 ASSERT_EQ(value, counter.Value());
690 }
691
692 // Test to verify that deleting a repeatable timer disables the callbacks.
TEST(time,timer_delete_terminates)693 TEST(time, timer_delete_terminates) {
694 Counter counter(Counter::CountNotifyFunction);
695 ASSERT_EQ(0, counter.Value());
696
697 counter.SetTime(0, 1, 0, 1);
698 ASSERT_TRUE(counter.ValueUpdated());
699 ASSERT_TRUE(counter.ValueUpdated());
700 ASSERT_TRUE(counter.ValueUpdated());
701
702 counter.DeleteTimer();
703 // Add a sleep as other threads may be calling the callback function when the timer is deleted.
704 usleep(500000);
705 int value = counter.Value();
706 usleep(500000);
707
708 // Verify the counter has not been incremented.
709 ASSERT_EQ(value, counter.Value());
710 }
711
712 struct TimerDeleteData {
713 timer_t timer_id;
714 pid_t tid;
715 volatile bool complete;
716 };
717
TimerDeleteCallback(sigval_t value)718 static void TimerDeleteCallback(sigval_t value) {
719 TimerDeleteData* tdd = reinterpret_cast<TimerDeleteData*>(value.sival_ptr);
720
721 tdd->tid = gettid();
722 timer_delete(tdd->timer_id);
723 tdd->complete = true;
724 }
725
TEST(time,timer_delete_from_timer_thread)726 TEST(time, timer_delete_from_timer_thread) {
727 TimerDeleteData tdd;
728 sigevent_t se;
729
730 memset(&se, 0, sizeof(se));
731 se.sigev_notify = SIGEV_THREAD;
732 se.sigev_notify_function = TimerDeleteCallback;
733 se.sigev_value.sival_ptr = &tdd;
734
735 tdd.complete = false;
736 ASSERT_EQ(0, timer_create(CLOCK_REALTIME, &se, &tdd.timer_id));
737
738 itimerspec ts;
739 ts.it_value.tv_sec = 1;
740 ts.it_value.tv_nsec = 0;
741 ts.it_interval.tv_sec = 0;
742 ts.it_interval.tv_nsec = 0;
743 ASSERT_EQ(0, timer_settime(tdd.timer_id, 0, &ts, nullptr));
744
745 time_t cur_time = time(nullptr);
746 while (!tdd.complete && (time(nullptr) - cur_time) < 5);
747 ASSERT_TRUE(tdd.complete);
748
749 #if defined(__BIONIC__)
750 // Since bionic timers are implemented by creating a thread to handle the
751 // callback, verify that the thread actually completes.
752 cur_time = time(NULL);
753 while ((kill(tdd.tid, 0) != -1 || errno != ESRCH) && (time(NULL) - cur_time) < 5);
754 ASSERT_EQ(-1, kill(tdd.tid, 0));
755 ASSERT_EQ(ESRCH, errno);
756 #endif
757 }
758
TEST(time,clock_gettime)759 TEST(time, clock_gettime) {
760 // Try to ensure that our vdso clock_gettime is working.
761 timespec ts0;
762 timespec ts1;
763 timespec ts2;
764 ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &ts0));
765 ASSERT_EQ(0, syscall(__NR_clock_gettime, CLOCK_MONOTONIC, &ts1));
766 ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &ts2));
767
768 // Check we have a nice monotonic timestamp sandwich.
769 ASSERT_LE(ts0.tv_sec, ts1.tv_sec);
770 if (ts0.tv_sec == ts1.tv_sec) {
771 ASSERT_LE(ts0.tv_nsec, ts1.tv_nsec);
772 }
773 ASSERT_LE(ts1.tv_sec, ts2.tv_sec);
774 if (ts1.tv_sec == ts2.tv_sec) {
775 ASSERT_LE(ts1.tv_nsec, ts2.tv_nsec);
776 }
777 }
778
TEST(time,clock_gettime_CLOCK_REALTIME)779 TEST(time, clock_gettime_CLOCK_REALTIME) {
780 timespec ts;
781 ASSERT_EQ(0, clock_gettime(CLOCK_REALTIME, &ts));
782 }
783
TEST(time,clock_gettime_CLOCK_MONOTONIC)784 TEST(time, clock_gettime_CLOCK_MONOTONIC) {
785 timespec ts;
786 ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &ts));
787 }
788
TEST(time,clock_gettime_CLOCK_PROCESS_CPUTIME_ID)789 TEST(time, clock_gettime_CLOCK_PROCESS_CPUTIME_ID) {
790 timespec ts;
791 ASSERT_EQ(0, clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts));
792 }
793
TEST(time,clock_gettime_CLOCK_THREAD_CPUTIME_ID)794 TEST(time, clock_gettime_CLOCK_THREAD_CPUTIME_ID) {
795 timespec ts;
796 ASSERT_EQ(0, clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts));
797 }
798
TEST(time,clock_gettime_CLOCK_BOOTTIME)799 TEST(time, clock_gettime_CLOCK_BOOTTIME) {
800 timespec ts;
801 ASSERT_EQ(0, clock_gettime(CLOCK_BOOTTIME, &ts));
802 }
803
TEST(time,clock_gettime_unknown)804 TEST(time, clock_gettime_unknown) {
805 errno = 0;
806 timespec ts;
807 ASSERT_EQ(-1, clock_gettime(-1, &ts));
808 ASSERT_EQ(EINVAL, errno);
809 }
810
TEST(time,clock_getres_CLOCK_REALTIME)811 TEST(time, clock_getres_CLOCK_REALTIME) {
812 timespec ts;
813 ASSERT_EQ(0, clock_getres(CLOCK_REALTIME, &ts));
814 ASSERT_EQ(1, ts.tv_nsec);
815 ASSERT_EQ(0, ts.tv_sec);
816 }
817
TEST(time,clock_getres_CLOCK_MONOTONIC)818 TEST(time, clock_getres_CLOCK_MONOTONIC) {
819 timespec ts;
820 ASSERT_EQ(0, clock_getres(CLOCK_MONOTONIC, &ts));
821 ASSERT_EQ(1, ts.tv_nsec);
822 ASSERT_EQ(0, ts.tv_sec);
823 }
824
TEST(time,clock_getres_CLOCK_PROCESS_CPUTIME_ID)825 TEST(time, clock_getres_CLOCK_PROCESS_CPUTIME_ID) {
826 timespec ts;
827 ASSERT_EQ(0, clock_getres(CLOCK_PROCESS_CPUTIME_ID, &ts));
828 }
829
TEST(time,clock_getres_CLOCK_THREAD_CPUTIME_ID)830 TEST(time, clock_getres_CLOCK_THREAD_CPUTIME_ID) {
831 timespec ts;
832 ASSERT_EQ(0, clock_getres(CLOCK_THREAD_CPUTIME_ID, &ts));
833 }
834
TEST(time,clock_getres_CLOCK_BOOTTIME)835 TEST(time, clock_getres_CLOCK_BOOTTIME) {
836 timespec ts;
837 ASSERT_EQ(0, clock_getres(CLOCK_BOOTTIME, &ts));
838 ASSERT_EQ(1, ts.tv_nsec);
839 ASSERT_EQ(0, ts.tv_sec);
840 }
841
TEST(time,clock_getres_unknown)842 TEST(time, clock_getres_unknown) {
843 errno = 0;
844 timespec ts = { -1, -1 };
845 ASSERT_EQ(-1, clock_getres(-1, &ts));
846 ASSERT_EQ(EINVAL, errno);
847 ASSERT_EQ(-1, ts.tv_nsec);
848 ASSERT_EQ(-1, ts.tv_sec);
849 }
850
TEST(time,clock)851 TEST(time, clock) {
852 // clock(3) is hard to test, but a 1s sleep should cost less than 10ms on average.
853 static const clock_t N = 5;
854 static const clock_t mean_limit_ms = 10;
855 clock_t t0 = clock();
856 for (size_t i = 0; i < N; ++i) {
857 sleep(1);
858 }
859 clock_t t1 = clock();
860 ASSERT_LT(t1 - t0, N * mean_limit_ms * (CLOCKS_PER_SEC / 1000));
861 }
862
GetInvalidPid()863 static pid_t GetInvalidPid() {
864 std::unique_ptr<FILE, decltype(&fclose)> fp{fopen("/proc/sys/kernel/pid_max", "r"), fclose};
865 long pid_max;
866 fscanf(fp.get(), "%ld", &pid_max);
867 return static_cast<pid_t>(pid_max + 1);
868 }
869
TEST(time,clock_getcpuclockid_current)870 TEST(time, clock_getcpuclockid_current) {
871 clockid_t clockid;
872 ASSERT_EQ(0, clock_getcpuclockid(getpid(), &clockid));
873 timespec ts;
874 ASSERT_EQ(0, clock_gettime(clockid, &ts));
875 }
876
TEST(time,clock_getcpuclockid_parent)877 TEST(time, clock_getcpuclockid_parent) {
878 clockid_t clockid;
879 ASSERT_EQ(0, clock_getcpuclockid(getppid(), &clockid));
880 timespec ts;
881 ASSERT_EQ(0, clock_gettime(clockid, &ts));
882 }
883
TEST(time,clock_getcpuclockid_ESRCH)884 TEST(time, clock_getcpuclockid_ESRCH) {
885 // We can't use -1 for invalid pid here, because clock_getcpuclockid() can't detect it.
886 errno = 0;
887 // If this fails, your kernel needs commit e1b6b6ce to be backported.
888 clockid_t clockid;
889 ASSERT_EQ(ESRCH, clock_getcpuclockid(GetInvalidPid(), &clockid)) << "\n"
890 << "Please ensure that the following kernel patches or their replacements have been applied:\n"
891 << "* https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/"
892 << "commit/?id=e1b6b6ce55a0a25c8aa8af019095253b2133a41a\n"
893 << "* https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/"
894 << "commit/?id=c80ed088a519da53f27b798a69748eaabc66aadf\n";
895 ASSERT_EQ(0, errno);
896 }
897
TEST(time,clock_settime)898 TEST(time, clock_settime) {
899 errno = 0;
900 timespec ts;
901 ASSERT_EQ(-1, clock_settime(-1, &ts));
902 ASSERT_EQ(EINVAL, errno);
903 }
904
TEST(time,clock_nanosleep_EINVAL)905 TEST(time, clock_nanosleep_EINVAL) {
906 timespec in;
907 timespec out;
908 ASSERT_EQ(EINVAL, clock_nanosleep(-1, 0, &in, &out));
909 }
910
TEST(time,clock_nanosleep_thread_cputime_id)911 TEST(time, clock_nanosleep_thread_cputime_id) {
912 timespec in;
913 in.tv_sec = 1;
914 in.tv_nsec = 0;
915 ASSERT_EQ(EINVAL, clock_nanosleep(CLOCK_THREAD_CPUTIME_ID, 0, &in, nullptr));
916 }
917
TEST(time,clock_nanosleep)918 TEST(time, clock_nanosleep) {
919 auto t0 = std::chrono::steady_clock::now();
920 const timespec ts = {.tv_nsec = 5000000};
921 ASSERT_EQ(0, clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, nullptr));
922 auto t1 = std::chrono::steady_clock::now();
923 ASSERT_GE(t1-t0, 5000000ns);
924 }
925
TEST(time,nanosleep)926 TEST(time, nanosleep) {
927 auto t0 = std::chrono::steady_clock::now();
928 const timespec ts = {.tv_nsec = 5000000};
929 ASSERT_EQ(0, nanosleep(&ts, nullptr));
930 auto t1 = std::chrono::steady_clock::now();
931 ASSERT_GE(t1-t0, 5000000ns);
932 }
933
TEST(time,nanosleep_EINVAL)934 TEST(time, nanosleep_EINVAL) {
935 timespec ts = {.tv_sec = -1};
936 errno = 0;
937 ASSERT_EQ(-1, nanosleep(&ts, nullptr));
938 ASSERT_EQ(EINVAL, errno);
939 }
940
TEST(time,bug_31938693)941 TEST(time, bug_31938693) {
942 // User-visible symptoms in N:
943 // http://b/31938693
944 // https://code.google.com/p/android/issues/detail?id=225132
945
946 // Actual underlying bug (the code change, not the tzdata upgrade that first exposed the bug):
947 // http://b/31848040
948
949 // This isn't a great test, because very few time zones were actually affected, and there's
950 // no real logic to which ones were affected: it was just a coincidence of the data that came
951 // after them in the tzdata file.
952
953 time_t t = 1475619727;
954 struct tm tm;
955
956 setenv("TZ", "America/Los_Angeles", 1);
957 tzset();
958 ASSERT_TRUE(localtime_r(&t, &tm) != nullptr);
959 EXPECT_EQ(15, tm.tm_hour);
960
961 setenv("TZ", "Europe/London", 1);
962 tzset();
963 ASSERT_TRUE(localtime_r(&t, &tm) != nullptr);
964 EXPECT_EQ(23, tm.tm_hour);
965
966 setenv("TZ", "America/Atka", 1);
967 tzset();
968 ASSERT_TRUE(localtime_r(&t, &tm) != nullptr);
969 EXPECT_EQ(13, tm.tm_hour);
970
971 setenv("TZ", "Pacific/Apia", 1);
972 tzset();
973 ASSERT_TRUE(localtime_r(&t, &tm) != nullptr);
974 EXPECT_EQ(12, tm.tm_hour);
975
976 setenv("TZ", "Pacific/Honolulu", 1);
977 tzset();
978 ASSERT_TRUE(localtime_r(&t, &tm) != nullptr);
979 EXPECT_EQ(12, tm.tm_hour);
980
981 setenv("TZ", "Asia/Magadan", 1);
982 tzset();
983 ASSERT_TRUE(localtime_r(&t, &tm) != nullptr);
984 EXPECT_EQ(9, tm.tm_hour);
985 }
986
TEST(time,bug_31339449)987 TEST(time, bug_31339449) {
988 // POSIX says localtime acts as if it calls tzset.
989 // tzset does two things:
990 // 1. it sets the time zone ctime/localtime/mktime/strftime will use.
991 // 2. it sets the global `tzname`.
992 // POSIX says localtime_r need not set `tzname` (2).
993 // Q: should localtime_r set the time zone (1)?
994 // Upstream tzcode (and glibc) answer "no", everyone else answers "yes".
995
996 // Pick a time, any time...
997 time_t t = 1475619727;
998
999 // Call tzset with a specific timezone.
1000 setenv("TZ", "America/Atka", 1);
1001 tzset();
1002
1003 // If we change the timezone and call localtime, localtime should use the new timezone.
1004 setenv("TZ", "America/Los_Angeles", 1);
1005 struct tm* tm_p = localtime(&t);
1006 EXPECT_EQ(15, tm_p->tm_hour);
1007
1008 // Reset the timezone back.
1009 setenv("TZ", "America/Atka", 1);
1010 tzset();
1011
1012 #if defined(__BIONIC__)
1013 // If we change the timezone again and call localtime_r, localtime_r should use the new timezone.
1014 setenv("TZ", "America/Los_Angeles", 1);
1015 struct tm tm = {};
1016 localtime_r(&t, &tm);
1017 EXPECT_EQ(15, tm.tm_hour);
1018 #else
1019 // The BSDs agree with us, but glibc gets this wrong.
1020 #endif
1021 }
1022
TEST(time,asctime)1023 TEST(time, asctime) {
1024 const struct tm tm = {};
1025 ASSERT_STREQ("Sun Jan 0 00:00:00 1900\n", asctime(&tm));
1026 }
1027
TEST(time,asctime_r)1028 TEST(time, asctime_r) {
1029 const struct tm tm = {};
1030 char buf[256];
1031 ASSERT_EQ(buf, asctime_r(&tm, buf));
1032 ASSERT_STREQ("Sun Jan 0 00:00:00 1900\n", buf);
1033 }
1034
TEST(time,ctime)1035 TEST(time, ctime) {
1036 setenv("TZ", "UTC", 1);
1037 const time_t t = 0;
1038 ASSERT_STREQ("Thu Jan 1 00:00:00 1970\n", ctime(&t));
1039 }
1040
TEST(time,ctime_r)1041 TEST(time, ctime_r) {
1042 setenv("TZ", "UTC", 1);
1043 const time_t t = 0;
1044 char buf[256];
1045 ASSERT_EQ(buf, ctime_r(&t, buf));
1046 ASSERT_STREQ("Thu Jan 1 00:00:00 1970\n", buf);
1047 }
1048
1049 // https://issuetracker.google.com/37128336
TEST(time,strftime_strptime_s)1050 TEST(time, strftime_strptime_s) {
1051 char buf[32];
1052 const struct tm tm0 = { .tm_year = 1982-1900, .tm_mon = 0, .tm_mday = 1 };
1053
1054 setenv("TZ", "America/Los_Angeles", 1);
1055 strftime(buf, sizeof(buf), "<%s>", &tm0);
1056 EXPECT_STREQ("<378720000>", buf);
1057
1058 setenv("TZ", "UTC", 1);
1059 strftime(buf, sizeof(buf), "<%s>", &tm0);
1060 EXPECT_STREQ("<378691200>", buf);
1061
1062 struct tm tm;
1063
1064 setenv("TZ", "America/Los_Angeles", 1);
1065 tzset();
1066 memset(&tm, 0xff, sizeof(tm));
1067 char* p = strptime("378720000x", "%s", &tm);
1068 ASSERT_EQ('x', *p);
1069 EXPECT_EQ(0, tm.tm_sec);
1070 EXPECT_EQ(0, tm.tm_min);
1071 EXPECT_EQ(0, tm.tm_hour);
1072 EXPECT_EQ(1, tm.tm_mday);
1073 EXPECT_EQ(0, tm.tm_mon);
1074 EXPECT_EQ(82, tm.tm_year);
1075 EXPECT_EQ(5, tm.tm_wday);
1076 EXPECT_EQ(0, tm.tm_yday);
1077 EXPECT_EQ(0, tm.tm_isdst);
1078
1079 setenv("TZ", "UTC", 1);
1080 tzset();
1081 memset(&tm, 0xff, sizeof(tm));
1082 p = strptime("378691200x", "%s", &tm);
1083 ASSERT_EQ('x', *p);
1084 EXPECT_EQ(0, tm.tm_sec);
1085 EXPECT_EQ(0, tm.tm_min);
1086 EXPECT_EQ(0, tm.tm_hour);
1087 EXPECT_EQ(1, tm.tm_mday);
1088 EXPECT_EQ(0, tm.tm_mon);
1089 EXPECT_EQ(82, tm.tm_year);
1090 EXPECT_EQ(5, tm.tm_wday);
1091 EXPECT_EQ(0, tm.tm_yday);
1092 EXPECT_EQ(0, tm.tm_isdst);
1093 }
1094
TEST(time,strptime_s_nothing)1095 TEST(time, strptime_s_nothing) {
1096 struct tm tm;
1097 ASSERT_EQ(nullptr, strptime("x", "%s", &tm));
1098 }
1099
TEST(time,timespec_get)1100 TEST(time, timespec_get) {
1101 #if __BIONIC__
1102 timespec ts = {};
1103 ASSERT_EQ(0, timespec_get(&ts, 123));
1104 ASSERT_EQ(TIME_UTC, timespec_get(&ts, TIME_UTC));
1105 #else
1106 GTEST_SKIP() << "glibc doesn't have timespec_get until 2.21";
1107 #endif
1108 }
1109
TEST(time,difftime)1110 TEST(time, difftime) {
1111 ASSERT_EQ(1.0, difftime(1, 0));
1112 ASSERT_EQ(-1.0, difftime(0, 1));
1113 }
1114