• Home
  • History
  • Annotate
  • 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/cdefs.h>
24  #include <sys/syscall.h>
25  #include <sys/types.h>
26  #include <sys/wait.h>
27  #include <unistd.h>
28  
29  #include <atomic>
30  #include <chrono>
31  #include <thread>
32  
33  #include "SignalUtils.h"
34  #include "android-base/file.h"
35  #include "android-base/strings.h"
36  #include "utils.h"
37  
38  using namespace std::chrono_literals;
39  
TEST(time,time)40  TEST(time, time) {
41    // Acquire time
42    time_t p1, t1 = time(&p1);
43    // valid?
44    ASSERT_NE(static_cast<time_t>(0), t1);
45    ASSERT_NE(static_cast<time_t>(-1), t1);
46    ASSERT_EQ(p1, t1);
47  
48    // Acquire time one+ second later
49    usleep(1010000);
50    time_t p2, t2 = time(&p2);
51    // valid?
52    ASSERT_NE(static_cast<time_t>(0), t2);
53    ASSERT_NE(static_cast<time_t>(-1), t2);
54    ASSERT_EQ(p2, t2);
55  
56    // Expect time progression
57    ASSERT_LT(p1, p2);
58    ASSERT_LE(t2 - t1, static_cast<time_t>(2));
59  
60    // Expect nullptr call to produce same results
61    ASSERT_LE(t2, time(nullptr));
62    ASSERT_LE(time(nullptr) - t2, static_cast<time_t>(1));
63  }
64  
TEST(time,gmtime)65  TEST(time, gmtime) {
66    time_t t = 0;
67    tm* broken_down = gmtime(&t);
68    ASSERT_TRUE(broken_down != nullptr);
69    ASSERT_EQ(0, broken_down->tm_sec);
70    ASSERT_EQ(0, broken_down->tm_min);
71    ASSERT_EQ(0, broken_down->tm_hour);
72    ASSERT_EQ(1, broken_down->tm_mday);
73    ASSERT_EQ(0, broken_down->tm_mon);
74    ASSERT_EQ(1970, broken_down->tm_year + 1900);
75  }
76  
TEST(time,gmtime_r)77  TEST(time, gmtime_r) {
78    struct tm tm = {};
79    time_t t = 0;
80    struct tm* broken_down = gmtime_r(&t, &tm);
81    ASSERT_EQ(broken_down, &tm);
82    ASSERT_EQ(0, broken_down->tm_sec);
83    ASSERT_EQ(0, broken_down->tm_min);
84    ASSERT_EQ(0, broken_down->tm_hour);
85    ASSERT_EQ(1, broken_down->tm_mday);
86    ASSERT_EQ(0, broken_down->tm_mon);
87    ASSERT_EQ(1970, broken_down->tm_year + 1900);
88  }
89  
TEST(time,mktime_TZ_as_UTC_and_offset)90  TEST(time, mktime_TZ_as_UTC_and_offset) {
91    struct tm tm = {.tm_year = 70, .tm_mon = 0, .tm_mday = 1};
92  
93    // This TZ value is not a valid Olson ID and is not present in tzdata file,
94    // but is a valid TZ string according to POSIX standard.
95    setenv("TZ", "UTC+08:00:00", 1);
96    tzset();
97    ASSERT_EQ(static_cast<time_t>(8 * 60 * 60), mktime(&tm));
98  }
99  
gmtime_no_stack_overflow_14313703_fn(void *)100  static void* gmtime_no_stack_overflow_14313703_fn(void*) {
101    const char* original_tz = getenv("TZ");
102    // Ensure we'll actually have to enter tzload by using a timezone that doesn't exist.
103    setenv("TZ", "gmtime_stack_overflow_14313703", 1);
104    tzset();
105    if (original_tz != nullptr) {
106      setenv("TZ", original_tz, 1);
107    }
108    tzset();
109    return nullptr;
110  }
111  
TEST(time,gmtime_no_stack_overflow_14313703)112  TEST(time, gmtime_no_stack_overflow_14313703) {
113    // Is it safe to call tzload on a thread with a small stack?
114    // http://b/14313703
115    // https://code.google.com/p/android/issues/detail?id=61130
116    pthread_attr_t a;
117    ASSERT_EQ(0, pthread_attr_init(&a));
118    ASSERT_EQ(0, pthread_attr_setstacksize(&a, PTHREAD_STACK_MIN));
119  
120    pthread_t t;
121    ASSERT_EQ(0, pthread_create(&t, &a, gmtime_no_stack_overflow_14313703_fn, nullptr));
122    ASSERT_EQ(0, pthread_join(t, nullptr));
123  }
124  
TEST(time,mktime_empty_TZ)125  TEST(time, mktime_empty_TZ) {
126    // tzcode used to have a bug where it didn't reinitialize some internal state.
127  
128    // Choose a time where DST is set.
129    struct tm t;
130    memset(&t, 0, sizeof(tm));
131    t.tm_year = 1980 - 1900;
132    t.tm_mon = 6;
133    t.tm_mday = 2;
134  
135    setenv("TZ", "America/Los_Angeles", 1);
136    tzset();
137    ASSERT_EQ(static_cast<time_t>(331372800U), mktime(&t));
138  
139    memset(&t, 0, sizeof(tm));
140    t.tm_year = 1980 - 1900;
141    t.tm_mon = 6;
142    t.tm_mday = 2;
143  
144    setenv("TZ", "", 1); // Implies UTC.
145    tzset();
146    ASSERT_EQ(static_cast<time_t>(331344000U), mktime(&t));
147  }
148  
TEST(time,mktime_10310929)149  TEST(time, mktime_10310929) {
150    struct tm tm = {.tm_year = 2100 - 1900, .tm_mon = 2, .tm_mday = 10};
151  
152  #if !defined(__LP64__)
153    // 32-bit bionic has a signed 32-bit time_t.
154    ASSERT_EQ(-1, mktime(&tm));
155    ASSERT_ERRNO(EOVERFLOW);
156  #else
157    // Everyone else should be using a signed 64-bit time_t.
158    ASSERT_GE(sizeof(time_t) * 8, 64U);
159  
160    setenv("TZ", "America/Los_Angeles", 1);
161    tzset();
162    errno = 0;
163  
164    // On the date/time specified by tm America/Los_Angeles
165    // follows DST. But tm_isdst is set to 0, which forces
166    // mktime to interpret that time as local standard, hence offset
167    // is 8 hours, not 7.
168    ASSERT_EQ(static_cast<time_t>(4108348800U), mktime(&tm));
169    ASSERT_ERRNO(0);
170  #endif
171  }
172  
TEST(time,mktime_EOVERFLOW)173  TEST(time, mktime_EOVERFLOW) {
174    setenv("TZ", "UTC", 1);
175  
176    struct tm t;
177    memset(&t, 0, sizeof(tm));
178  
179    // LP32 year range is 1901-2038, so this year is guaranteed not to overflow.
180    t.tm_year = 2016 - 1900;
181  
182    t.tm_mon = 2;
183    t.tm_mday = 10;
184  
185    errno = 0;
186    ASSERT_NE(static_cast<time_t>(-1), mktime(&t));
187    ASSERT_ERRNO(0);
188  
189    // This will overflow for LP32.
190    t.tm_year = INT_MAX;
191  
192    errno = 0;
193  #if !defined(__LP64__)
194    ASSERT_EQ(static_cast<time_t>(-1), mktime(&t));
195    ASSERT_ERRNO(EOVERFLOW);
196  #else
197    ASSERT_EQ(static_cast<time_t>(67768036166016000U), mktime(&t));
198    ASSERT_ERRNO(0);
199  #endif
200  
201    // This will overflow for LP32 or LP64.
202    // tm_year is int, this t struct points to INT_MAX + 1 no matter what TZ is.
203    t.tm_year = INT_MAX;
204    t.tm_mon = 11;
205    t.tm_mday = 45;
206  
207    errno = 0;
208    ASSERT_EQ(static_cast<time_t>(-1), mktime(&t));
209    ASSERT_ERRNO(EOVERFLOW);
210  }
211  
TEST(time,mktime_invalid_tm_TZ_combination)212  TEST(time, mktime_invalid_tm_TZ_combination) {
213    setenv("TZ", "UTC", 1);
214  
215    struct tm t;
216    memset(&t, 0, sizeof(tm));
217    t.tm_year = 2022 - 1900;
218    t.tm_mon = 11;
219    t.tm_mday = 31;
220    // UTC does not observe DST
221    t.tm_isdst = 1;
222  
223    errno = 0;
224  
225    EXPECT_EQ(static_cast<time_t>(-1), mktime(&t));
226    // mktime sets errno to EOVERFLOW if result is unrepresentable.
227    EXPECT_ERRNO(EOVERFLOW);
228  }
229  
230  // Transitions in the tzdata file are generated up to the year 2100. Testing
231  // that dates beyond that are handled properly too.
TEST(time,mktime_after_2100)232  TEST(time, mktime_after_2100) {
233    struct tm tm = {.tm_year = 2150 - 1900, .tm_mon = 2, .tm_mday = 10, .tm_isdst = -1};
234  
235  #if !defined(__LP64__)
236    // 32-bit bionic has a signed 32-bit time_t.
237    ASSERT_EQ(-1, mktime(&tm));
238    ASSERT_ERRNO(EOVERFLOW);
239  #else
240    setenv("TZ", "Europe/London", 1);
241    tzset();
242    errno = 0;
243    ASSERT_EQ(static_cast<time_t>(5686156800U), mktime(&tm));
244    ASSERT_ERRNO(0);
245  #endif
246  }
247  
TEST(time,strftime)248  TEST(time, strftime) {
249    setenv("TZ", "UTC", 1);
250  
251    struct tm t;
252    memset(&t, 0, sizeof(tm));
253    t.tm_year = 200;
254    t.tm_mon = 2;
255    t.tm_mday = 10;
256  
257    char buf[64];
258  
259    // Seconds since the epoch.
260  #if defined(__BIONIC__) || defined(__LP64__) // Not 32-bit glibc.
261    EXPECT_EQ(10U, strftime(buf, sizeof(buf), "%s", &t));
262    EXPECT_STREQ("4108320000", buf);
263  #endif
264  
265    // Date and time as text.
266    EXPECT_EQ(24U, strftime(buf, sizeof(buf), "%c", &t));
267    EXPECT_STREQ("Sun Mar 10 00:00:00 2100", buf);
268  }
269  
TEST(time,strftime_second_before_epoch)270  TEST(time, strftime_second_before_epoch) {
271    setenv("TZ", "UTC", 1);
272  
273    struct tm t;
274    memset(&t, 0, sizeof(tm));
275    t.tm_year = 1969 - 1900;
276    t.tm_mon = 11;
277    t.tm_mday = 31;
278    t.tm_hour = 23;
279    t.tm_min = 59;
280    t.tm_sec = 59;
281  
282    char buf[64];
283  
284    EXPECT_EQ(2U, strftime(buf, sizeof(buf), "%s", &t));
285    EXPECT_STREQ("-1", buf);
286  }
287  
TEST(time,strftime_Z_null_tm_zone)288  TEST(time, strftime_Z_null_tm_zone) {
289    // Netflix on Nexus Player wouldn't start (http://b/25170306).
290    struct tm t;
291    memset(&t, 0, sizeof(tm));
292  
293    char buf[64];
294  
295    setenv("TZ", "America/Los_Angeles", 1);
296    tzset();
297  
298    t.tm_isdst = 0; // "0 if Daylight Savings Time is not in effect".
299    EXPECT_EQ(5U, strftime(buf, sizeof(buf), "<%Z>", &t));
300    EXPECT_STREQ("<PST>", buf);
301  
302  #if defined(__BIONIC__) // glibc 2.19 only copes with tm_isdst being 0 and 1.
303    t.tm_isdst = 2; // "positive if Daylight Savings Time is in effect"
304    EXPECT_EQ(5U, strftime(buf, sizeof(buf), "<%Z>", &t));
305    EXPECT_STREQ("<PDT>", buf);
306  
307    t.tm_isdst = -123; // "and negative if the information is not available".
308    EXPECT_EQ(2U, strftime(buf, sizeof(buf), "<%Z>", &t));
309    EXPECT_STREQ("<>", buf);
310  #endif
311  
312    setenv("TZ", "UTC", 1);
313    tzset();
314  
315    t.tm_isdst = 0;
316    EXPECT_EQ(5U, strftime(buf, sizeof(buf), "<%Z>", &t));
317    EXPECT_STREQ("<UTC>", buf);
318  
319  #if defined(__BIONIC__) // glibc 2.19 thinks UTC DST is "UTC".
320    t.tm_isdst = 1; // UTC has no DST.
321    EXPECT_EQ(2U, strftime(buf, sizeof(buf), "<%Z>", &t));
322    EXPECT_STREQ("<>", buf);
323  #endif
324  }
325  
326  // According to C language specification the only tm struct field needed to
327  // find out replacement for %z and %Z in strftime is tm_isdst. Which is
328  // wrong, as timezones change their standard offset and even DST savings.
329  // tzcode deviates from C language specification and requires tm struct either
330  // to be output of localtime-like functions or to be modified by mktime call
331  // before passing to strftime. See tz mailing discussion for more details
332  // https://mm.icann.org/pipermail/tz/2022-July/031674.html
333  // But we are testing case when tm.tm_zone is null, which means that tm struct
334  // is not coming from localtime and is neither modified by mktime. That's why
335  // we are comparing against +0000, even though America/Los_Angeles never
336  // observes it.
TEST(time,strftime_z_null_tm_zone)337  TEST(time, strftime_z_null_tm_zone) {
338    char str[64];
339    struct tm tm = {.tm_year = 109, .tm_mon = 4, .tm_mday = 2, .tm_isdst = 0};
340  
341    setenv("TZ", "America/Los_Angeles", 1);
342    tzset();
343  
344    tm.tm_zone = NULL;
345  
346    size_t result = strftime(str, sizeof(str), "%z", &tm);
347  
348    EXPECT_EQ(5U, result);
349    EXPECT_STREQ("+0000", str);
350  
351    tm.tm_isdst = 1;
352  
353    result = strftime(str, sizeof(str), "%z", &tm);
354  
355    EXPECT_EQ(5U, result);
356    EXPECT_STREQ("+0000", str);
357  
358    setenv("TZ", "UTC", 1);
359    tzset();
360  
361    tm.tm_isdst = 0;
362  
363    result = strftime(str, sizeof(str), "%z", &tm);
364  
365    EXPECT_EQ(5U, result);
366    EXPECT_STREQ("+0000", str);
367  
368    tm.tm_isdst = 1;
369  
370    result = strftime(str, sizeof(str), "%z", &tm);
371  
372    EXPECT_EQ(5U, result);
373    EXPECT_STREQ("+0000", str);
374  }
375  
TEST(time,strftime_z_Europe_Lisbon)376  TEST(time, strftime_z_Europe_Lisbon) {
377    char str[64];
378    // During 1992-1996 Europe/Lisbon standard offset was 1 hour.
379    // tm_isdst is not set as it will be overridden by mktime call anyway.
380    struct tm tm = {.tm_year = 1996 - 1900, .tm_mon = 2, .tm_mday = 13};
381  
382    setenv("TZ", "Europe/Lisbon", 1);
383    tzset();
384  
385    // tzcode's strftime implementation for %z relies on prior mktime call.
386    // At the moment of writing %z value is taken from tm_gmtoff. So without
387    // mktime call %z is replaced with +0000.
388    // See https://mm.icann.org/pipermail/tz/2022-July/031674.html
389    mktime(&tm);
390  
391    size_t result = strftime(str, sizeof(str), "%z", &tm);
392  
393    EXPECT_EQ(5U, result);
394    EXPECT_STREQ("+0100", str);
395  
396    // Now standard offset is 0.
397    tm = {.tm_year = 2022 - 1900, .tm_mon = 2, .tm_mday = 13};
398  
399    mktime(&tm);
400    result = strftime(str, sizeof(str), "%z", &tm);
401  
402    EXPECT_EQ(5U, result);
403    EXPECT_STREQ("+0000", str);
404  }
405  
TEST(time,strftime_l)406  TEST(time, strftime_l) {
407    locale_t cloc = newlocale(LC_ALL, "C.UTF-8", nullptr);
408    locale_t old_locale = uselocale(cloc);
409  
410    setenv("TZ", "UTC", 1);
411  
412    struct tm t;
413    memset(&t, 0, sizeof(tm));
414    t.tm_year = 200;
415    t.tm_mon = 2;
416    t.tm_mday = 10;
417  
418    // Date and time as text.
419    char buf[64];
420    EXPECT_EQ(24U, strftime_l(buf, sizeof(buf), "%c", &t, cloc));
421    EXPECT_STREQ("Sun Mar 10 00:00:00 2100", buf);
422  
423    uselocale(old_locale);
424    freelocale(cloc);
425  }
426  
TEST(time,strptime)427  TEST(time, strptime) {
428    setenv("TZ", "UTC", 1);
429  
430    struct tm t;
431    char buf[64];
432  
433    memset(&t, 0, sizeof(t));
434    strptime("11:14", "%R", &t);
435    strftime(buf, sizeof(buf), "%H:%M", &t);
436    EXPECT_STREQ("11:14", buf);
437  
438    memset(&t, 0, sizeof(t));
439    strptime("09:41:53", "%T", &t);
440    strftime(buf, sizeof(buf), "%H:%M:%S", &t);
441    EXPECT_STREQ("09:41:53", buf);
442  }
443  
TEST(time,strptime_l)444  TEST(time, strptime_l) {
445  #if !defined(ANDROID_HOST_MUSL)
446    setenv("TZ", "UTC", 1);
447  
448    struct tm t;
449    char buf[64];
450  
451    memset(&t, 0, sizeof(t));
452    strptime_l("11:14", "%R", &t, LC_GLOBAL_LOCALE);
453    strftime_l(buf, sizeof(buf), "%H:%M", &t, LC_GLOBAL_LOCALE);
454    EXPECT_STREQ("11:14", buf);
455  
456    memset(&t, 0, sizeof(t));
457    strptime_l("09:41:53", "%T", &t, LC_GLOBAL_LOCALE);
458    strftime_l(buf, sizeof(buf), "%H:%M:%S", &t, LC_GLOBAL_LOCALE);
459    EXPECT_STREQ("09:41:53", buf);
460  #else
461    GTEST_SKIP() << "musl doesn't support strptime_l";
462  #endif
463  }
464  
TEST(time,strptime_F)465  TEST(time, strptime_F) {
466    setenv("TZ", "UTC", 1);
467  
468    struct tm tm = {};
469    ASSERT_EQ('\0', *strptime("2019-03-26", "%F", &tm));
470    EXPECT_EQ(119, tm.tm_year);
471    EXPECT_EQ(2, tm.tm_mon);
472    EXPECT_EQ(26, tm.tm_mday);
473  }
474  
TEST(time,strptime_P_p)475  TEST(time, strptime_P_p) {
476    setenv("TZ", "UTC", 1);
477  
478    // For parsing, %P and %p are the same: case doesn't matter.
479  
480    struct tm tm = {.tm_hour = 12};
481    ASSERT_EQ('\0', *strptime("AM", "%p", &tm));
482    EXPECT_EQ(0, tm.tm_hour);
483  
484    tm = {.tm_hour = 12};
485    ASSERT_EQ('\0', *strptime("am", "%p", &tm));
486    EXPECT_EQ(0, tm.tm_hour);
487  
488    tm = {.tm_hour = 12};
489    ASSERT_EQ('\0', *strptime("AM", "%P", &tm));
490    EXPECT_EQ(0, tm.tm_hour);
491  
492    tm = {.tm_hour = 12};
493    ASSERT_EQ('\0', *strptime("am", "%P", &tm));
494    EXPECT_EQ(0, tm.tm_hour);
495  }
496  
TEST(time,strptime_u)497  TEST(time, strptime_u) {
498    setenv("TZ", "UTC", 1);
499  
500    struct tm tm = {};
501    ASSERT_EQ('\0', *strptime("2", "%u", &tm));
502    EXPECT_EQ(2, tm.tm_wday);
503  }
504  
TEST(time,strptime_v)505  TEST(time, strptime_v) {
506    setenv("TZ", "UTC", 1);
507  
508    struct tm tm = {};
509    ASSERT_EQ('\0', *strptime("26-Mar-1980", "%v", &tm));
510    EXPECT_EQ(80, tm.tm_year);
511    EXPECT_EQ(2, tm.tm_mon);
512    EXPECT_EQ(26, tm.tm_mday);
513  }
514  
TEST(time,strptime_V_G_g)515  TEST(time, strptime_V_G_g) {
516    setenv("TZ", "UTC", 1);
517  
518    // %V (ISO-8601 week number), %G (year of week number, without century), and
519    // %g (year of week number) have no effect when parsed, and are supported
520    // solely so that it's possible for strptime(3) to parse everything that
521    // strftime(3) can output.
522    struct tm tm = {};
523    ASSERT_EQ('\0', *strptime("1 2 3", "%V %G %g", &tm));
524    struct tm zero = {};
525    EXPECT_TRUE(memcmp(&tm, &zero, sizeof(tm)) == 0);
526  }
527  
TEST(time,strptime_Z)528  TEST(time, strptime_Z) {
529  #if defined(__BIONIC__)
530    // glibc doesn't handle %Z at all.
531    // The BSDs only handle hard-coded "GMT" and "UTC", plus whatever two strings
532    // are in the global `tzname` (which correspond to the current $TZ).
533    struct tm tm;
534    setenv("TZ", "Europe/Berlin", 1);
535  
536    // "GMT" always works.
537    tm = {};
538    ASSERT_EQ('\0', *strptime("GMT", "%Z", &tm));
539    EXPECT_STREQ("GMT", tm.tm_zone);
540    EXPECT_EQ(0, tm.tm_isdst);
541    EXPECT_EQ(0, tm.tm_gmtoff);
542  
543    // As does "UTC".
544    tm = {};
545    ASSERT_EQ('\0', *strptime("UTC", "%Z", &tm));
546    EXPECT_STREQ("UTC", tm.tm_zone);
547    EXPECT_EQ(0, tm.tm_isdst);
548    EXPECT_EQ(0, tm.tm_gmtoff);
549  
550    // Europe/Berlin is known as "CET" when there's no DST.
551    tm = {};
552    ASSERT_EQ('\0', *strptime("CET", "%Z", &tm));
553    EXPECT_STREQ("CET", tm.tm_zone);
554    EXPECT_EQ(0, tm.tm_isdst);
555    EXPECT_EQ(3600, tm.tm_gmtoff);
556  
557    // Europe/Berlin is known as "CEST" when there's no DST.
558    tm = {};
559    ASSERT_EQ('\0', *strptime("CEST", "%Z", &tm));
560    EXPECT_STREQ("CEST", tm.tm_zone);
561    EXPECT_EQ(1, tm.tm_isdst);
562    EXPECT_EQ(3600, tm.tm_gmtoff);
563  
564    // And as long as we're in Europe/Berlin, those are the only timezone
565    // abbreviations that are recognized.
566    tm = {};
567    ASSERT_TRUE(strptime("PDT", "%Z", &tm) == nullptr);
568  #endif
569  }
570  
TEST(time,strptime_z)571  TEST(time, strptime_z) {
572    struct tm tm;
573    setenv("TZ", "Europe/Berlin", 1);
574  
575    // "UT" is what RFC822 called UTC.
576    tm = {};
577    ASSERT_EQ('\0', *strptime("UT", "%z", &tm));
578    EXPECT_STREQ("UTC", tm.tm_zone);
579    EXPECT_EQ(0, tm.tm_isdst);
580    EXPECT_EQ(0, tm.tm_gmtoff);
581    // "GMT" is RFC822's other name for UTC.
582    tm = {};
583    ASSERT_EQ('\0', *strptime("GMT", "%z", &tm));
584    EXPECT_STREQ("UTC", tm.tm_zone);
585    EXPECT_EQ(0, tm.tm_isdst);
586    EXPECT_EQ(0, tm.tm_gmtoff);
587  
588    // "Z" ("Zulu") is a synonym for UTC.
589    tm = {};
590    ASSERT_EQ('\0', *strptime("Z", "%z", &tm));
591    EXPECT_STREQ("UTC", tm.tm_zone);
592    EXPECT_EQ(0, tm.tm_isdst);
593    EXPECT_EQ(0, tm.tm_gmtoff);
594  
595    // "PST"/"PDT" and the other common US zone abbreviations are all supported.
596    tm = {};
597    ASSERT_EQ('\0', *strptime("PST", "%z", &tm));
598    EXPECT_STREQ("PST", tm.tm_zone);
599    EXPECT_EQ(0, tm.tm_isdst);
600    EXPECT_EQ(-28800, tm.tm_gmtoff);
601    tm = {};
602    ASSERT_EQ('\0', *strptime("PDT", "%z", &tm));
603    EXPECT_STREQ("PDT", tm.tm_zone);
604    EXPECT_EQ(1, tm.tm_isdst);
605    EXPECT_EQ(-25200, tm.tm_gmtoff);
606  
607    // +-hh
608    tm = {};
609    ASSERT_EQ('\0', *strptime("+01", "%z", &tm));
610    EXPECT_EQ(3600, tm.tm_gmtoff);
611    EXPECT_TRUE(tm.tm_zone == nullptr);
612    EXPECT_EQ(0, tm.tm_isdst);
613    // +-hhmm
614    tm = {};
615    ASSERT_EQ('\0', *strptime("+0130", "%z", &tm));
616    EXPECT_EQ(5400, tm.tm_gmtoff);
617    EXPECT_TRUE(tm.tm_zone == nullptr);
618    EXPECT_EQ(0, tm.tm_isdst);
619    // +-hh:mm
620    tm = {};
621    ASSERT_EQ('\0', *strptime("+01:30", "%z", &tm));
622    EXPECT_EQ(5400, tm.tm_gmtoff);
623    EXPECT_TRUE(tm.tm_zone == nullptr);
624    EXPECT_EQ(0, tm.tm_isdst);
625  }
626  
SetTime(timer_t t,time_t value_s,time_t value_ns,time_t interval_s,time_t interval_ns)627  void SetTime(timer_t t, time_t value_s, time_t value_ns, time_t interval_s, time_t interval_ns) {
628    itimerspec ts;
629    ts.it_value.tv_sec = value_s;
630    ts.it_value.tv_nsec = value_ns;
631    ts.it_interval.tv_sec = interval_s;
632    ts.it_interval.tv_nsec = interval_ns;
633    ASSERT_EQ(0, timer_settime(t, 0, &ts, nullptr));
634  }
635  
NoOpNotifyFunction(sigval)636  static void NoOpNotifyFunction(sigval) {
637  }
638  
TEST(time,timer_create)639  TEST(time, timer_create) {
640    sigevent se;
641    memset(&se, 0, sizeof(se));
642    se.sigev_notify = SIGEV_THREAD;
643    se.sigev_notify_function = NoOpNotifyFunction;
644    timer_t timer_id;
645    ASSERT_EQ(0, timer_create(CLOCK_MONOTONIC, &se, &timer_id));
646  
647    pid_t pid = fork();
648    ASSERT_NE(-1, pid) << strerror(errno);
649  
650    if (pid == 0) {
651      // Timers are not inherited by the child.
652      ASSERT_EQ(-1, timer_delete(timer_id));
653      ASSERT_ERRNO(EINVAL);
654      _exit(0);
655    }
656  
657    AssertChildExited(pid, 0);
658  
659    ASSERT_EQ(0, timer_delete(timer_id));
660  }
661  
662  static int timer_create_SIGEV_SIGNAL_signal_handler_invocation_count;
timer_create_SIGEV_SIGNAL_signal_handler(int signal_number)663  static void timer_create_SIGEV_SIGNAL_signal_handler(int signal_number) {
664    ++timer_create_SIGEV_SIGNAL_signal_handler_invocation_count;
665    ASSERT_EQ(SIGUSR1, signal_number);
666  }
667  
TEST(time,timer_create_SIGEV_SIGNAL)668  TEST(time, timer_create_SIGEV_SIGNAL) {
669    sigevent se;
670    memset(&se, 0, sizeof(se));
671    se.sigev_notify = SIGEV_SIGNAL;
672    se.sigev_signo = SIGUSR1;
673  
674    timer_t timer_id;
675    ASSERT_EQ(0, timer_create(CLOCK_MONOTONIC, &se, &timer_id));
676  
677    timer_create_SIGEV_SIGNAL_signal_handler_invocation_count = 0;
678    ScopedSignalHandler ssh(SIGUSR1, timer_create_SIGEV_SIGNAL_signal_handler);
679  
680    ASSERT_EQ(0, timer_create_SIGEV_SIGNAL_signal_handler_invocation_count);
681  
682    itimerspec ts;
683    ts.it_value.tv_sec =  0;
684    ts.it_value.tv_nsec = 1;
685    ts.it_interval.tv_sec = 0;
686    ts.it_interval.tv_nsec = 0;
687    ASSERT_EQ(0, timer_settime(timer_id, 0, &ts, nullptr));
688  
689    usleep(500000);
690    ASSERT_EQ(1, timer_create_SIGEV_SIGNAL_signal_handler_invocation_count);
691  }
692  
693  struct Counter {
694   private:
695    std::atomic<int> value;
696    timer_t timer_id;
697    sigevent se;
698    bool timer_valid;
699  
CreateCounter700    void Create() {
701      ASSERT_FALSE(timer_valid);
702      ASSERT_EQ(0, timer_create(CLOCK_REALTIME, &se, &timer_id));
703      timer_valid = true;
704    }
705  
706   public:
CounterCounter707    explicit Counter(void (*fn)(sigval)) : value(0), timer_valid(false) {
708      memset(&se, 0, sizeof(se));
709      se.sigev_notify = SIGEV_THREAD;
710      se.sigev_notify_function = fn;
711      se.sigev_value.sival_ptr = this;
712      Create();
713    }
DeleteTimerCounter714    void DeleteTimer() {
715      ASSERT_TRUE(timer_valid);
716      ASSERT_EQ(0, timer_delete(timer_id));
717      timer_valid = false;
718    }
719  
~CounterCounter720    ~Counter() {
721      if (timer_valid) {
722        DeleteTimer();
723      }
724    }
725  
ValueCounter726    int Value() const {
727      return value;
728    }
729  
SetTimeCounter730    void SetTime(time_t value_s, time_t value_ns, time_t interval_s, time_t interval_ns) {
731      ::SetTime(timer_id, value_s, value_ns, interval_s, interval_ns);
732    }
733  
ValueUpdatedCounter734    bool ValueUpdated() {
735      int current_value = value;
736      time_t start = time(nullptr);
737      while (current_value == value && (time(nullptr) - start) < 5) {
738      }
739      return current_value != value;
740    }
741  
CountNotifyFunctionCounter742    static void CountNotifyFunction(sigval value) {
743      Counter* cd = reinterpret_cast<Counter*>(value.sival_ptr);
744      ++cd->value;
745    }
746  
CountAndDisarmNotifyFunctionCounter747    static void CountAndDisarmNotifyFunction(sigval value) {
748      Counter* cd = reinterpret_cast<Counter*>(value.sival_ptr);
749      ++cd->value;
750  
751      // Setting the initial expiration time to 0 disarms the timer.
752      cd->SetTime(0, 0, 1, 0);
753    }
754  };
755  
TEST(time,timer_settime_0)756  TEST(time, timer_settime_0) {
757    Counter counter(Counter::CountAndDisarmNotifyFunction);
758    ASSERT_EQ(0, counter.Value());
759  
760    counter.SetTime(0, 500000000, 1, 0);
761    sleep(1);
762  
763    // The count should just be 1 because we disarmed the timer the first time it fired.
764    ASSERT_EQ(1, counter.Value());
765  }
766  
TEST(time,timer_settime_repeats)767  TEST(time, timer_settime_repeats) {
768    Counter counter(Counter::CountNotifyFunction);
769    ASSERT_EQ(0, counter.Value());
770  
771    counter.SetTime(0, 1, 0, 10);
772    ASSERT_TRUE(counter.ValueUpdated());
773    ASSERT_TRUE(counter.ValueUpdated());
774    ASSERT_TRUE(counter.ValueUpdated());
775    counter.DeleteTimer();
776    // Add a sleep as other threads may be calling the callback function when the timer is deleted.
777    usleep(500000);
778  }
779  
780  static int timer_create_NULL_signal_handler_invocation_count;
timer_create_NULL_signal_handler(int signal_number)781  static void timer_create_NULL_signal_handler(int signal_number) {
782    ++timer_create_NULL_signal_handler_invocation_count;
783    ASSERT_EQ(SIGALRM, signal_number);
784  }
785  
TEST(time,timer_create_NULL)786  TEST(time, timer_create_NULL) {
787    // A NULL sigevent* is equivalent to asking for SIGEV_SIGNAL for SIGALRM.
788    timer_t timer_id;
789    ASSERT_EQ(0, timer_create(CLOCK_MONOTONIC, nullptr, &timer_id));
790  
791    timer_create_NULL_signal_handler_invocation_count = 0;
792    ScopedSignalHandler ssh(SIGALRM, timer_create_NULL_signal_handler);
793  
794    ASSERT_EQ(0, timer_create_NULL_signal_handler_invocation_count);
795  
796    SetTime(timer_id, 0, 1, 0, 0);
797    usleep(500000);
798  
799    ASSERT_EQ(1, timer_create_NULL_signal_handler_invocation_count);
800  }
801  
GetThreadCount()802  static int GetThreadCount() {
803    std::string status;
804    if (android::base::ReadFileToString("/proc/self/status", &status)) {
805      for (const auto& line : android::base::Split(status, "\n")) {
806        int thread_count;
807        if (sscanf(line.c_str(), "Threads: %d", &thread_count) == 1) {
808          return thread_count;
809        }
810      }
811    }
812    return -1;
813  }
814  
TEST(time,timer_create_EINVAL)815  TEST(time, timer_create_EINVAL) {
816    const clockid_t kInvalidClock = 16;
817  
818    // A SIGEV_SIGNAL timer failure is easy; that's the kernel's problem.
819    timer_t timer_id;
820    ASSERT_EQ(-1, timer_create(kInvalidClock, nullptr, &timer_id));
821    ASSERT_ERRNO(EINVAL);
822  
823    // A SIGEV_THREAD timer failure is more interesting because we have a thread
824    // to clean up (https://issuetracker.google.com/340125671).
825    sigevent se = {};
826    se.sigev_notify = SIGEV_THREAD;
827    se.sigev_notify_function = NoOpNotifyFunction;
828    ASSERT_EQ(-1, timer_create(kInvalidClock, &se, &timer_id));
829    ASSERT_ERRNO(EINVAL);
830  
831    // timer_create() doesn't guarantee that the thread will be dead _before_
832    // it returns because that would require extra synchronization that's
833    // unnecessary in the normal (successful) case. A timeout here means we
834    // leaked a thread.
835    while (GetThreadCount() > 1) {
836    }
837  }
838  
TEST(time,timer_create_multiple)839  TEST(time, timer_create_multiple) {
840    Counter counter1(Counter::CountNotifyFunction);
841    Counter counter2(Counter::CountNotifyFunction);
842    Counter counter3(Counter::CountNotifyFunction);
843  
844    ASSERT_EQ(0, counter1.Value());
845    ASSERT_EQ(0, counter2.Value());
846    ASSERT_EQ(0, counter3.Value());
847  
848    counter2.SetTime(0, 500000000, 0, 0);
849    sleep(1);
850  
851    EXPECT_EQ(0, counter1.Value());
852    EXPECT_EQ(1, counter2.Value());
853    EXPECT_EQ(0, counter3.Value());
854  }
855  
856  // Test to verify that disarming a repeatable timer disables the callbacks.
TEST(time,timer_disarm_terminates)857  TEST(time, timer_disarm_terminates) {
858    Counter counter(Counter::CountNotifyFunction);
859    ASSERT_EQ(0, counter.Value());
860  
861    counter.SetTime(0, 1, 0, 1);
862    ASSERT_TRUE(counter.ValueUpdated());
863    ASSERT_TRUE(counter.ValueUpdated());
864    ASSERT_TRUE(counter.ValueUpdated());
865  
866    counter.SetTime(0, 0, 0, 0);
867    // Add a sleep as the kernel may have pending events when the timer is disarmed.
868    usleep(500000);
869    int value = counter.Value();
870    usleep(500000);
871  
872    // Verify the counter has not been incremented.
873    ASSERT_EQ(value, counter.Value());
874  }
875  
876  // Test to verify that deleting a repeatable timer disables the callbacks.
TEST(time,timer_delete_terminates)877  TEST(time, timer_delete_terminates) {
878    Counter counter(Counter::CountNotifyFunction);
879    ASSERT_EQ(0, counter.Value());
880  
881    counter.SetTime(0, 1, 0, 1);
882    ASSERT_TRUE(counter.ValueUpdated());
883    ASSERT_TRUE(counter.ValueUpdated());
884    ASSERT_TRUE(counter.ValueUpdated());
885  
886    counter.DeleteTimer();
887    // Add a sleep as other threads may be calling the callback function when the timer is deleted.
888    usleep(500000);
889    int value = counter.Value();
890    usleep(500000);
891  
892    // Verify the counter has not been incremented.
893    ASSERT_EQ(value, counter.Value());
894  }
895  
896  struct TimerDeleteData {
897    timer_t timer_id;
898    pid_t tid;
899    volatile bool complete;
900  };
901  
TimerDeleteCallback(sigval value)902  static void TimerDeleteCallback(sigval value) {
903    TimerDeleteData* tdd = reinterpret_cast<TimerDeleteData*>(value.sival_ptr);
904  
905    tdd->tid = gettid();
906    timer_delete(tdd->timer_id);
907    tdd->complete = true;
908  }
909  
TEST(time,timer_delete_from_timer_thread)910  TEST(time, timer_delete_from_timer_thread) {
911    TimerDeleteData tdd;
912    sigevent se;
913  
914    memset(&se, 0, sizeof(se));
915    se.sigev_notify = SIGEV_THREAD;
916    se.sigev_notify_function = TimerDeleteCallback;
917    se.sigev_value.sival_ptr = &tdd;
918  
919    tdd.complete = false;
920    ASSERT_EQ(0, timer_create(CLOCK_REALTIME, &se, &tdd.timer_id));
921  
922    itimerspec ts;
923    ts.it_value.tv_sec = 1;
924    ts.it_value.tv_nsec = 0;
925    ts.it_interval.tv_sec = 0;
926    ts.it_interval.tv_nsec = 0;
927    ASSERT_EQ(0, timer_settime(tdd.timer_id, 0, &ts, nullptr));
928  
929    time_t cur_time = time(nullptr);
930    while (!tdd.complete && (time(nullptr) - cur_time) < 5);
931    ASSERT_TRUE(tdd.complete);
932  
933  #if defined(__BIONIC__)
934    // Since bionic timers are implemented by creating a thread to handle the
935    // callback, verify that the thread actually completes.
936    cur_time = time(NULL);
937    while ((kill(tdd.tid, 0) != -1 || errno != ESRCH) && (time(NULL) - cur_time) < 5);
938    ASSERT_EQ(-1, kill(tdd.tid, 0));
939    ASSERT_ERRNO(ESRCH);
940  #endif
941  }
942  
943  // Musl doesn't define __NR_clock_gettime on 32-bit architectures.
944  #if !defined(__NR_clock_gettime)
945  #define __NR_clock_gettime __NR_clock_gettime32
946  #endif
947  
TEST(time,clock_gettime)948  TEST(time, clock_gettime) {
949    // Try to ensure that our vdso clock_gettime is working.
950    timespec ts0;
951    timespec ts1;
952    timespec ts2;
953    ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &ts0));
954    ASSERT_EQ(0, syscall(__NR_clock_gettime, CLOCK_MONOTONIC, &ts1));
955    ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &ts2));
956  
957    // Check we have a nice monotonic timestamp sandwich.
958    ASSERT_LE(ts0.tv_sec, ts1.tv_sec);
959    if (ts0.tv_sec == ts1.tv_sec) {
960      ASSERT_LE(ts0.tv_nsec, ts1.tv_nsec);
961    }
962    ASSERT_LE(ts1.tv_sec, ts2.tv_sec);
963    if (ts1.tv_sec == ts2.tv_sec) {
964      ASSERT_LE(ts1.tv_nsec, ts2.tv_nsec);
965    }
966  }
967  
TEST(time,clock_gettime_CLOCK_REALTIME)968  TEST(time, clock_gettime_CLOCK_REALTIME) {
969    timespec ts;
970    ASSERT_EQ(0, clock_gettime(CLOCK_REALTIME, &ts));
971  }
972  
TEST(time,clock_gettime_CLOCK_MONOTONIC)973  TEST(time, clock_gettime_CLOCK_MONOTONIC) {
974    timespec ts;
975    ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &ts));
976  }
977  
TEST(time,clock_gettime_CLOCK_PROCESS_CPUTIME_ID)978  TEST(time, clock_gettime_CLOCK_PROCESS_CPUTIME_ID) {
979    timespec ts;
980    ASSERT_EQ(0, clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts));
981  }
982  
TEST(time,clock_gettime_CLOCK_THREAD_CPUTIME_ID)983  TEST(time, clock_gettime_CLOCK_THREAD_CPUTIME_ID) {
984    timespec ts;
985    ASSERT_EQ(0, clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts));
986  }
987  
TEST(time,clock_gettime_CLOCK_BOOTTIME)988  TEST(time, clock_gettime_CLOCK_BOOTTIME) {
989    timespec ts;
990    ASSERT_EQ(0, clock_gettime(CLOCK_BOOTTIME, &ts));
991  }
992  
TEST(time,clock_gettime_unknown)993  TEST(time, clock_gettime_unknown) {
994    errno = 0;
995    timespec ts;
996    ASSERT_EQ(-1, clock_gettime(-1, &ts));
997    ASSERT_ERRNO(EINVAL);
998  }
999  
TEST(time,clock_getres_CLOCK_REALTIME)1000  TEST(time, clock_getres_CLOCK_REALTIME) {
1001    timespec ts;
1002    ASSERT_EQ(0, clock_getres(CLOCK_REALTIME, &ts));
1003    ASSERT_EQ(1, ts.tv_nsec);
1004    ASSERT_EQ(0, ts.tv_sec);
1005  }
1006  
TEST(time,clock_getres_CLOCK_MONOTONIC)1007  TEST(time, clock_getres_CLOCK_MONOTONIC) {
1008    timespec ts;
1009    ASSERT_EQ(0, clock_getres(CLOCK_MONOTONIC, &ts));
1010    ASSERT_EQ(1, ts.tv_nsec);
1011    ASSERT_EQ(0, ts.tv_sec);
1012  }
1013  
TEST(time,clock_getres_CLOCK_PROCESS_CPUTIME_ID)1014  TEST(time, clock_getres_CLOCK_PROCESS_CPUTIME_ID) {
1015    timespec ts;
1016    ASSERT_EQ(0, clock_getres(CLOCK_PROCESS_CPUTIME_ID, &ts));
1017  }
1018  
TEST(time,clock_getres_CLOCK_THREAD_CPUTIME_ID)1019  TEST(time, clock_getres_CLOCK_THREAD_CPUTIME_ID) {
1020    timespec ts;
1021    ASSERT_EQ(0, clock_getres(CLOCK_THREAD_CPUTIME_ID, &ts));
1022  }
1023  
TEST(time,clock_getres_CLOCK_BOOTTIME)1024  TEST(time, clock_getres_CLOCK_BOOTTIME) {
1025    timespec ts;
1026    ASSERT_EQ(0, clock_getres(CLOCK_BOOTTIME, &ts));
1027    ASSERT_EQ(1, ts.tv_nsec);
1028    ASSERT_EQ(0, ts.tv_sec);
1029  }
1030  
TEST(time,clock_getres_unknown)1031  TEST(time, clock_getres_unknown) {
1032    errno = 0;
1033    timespec ts = { -1, -1 };
1034    ASSERT_EQ(-1, clock_getres(-1, &ts));
1035    ASSERT_ERRNO(EINVAL);
1036    ASSERT_EQ(-1, ts.tv_nsec);
1037    ASSERT_EQ(-1, ts.tv_sec);
1038  }
1039  
TEST(time,clock_getres_null_resolution)1040  TEST(time, clock_getres_null_resolution) {
1041    ASSERT_EQ(0, clock_getres(CLOCK_REALTIME, nullptr));
1042  }
1043  
TEST(time,clock)1044  TEST(time, clock) {
1045    // clock(3) is hard to test, but a 1s sleep should cost less than 10ms on average.
1046    static const clock_t N = 5;
1047    static const clock_t mean_limit_ms = 10;
1048    clock_t t0 = clock();
1049    for (size_t i = 0; i < N; ++i) {
1050      sleep(1);
1051    }
1052    clock_t t1 = clock();
1053    ASSERT_LT(t1 - t0, N * mean_limit_ms * (CLOCKS_PER_SEC / 1000));
1054  }
1055  
GetInvalidPid()1056  static pid_t GetInvalidPid() {
1057    std::unique_ptr<FILE, decltype(&fclose)> fp{fopen("/proc/sys/kernel/pid_max", "r"), fclose};
1058    long pid_max;
1059    fscanf(fp.get(), "%ld", &pid_max);
1060    return static_cast<pid_t>(pid_max + 1);
1061  }
1062  
TEST(time,clock_getcpuclockid_current)1063  TEST(time, clock_getcpuclockid_current) {
1064    clockid_t clockid;
1065    ASSERT_EQ(0, clock_getcpuclockid(getpid(), &clockid));
1066    timespec ts;
1067    ASSERT_EQ(0, clock_gettime(clockid, &ts));
1068  }
1069  
TEST(time,clock_getcpuclockid_parent)1070  TEST(time, clock_getcpuclockid_parent) {
1071    clockid_t clockid;
1072    ASSERT_EQ(0, clock_getcpuclockid(getppid(), &clockid));
1073    timespec ts;
1074    ASSERT_EQ(0, clock_gettime(clockid, &ts));
1075  }
1076  
TEST(time,clock_getcpuclockid_ESRCH)1077  TEST(time, clock_getcpuclockid_ESRCH) {
1078    // We can't use -1 for invalid pid here, because clock_getcpuclockid() can't detect it.
1079    errno = 0;
1080    // If this fails, your kernel needs commit e1b6b6ce to be backported.
1081    clockid_t clockid;
1082    ASSERT_EQ(ESRCH, clock_getcpuclockid(GetInvalidPid(), &clockid)) << "\n"
1083      << "Please ensure that the following kernel patches or their replacements have been applied:\n"
1084      << "* https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/"
1085      << "commit/?id=e1b6b6ce55a0a25c8aa8af019095253b2133a41a\n"
1086      << "* https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/"
1087      << "commit/?id=c80ed088a519da53f27b798a69748eaabc66aadf\n";
1088    ASSERT_ERRNO(0);
1089  }
1090  
TEST(time,clock_settime)1091  TEST(time, clock_settime) {
1092    errno = 0;
1093    timespec ts;
1094    ASSERT_EQ(-1, clock_settime(-1, &ts));
1095    ASSERT_ERRNO(EINVAL);
1096  }
1097  
TEST(time,clock_nanosleep_EINVAL)1098  TEST(time, clock_nanosleep_EINVAL) {
1099    timespec in;
1100    timespec out;
1101    ASSERT_EQ(EINVAL, clock_nanosleep(-1, 0, &in, &out));
1102  }
1103  
TEST(time,clock_nanosleep_thread_cputime_id)1104  TEST(time, clock_nanosleep_thread_cputime_id) {
1105    timespec in;
1106    in.tv_sec = 1;
1107    in.tv_nsec = 0;
1108    ASSERT_EQ(EINVAL, clock_nanosleep(CLOCK_THREAD_CPUTIME_ID, 0, &in, nullptr));
1109  }
1110  
TEST(time,clock_nanosleep)1111  TEST(time, clock_nanosleep) {
1112    auto t0 = std::chrono::steady_clock::now();
1113    const timespec ts = {.tv_nsec = 5000000};
1114    ASSERT_EQ(0, clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, nullptr));
1115    auto t1 = std::chrono::steady_clock::now();
1116    ASSERT_GE(t1-t0, 5000000ns);
1117  }
1118  
TEST(time,nanosleep)1119  TEST(time, nanosleep) {
1120    auto t0 = std::chrono::steady_clock::now();
1121    const timespec ts = {.tv_nsec = 5000000};
1122    ASSERT_EQ(0, nanosleep(&ts, nullptr));
1123    auto t1 = std::chrono::steady_clock::now();
1124    ASSERT_GE(t1-t0, 5000000ns);
1125  }
1126  
TEST(time,nanosleep_EINVAL)1127  TEST(time, nanosleep_EINVAL) {
1128    timespec ts = {.tv_sec = -1};
1129    errno = 0;
1130    ASSERT_EQ(-1, nanosleep(&ts, nullptr));
1131    ASSERT_ERRNO(EINVAL);
1132  }
1133  
TEST(time,bug_31938693)1134  TEST(time, bug_31938693) {
1135    // User-visible symptoms in N:
1136    // http://b/31938693
1137    // https://code.google.com/p/android/issues/detail?id=225132
1138  
1139    // Actual underlying bug (the code change, not the tzdata upgrade that first exposed the bug):
1140    // http://b/31848040
1141  
1142    // This isn't a great test, because very few timezones were actually affected, and there's
1143    // no real logic to which ones were affected: it was just a coincidence of the data that came
1144    // after them in the tzdata file.
1145  
1146    time_t t = 1475619727;
1147    struct tm tm;
1148  
1149    setenv("TZ", "America/Los_Angeles", 1);
1150    tzset();
1151    ASSERT_TRUE(localtime_r(&t, &tm) != nullptr);
1152    EXPECT_EQ(15, tm.tm_hour);
1153  
1154    setenv("TZ", "Europe/London", 1);
1155    tzset();
1156    ASSERT_TRUE(localtime_r(&t, &tm) != nullptr);
1157    EXPECT_EQ(23, tm.tm_hour);
1158  
1159    setenv("TZ", "America/Atka", 1);
1160    tzset();
1161    ASSERT_TRUE(localtime_r(&t, &tm) != nullptr);
1162    EXPECT_EQ(13, tm.tm_hour);
1163  
1164    setenv("TZ", "Pacific/Apia", 1);
1165    tzset();
1166    ASSERT_TRUE(localtime_r(&t, &tm) != nullptr);
1167    EXPECT_EQ(12, tm.tm_hour);
1168  
1169    setenv("TZ", "Pacific/Honolulu", 1);
1170    tzset();
1171    ASSERT_TRUE(localtime_r(&t, &tm) != nullptr);
1172    EXPECT_EQ(12, tm.tm_hour);
1173  
1174    setenv("TZ", "Asia/Magadan", 1);
1175    tzset();
1176    ASSERT_TRUE(localtime_r(&t, &tm) != nullptr);
1177    EXPECT_EQ(9, tm.tm_hour);
1178  }
1179  
TEST(time,bug_31339449)1180  TEST(time, bug_31339449) {
1181    // POSIX says localtime acts as if it calls tzset.
1182    // tzset does two things:
1183    //  1. it sets the timezone ctime/localtime/mktime/strftime will use.
1184    //  2. it sets the global `tzname`.
1185    // POSIX says localtime_r need not set `tzname` (2).
1186    // Q: should localtime_r set the timezone (1)?
1187    // Upstream tzcode (and glibc) answer "no", everyone else answers "yes".
1188  
1189    // Pick a time, any time...
1190    time_t t = 1475619727;
1191  
1192    // Call tzset with a specific timezone.
1193    setenv("TZ", "America/Atka", 1);
1194    tzset();
1195  
1196    // If we change the timezone and call localtime, localtime should use the new timezone.
1197    setenv("TZ", "America/Los_Angeles", 1);
1198    struct tm* tm_p = localtime(&t);
1199    EXPECT_EQ(15, tm_p->tm_hour);
1200  
1201    // Reset the timezone back.
1202    setenv("TZ", "America/Atka", 1);
1203    tzset();
1204  
1205  #if defined(__BIONIC__)
1206    // If we change the timezone again and call localtime_r, localtime_r should use the new timezone.
1207    setenv("TZ", "America/Los_Angeles", 1);
1208    struct tm tm = {};
1209    localtime_r(&t, &tm);
1210    EXPECT_EQ(15, tm.tm_hour);
1211  #else
1212    // The BSDs agree with us, but glibc gets this wrong.
1213  #endif
1214  }
1215  
TEST(time,asctime)1216  TEST(time, asctime) {
1217    const struct tm tm = {};
1218    ASSERT_STREQ("Sun Jan  0 00:00:00 1900\n", asctime(&tm));
1219  }
1220  
TEST(time,asctime_r)1221  TEST(time, asctime_r) {
1222    const struct tm tm = {};
1223    char buf[256];
1224    ASSERT_EQ(buf, asctime_r(&tm, buf));
1225    ASSERT_STREQ("Sun Jan  0 00:00:00 1900\n", buf);
1226  }
1227  
TEST(time,ctime)1228  TEST(time, ctime) {
1229    setenv("TZ", "UTC", 1);
1230    const time_t t = 0;
1231    ASSERT_STREQ("Thu Jan  1 00:00:00 1970\n", ctime(&t));
1232  }
1233  
TEST(time,ctime_r)1234  TEST(time, ctime_r) {
1235    setenv("TZ", "UTC", 1);
1236    const time_t t = 0;
1237    char buf[256];
1238    ASSERT_EQ(buf, ctime_r(&t, buf));
1239    ASSERT_STREQ("Thu Jan  1 00:00:00 1970\n", buf);
1240  }
1241  
1242  // https://issuetracker.google.com/37128336
TEST(time,strftime_strptime_s)1243  TEST(time, strftime_strptime_s) {
1244    char buf[32];
1245    const struct tm tm0 = { .tm_year = 1982-1900, .tm_mon = 0, .tm_mday = 1 };
1246  
1247    setenv("TZ", "America/Los_Angeles", 1);
1248    strftime(buf, sizeof(buf), "<%s>", &tm0);
1249    EXPECT_STREQ("<378720000>", buf);
1250  
1251    setenv("TZ", "UTC", 1);
1252    strftime(buf, sizeof(buf), "<%s>", &tm0);
1253    EXPECT_STREQ("<378691200>", buf);
1254  
1255    struct tm tm;
1256  
1257    setenv("TZ", "America/Los_Angeles", 1);
1258    tzset();
1259    memset(&tm, 0xff, sizeof(tm));
1260    char* p = strptime("378720000x", "%s", &tm);
1261    ASSERT_EQ('x', *p);
1262    EXPECT_EQ(0, tm.tm_sec);
1263    EXPECT_EQ(0, tm.tm_min);
1264    EXPECT_EQ(0, tm.tm_hour);
1265    EXPECT_EQ(1, tm.tm_mday);
1266    EXPECT_EQ(0, tm.tm_mon);
1267    EXPECT_EQ(82, tm.tm_year);
1268    EXPECT_EQ(5, tm.tm_wday);
1269    EXPECT_EQ(0, tm.tm_yday);
1270    EXPECT_EQ(0, tm.tm_isdst);
1271  
1272    setenv("TZ", "UTC", 1);
1273    tzset();
1274    memset(&tm, 0xff, sizeof(tm));
1275    p = strptime("378691200x", "%s", &tm);
1276    ASSERT_EQ('x', *p);
1277    EXPECT_EQ(0, tm.tm_sec);
1278    EXPECT_EQ(0, tm.tm_min);
1279    EXPECT_EQ(0, tm.tm_hour);
1280    EXPECT_EQ(1, tm.tm_mday);
1281    EXPECT_EQ(0, tm.tm_mon);
1282    EXPECT_EQ(82, tm.tm_year);
1283    EXPECT_EQ(5, tm.tm_wday);
1284    EXPECT_EQ(0, tm.tm_yday);
1285    EXPECT_EQ(0, tm.tm_isdst);
1286  }
1287  
TEST(time,strptime_s_nothing)1288  TEST(time, strptime_s_nothing) {
1289    struct tm tm;
1290    ASSERT_EQ(nullptr, strptime("x", "%s", &tm));
1291  }
1292  
TEST(time,timespec_get)1293  TEST(time, timespec_get) {
1294  #if defined(__BIONIC__)
1295    timespec ts = {};
1296    ASSERT_EQ(TIME_UTC, timespec_get(&ts, TIME_UTC));
1297    ASSERT_EQ(TIME_MONOTONIC, timespec_get(&ts, TIME_MONOTONIC));
1298    ASSERT_EQ(TIME_ACTIVE, timespec_get(&ts, TIME_ACTIVE));
1299    ASSERT_EQ(TIME_THREAD_ACTIVE, timespec_get(&ts, TIME_THREAD_ACTIVE));
1300  #else
1301    GTEST_SKIP() << "glibc doesn't have timespec_get until 2.21";
1302  #endif
1303  }
1304  
TEST(time,timespec_get_invalid)1305  TEST(time, timespec_get_invalid) {
1306  #if defined(__BIONIC__)
1307    timespec ts = {};
1308    ASSERT_EQ(0, timespec_get(&ts, 123));
1309  #else
1310    GTEST_SKIP() << "glibc doesn't have timespec_get until 2.21";
1311  #endif
1312  }
1313  
TEST(time,timespec_getres)1314  TEST(time, timespec_getres) {
1315  #if defined(__BIONIC__)
1316    timespec ts = {};
1317    ASSERT_EQ(TIME_UTC, timespec_getres(&ts, TIME_UTC));
1318    ASSERT_EQ(1, ts.tv_nsec);
1319    ASSERT_EQ(0, ts.tv_sec);
1320  #else
1321    GTEST_SKIP() << "glibc doesn't have timespec_get until 2.21";
1322  #endif
1323  }
1324  
TEST(time,timespec_getres_invalid)1325  TEST(time, timespec_getres_invalid) {
1326  #if defined(__BIONIC__)
1327    timespec ts = {};
1328    ASSERT_EQ(0, timespec_getres(&ts, 123));
1329  #else
1330    GTEST_SKIP() << "glibc doesn't have timespec_get until 2.21";
1331  #endif
1332  }
1333  
TEST(time,difftime)1334  TEST(time, difftime) {
1335    ASSERT_EQ(1.0, difftime(1, 0));
1336    ASSERT_EQ(-1.0, difftime(0, 1));
1337  }
1338  
TEST(time,tzfree_null)1339  TEST(time, tzfree_null) {
1340  #if defined(__BIONIC__)
1341    tzfree(nullptr);
1342  #else
1343    GTEST_SKIP() << "glibc doesn't have timezone_t";
1344  #endif
1345  }
1346  
TEST(time,localtime_rz)1347  TEST(time, localtime_rz) {
1348  #if defined(__BIONIC__)
1349    setenv("TZ", "America/Los_Angeles", 1);
1350    tzset();
1351  
1352    auto AssertTmEq = [](const struct tm& rhs, int hour) {
1353      ASSERT_EQ(93, rhs.tm_year);
1354      ASSERT_EQ(0, rhs.tm_mon);
1355      ASSERT_EQ(1, rhs.tm_mday);
1356      ASSERT_EQ(hour, rhs.tm_hour);
1357      ASSERT_EQ(0, rhs.tm_min);
1358      ASSERT_EQ(0, rhs.tm_sec);
1359    };
1360  
1361    const time_t t = 725875200;
1362  
1363    // Spam localtime_r() while we use localtime_rz().
1364    std::atomic<bool> done = false;
1365    std::thread thread{[&] {
1366      while (!done) {
1367        struct tm tm {};
1368        ASSERT_EQ(&tm, localtime_r(&t, &tm));
1369        AssertTmEq(tm, 0);
1370      }
1371    }};
1372  
1373    struct tm tm;
1374  
1375    timezone_t london{tzalloc("Europe/London")};
1376    tm = {};
1377    ASSERT_EQ(&tm, localtime_rz(london, &t, &tm));
1378    AssertTmEq(tm, 8);
1379  
1380    timezone_t seoul{tzalloc("Asia/Seoul")};
1381    tm = {};
1382    ASSERT_EQ(&tm, localtime_rz(seoul, &t, &tm));
1383    AssertTmEq(tm, 17);
1384  
1385    // Just check that mktime()'s timezone didn't change.
1386    tm = {};
1387    ASSERT_EQ(&tm, localtime_r(&t, &tm));
1388    ASSERT_EQ(0, tm.tm_hour);
1389    AssertTmEq(tm, 0);
1390  
1391    done = true;
1392    thread.join();
1393  
1394    tzfree(london);
1395    tzfree(seoul);
1396  #else
1397    GTEST_SKIP() << "glibc doesn't have timezone_t";
1398  #endif
1399  }
1400  
TEST(time,mktime_z)1401  TEST(time, mktime_z) {
1402  #if defined(__BIONIC__)
1403    setenv("TZ", "America/Los_Angeles", 1);
1404    tzset();
1405  
1406    // Spam mktime() while we use mktime_z().
1407    std::atomic<bool> done = false;
1408    std::thread thread{[&done] {
1409      while (!done) {
1410        struct tm tm {
1411          .tm_year = 93, .tm_mday = 1
1412        };
1413        ASSERT_EQ(725875200, mktime(&tm));
1414      }
1415    }};
1416  
1417    struct tm tm;
1418  
1419    timezone_t london{tzalloc("Europe/London")};
1420    tm = {.tm_year = 93, .tm_mday = 1};
1421    ASSERT_EQ(725846400, mktime_z(london, &tm));
1422  
1423    timezone_t seoul{tzalloc("Asia/Seoul")};
1424    tm = {.tm_year = 93, .tm_mday = 1};
1425    ASSERT_EQ(725814000, mktime_z(seoul, &tm));
1426  
1427    // Just check that mktime()'s timezone didn't change.
1428    tm = {.tm_year = 93, .tm_mday = 1};
1429    ASSERT_EQ(725875200, mktime(&tm));
1430  
1431    done = true;
1432    thread.join();
1433  
1434    tzfree(london);
1435    tzfree(seoul);
1436  #else
1437    GTEST_SKIP() << "glibc doesn't have timezone_t";
1438  #endif
1439  }
1440  
TEST(time,tzalloc_nullptr)1441  TEST(time, tzalloc_nullptr) {
1442  #if defined(__BIONIC__)
1443    // tzalloc(nullptr) returns the system timezone.
1444    timezone_t default_tz = tzalloc(nullptr);
1445    ASSERT_NE(nullptr, default_tz);
1446  
1447    // Check that mktime_z() with the default timezone matches mktime().
1448    // This assumes that the system timezone doesn't change during the test,
1449    // but that should be unlikely, and we don't have much choice if we
1450    // want to write a test at all.
1451    // We unset $TZ before calling mktime() because mktime() honors $TZ.
1452    unsetenv("TZ");
1453    struct tm tm = {.tm_year = 93, .tm_mday = 1};
1454    time_t t = mktime(&tm);
1455    ASSERT_EQ(t, mktime_z(default_tz, &tm));
1456  
1457    // Check that changing $TZ doesn't affect the tzalloc() default in
1458    // the same way it would the mktime() default.
1459    setenv("TZ", "America/Los_Angeles", 1);
1460    tzset();
1461    ASSERT_EQ(t, mktime_z(default_tz, &tm));
1462  
1463    setenv("TZ", "Europe/London", 1);
1464    tzset();
1465    ASSERT_EQ(t, mktime_z(default_tz, &tm));
1466  
1467    setenv("TZ", "Asia/Seoul", 1);
1468    tzset();
1469    ASSERT_EQ(t, mktime_z(default_tz, &tm));
1470  
1471    tzfree(default_tz);
1472  #else
1473    GTEST_SKIP() << "glibc doesn't have timezone_t";
1474  #endif
1475  }
1476  
TEST(time,tzalloc_unique_ptr)1477  TEST(time, tzalloc_unique_ptr) {
1478  #if defined(__BIONIC__)
1479    std::unique_ptr<std::remove_pointer_t<timezone_t>, decltype(&tzfree)> tz{tzalloc("Asia/Seoul"),
1480                                                                             tzfree};
1481  #else
1482    GTEST_SKIP() << "glibc doesn't have timezone_t";
1483  #endif
1484  }
1485