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