1/****************************************************************************** 2 * 3 * Copyright (C) 2014 Google, Inc. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19#include <gtest/gtest.h> 20 21#include "AlarmTestHarness.h" 22 23extern "C" { 24#include "osi/include/alarm.h" 25#include "osi/include/fixed_queue.h" 26#include "osi/include/osi.h" 27#include "osi/include/semaphore.h" 28#include "osi/include/thread.h" 29} 30 31static semaphore_t *semaphore; 32static int cb_counter; 33static int cb_misordered_counter; 34 35static const uint64_t EPSILON_MS = 5; 36 37static void msleep(uint64_t ms) { 38 usleep(ms * 1000); 39} 40 41class AlarmTest : public AlarmTestHarness { 42 protected: 43 virtual void SetUp() { 44 AlarmTestHarness::SetUp(); 45 cb_counter = 0; 46 cb_misordered_counter = 0; 47 48 semaphore = semaphore_new(0); 49 } 50 51 virtual void TearDown() { 52 semaphore_free(semaphore); 53 AlarmTestHarness::TearDown(); 54 } 55}; 56 57static void cb(UNUSED_ATTR void *data) { 58 ++cb_counter; 59 semaphore_post(semaphore); 60} 61 62static void ordered_cb(void *data) { 63 int i = PTR_TO_INT(data); 64 if (i != cb_counter) 65 cb_misordered_counter++; 66 ++cb_counter; 67 semaphore_post(semaphore); 68} 69 70TEST_F(AlarmTest, test_new_free_simple) { 71 alarm_t *alarm = alarm_new("alarm_test.test_new_free_simple"); 72 ASSERT_TRUE(alarm != NULL); 73 alarm_free(alarm); 74} 75 76TEST_F(AlarmTest, test_free_null) { 77 alarm_free(NULL); 78} 79 80TEST_F(AlarmTest, test_simple_cancel) { 81 alarm_t *alarm = alarm_new("alarm_test.test_simple_cancel"); 82 alarm_cancel(alarm); 83 alarm_free(alarm); 84} 85 86TEST_F(AlarmTest, test_cancel) { 87 alarm_t *alarm = alarm_new("alarm_test.test_cancel"); 88 alarm_set(alarm, 10, cb, NULL); 89 alarm_cancel(alarm); 90 91 msleep(10 + EPSILON_MS); 92 93 EXPECT_EQ(cb_counter, 0); 94 EXPECT_FALSE(WakeLockHeld()); 95 alarm_free(alarm); 96} 97 98TEST_F(AlarmTest, test_cancel_idempotent) { 99 alarm_t *alarm = alarm_new("alarm_test.test_cancel_idempotent"); 100 alarm_set(alarm, 10, cb, NULL); 101 alarm_cancel(alarm); 102 alarm_cancel(alarm); 103 alarm_cancel(alarm); 104 alarm_free(alarm); 105} 106 107TEST_F(AlarmTest, test_set_short) { 108 alarm_t *alarm = alarm_new("alarm_test.test_set_short"); 109 110 alarm_set(alarm, 10, cb, NULL); 111 112 EXPECT_EQ(cb_counter, 0); 113 EXPECT_TRUE(WakeLockHeld()); 114 115 semaphore_wait(semaphore); 116 117 EXPECT_EQ(cb_counter, 1); 118 EXPECT_FALSE(WakeLockHeld()); 119 120 alarm_free(alarm); 121} 122 123TEST_F(AlarmTest, test_set_short_periodic) { 124 alarm_t *alarm = alarm_new_periodic("alarm_test.test_set_short_periodic"); 125 126 alarm_set(alarm, 10, cb, NULL); 127 128 EXPECT_EQ(cb_counter, 0); 129 EXPECT_TRUE(WakeLockHeld()); 130 131 for (int i = 1; i <= 10; i++) { 132 semaphore_wait(semaphore); 133 134 EXPECT_GE(cb_counter, i); 135 EXPECT_TRUE(WakeLockHeld()); 136 } 137 alarm_cancel(alarm); 138 EXPECT_FALSE(WakeLockHeld()); 139 140 alarm_free(alarm); 141} 142 143TEST_F(AlarmTest, test_set_zero_periodic) { 144 alarm_t *alarm = alarm_new_periodic("alarm_test.test_set_zero_periodic"); 145 146 alarm_set(alarm, 0, cb, NULL); 147 148 EXPECT_TRUE(WakeLockHeld()); 149 150 for (int i = 1; i <= 10; i++) { 151 semaphore_wait(semaphore); 152 153 EXPECT_GE(cb_counter, i); 154 EXPECT_TRUE(WakeLockHeld()); 155 } 156 alarm_cancel(alarm); 157 EXPECT_FALSE(WakeLockHeld()); 158 159 alarm_free(alarm); 160} 161 162TEST_F(AlarmTest, test_set_long) { 163 alarm_t *alarm = alarm_new("alarm_test.test_set_long"); 164 alarm_set(alarm, TIMER_INTERVAL_FOR_WAKELOCK_IN_MS + EPSILON_MS, cb, NULL); 165 166 EXPECT_EQ(cb_counter, 0); 167 EXPECT_FALSE(WakeLockHeld()); 168 169 semaphore_wait(semaphore); 170 171 EXPECT_EQ(cb_counter, 1); 172 EXPECT_FALSE(WakeLockHeld()); 173 174 alarm_free(alarm); 175} 176 177TEST_F(AlarmTest, test_set_short_short) { 178 alarm_t *alarm[2] = { 179 alarm_new("alarm_test.test_set_short_short_0"), 180 alarm_new("alarm_test.test_set_short_short_1") 181 }; 182 183 alarm_set(alarm[0], 10, cb, NULL); 184 alarm_set(alarm[1], 20, cb, NULL); 185 186 EXPECT_EQ(cb_counter, 0); 187 EXPECT_TRUE(WakeLockHeld()); 188 189 semaphore_wait(semaphore); 190 191 EXPECT_EQ(cb_counter, 1); 192 EXPECT_TRUE(WakeLockHeld()); 193 194 semaphore_wait(semaphore); 195 196 EXPECT_EQ(cb_counter, 2); 197 EXPECT_FALSE(WakeLockHeld()); 198 199 alarm_free(alarm[0]); 200 alarm_free(alarm[1]); 201} 202 203TEST_F(AlarmTest, test_set_short_long) { 204 alarm_t *alarm[2] = { 205 alarm_new("alarm_test.test_set_short_long_0"), 206 alarm_new("alarm_test.test_set_short_long_1") 207 }; 208 209 alarm_set(alarm[0], 10, cb, NULL); 210 alarm_set(alarm[1], 10 + TIMER_INTERVAL_FOR_WAKELOCK_IN_MS + EPSILON_MS, cb, NULL); 211 212 EXPECT_EQ(cb_counter, 0); 213 EXPECT_TRUE(WakeLockHeld()); 214 215 semaphore_wait(semaphore); 216 217 EXPECT_EQ(cb_counter, 1); 218 EXPECT_FALSE(WakeLockHeld()); 219 220 semaphore_wait(semaphore); 221 222 EXPECT_EQ(cb_counter, 2); 223 EXPECT_FALSE(WakeLockHeld()); 224 225 alarm_free(alarm[0]); 226 alarm_free(alarm[1]); 227} 228 229TEST_F(AlarmTest, test_set_long_long) { 230 alarm_t *alarm[2] = { 231 alarm_new("alarm_test.test_set_long_long_0"), 232 alarm_new("alarm_test.test_set_long_long_1") 233 }; 234 235 alarm_set(alarm[0], TIMER_INTERVAL_FOR_WAKELOCK_IN_MS + EPSILON_MS, cb, NULL); 236 alarm_set(alarm[1], 2 * (TIMER_INTERVAL_FOR_WAKELOCK_IN_MS + EPSILON_MS), cb, NULL); 237 238 EXPECT_EQ(cb_counter, 0); 239 EXPECT_FALSE(WakeLockHeld()); 240 241 semaphore_wait(semaphore); 242 243 EXPECT_EQ(cb_counter, 1); 244 EXPECT_FALSE(WakeLockHeld()); 245 246 semaphore_wait(semaphore); 247 248 EXPECT_EQ(cb_counter, 2); 249 EXPECT_FALSE(WakeLockHeld()); 250 251 alarm_free(alarm[0]); 252 alarm_free(alarm[1]); 253} 254 255TEST_F(AlarmTest, test_is_scheduled) { 256 alarm_t *alarm = alarm_new("alarm_test.test_is_scheduled"); 257 258 EXPECT_FALSE(alarm_is_scheduled((alarm_t *)NULL)); 259 EXPECT_FALSE(alarm_is_scheduled(alarm)); 260 alarm_set(alarm, TIMER_INTERVAL_FOR_WAKELOCK_IN_MS + EPSILON_MS, cb, NULL); 261 EXPECT_TRUE(alarm_is_scheduled(alarm)); 262 263 EXPECT_EQ(cb_counter, 0); 264 EXPECT_FALSE(WakeLockHeld()); 265 266 semaphore_wait(semaphore); 267 268 EXPECT_FALSE(alarm_is_scheduled(alarm)); 269 EXPECT_EQ(cb_counter, 1); 270 EXPECT_FALSE(WakeLockHeld()); 271 272 alarm_free(alarm); 273} 274 275// Test whether the callbacks are invoked in the expected order 276TEST_F(AlarmTest, test_callback_ordering) { 277 alarm_t *alarms[100]; 278 279 for (int i = 0; i < 100; i++) { 280 const std::string alarm_name = "alarm_test.test_callback_ordering[" + 281 std::to_string(i) + "]"; 282 alarms[i] = alarm_new(alarm_name.c_str()); 283 } 284 285 for (int i = 0; i < 100; i++) { 286 alarm_set(alarms[i], 100, ordered_cb, INT_TO_PTR(i)); 287 } 288 289 for (int i = 1; i <= 100; i++) { 290 semaphore_wait(semaphore); 291 EXPECT_GE(cb_counter, i); 292 } 293 EXPECT_EQ(cb_counter, 100); 294 EXPECT_EQ(cb_misordered_counter, 0); 295 296 for (int i = 0; i < 100; i++) 297 alarm_free(alarms[i]); 298 299 EXPECT_FALSE(WakeLockHeld()); 300} 301 302// Test whether the callbacks are involed in the expected order on a 303// separate queue. 304TEST_F(AlarmTest, test_callback_ordering_on_queue) { 305 alarm_t *alarms[100]; 306 fixed_queue_t *queue = fixed_queue_new(SIZE_MAX); 307 thread_t *thread = thread_new("timers.test_callback_ordering_on_queue.thread"); 308 309 alarm_register_processing_queue(queue, thread); 310 311 for (int i = 0; i < 100; i++) { 312 const std::string alarm_name = 313 "alarm_test.test_callback_ordering_on_queue[" + 314 std::to_string(i) + "]"; 315 alarms[i] = alarm_new(alarm_name.c_str()); 316 } 317 318 for (int i = 0; i < 100; i++) { 319 alarm_set_on_queue(alarms[i], 100, ordered_cb, INT_TO_PTR(i), queue); 320 } 321 322 for (int i = 1; i <= 100; i++) { 323 semaphore_wait(semaphore); 324 EXPECT_GE(cb_counter, i); 325 } 326 EXPECT_EQ(cb_counter, 100); 327 EXPECT_EQ(cb_misordered_counter, 0); 328 329 for (int i = 0; i < 100; i++) 330 alarm_free(alarms[i]); 331 332 EXPECT_FALSE(WakeLockHeld()); 333 334 alarm_unregister_processing_queue(queue); 335 fixed_queue_free(queue, NULL); 336 thread_free(thread); 337} 338 339// Test whether unregistering a processing queue cancels all timers using 340// that queue. 341TEST_F(AlarmTest, test_unregister_processing_queue) { 342 alarm_t *alarms[100]; 343 fixed_queue_t *queue = fixed_queue_new(SIZE_MAX); 344 thread_t *thread = 345 thread_new("timers.test_unregister_processing_queue.thread"); 346 347 alarm_register_processing_queue(queue, thread); 348 349 for (int i = 0; i < 100; i++) { 350 const std::string alarm_name = 351 "alarm_test.test_unregister_processing_queue[" + 352 std::to_string(i) + "]"; 353 alarms[i] = alarm_new(alarm_name.c_str()); 354 } 355 356 // Schedule half of the timers to expire soon, and the rest far in the future 357 for (int i = 0; i < 50; i++) { 358 alarm_set_on_queue(alarms[i], 100, ordered_cb, INT_TO_PTR(i), queue); 359 } 360 for (int i = 50; i < 100; i++) { 361 alarm_set_on_queue(alarms[i], 1000 * 1000, ordered_cb, INT_TO_PTR(i), queue); 362 } 363 364 // Wait until half of the timers have expired 365 for (int i = 1; i <= 50; i++) { 366 semaphore_wait(semaphore); 367 EXPECT_GE(cb_counter, i); 368 } 369 EXPECT_EQ(cb_counter, 50); 370 EXPECT_EQ(cb_misordered_counter, 0); 371 372 // Test that only the expired timers are not scheduled 373 for (int i = 0; i < 50; i++) { 374 EXPECT_FALSE(alarm_is_scheduled(alarms[i])); 375 } 376 for (int i = 50; i < 100; i++) { 377 EXPECT_TRUE(alarm_is_scheduled(alarms[i])); 378 } 379 380 alarm_unregister_processing_queue(queue); 381 382 // Test that none of the timers are scheduled 383 for (int i = 0; i < 100; i++) { 384 EXPECT_FALSE(alarm_is_scheduled(alarms[i])); 385 } 386 387 for (int i = 0; i < 100; i++) { 388 alarm_free(alarms[i]); 389 } 390 391 EXPECT_FALSE(WakeLockHeld()); 392 393 fixed_queue_free(queue, NULL); 394 thread_free(thread); 395} 396 397// Test whether unregistering a processing queue cancels all periodic timers 398// using that queue. 399TEST_F(AlarmTest, test_periodic_unregister_processing_queue) { 400 alarm_t *alarms[5]; 401 fixed_queue_t *queue = fixed_queue_new(SIZE_MAX); 402 thread_t *thread = 403 thread_new("timers.test_periodic_unregister_processing_queue.thread"); 404 405 alarm_register_processing_queue(queue, thread); 406 407 for (int i = 0; i < 5; i++) { 408 const std::string alarm_name = 409 "alarm_test.test_periodic_unregister_processing_queue[" + 410 std::to_string(i) + "]"; 411 alarms[i] = alarm_new_periodic(alarm_name.c_str()); 412 } 413 414 // Schedule each of the timers with different period 415 for (int i = 0; i < 5; i++) { 416 alarm_set_on_queue(alarms[i], 20 + i, cb, INT_TO_PTR(i), queue); 417 } 418 EXPECT_TRUE(WakeLockHeld()); 419 420 for (int i = 1; i <= 20; i++) { 421 semaphore_wait(semaphore); 422 423 EXPECT_GE(cb_counter, i); 424 EXPECT_TRUE(WakeLockHeld()); 425 } 426 427 // Test that all timers are still scheduled 428 for (int i = 0; i < 5; i++) { 429 EXPECT_TRUE(alarm_is_scheduled(alarms[i])); 430 } 431 432 alarm_unregister_processing_queue(queue); 433 434 int saved_cb_counter = cb_counter; 435 436 // Test that none of the timers are scheduled 437 for (int i = 0; i < 5; i++) { 438 EXPECT_FALSE(alarm_is_scheduled(alarms[i])); 439 } 440 441 // Sleep for 500ms and test again that the cb_counter hasn't been modified 442 usleep(500 * 1000); 443 EXPECT_TRUE(cb_counter == saved_cb_counter); 444 445 for (int i = 0; i < 5; i++) { 446 alarm_free(alarms[i]); 447 } 448 449 EXPECT_FALSE(WakeLockHeld()); 450 451 fixed_queue_free(queue, NULL); 452 thread_free(thread); 453} 454 455// Try to catch any race conditions between the timer callback and |alarm_free|. 456TEST_F(AlarmTest, test_callback_free_race) { 457 for (int i = 0; i < 1000; ++i) { 458 const std::string alarm_name = "alarm_test.test_callback_free_race[" + 459 std::to_string(i) + "]"; 460 alarm_t *alarm = alarm_new(alarm_name.c_str()); 461 alarm_set(alarm, 0, cb, NULL); 462 alarm_free(alarm); 463 } 464 alarm_cleanup(); 465} 466