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