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 #include "utils.h"
     31 
     32 #include "private/bionic_constants.h"
     33 
     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 
     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 
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    205 static void NoOpNotifyFunction(sigval_t) {
    206 }
    207 
    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;
    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 
    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 
    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 
    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 
    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;
    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 
    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 
    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 
    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 
    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.
    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.
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    571 TEST(time, clock_nanosleep) {
    572   timespec in;
    573   timespec out;
    574   ASSERT_EQ(EINVAL, clock_nanosleep(-1, 0, &in, &out));
    575 }
    576