• 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 #include "utils.h"
31 
32 #include "private/bionic_constants.h"
33 
TEST(time,gmtime)34 TEST(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 
gmtime_no_stack_overflow_14313703_fn(void *)46 static 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 
TEST(time,gmtime_no_stack_overflow_14313703)58 TEST(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 
TEST(time,mktime_empty_TZ)71 TEST(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 
TEST(time,mktime_10310929)95 TEST(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 
TEST(time,strftime)119 TEST(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 
TEST(time,strftime_null_tm_zone)141 TEST(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 
TEST(time,strptime)179 TEST(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 
SetTime(timer_t t,time_t value_s,time_t value_ns,time_t interval_s,time_t interval_ns)196 void 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 
NoOpNotifyFunction(sigval_t)205 static void NoOpNotifyFunction(sigval_t) {
206 }
207 
TEST(time,timer_create)208 TEST(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 
231 static int timer_create_SIGEV_SIGNAL_signal_handler_invocation_count;
timer_create_SIGEV_SIGNAL_signal_handler(int signal_number)232 static 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 
TEST(time,timer_create_SIGEV_SIGNAL)237 TEST(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 
262 struct Counter {
263  private:
264   std::atomic<int> value;
265   timer_t timer_id;
266   sigevent_t se;
267   bool timer_valid;
268 
CreateCounter269   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:
CounterCounter276   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   }
DeleteTimerCounter283   void DeleteTimer() {
284     ASSERT_TRUE(timer_valid);
285     ASSERT_EQ(0, timer_delete(timer_id));
286     timer_valid = false;
287   }
288 
~CounterCounter289   ~Counter() {
290     if (timer_valid) {
291       DeleteTimer();
292     }
293   }
294 
ValueCounter295   int Value() const {
296     return value;
297   }
298 
SetTimeCounter299   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 
ValueUpdatedCounter303   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 
CountNotifyFunctionCounter311   static void CountNotifyFunction(sigval_t value) {
312     Counter* cd = reinterpret_cast<Counter*>(value.sival_ptr);
313     ++cd->value;
314   }
315 
CountAndDisarmNotifyFunctionCounter316   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 
TEST(time,timer_settime_0)325 TEST(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 
TEST(time,timer_settime_repeats)336 TEST(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 
349 static int timer_create_NULL_signal_handler_invocation_count;
timer_create_NULL_signal_handler(int signal_number)350 static 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 
TEST(time,timer_create_NULL)355 TEST(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 
TEST(time,timer_create_EINVAL)371 TEST(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 
TEST(time,timer_delete_multiple)388 TEST(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 
TEST(time,timer_create_multiple)405 TEST(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.
TEST(time,timer_disarm_terminates)423 TEST(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.
TEST(time,timer_delete_terminates)443 TEST(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 
462 struct TimerDeleteData {
463   timer_t timer_id;
464   pthread_t thread_id;
465   volatile bool complete;
466 };
467 
TimerDeleteCallback(sigval_t value)468 static 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 
TEST(time,timer_delete_from_timer_thread)476 TEST(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 
TEST(time,clock_gettime)508 TEST(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 
TEST(time,clock)528 TEST(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 
GetInvalidPid()536 pid_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 
TEST(time,clock_getcpuclockid)545 TEST(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 
TEST(time,clock_settime)564 TEST(time, clock_settime) {
565   errno = 0;
566   timespec ts;
567   ASSERT_EQ(-1, clock_settime(-1, &ts));
568   ASSERT_EQ(EINVAL, errno);
569 }
570 
TEST(time,clock_nanosleep)571 TEST(time, clock_nanosleep) {
572   timespec in;
573   timespec out;
574   ASSERT_EQ(EINVAL, clock_nanosleep(-1, 0, &in, &out));
575 }
576