1 /******************************************************************************
2 *
3 * Copyright 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 "osi/include/alarm.h"
20
21 #include <base/run_loop.h>
22 #include <gtest/gtest.h>
23 #include <hardware/bluetooth.h>
24
25 #include "common/message_loop_thread.h"
26 #include "osi/include/fixed_queue.h"
27 #include "osi/include/osi.h"
28 #include "osi/include/wakelock.h"
29 #include "osi/semaphore.h"
30 #include "stack/include/main_thread.h"
31
32 using base::Closure;
33 using bluetooth::common::MessageLoopThread;
34
35 static semaphore_t* semaphore;
36 static int cb_counter;
37 static int cb_misordered_counter;
38
39 static const uint64_t EPSILON_MS = 50;
40
msleep(uint64_t ms)41 static void msleep(uint64_t ms) { usleep(ms * 1000); }
42
43 static MessageLoopThread* thread_;
44
get_main_thread()45 bluetooth::common::MessageLoopThread* get_main_thread() { return thread_; }
46
47 extern int64_t TIMER_INTERVAL_FOR_WAKELOCK_IN_MS;
48
49 static bool is_wake_lock_acquired = false;
50
acquire_wake_lock_cb(const char *)51 static int acquire_wake_lock_cb(const char* /*lock_name*/) {
52 is_wake_lock_acquired = true;
53 return BT_STATUS_SUCCESS;
54 }
55
release_wake_lock_cb(const char *)56 static int release_wake_lock_cb(const char* /*lock_name*/) {
57 is_wake_lock_acquired = false;
58 return BT_STATUS_SUCCESS;
59 }
60
61 static bt_os_callouts_t bt_wakelock_callouts = {sizeof(bt_os_callouts_t), acquire_wake_lock_cb,
62 release_wake_lock_cb};
63
64 class AlarmTest : public ::testing::Test {
65 protected:
SetUp()66 void SetUp() override {
67 TIMER_INTERVAL_FOR_WAKELOCK_IN_MS = 500;
68
69 wakelock_set_os_callouts(&bt_wakelock_callouts);
70
71 cb_counter = 0;
72 cb_misordered_counter = 0;
73
74 semaphore = semaphore_new(0);
75 }
76
TearDown()77 void TearDown() override {
78 semaphore_free(semaphore);
79 alarm_cleanup();
80 wakelock_cleanup();
81 wakelock_set_os_callouts(NULL);
82 }
83 };
84
cb(void *)85 static void cb(void* /* data */) {
86 ++cb_counter;
87 semaphore_post(semaphore);
88 }
89
ordered_cb(void * data)90 static void ordered_cb(void* data) {
91 int i = PTR_TO_INT(data);
92 if (i != cb_counter) {
93 cb_misordered_counter++;
94 }
95 ++cb_counter;
96 semaphore_post(semaphore);
97 }
98
TEST_F(AlarmTest,test_new_free_simple)99 TEST_F(AlarmTest, test_new_free_simple) {
100 alarm_t* alarm = alarm_new("alarm_test.test_new_free_simple");
101 ASSERT_TRUE(alarm != NULL);
102 alarm_free(alarm);
103 }
104
TEST_F(AlarmTest,test_free_null)105 TEST_F(AlarmTest, test_free_null) { alarm_free(NULL); }
106
TEST_F(AlarmTest,test_simple_cancel)107 TEST_F(AlarmTest, test_simple_cancel) {
108 alarm_t* alarm = alarm_new("alarm_test.test_simple_cancel");
109 alarm_cancel(alarm);
110 alarm_free(alarm);
111 }
112
TEST_F(AlarmTest,test_cancel)113 TEST_F(AlarmTest, test_cancel) {
114 alarm_t* alarm = alarm_new("alarm_test.test_cancel");
115 alarm_set(alarm, 10, cb, NULL);
116 alarm_cancel(alarm);
117
118 msleep(10 + EPSILON_MS);
119
120 EXPECT_EQ(cb_counter, 0);
121 EXPECT_FALSE(is_wake_lock_acquired);
122 alarm_free(alarm);
123 }
124
TEST_F(AlarmTest,test_cancel_idempotent)125 TEST_F(AlarmTest, test_cancel_idempotent) {
126 alarm_t* alarm = alarm_new("alarm_test.test_cancel_idempotent");
127 alarm_set(alarm, 10, cb, NULL);
128 alarm_cancel(alarm);
129 alarm_cancel(alarm);
130 alarm_cancel(alarm);
131 alarm_free(alarm);
132 }
133
TEST_F(AlarmTest,test_set_short)134 TEST_F(AlarmTest, test_set_short) {
135 alarm_t* alarm = alarm_new("alarm_test.test_set_short");
136
137 alarm_set(alarm, 10, cb, NULL);
138
139 EXPECT_EQ(cb_counter, 0);
140 EXPECT_TRUE(is_wake_lock_acquired);
141
142 semaphore_wait(semaphore);
143
144 EXPECT_EQ(cb_counter, 1);
145 EXPECT_FALSE(is_wake_lock_acquired);
146
147 alarm_free(alarm);
148 }
149
TEST_F(AlarmTest,test_set_short_periodic)150 TEST_F(AlarmTest, test_set_short_periodic) {
151 alarm_t* alarm = alarm_new_periodic("alarm_test.test_set_short_periodic");
152
153 alarm_set(alarm, 10, cb, NULL);
154
155 EXPECT_EQ(cb_counter, 0);
156 EXPECT_TRUE(is_wake_lock_acquired);
157
158 for (int i = 1; i <= 10; i++) {
159 semaphore_wait(semaphore);
160
161 EXPECT_GE(cb_counter, i);
162 EXPECT_TRUE(is_wake_lock_acquired);
163 }
164 alarm_cancel(alarm);
165 EXPECT_FALSE(is_wake_lock_acquired);
166
167 alarm_free(alarm);
168 }
169
TEST_F(AlarmTest,test_set_zero_periodic)170 TEST_F(AlarmTest, test_set_zero_periodic) {
171 alarm_t* alarm = alarm_new_periodic("alarm_test.test_set_zero_periodic");
172
173 alarm_set(alarm, 0, cb, NULL);
174
175 EXPECT_TRUE(is_wake_lock_acquired);
176
177 for (int i = 1; i <= 10; i++) {
178 semaphore_wait(semaphore);
179
180 EXPECT_GE(cb_counter, i);
181 EXPECT_TRUE(is_wake_lock_acquired);
182 }
183 alarm_cancel(alarm);
184 EXPECT_FALSE(is_wake_lock_acquired);
185
186 alarm_free(alarm);
187 }
188
TEST_F(AlarmTest,test_set_long)189 TEST_F(AlarmTest, test_set_long) {
190 alarm_t* alarm = alarm_new("alarm_test.test_set_long");
191 alarm_set(alarm, TIMER_INTERVAL_FOR_WAKELOCK_IN_MS + EPSILON_MS, cb, NULL);
192
193 EXPECT_EQ(cb_counter, 0);
194 EXPECT_FALSE(is_wake_lock_acquired);
195
196 semaphore_wait(semaphore);
197
198 EXPECT_EQ(cb_counter, 1);
199 EXPECT_FALSE(is_wake_lock_acquired);
200
201 alarm_free(alarm);
202 }
203
TEST_F(AlarmTest,test_set_short_short)204 TEST_F(AlarmTest, test_set_short_short) {
205 alarm_t* alarm[2] = {alarm_new("alarm_test.test_set_short_short_0"),
206 alarm_new("alarm_test.test_set_short_short_1")};
207
208 alarm_set(alarm[0], 10, cb, NULL);
209 alarm_set(alarm[1], 200, cb, NULL);
210
211 EXPECT_EQ(cb_counter, 0);
212 EXPECT_TRUE(is_wake_lock_acquired);
213
214 semaphore_wait(semaphore);
215
216 EXPECT_EQ(cb_counter, 1);
217 EXPECT_TRUE(is_wake_lock_acquired);
218
219 semaphore_wait(semaphore);
220
221 EXPECT_EQ(cb_counter, 2);
222 EXPECT_FALSE(is_wake_lock_acquired);
223
224 alarm_free(alarm[0]);
225 alarm_free(alarm[1]);
226 }
227
TEST_F(AlarmTest,test_set_short_long)228 TEST_F(AlarmTest, test_set_short_long) {
229 alarm_t* alarm[2] = {alarm_new("alarm_test.test_set_short_long_0"),
230 alarm_new("alarm_test.test_set_short_long_1")};
231
232 alarm_set(alarm[0], 10, cb, NULL);
233 alarm_set(alarm[1], 10 + TIMER_INTERVAL_FOR_WAKELOCK_IN_MS + EPSILON_MS, cb, NULL);
234
235 EXPECT_EQ(cb_counter, 0);
236 EXPECT_TRUE(is_wake_lock_acquired);
237
238 semaphore_wait(semaphore);
239
240 EXPECT_EQ(cb_counter, 1);
241 EXPECT_FALSE(is_wake_lock_acquired);
242
243 semaphore_wait(semaphore);
244
245 EXPECT_EQ(cb_counter, 2);
246 EXPECT_FALSE(is_wake_lock_acquired);
247
248 alarm_free(alarm[0]);
249 alarm_free(alarm[1]);
250 }
251
TEST_F(AlarmTest,test_set_long_long)252 TEST_F(AlarmTest, test_set_long_long) {
253 alarm_t* alarm[2] = {alarm_new("alarm_test.test_set_long_long_0"),
254 alarm_new("alarm_test.test_set_long_long_1")};
255
256 alarm_set(alarm[0], TIMER_INTERVAL_FOR_WAKELOCK_IN_MS + EPSILON_MS, cb, NULL);
257 alarm_set(alarm[1], 2 * (TIMER_INTERVAL_FOR_WAKELOCK_IN_MS + EPSILON_MS), cb, NULL);
258
259 EXPECT_EQ(cb_counter, 0);
260 EXPECT_FALSE(is_wake_lock_acquired);
261
262 semaphore_wait(semaphore);
263
264 EXPECT_EQ(cb_counter, 1);
265 EXPECT_FALSE(is_wake_lock_acquired);
266
267 semaphore_wait(semaphore);
268
269 EXPECT_EQ(cb_counter, 2);
270 EXPECT_FALSE(is_wake_lock_acquired);
271
272 alarm_free(alarm[0]);
273 alarm_free(alarm[1]);
274 }
275
TEST_F(AlarmTest,test_is_scheduled)276 TEST_F(AlarmTest, test_is_scheduled) {
277 alarm_t* alarm = alarm_new("alarm_test.test_is_scheduled");
278
279 EXPECT_FALSE(alarm_is_scheduled((alarm_t*)NULL));
280 EXPECT_FALSE(alarm_is_scheduled(alarm));
281 alarm_set(alarm, TIMER_INTERVAL_FOR_WAKELOCK_IN_MS + EPSILON_MS, cb, NULL);
282 EXPECT_TRUE(alarm_is_scheduled(alarm));
283
284 EXPECT_EQ(cb_counter, 0);
285 EXPECT_FALSE(is_wake_lock_acquired);
286
287 semaphore_wait(semaphore);
288
289 EXPECT_FALSE(alarm_is_scheduled(alarm));
290 EXPECT_EQ(cb_counter, 1);
291 EXPECT_FALSE(is_wake_lock_acquired);
292
293 alarm_free(alarm);
294 }
295
296 // Test whether the callbacks are invoked in the expected order
TEST_F(AlarmTest,test_callback_ordering)297 TEST_F(AlarmTest, test_callback_ordering) {
298 alarm_t* alarms[100];
299
300 for (int i = 0; i < 100; i++) {
301 const std::string alarm_name = "alarm_test.test_callback_ordering[" + std::to_string(i) + "]";
302 alarms[i] = alarm_new(alarm_name.c_str());
303 }
304
305 for (int i = 0; i < 100; i++) {
306 alarm_set(alarms[i], 100, ordered_cb, INT_TO_PTR(i));
307 }
308
309 for (int i = 1; i <= 100; i++) {
310 semaphore_wait(semaphore);
311 EXPECT_GE(cb_counter, i);
312 }
313 EXPECT_EQ(cb_counter, 100);
314 EXPECT_EQ(cb_misordered_counter, 0);
315
316 for (int i = 0; i < 100; i++) {
317 alarm_free(alarms[i]);
318 }
319
320 EXPECT_FALSE(is_wake_lock_acquired);
321 }
322
323 // Test whether the callbacks are involed in the expected order on a
324 // message loop.
TEST_F(AlarmTest,test_callback_ordering_on_mloop)325 TEST_F(AlarmTest, test_callback_ordering_on_mloop) {
326 alarm_t* alarms[100];
327
328 // Initialize MesageLoop, and wait till it's initialized.
329 MessageLoopThread message_loop_thread("btu message loop");
330 message_loop_thread.StartUp();
331 if (!message_loop_thread.IsRunning()) {
332 FAIL() << "unable to create btu message loop thread.";
333 }
334 thread_ = &message_loop_thread;
335
336 for (int i = 0; i < 100; i++) {
337 const std::string alarm_name =
338 "alarm_test.test_callback_ordering_on_mloop[" + std::to_string(i) + "]";
339 alarms[i] = alarm_new(alarm_name.c_str());
340 }
341
342 for (int i = 0; i < 100; i++) {
343 alarm_set_on_mloop(alarms[i], 100, ordered_cb, INT_TO_PTR(i));
344 }
345
346 for (int i = 1; i <= 100; i++) {
347 semaphore_wait(semaphore);
348 EXPECT_GE(cb_counter, i);
349 }
350 EXPECT_EQ(cb_counter, 100);
351 EXPECT_EQ(cb_misordered_counter, 0);
352
353 for (int i = 0; i < 100; i++) {
354 alarm_free(alarms[i]);
355 }
356
357 message_loop_thread.ShutDown();
358 EXPECT_FALSE(is_wake_lock_acquired);
359 }
360
361 // Try to catch any race conditions between the timer callback and |alarm_free|.
TEST_F(AlarmTest,test_callback_free_race)362 TEST_F(AlarmTest, test_callback_free_race) {
363 for (int i = 0; i < 1000; ++i) {
364 const std::string alarm_name = "alarm_test.test_callback_free_race[" + std::to_string(i) + "]";
365 alarm_t* alarm = alarm_new(alarm_name.c_str());
366 alarm_set(alarm, 0, cb, NULL);
367 alarm_free(alarm);
368 }
369 alarm_cleanup();
370 }
371
remove_cb(void * data)372 static void remove_cb(void* data) {
373 alarm_free((alarm_t*)data);
374 semaphore_post(semaphore);
375 }
376
TEST_F(AlarmTest,test_delete_during_callback)377 TEST_F(AlarmTest, test_delete_during_callback) {
378 for (int i = 0; i < 1000; ++i) {
379 alarm_t* alarm = alarm_new("alarm_test.test_delete_during_callback");
380 alarm_set(alarm, 0, remove_cb, alarm);
381 semaphore_wait(semaphore);
382 }
383 alarm_cleanup();
384 }
385