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 <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 
     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 
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    172 static void NoOpNotifyFunction(sigval_t) {
    173 }
    174 
    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;
    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 
    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 
    239   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:
    246   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   }
    253   void DeleteTimer() {
    254     ASSERT_TRUE(timer_valid);
    255     ASSERT_EQ(0, timer_delete(timer_id));
    256     timer_valid = false;
    257   }
    258 
    259   ~Counter() {
    260     if (timer_valid) {
    261       DeleteTimer();
    262     }
    263   }
    264 
    265   int Value() const {
    266     return value;
    267   }
    268 
    269   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 
    273   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 
    281   static void CountNotifyFunction(sigval_t value) {
    282     Counter* cd = reinterpret_cast<Counter*>(value.sival_ptr);
    283     ++cd->value;
    284   }
    285 
    286   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 
    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 
    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;
    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 
    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 
    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 
    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 
    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.
    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.
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    541 TEST(time, clock_nanosleep) {
    542   timespec in;
    543   timespec out;
    544   ASSERT_EQ(EINVAL, clock_nanosleep(-1, 0, &in, &out));
    545 }
    546