1 #include <gtest/gtest.h> 2 #include <hardware/bluetooth.h> 3 #include <unistd.h> 4 5 extern "C" { 6 #include "alarm.h" 7 #include "osi.h" 8 #include "semaphore.h" 9 } 10 11 extern int64_t TIMER_INTERVAL_FOR_WAKELOCK_IN_MS; 12 13 static semaphore_t *semaphore; 14 static int cb_counter; 15 static int lock_count; 16 static timer_t timer; 17 static alarm_cb saved_callback; 18 static void *saved_data; 19 20 static const uint64_t EPSILON_MS = 5; 21 22 static void msleep(uint64_t ms) { 23 usleep(ms * 1000); 24 } 25 26 static void timer_callback(void *) { 27 saved_callback(saved_data); 28 } 29 30 class AlarmTest : public ::testing::Test { 31 protected: 32 virtual void SetUp() { 33 TIMER_INTERVAL_FOR_WAKELOCK_IN_MS = 100; 34 cb_counter = 0; 35 lock_count = 0; 36 37 semaphore = semaphore_new(0); 38 39 struct sigevent sigevent; 40 memset(&sigevent, 0, sizeof(sigevent)); 41 sigevent.sigev_notify = SIGEV_THREAD; 42 sigevent.sigev_notify_function = (void (*)(union sigval))timer_callback; 43 sigevent.sigev_value.sival_ptr = NULL; 44 timer_create(CLOCK_BOOTTIME, &sigevent, &timer); 45 } 46 47 virtual void TearDown() { 48 timer_delete(timer); 49 } 50 }; 51 52 static void cb(UNUSED_ATTR void *data) { 53 ++cb_counter; 54 semaphore_post(semaphore); 55 } 56 57 static bool set_wake_alarm(uint64_t delay_millis, bool, alarm_cb cb, void *data) { 58 saved_callback = cb; 59 saved_data = data; 60 61 struct itimerspec wakeup_time; 62 memset(&wakeup_time, 0, sizeof(wakeup_time)); 63 wakeup_time.it_value.tv_sec = (delay_millis / 1000); 64 wakeup_time.it_value.tv_nsec = (delay_millis % 1000) * 1000000LL; 65 timer_settime(timer, 0, &wakeup_time, NULL); 66 return true; 67 } 68 69 static int acquire_wake_lock(const char *) { 70 if (!lock_count) 71 lock_count = 1; 72 return BT_STATUS_SUCCESS; 73 } 74 75 static int release_wake_lock(const char *) { 76 if (lock_count) 77 lock_count = 0; 78 return BT_STATUS_SUCCESS; 79 } 80 81 static bt_os_callouts_t stub = { 82 sizeof(bt_os_callouts_t), 83 set_wake_alarm, 84 acquire_wake_lock, 85 release_wake_lock, 86 }; 87 88 bt_os_callouts_t *bt_os_callouts = &stub; 89 90 TEST_F(AlarmTest, test_new_simple) { 91 alarm_t *alarm = alarm_new(); 92 ASSERT_TRUE(alarm != NULL); 93 } 94 95 TEST_F(AlarmTest, test_free_simple) { 96 alarm_t *alarm = alarm_new(); 97 alarm_free(alarm); 98 } 99 100 TEST_F(AlarmTest, test_free_null) { 101 alarm_free(NULL); 102 } 103 104 TEST_F(AlarmTest, test_simple_cancel) { 105 alarm_t *alarm = alarm_new(); 106 alarm_cancel(alarm); 107 alarm_free(alarm); 108 } 109 110 TEST_F(AlarmTest, test_cancel) { 111 alarm_t *alarm = alarm_new(); 112 alarm_set(alarm, 10, cb, NULL); 113 alarm_cancel(alarm); 114 115 msleep(10 + EPSILON_MS); 116 117 EXPECT_EQ(cb_counter, 0); 118 EXPECT_EQ(lock_count, 0); 119 alarm_free(alarm); 120 } 121 122 TEST_F(AlarmTest, test_cancel_idempotent) { 123 alarm_t *alarm = alarm_new(); 124 alarm_set(alarm, 10, cb, NULL); 125 alarm_cancel(alarm); 126 alarm_cancel(alarm); 127 alarm_cancel(alarm); 128 alarm_free(alarm); 129 } 130 131 TEST_F(AlarmTest, test_set_short) { 132 alarm_t *alarm = alarm_new(); 133 alarm_set(alarm, 10, cb, NULL); 134 135 EXPECT_EQ(cb_counter, 0); 136 EXPECT_EQ(lock_count, 1); 137 138 semaphore_wait(semaphore); 139 140 EXPECT_EQ(cb_counter, 1); 141 EXPECT_EQ(lock_count, 0); 142 143 alarm_free(alarm); 144 } 145 146 TEST_F(AlarmTest, test_set_long) { 147 alarm_t *alarm = alarm_new(); 148 alarm_set(alarm, TIMER_INTERVAL_FOR_WAKELOCK_IN_MS, cb, NULL); 149 150 EXPECT_EQ(cb_counter, 0); 151 EXPECT_EQ(lock_count, 0); 152 153 semaphore_wait(semaphore); 154 155 EXPECT_EQ(cb_counter, 1); 156 EXPECT_EQ(lock_count, 0); 157 158 alarm_free(alarm); 159 } 160 161 TEST_F(AlarmTest, test_set_short_short) { 162 alarm_t *alarm[2] = { 163 alarm_new(), 164 alarm_new() 165 }; 166 167 alarm_set(alarm[0], 10, cb, NULL); 168 alarm_set(alarm[1], 20, cb, NULL); 169 170 EXPECT_EQ(cb_counter, 0); 171 EXPECT_EQ(lock_count, 1); 172 173 semaphore_wait(semaphore); 174 175 EXPECT_EQ(cb_counter, 1); 176 EXPECT_EQ(lock_count, 1); 177 178 semaphore_wait(semaphore); 179 180 EXPECT_EQ(cb_counter, 2); 181 EXPECT_EQ(lock_count, 0); 182 183 alarm_free(alarm[0]); 184 alarm_free(alarm[1]); 185 } 186 187 TEST_F(AlarmTest, test_set_short_long) { 188 alarm_t *alarm[2] = { 189 alarm_new(), 190 alarm_new() 191 }; 192 193 alarm_set(alarm[0], 10, cb, NULL); 194 alarm_set(alarm[1], 10 + TIMER_INTERVAL_FOR_WAKELOCK_IN_MS + EPSILON_MS, cb, NULL); 195 196 EXPECT_EQ(cb_counter, 0); 197 EXPECT_EQ(lock_count, 1); 198 199 semaphore_wait(semaphore); 200 201 EXPECT_EQ(cb_counter, 1); 202 EXPECT_EQ(lock_count, 0); 203 204 semaphore_wait(semaphore); 205 206 EXPECT_EQ(cb_counter, 2); 207 EXPECT_EQ(lock_count, 0); 208 209 alarm_free(alarm[0]); 210 alarm_free(alarm[1]); 211 } 212 213 TEST_F(AlarmTest, test_set_long_long) { 214 alarm_t *alarm[2] = { 215 alarm_new(), 216 alarm_new() 217 }; 218 219 alarm_set(alarm[0], TIMER_INTERVAL_FOR_WAKELOCK_IN_MS, cb, NULL); 220 alarm_set(alarm[1], 2 * TIMER_INTERVAL_FOR_WAKELOCK_IN_MS + EPSILON_MS, cb, NULL); 221 222 EXPECT_EQ(cb_counter, 0); 223 EXPECT_EQ(lock_count, 0); 224 225 semaphore_wait(semaphore); 226 227 EXPECT_EQ(cb_counter, 1); 228 EXPECT_EQ(lock_count, 0); 229 230 semaphore_wait(semaphore); 231 232 EXPECT_EQ(cb_counter, 2); 233 EXPECT_EQ(lock_count, 0); 234 235 alarm_free(alarm[0]); 236 alarm_free(alarm[1]); 237 } 238 239 // Try to catch any race conditions between the timer callback and |alarm_free|. 240 TEST_F(AlarmTest, test_callback_free_race) { 241 for (int i = 0; i < 1000; ++i) { 242 alarm_t *alarm = alarm_new(); 243 alarm_set(alarm, 0, cb, NULL); 244 alarm_free(alarm); 245 } 246 } 247