Home | History | Annotate | Download | only in tests
      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 <features.h>
     21 #include <gtest/gtest.h>
     22 #include <pthread.h>
     23 #include <signal.h>
     24 #include <sys/syscall.h>
     25 #include <sys/types.h>
     26 #include <sys/wait.h>
     27 
     28 #include "ScopedSignalHandler.h"
     29 
     30 TEST(time, gmtime) {
     31   time_t t = 0;
     32   tm* broken_down = gmtime(&t);
     33   ASSERT_TRUE(broken_down != NULL);
     34   ASSERT_EQ(0, broken_down->tm_sec);
     35   ASSERT_EQ(0, broken_down->tm_min);
     36   ASSERT_EQ(0, broken_down->tm_hour);
     37   ASSERT_EQ(1, broken_down->tm_mday);
     38   ASSERT_EQ(0, broken_down->tm_mon);
     39   ASSERT_EQ(1970, broken_down->tm_year + 1900);
     40 }
     41 
     42 static void* gmtime_no_stack_overflow_14313703_fn(void*) {
     43   const char* original_tz = getenv("TZ");
     44   // Ensure we'll actually have to enter tzload by using a time zone that doesn't exist.
     45   setenv("TZ", "gmtime_stack_overflow_14313703", 1);
     46   tzset();
     47   if (original_tz != NULL) {
     48     setenv("TZ", original_tz, 1);
     49   }
     50   tzset();
     51   return NULL;
     52 }
     53 
     54 TEST(time, gmtime_no_stack_overflow_14313703) {
     55   // Is it safe to call tzload on a thread with a small stack?
     56   // http://b/14313703
     57   // https://code.google.com/p/android/issues/detail?id=61130
     58   pthread_attr_t attributes;
     59   ASSERT_EQ(0, pthread_attr_init(&attributes));
     60 #if defined(__BIONIC__)
     61   ASSERT_EQ(0, pthread_attr_setstacksize(&attributes, PTHREAD_STACK_MIN));
     62 #else
     63   // PTHREAD_STACK_MIN not currently in the host GCC sysroot.
     64   ASSERT_EQ(0, pthread_attr_setstacksize(&attributes, 4 * getpagesize()));
     65 #endif
     66 
     67   pthread_t t;
     68   ASSERT_EQ(0, pthread_create(&t, &attributes, gmtime_no_stack_overflow_14313703_fn, NULL));
     69   void* result;
     70   ASSERT_EQ(0, pthread_join(t, &result));
     71 }
     72 
     73 TEST(time, mktime_10310929) {
     74   struct tm t;
     75   memset(&t, 0, sizeof(tm));
     76   t.tm_year = 200;
     77   t.tm_mon = 2;
     78   t.tm_mday = 10;
     79 
     80 #if !defined(__LP64__)
     81   // 32-bit bionic stupidly had a signed 32-bit time_t.
     82   ASSERT_EQ(-1, mktime(&t));
     83 #else
     84   // Everyone else should be using a signed 64-bit time_t.
     85   ASSERT_GE(sizeof(time_t) * 8, 64U);
     86 
     87   setenv("TZ", "America/Los_Angeles", 1);
     88   tzset();
     89   ASSERT_EQ(static_cast<time_t>(4108348800U), mktime(&t));
     90 
     91   setenv("TZ", "UTC", 1);
     92   tzset();
     93   ASSERT_EQ(static_cast<time_t>(4108320000U), mktime(&t));
     94 #endif
     95 }
     96 
     97 TEST(time, strftime) {
     98   setenv("TZ", "UTC", 1);
     99 
    100   struct tm t;
    101   memset(&t, 0, sizeof(tm));
    102   t.tm_year = 200;
    103   t.tm_mon = 2;
    104   t.tm_mday = 10;
    105 
    106   char buf[64];
    107 
    108   // Seconds since the epoch.
    109 #if defined(__BIONIC__) || defined(__LP64__) // Not 32-bit glibc.
    110   EXPECT_EQ(10U, strftime(buf, sizeof(buf), "%s", &t));
    111   EXPECT_STREQ("4108320000", buf);
    112 #endif
    113 
    114   // Date and time as text.
    115   EXPECT_EQ(24U, strftime(buf, sizeof(buf), "%c", &t));
    116   EXPECT_STREQ("Sun Mar 10 00:00:00 2100", buf);
    117 }
    118 
    119 TEST(time, strptime) {
    120   setenv("TZ", "UTC", 1);
    121 
    122   struct tm t;
    123   char buf[64];
    124 
    125   memset(&t, 0, sizeof(t));
    126   strptime("11:14", "%R", &t);
    127   strftime(buf, sizeof(buf), "%H:%M", &t);
    128   EXPECT_STREQ("11:14", buf);
    129 
    130   memset(&t, 0, sizeof(t));
    131   strptime("09:41:53", "%T", &t);
    132   strftime(buf, sizeof(buf), "%H:%M:%S", &t);
    133   EXPECT_STREQ("09:41:53", buf);
    134 }
    135 
    136 void SetTime(timer_t t, time_t value_s, time_t value_ns, time_t interval_s, time_t interval_ns) {
    137   itimerspec ts;
    138   ts.it_value.tv_sec = value_s;
    139   ts.it_value.tv_nsec = value_ns;
    140   ts.it_interval.tv_sec = interval_s;
    141   ts.it_interval.tv_nsec = interval_ns;
    142   ASSERT_EQ(0, timer_settime(t, TIMER_ABSTIME, &ts, NULL));
    143 }
    144 
    145 static void NoOpNotifyFunction(sigval_t) {
    146 }
    147 
    148 TEST(time, timer_create) {
    149   sigevent_t se;
    150   memset(&se, 0, sizeof(se));
    151   se.sigev_notify = SIGEV_THREAD;
    152   se.sigev_notify_function = NoOpNotifyFunction;
    153   timer_t timer_id;
    154   ASSERT_EQ(0, timer_create(CLOCK_MONOTONIC, &se, &timer_id));
    155 
    156   int pid = fork();
    157   ASSERT_NE(-1, pid) << strerror(errno);
    158 
    159   if (pid == 0) {
    160     // Timers are not inherited by the child.
    161     ASSERT_EQ(-1, timer_delete(timer_id));
    162     ASSERT_EQ(EINVAL, errno);
    163     _exit(0);
    164   }
    165 
    166   int status;
    167   ASSERT_EQ(pid, waitpid(pid, &status, 0));
    168   ASSERT_TRUE(WIFEXITED(status));
    169   ASSERT_EQ(0, WEXITSTATUS(status));
    170 
    171   ASSERT_EQ(0, timer_delete(timer_id));
    172 }
    173 
    174 static int timer_create_SIGEV_SIGNAL_signal_handler_invocation_count = 0;
    175 static void timer_create_SIGEV_SIGNAL_signal_handler(int signal_number) {
    176   ++timer_create_SIGEV_SIGNAL_signal_handler_invocation_count;
    177   ASSERT_EQ(SIGUSR1, signal_number);
    178 }
    179 
    180 TEST(time, timer_create_SIGEV_SIGNAL) {
    181   sigevent_t se;
    182   memset(&se, 0, sizeof(se));
    183   se.sigev_notify = SIGEV_SIGNAL;
    184   se.sigev_signo = SIGUSR1;
    185 
    186   timer_t timer_id;
    187   ASSERT_EQ(0, timer_create(CLOCK_MONOTONIC, &se, &timer_id));
    188 
    189   ScopedSignalHandler ssh(SIGUSR1, timer_create_SIGEV_SIGNAL_signal_handler);
    190 
    191   ASSERT_EQ(0, timer_create_SIGEV_SIGNAL_signal_handler_invocation_count);
    192 
    193   itimerspec ts;
    194   ts.it_value.tv_sec =  0;
    195   ts.it_value.tv_nsec = 1;
    196   ts.it_interval.tv_sec = 0;
    197   ts.it_interval.tv_nsec = 0;
    198   ASSERT_EQ(0, timer_settime(timer_id, TIMER_ABSTIME, &ts, NULL));
    199 
    200   usleep(500000);
    201   ASSERT_EQ(1, timer_create_SIGEV_SIGNAL_signal_handler_invocation_count);
    202 }
    203 
    204 struct Counter {
    205   volatile int value;
    206   timer_t timer_id;
    207   sigevent_t se;
    208   bool timer_valid;
    209 
    210   Counter(void (*fn)(sigval_t)) : value(0), timer_valid(false) {
    211     memset(&se, 0, sizeof(se));
    212     se.sigev_notify = SIGEV_THREAD;
    213     se.sigev_notify_function = fn;
    214     se.sigev_value.sival_ptr = this;
    215     Create();
    216   }
    217 
    218   void Create() {
    219     ASSERT_FALSE(timer_valid);
    220     ASSERT_EQ(0, timer_create(CLOCK_REALTIME, &se, &timer_id));
    221     timer_valid = true;
    222   }
    223 
    224   void DeleteTimer() {
    225     ASSERT_TRUE(timer_valid);
    226     ASSERT_EQ(0, timer_delete(timer_id));
    227     timer_valid = false;
    228   }
    229 
    230   ~Counter() {
    231     if (timer_valid) {
    232       DeleteTimer();
    233     }
    234   }
    235 
    236   void SetTime(time_t value_s, time_t value_ns, time_t interval_s, time_t interval_ns) {
    237     ::SetTime(timer_id, value_s, value_ns, interval_s, interval_ns);
    238   }
    239 
    240   bool ValueUpdated() {
    241     volatile int current_value = value;
    242     time_t start = time(NULL);
    243     while (current_value == value && (time(NULL) - start) < 5) {
    244     }
    245     return current_value != value;
    246   }
    247 
    248   static void CountNotifyFunction(sigval_t value) {
    249     Counter* cd = reinterpret_cast<Counter*>(value.sival_ptr);
    250     ++cd->value;
    251   }
    252 
    253   static void CountAndDisarmNotifyFunction(sigval_t value) {
    254     Counter* cd = reinterpret_cast<Counter*>(value.sival_ptr);
    255     ++cd->value;
    256 
    257     // Setting the initial expiration time to 0 disarms the timer.
    258     cd->SetTime(0, 0, 1, 0);
    259   }
    260 };
    261 
    262 TEST(time, timer_settime_0) {
    263   Counter counter(Counter::CountAndDisarmNotifyFunction);
    264   ASSERT_TRUE(counter.timer_valid);
    265 
    266   ASSERT_EQ(0, counter.value);
    267 
    268   counter.SetTime(0, 1, 1, 0);
    269   usleep(500000);
    270 
    271   // The count should just be 1 because we disarmed the timer the first time it fired.
    272   ASSERT_EQ(1, counter.value);
    273 }
    274 
    275 TEST(time, timer_settime_repeats) {
    276   Counter counter(Counter::CountNotifyFunction);
    277   ASSERT_TRUE(counter.timer_valid);
    278 
    279   ASSERT_EQ(0, counter.value);
    280 
    281   counter.SetTime(0, 1, 0, 10);
    282   ASSERT_TRUE(counter.ValueUpdated());
    283   ASSERT_TRUE(counter.ValueUpdated());
    284   ASSERT_TRUE(counter.ValueUpdated());
    285 }
    286 
    287 static int timer_create_NULL_signal_handler_invocation_count = 0;
    288 static void timer_create_NULL_signal_handler(int signal_number) {
    289   ++timer_create_NULL_signal_handler_invocation_count;
    290   ASSERT_EQ(SIGALRM, signal_number);
    291 }
    292 
    293 TEST(time, timer_create_NULL) {
    294   // A NULL sigevent* is equivalent to asking for SIGEV_SIGNAL for SIGALRM.
    295   timer_t timer_id;
    296   ASSERT_EQ(0, timer_create(CLOCK_MONOTONIC, NULL, &timer_id));
    297 
    298   ScopedSignalHandler ssh(SIGALRM, timer_create_NULL_signal_handler);
    299 
    300   ASSERT_EQ(0, timer_create_NULL_signal_handler_invocation_count);
    301 
    302   SetTime(timer_id, 0, 1, 0, 0);
    303   usleep(500000);
    304 
    305   ASSERT_EQ(1, timer_create_NULL_signal_handler_invocation_count);
    306 }
    307 
    308 TEST(time, timer_create_EINVAL) {
    309   clockid_t invalid_clock = 16;
    310 
    311   // A SIGEV_SIGNAL timer is easy; the kernel does all that.
    312   timer_t timer_id;
    313   ASSERT_EQ(-1, timer_create(invalid_clock, NULL, &timer_id));
    314   ASSERT_EQ(EINVAL, errno);
    315 
    316   // A SIGEV_THREAD timer is more interesting because we have stuff to clean up.
    317   sigevent_t se;
    318   memset(&se, 0, sizeof(se));
    319   se.sigev_notify = SIGEV_THREAD;
    320   se.sigev_notify_function = NoOpNotifyFunction;
    321   ASSERT_EQ(-1, timer_create(invalid_clock, &se, &timer_id));
    322   ASSERT_EQ(EINVAL, errno);
    323 }
    324 
    325 TEST(time, timer_delete_multiple) {
    326   timer_t timer_id;
    327   ASSERT_EQ(0, timer_create(CLOCK_MONOTONIC, NULL, &timer_id));
    328   ASSERT_EQ(0, timer_delete(timer_id));
    329   ASSERT_EQ(-1, timer_delete(timer_id));
    330   ASSERT_EQ(EINVAL, errno);
    331 
    332   sigevent_t se;
    333   memset(&se, 0, sizeof(se));
    334   se.sigev_notify = SIGEV_THREAD;
    335   se.sigev_notify_function = NoOpNotifyFunction;
    336   ASSERT_EQ(0, timer_create(CLOCK_MONOTONIC, &se, &timer_id));
    337   ASSERT_EQ(0, timer_delete(timer_id));
    338   ASSERT_EQ(-1, timer_delete(timer_id));
    339   ASSERT_EQ(EINVAL, errno);
    340 }
    341 
    342 TEST(time, timer_create_multiple) {
    343   Counter counter1(Counter::CountNotifyFunction);
    344   ASSERT_TRUE(counter1.timer_valid);
    345   Counter counter2(Counter::CountNotifyFunction);
    346   ASSERT_TRUE(counter2.timer_valid);
    347   Counter counter3(Counter::CountNotifyFunction);
    348   ASSERT_TRUE(counter3.timer_valid);
    349 
    350   ASSERT_EQ(0, counter1.value);
    351   ASSERT_EQ(0, counter2.value);
    352   ASSERT_EQ(0, counter3.value);
    353 
    354   counter2.SetTime(0, 1, 0, 0);
    355   usleep(500000);
    356 
    357   EXPECT_EQ(0, counter1.value);
    358   EXPECT_EQ(1, counter2.value);
    359   EXPECT_EQ(0, counter3.value);
    360 }
    361 
    362 struct TimerDeleteData {
    363   timer_t timer_id;
    364   pthread_t thread_id;
    365   volatile bool complete;
    366 };
    367 
    368 static void TimerDeleteCallback(sigval_t value) {
    369   TimerDeleteData* tdd = reinterpret_cast<TimerDeleteData*>(value.sival_ptr);
    370 
    371   tdd->thread_id = pthread_self();
    372   timer_delete(tdd->timer_id);
    373   tdd->complete = true;
    374 }
    375 
    376 TEST(time, timer_delete_from_timer_thread) {
    377   TimerDeleteData tdd;
    378   sigevent_t se;
    379 
    380   memset(&se, 0, sizeof(se));
    381   se.sigev_notify = SIGEV_THREAD;
    382   se.sigev_notify_function = TimerDeleteCallback;
    383   se.sigev_value.sival_ptr = &tdd;
    384 
    385   tdd.complete = false;
    386   ASSERT_EQ(0, timer_create(CLOCK_REALTIME, &se, &tdd.timer_id));
    387 
    388   itimerspec ts;
    389   ts.it_value.tv_sec = 0;
    390   ts.it_value.tv_nsec = 100;
    391   ts.it_interval.tv_sec = 0;
    392   ts.it_interval.tv_nsec = 0;
    393   ASSERT_EQ(0, timer_settime(tdd.timer_id, TIMER_ABSTIME, &ts, NULL));
    394 
    395   time_t cur_time = time(NULL);
    396   while (!tdd.complete && (time(NULL) - cur_time) < 5);
    397   ASSERT_TRUE(tdd.complete);
    398 
    399 #if defined(__BIONIC__)
    400   // Since bionic timers are implemented by creating a thread to handle the
    401   // callback, verify that the thread actually completes.
    402   cur_time = time(NULL);
    403   while (pthread_detach(tdd.thread_id) != ESRCH && (time(NULL) - cur_time) < 5);
    404   ASSERT_EQ(ESRCH, pthread_detach(tdd.thread_id));
    405 #endif
    406 }
    407 
    408 TEST(time, clock_gettime) {
    409   // Try to ensure that our vdso clock_gettime is working.
    410   timespec ts1;
    411   ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &ts1));
    412   timespec ts2;
    413   ASSERT_EQ(0, syscall(__NR_clock_gettime, CLOCK_MONOTONIC, &ts2));
    414 
    415   // What's the difference between the two?
    416   ts2.tv_sec -= ts1.tv_sec;
    417   ts2.tv_nsec -= ts1.tv_nsec;
    418   if (ts2.tv_nsec < 0) {
    419     --ts2.tv_sec;
    420     ts2.tv_nsec += 1000000000;
    421   }
    422 
    423   // Should be less than (a very generous, to try to avoid flakiness) 1000000ns.
    424   ASSERT_EQ(0, ts2.tv_sec);
    425   ASSERT_LT(ts2.tv_nsec, 1000000);
    426 }
    427 
    428 // Test to verify that disarming a repeatable timer disables the
    429 // callbacks.
    430 TEST(time, timer_disarm_terminates) {
    431   Counter counter(Counter::CountNotifyFunction);
    432   ASSERT_TRUE(counter.timer_valid);
    433 
    434   ASSERT_EQ(0, counter.value);
    435 
    436   counter.SetTime(0, 1, 0, 1);
    437   ASSERT_TRUE(counter.ValueUpdated());
    438   ASSERT_TRUE(counter.ValueUpdated());
    439   ASSERT_TRUE(counter.ValueUpdated());
    440 
    441   counter.SetTime(0, 0, 1, 0);
    442   volatile int value = counter.value;
    443   usleep(500000);
    444 
    445   // Verify the counter has not been incremented.
    446   ASSERT_EQ(value, counter.value);
    447 }
    448 
    449 // Test to verify that deleting a repeatable timer disables the
    450 // callbacks.
    451 TEST(time, timer_delete_terminates) {
    452   Counter counter(Counter::CountNotifyFunction);
    453   ASSERT_TRUE(counter.timer_valid);
    454 
    455   ASSERT_EQ(0, counter.value);
    456 
    457   counter.SetTime(0, 1, 0, 1);
    458   ASSERT_TRUE(counter.ValueUpdated());
    459   ASSERT_TRUE(counter.ValueUpdated());
    460   ASSERT_TRUE(counter.ValueUpdated());
    461 
    462   counter.DeleteTimer();
    463   volatile int value = counter.value;
    464   usleep(500000);
    465 
    466   // Verify the counter has not been incremented.
    467   ASSERT_EQ(value, counter.value);
    468 }
    469