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