Home | History | Annotate | Download | only in test
      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