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#include <atomic>
28
29#include "ScopedSignalHandler.h"
30#include "utils.h"
31
32#include "private/bionic_constants.h"
33
34TEST(time, gmtime) {
35  time_t t = 0;
36  tm* broken_down = gmtime(&t);
37  ASSERT_TRUE(broken_down != NULL);
38  ASSERT_EQ(0, broken_down->tm_sec);
39  ASSERT_EQ(0, broken_down->tm_min);
40  ASSERT_EQ(0, broken_down->tm_hour);
41  ASSERT_EQ(1, broken_down->tm_mday);
42  ASSERT_EQ(0, broken_down->tm_mon);
43  ASSERT_EQ(1970, broken_down->tm_year + 1900);
44}
45
46static void* gmtime_no_stack_overflow_14313703_fn(void*) {
47  const char* original_tz = getenv("TZ");
48  // Ensure we'll actually have to enter tzload by using a time zone that doesn't exist.
49  setenv("TZ", "gmtime_stack_overflow_14313703", 1);
50  tzset();
51  if (original_tz != NULL) {
52    setenv("TZ", original_tz, 1);
53  }
54  tzset();
55  return NULL;
56}
57
58TEST(time, gmtime_no_stack_overflow_14313703) {
59  // Is it safe to call tzload on a thread with a small stack?
60  // http://b/14313703
61  // https://code.google.com/p/android/issues/detail?id=61130
62  pthread_attr_t a;
63  ASSERT_EQ(0, pthread_attr_init(&a));
64  ASSERT_EQ(0, pthread_attr_setstacksize(&a, PTHREAD_STACK_MIN));
65
66  pthread_t t;
67  ASSERT_EQ(0, pthread_create(&t, &a, gmtime_no_stack_overflow_14313703_fn, NULL));
68  ASSERT_EQ(0, pthread_join(t, nullptr));
69}
70
71TEST(time, mktime_empty_TZ) {
72  // tzcode used to have a bug where it didn't reinitialize some internal state.
73
74  // Choose a time where DST is set.
75  struct tm t;
76  memset(&t, 0, sizeof(tm));
77  t.tm_year = 1980 - 1900;
78  t.tm_mon = 6;
79  t.tm_mday = 2;
80
81  setenv("TZ", "America/Los_Angeles", 1);
82  tzset();
83  ASSERT_EQ(static_cast<time_t>(331372800U), mktime(&t));
84
85  memset(&t, 0, sizeof(tm));
86  t.tm_year = 1980 - 1900;
87  t.tm_mon = 6;
88  t.tm_mday = 2;
89
90  setenv("TZ", "", 1); // Implies UTC.
91  tzset();
92  ASSERT_EQ(static_cast<time_t>(331344000U), mktime(&t));
93}
94
95TEST(time, mktime_10310929) {
96  struct tm t;
97  memset(&t, 0, sizeof(tm));
98  t.tm_year = 200;
99  t.tm_mon = 2;
100  t.tm_mday = 10;
101
102#if !defined(__LP64__)
103  // 32-bit bionic stupidly had a signed 32-bit time_t.
104  ASSERT_EQ(-1, mktime(&t));
105#else
106  // Everyone else should be using a signed 64-bit time_t.
107  ASSERT_GE(sizeof(time_t) * 8, 64U);
108
109  setenv("TZ", "America/Los_Angeles", 1);
110  tzset();
111  ASSERT_EQ(static_cast<time_t>(4108348800U), mktime(&t));
112
113  setenv("TZ", "UTC", 1);
114  tzset();
115  ASSERT_EQ(static_cast<time_t>(4108320000U), mktime(&t));
116#endif
117}
118
119TEST(time, strftime) {
120  setenv("TZ", "UTC", 1);
121
122  struct tm t;
123  memset(&t, 0, sizeof(tm));
124  t.tm_year = 200;
125  t.tm_mon = 2;
126  t.tm_mday = 10;
127
128  char buf[64];
129
130  // Seconds since the epoch.
131#if defined(__BIONIC__) || defined(__LP64__) // Not 32-bit glibc.
132  EXPECT_EQ(10U, strftime(buf, sizeof(buf), "%s", &t));
133  EXPECT_STREQ("4108320000", buf);
134#endif
135
136  // Date and time as text.
137  EXPECT_EQ(24U, strftime(buf, sizeof(buf), "%c", &t));
138  EXPECT_STREQ("Sun Mar 10 00:00:00 2100", buf);
139}
140
141TEST(time, strftime_null_tm_zone) {
142  // Netflix on Nexus Player wouldn't start (http://b/25170306).
143  struct tm t;
144  memset(&t, 0, sizeof(tm));
145
146  char buf[64];
147
148  setenv("TZ", "America/Los_Angeles", 1);
149  tzset();
150
151  t.tm_isdst = 0; // "0 if Daylight Savings Time is not in effect".
152  EXPECT_EQ(5U, strftime(buf, sizeof(buf), "<%Z>", &t));
153  EXPECT_STREQ("<PST>", buf);
154
155#if defined(__BIONIC__) // glibc 2.19 only copes with tm_isdst being 0 and 1.
156  t.tm_isdst = 2; // "positive if Daylight Savings Time is in effect"
157  EXPECT_EQ(5U, strftime(buf, sizeof(buf), "<%Z>", &t));
158  EXPECT_STREQ("<PDT>", buf);
159
160  t.tm_isdst = -123; // "and negative if the information is not available".
161  EXPECT_EQ(2U, strftime(buf, sizeof(buf), "<%Z>", &t));
162  EXPECT_STREQ("<>", buf);
163#endif
164
165  setenv("TZ", "UTC", 1);
166  tzset();
167
168  t.tm_isdst = 0;
169  EXPECT_EQ(5U, strftime(buf, sizeof(buf), "<%Z>", &t));
170  EXPECT_STREQ("<UTC>", buf);
171
172#if defined(__BIONIC__) // glibc 2.19 thinks UTC DST is "UTC".
173  t.tm_isdst = 1; // UTC has no DST.
174  EXPECT_EQ(2U, strftime(buf, sizeof(buf), "<%Z>", &t));
175  EXPECT_STREQ("<>", buf);
176#endif
177}
178
179TEST(time, strptime) {
180  setenv("TZ", "UTC", 1);
181
182  struct tm t;
183  char buf[64];
184
185  memset(&t, 0, sizeof(t));
186  strptime("11:14", "%R", &t);
187  strftime(buf, sizeof(buf), "%H:%M", &t);
188  EXPECT_STREQ("11:14", buf);
189
190  memset(&t, 0, sizeof(t));
191  strptime("09:41:53", "%T", &t);
192  strftime(buf, sizeof(buf), "%H:%M:%S", &t);
193  EXPECT_STREQ("09:41:53", buf);
194}
195
196void SetTime(timer_t t, time_t value_s, time_t value_ns, time_t interval_s, time_t interval_ns) {
197  itimerspec ts;
198  ts.it_value.tv_sec = value_s;
199  ts.it_value.tv_nsec = value_ns;
200  ts.it_interval.tv_sec = interval_s;
201  ts.it_interval.tv_nsec = interval_ns;
202  ASSERT_EQ(0, timer_settime(t, 0, &ts, NULL));
203}
204
205static void NoOpNotifyFunction(sigval_t) {
206}
207
208TEST(time, timer_create) {
209  sigevent_t se;
210  memset(&se, 0, sizeof(se));
211  se.sigev_notify = SIGEV_THREAD;
212  se.sigev_notify_function = NoOpNotifyFunction;
213  timer_t timer_id;
214  ASSERT_EQ(0, timer_create(CLOCK_MONOTONIC, &se, &timer_id));
215
216  pid_t pid = fork();
217  ASSERT_NE(-1, pid) << strerror(errno);
218
219  if (pid == 0) {
220    // Timers are not inherited by the child.
221    ASSERT_EQ(-1, timer_delete(timer_id));
222    ASSERT_EQ(EINVAL, errno);
223    _exit(0);
224  }
225
226  AssertChildExited(pid, 0);
227
228  ASSERT_EQ(0, timer_delete(timer_id));
229}
230
231static int timer_create_SIGEV_SIGNAL_signal_handler_invocation_count;
232static void timer_create_SIGEV_SIGNAL_signal_handler(int signal_number) {
233  ++timer_create_SIGEV_SIGNAL_signal_handler_invocation_count;
234  ASSERT_EQ(SIGUSR1, signal_number);
235}
236
237TEST(time, timer_create_SIGEV_SIGNAL) {
238  sigevent_t se;
239  memset(&se, 0, sizeof(se));
240  se.sigev_notify = SIGEV_SIGNAL;
241  se.sigev_signo = SIGUSR1;
242
243  timer_t timer_id;
244  ASSERT_EQ(0, timer_create(CLOCK_MONOTONIC, &se, &timer_id));
245
246  timer_create_SIGEV_SIGNAL_signal_handler_invocation_count = 0;
247  ScopedSignalHandler ssh(SIGUSR1, timer_create_SIGEV_SIGNAL_signal_handler);
248
249  ASSERT_EQ(0, timer_create_SIGEV_SIGNAL_signal_handler_invocation_count);
250
251  itimerspec ts;
252  ts.it_value.tv_sec =  0;
253  ts.it_value.tv_nsec = 1;
254  ts.it_interval.tv_sec = 0;
255  ts.it_interval.tv_nsec = 0;
256  ASSERT_EQ(0, timer_settime(timer_id, 0, &ts, NULL));
257
258  usleep(500000);
259  ASSERT_EQ(1, timer_create_SIGEV_SIGNAL_signal_handler_invocation_count);
260}
261
262struct Counter {
263 private:
264  std::atomic<int> value;
265  timer_t timer_id;
266  sigevent_t se;
267  bool timer_valid;
268
269  void Create() {
270    ASSERT_FALSE(timer_valid);
271    ASSERT_EQ(0, timer_create(CLOCK_REALTIME, &se, &timer_id));
272    timer_valid = true;
273  }
274
275 public:
276  Counter(void (*fn)(sigval_t)) : value(0), timer_valid(false) {
277    memset(&se, 0, sizeof(se));
278    se.sigev_notify = SIGEV_THREAD;
279    se.sigev_notify_function = fn;
280    se.sigev_value.sival_ptr = this;
281    Create();
282  }
283  void DeleteTimer() {
284    ASSERT_TRUE(timer_valid);
285    ASSERT_EQ(0, timer_delete(timer_id));
286    timer_valid = false;
287  }
288
289  ~Counter() {
290    if (timer_valid) {
291      DeleteTimer();
292    }
293  }
294
295  int Value() const {
296    return value;
297  }
298
299  void SetTime(time_t value_s, time_t value_ns, time_t interval_s, time_t interval_ns) {
300    ::SetTime(timer_id, value_s, value_ns, interval_s, interval_ns);
301  }
302
303  bool ValueUpdated() {
304    int current_value = value;
305    time_t start = time(NULL);
306    while (current_value == value && (time(NULL) - start) < 5) {
307    }
308    return current_value != value;
309  }
310
311  static void CountNotifyFunction(sigval_t value) {
312    Counter* cd = reinterpret_cast<Counter*>(value.sival_ptr);
313    ++cd->value;
314  }
315
316  static void CountAndDisarmNotifyFunction(sigval_t value) {
317    Counter* cd = reinterpret_cast<Counter*>(value.sival_ptr);
318    ++cd->value;
319
320    // Setting the initial expiration time to 0 disarms the timer.
321    cd->SetTime(0, 0, 1, 0);
322  }
323};
324
325TEST(time, timer_settime_0) {
326  Counter counter(Counter::CountAndDisarmNotifyFunction);
327  ASSERT_EQ(0, counter.Value());
328
329  counter.SetTime(0, 500000000, 1, 0);
330  sleep(1);
331
332  // The count should just be 1 because we disarmed the timer the first time it fired.
333  ASSERT_EQ(1, counter.Value());
334}
335
336TEST(time, timer_settime_repeats) {
337  Counter counter(Counter::CountNotifyFunction);
338  ASSERT_EQ(0, counter.Value());
339
340  counter.SetTime(0, 1, 0, 10);
341  ASSERT_TRUE(counter.ValueUpdated());
342  ASSERT_TRUE(counter.ValueUpdated());
343  ASSERT_TRUE(counter.ValueUpdated());
344  counter.DeleteTimer();
345  // Add a sleep as other threads may be calling the callback function when the timer is deleted.
346  usleep(500000);
347}
348
349static int timer_create_NULL_signal_handler_invocation_count;
350static void timer_create_NULL_signal_handler(int signal_number) {
351  ++timer_create_NULL_signal_handler_invocation_count;
352  ASSERT_EQ(SIGALRM, signal_number);
353}
354
355TEST(time, timer_create_NULL) {
356  // A NULL sigevent* is equivalent to asking for SIGEV_SIGNAL for SIGALRM.
357  timer_t timer_id;
358  ASSERT_EQ(0, timer_create(CLOCK_MONOTONIC, NULL, &timer_id));
359
360  timer_create_NULL_signal_handler_invocation_count = 0;
361  ScopedSignalHandler ssh(SIGALRM, timer_create_NULL_signal_handler);
362
363  ASSERT_EQ(0, timer_create_NULL_signal_handler_invocation_count);
364
365  SetTime(timer_id, 0, 1, 0, 0);
366  usleep(500000);
367
368  ASSERT_EQ(1, timer_create_NULL_signal_handler_invocation_count);
369}
370
371TEST(time, timer_create_EINVAL) {
372  clockid_t invalid_clock = 16;
373
374  // A SIGEV_SIGNAL timer is easy; the kernel does all that.
375  timer_t timer_id;
376  ASSERT_EQ(-1, timer_create(invalid_clock, NULL, &timer_id));
377  ASSERT_EQ(EINVAL, errno);
378
379  // A SIGEV_THREAD timer is more interesting because we have stuff to clean up.
380  sigevent_t se;
381  memset(&se, 0, sizeof(se));
382  se.sigev_notify = SIGEV_THREAD;
383  se.sigev_notify_function = NoOpNotifyFunction;
384  ASSERT_EQ(-1, timer_create(invalid_clock, &se, &timer_id));
385  ASSERT_EQ(EINVAL, errno);
386}
387
388TEST(time, timer_delete_multiple) {
389  timer_t timer_id;
390  ASSERT_EQ(0, timer_create(CLOCK_MONOTONIC, NULL, &timer_id));
391  ASSERT_EQ(0, timer_delete(timer_id));
392  ASSERT_EQ(-1, timer_delete(timer_id));
393  ASSERT_EQ(EINVAL, errno);
394
395  sigevent_t se;
396  memset(&se, 0, sizeof(se));
397  se.sigev_notify = SIGEV_THREAD;
398  se.sigev_notify_function = NoOpNotifyFunction;
399  ASSERT_EQ(0, timer_create(CLOCK_MONOTONIC, &se, &timer_id));
400  ASSERT_EQ(0, timer_delete(timer_id));
401  ASSERT_EQ(-1, timer_delete(timer_id));
402  ASSERT_EQ(EINVAL, errno);
403}
404
405TEST(time, timer_create_multiple) {
406  Counter counter1(Counter::CountNotifyFunction);
407  Counter counter2(Counter::CountNotifyFunction);
408  Counter counter3(Counter::CountNotifyFunction);
409
410  ASSERT_EQ(0, counter1.Value());
411  ASSERT_EQ(0, counter2.Value());
412  ASSERT_EQ(0, counter3.Value());
413
414  counter2.SetTime(0, 500000000, 0, 0);
415  sleep(1);
416
417  EXPECT_EQ(0, counter1.Value());
418  EXPECT_EQ(1, counter2.Value());
419  EXPECT_EQ(0, counter3.Value());
420}
421
422// Test to verify that disarming a repeatable timer disables the callbacks.
423TEST(time, timer_disarm_terminates) {
424  Counter counter(Counter::CountNotifyFunction);
425  ASSERT_EQ(0, counter.Value());
426
427  counter.SetTime(0, 1, 0, 1);
428  ASSERT_TRUE(counter.ValueUpdated());
429  ASSERT_TRUE(counter.ValueUpdated());
430  ASSERT_TRUE(counter.ValueUpdated());
431
432  counter.SetTime(0, 0, 0, 0);
433  // Add a sleep as the kernel may have pending events when the timer is disarmed.
434  usleep(500000);
435  int value = counter.Value();
436  usleep(500000);
437
438  // Verify the counter has not been incremented.
439  ASSERT_EQ(value, counter.Value());
440}
441
442// Test to verify that deleting a repeatable timer disables the callbacks.
443TEST(time, timer_delete_terminates) {
444  Counter counter(Counter::CountNotifyFunction);
445  ASSERT_EQ(0, counter.Value());
446
447  counter.SetTime(0, 1, 0, 1);
448  ASSERT_TRUE(counter.ValueUpdated());
449  ASSERT_TRUE(counter.ValueUpdated());
450  ASSERT_TRUE(counter.ValueUpdated());
451
452  counter.DeleteTimer();
453  // Add a sleep as other threads may be calling the callback function when the timer is deleted.
454  usleep(500000);
455  int value = counter.Value();
456  usleep(500000);
457
458  // Verify the counter has not been incremented.
459  ASSERT_EQ(value, counter.Value());
460}
461
462struct TimerDeleteData {
463  timer_t timer_id;
464  pthread_t thread_id;
465  volatile bool complete;
466};
467
468static void TimerDeleteCallback(sigval_t value) {
469  TimerDeleteData* tdd = reinterpret_cast<TimerDeleteData*>(value.sival_ptr);
470
471  tdd->thread_id = pthread_self();
472  timer_delete(tdd->timer_id);
473  tdd->complete = true;
474}
475
476TEST(time, timer_delete_from_timer_thread) {
477  TimerDeleteData tdd;
478  sigevent_t se;
479
480  memset(&se, 0, sizeof(se));
481  se.sigev_notify = SIGEV_THREAD;
482  se.sigev_notify_function = TimerDeleteCallback;
483  se.sigev_value.sival_ptr = &tdd;
484
485  tdd.complete = false;
486  ASSERT_EQ(0, timer_create(CLOCK_REALTIME, &se, &tdd.timer_id));
487
488  itimerspec ts;
489  ts.it_value.tv_sec = 1;
490  ts.it_value.tv_nsec = 0;
491  ts.it_interval.tv_sec = 0;
492  ts.it_interval.tv_nsec = 0;
493  ASSERT_EQ(0, timer_settime(tdd.timer_id, 0, &ts, NULL));
494
495  time_t cur_time = time(NULL);
496  while (!tdd.complete && (time(NULL) - cur_time) < 5);
497  ASSERT_TRUE(tdd.complete);
498
499#if defined(__BIONIC__)
500  // Since bionic timers are implemented by creating a thread to handle the
501  // callback, verify that the thread actually completes.
502  cur_time = time(NULL);
503  while (pthread_detach(tdd.thread_id) != ESRCH && (time(NULL) - cur_time) < 5);
504  ASSERT_EQ(ESRCH, pthread_detach(tdd.thread_id));
505#endif
506}
507
508TEST(time, clock_gettime) {
509  // Try to ensure that our vdso clock_gettime is working.
510  timespec ts1;
511  ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &ts1));
512  timespec ts2;
513  ASSERT_EQ(0, syscall(__NR_clock_gettime, CLOCK_MONOTONIC, &ts2));
514
515  // What's the difference between the two?
516  ts2.tv_sec -= ts1.tv_sec;
517  ts2.tv_nsec -= ts1.tv_nsec;
518  if (ts2.tv_nsec < 0) {
519    --ts2.tv_sec;
520    ts2.tv_nsec += NS_PER_S;
521  }
522
523  // Should be less than (a very generous, to try to avoid flakiness) 1000000ns.
524  ASSERT_EQ(0, ts2.tv_sec);
525  ASSERT_LT(ts2.tv_nsec, 1000000);
526}
527
528TEST(time, clock) {
529  // clock(3) is hard to test, but a 1s sleep should cost less than 1ms.
530  clock_t t0 = clock();
531  sleep(1);
532  clock_t t1 = clock();
533  ASSERT_LT(t1 - t0, CLOCKS_PER_SEC / 1000);
534}
535
536pid_t GetInvalidPid() {
537  FILE* fp = fopen("/proc/sys/kernel/pid_max", "r");
538  long pid_max;
539  fscanf(fp, "%ld", &pid_max);
540  pid_t invalid_pid = static_cast<pid_t>(pid_max + 1);
541  fclose(fp);
542  return invalid_pid;
543}
544
545TEST(time, clock_getcpuclockid) {
546  // For current process.
547  clockid_t clockid;
548  ASSERT_EQ(0, clock_getcpuclockid(getpid(), &clockid));
549
550  timespec ts;
551  ASSERT_EQ(0, clock_gettime(clockid, &ts));
552
553  // For parent process.
554  ASSERT_EQ(0, clock_getcpuclockid(getppid(), &clockid));
555  ASSERT_EQ(0, clock_gettime(clockid, &ts));
556
557  // For invalid process.
558  // We can't use -1 for invalid pid here, because clock_getcpuclockid() can't detect it.
559  errno = 0;
560  ASSERT_EQ(ESRCH, clock_getcpuclockid(GetInvalidPid(), &clockid));
561  ASSERT_EQ(0, errno);
562}
563
564TEST(time, clock_settime) {
565  errno = 0;
566  timespec ts;
567  ASSERT_EQ(-1, clock_settime(-1, &ts));
568  ASSERT_EQ(EINVAL, errno);
569}
570
571TEST(time, clock_nanosleep) {
572  timespec in;
573  timespec out;
574  ASSERT_EQ(EINVAL, clock_nanosleep(-1, 0, &in, &out));
575}
576