• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
msleep(uint64_t ms)22 static void msleep(uint64_t ms) {
23   usleep(ms * 1000);
24 }
25 
timer_callback(void *)26 static void timer_callback(void *) {
27   saved_callback(saved_data);
28 }
29 
30 class AlarmTest : public ::testing::Test {
31   protected:
SetUp()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 
TearDown()47     virtual void TearDown() {
48       timer_delete(timer);
49     }
50 };
51 
cb(UNUSED_ATTR void * data)52 static void cb(UNUSED_ATTR void *data) {
53   ++cb_counter;
54   semaphore_post(semaphore);
55 }
56 
set_wake_alarm(uint64_t delay_millis,bool,alarm_cb cb,void * data)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 
acquire_wake_lock(const char *)69 static int acquire_wake_lock(const char *) {
70   if (!lock_count)
71     lock_count = 1;
72   return BT_STATUS_SUCCESS;
73 }
74 
release_wake_lock(const char *)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 
TEST_F(AlarmTest,test_new_simple)90 TEST_F(AlarmTest, test_new_simple) {
91   alarm_t *alarm = alarm_new();
92   ASSERT_TRUE(alarm != NULL);
93 }
94 
TEST_F(AlarmTest,test_free_simple)95 TEST_F(AlarmTest, test_free_simple) {
96   alarm_t *alarm = alarm_new();
97   alarm_free(alarm);
98 }
99 
TEST_F(AlarmTest,test_free_null)100 TEST_F(AlarmTest, test_free_null) {
101   alarm_free(NULL);
102 }
103 
TEST_F(AlarmTest,test_simple_cancel)104 TEST_F(AlarmTest, test_simple_cancel) {
105   alarm_t *alarm = alarm_new();
106   alarm_cancel(alarm);
107   alarm_free(alarm);
108 }
109 
TEST_F(AlarmTest,test_cancel)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 
TEST_F(AlarmTest,test_cancel_idempotent)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 
TEST_F(AlarmTest,test_set_short)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 
TEST_F(AlarmTest,test_set_long)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 
TEST_F(AlarmTest,test_set_short_short)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 
TEST_F(AlarmTest,test_set_short_long)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 
TEST_F(AlarmTest,test_set_long_long)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|.
TEST_F(AlarmTest,test_callback_free_race)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