• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
31 #include "private/bionic_constants.h"
32 
TEST(time,gmtime)33 TEST(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 }
44 
gmtime_no_stack_overflow_14313703_fn(void *)45 static 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 
TEST(time,gmtime_no_stack_overflow_14313703)57 TEST(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 
TEST(time,mktime_empty_TZ)76 TEST(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 
TEST(time,mktime_10310929)100 TEST(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 
107 #if !defined(__LP64__)
108   // 32-bit bionic stupidly had a signed 32-bit time_t.
109   ASSERT_EQ(-1, mktime(&t));
110 #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));
117 
118   setenv("TZ", "UTC", 1);
119   tzset();
120   ASSERT_EQ(static_cast<time_t>(4108320000U), mktime(&t));
121 #endif
122 }
123 
TEST(time,strftime)124 TEST(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 
TEST(time,strptime)146 TEST(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 
SetTime(timer_t t,time_t value_s,time_t value_ns,time_t interval_s,time_t interval_ns)163 void 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;
169   ASSERT_EQ(0, timer_settime(t, 0, &ts, NULL));
170 }
171 
NoOpNotifyFunction(sigval_t)172 static void NoOpNotifyFunction(sigval_t) {
173 }
174 
TEST(time,timer_create)175 TEST(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 
201 static int timer_create_SIGEV_SIGNAL_signal_handler_invocation_count;
timer_create_SIGEV_SIGNAL_signal_handler(int signal_number)202 static 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 
TEST(time,timer_create_SIGEV_SIGNAL)207 TEST(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 
216   timer_create_SIGEV_SIGNAL_signal_handler_invocation_count = 0;
217   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;
226   ASSERT_EQ(0, timer_settime(timer_id, TIMER_ABSTIME, &ts, NULL));
227 
228   usleep(500000);
229   ASSERT_EQ(1, timer_create_SIGEV_SIGNAL_signal_handler_invocation_count);
230 }
231 
232 struct Counter {
233  private:
234   std::atomic<int> value;
235   timer_t timer_id;
236   sigevent_t se;
237   bool timer_valid;
238 
CreateCounter239   void Create() {
240     ASSERT_FALSE(timer_valid);
241     ASSERT_EQ(0, timer_create(CLOCK_REALTIME, &se, &timer_id));
242     timer_valid = true;
243   }
244 
245  public:
CounterCounter246   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   }
DeleteTimerCounter253   void DeleteTimer() {
254     ASSERT_TRUE(timer_valid);
255     ASSERT_EQ(0, timer_delete(timer_id));
256     timer_valid = false;
257   }
258 
~CounterCounter259   ~Counter() {
260     if (timer_valid) {
261       DeleteTimer();
262     }
263   }
264 
ValueCounter265   int Value() const {
266     return value;
267   }
268 
SetTimeCounter269   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 
ValueUpdatedCounter273   bool ValueUpdated() {
274     int current_value = value;
275     time_t start = time(NULL);
276     while (current_value == value && (time(NULL) - start) < 5) {
277     }
278     return current_value != value;
279   }
280 
CountNotifyFunctionCounter281   static void CountNotifyFunction(sigval_t value) {
282     Counter* cd = reinterpret_cast<Counter*>(value.sival_ptr);
283     ++cd->value;
284   }
285 
CountAndDisarmNotifyFunctionCounter286   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.
291     cd->SetTime(0, 0, 1, 0);
292   }
293 };
294 
TEST(time,timer_settime_0)295 TEST(time, timer_settime_0) {
296   Counter counter(Counter::CountAndDisarmNotifyFunction);
297   ASSERT_EQ(0, counter.Value());
298 
299   counter.SetTime(0, 500000000, 1, 0);
300   sleep(1);
301 
302   // The count should just be 1 because we disarmed the timer the first time it fired.
303   ASSERT_EQ(1, counter.Value());
304 }
305 
TEST(time,timer_settime_repeats)306 TEST(time, timer_settime_repeats) {
307   Counter counter(Counter::CountNotifyFunction);
308   ASSERT_EQ(0, counter.Value());
309 
310   counter.SetTime(0, 1, 0, 10);
311   ASSERT_TRUE(counter.ValueUpdated());
312   ASSERT_TRUE(counter.ValueUpdated());
313   ASSERT_TRUE(counter.ValueUpdated());
314   counter.DeleteTimer();
315   // Add a sleep as other threads may be calling the callback function when the timer is deleted.
316   usleep(500000);
317 }
318 
319 static int timer_create_NULL_signal_handler_invocation_count;
timer_create_NULL_signal_handler(int signal_number)320 static 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 
TEST(time,timer_create_NULL)325 TEST(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 
330   timer_create_NULL_signal_handler_invocation_count = 0;
331   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 
TEST(time,timer_create_EINVAL)341 TEST(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 
TEST(time,timer_delete_multiple)358 TEST(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 
TEST(time,timer_create_multiple)375 TEST(time, timer_create_multiple) {
376   Counter counter1(Counter::CountNotifyFunction);
377   Counter counter2(Counter::CountNotifyFunction);
378   Counter counter3(Counter::CountNotifyFunction);
379 
380   ASSERT_EQ(0, counter1.Value());
381   ASSERT_EQ(0, counter2.Value());
382   ASSERT_EQ(0, counter3.Value());
383 
384   counter2.SetTime(0, 500000000, 0, 0);
385   sleep(1);
386 
387   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.
TEST(time,timer_disarm_terminates)393 TEST(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.
TEST(time,timer_delete_terminates)413 TEST(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());
430 }
431 
432 struct TimerDeleteData {
433   timer_t timer_id;
434   pthread_t thread_id;
435   volatile bool complete;
436 };
437 
TimerDeleteCallback(sigval_t value)438 static 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 
TEST(time,timer_delete_from_timer_thread)446 TEST(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;
459   ts.it_value.tv_sec = 1;
460   ts.it_value.tv_nsec = 0;
461   ts.it_interval.tv_sec = 0;
462   ts.it_interval.tv_nsec = 0;
463   ASSERT_EQ(0, timer_settime(tdd.timer_id, 0, &ts, NULL));
464 
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 }
477 
TEST(time,clock_gettime)478 TEST(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;
490     ts2.tv_nsec += NS_PER_S;
491   }
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 }
497 
TEST(time,clock)498 TEST(time, clock) {
499   // 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 
GetInvalidPid()506 pid_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 
TEST(time,clock_getcpuclockid)515 TEST(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 
TEST(time,clock_settime)534 TEST(time, clock_settime) {
535   errno = 0;
536   timespec ts;
537   ASSERT_EQ(-1, clock_settime(-1, &ts));
538   ASSERT_EQ(EINVAL, errno);
539 }
540 
TEST(time,clock_nanosleep)541 TEST(time, clock_nanosleep) {
542   timespec in;
543   timespec out;
544   ASSERT_EQ(EINVAL, clock_nanosleep(-1, 0, &in, &out));
545 }
546