• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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