1 /******************************************************************************
2 *
3 * Copyright (C) 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 <gtest/gtest.h>
20
21 #include "AlarmTestHarness.h"
22
23 extern "C" {
24 #include "alarm.h"
25 #include "osi.h"
26 #include "semaphore.h"
27 }
28
29 static semaphore_t *semaphore;
30 static int cb_counter;
31
32 static const uint64_t EPSILON_MS = 5;
33
msleep(uint64_t ms)34 static void msleep(uint64_t ms) {
35 usleep(ms * 1000);
36 }
37
38 class AlarmTest : public AlarmTestHarness {
39 protected:
SetUp()40 virtual void SetUp() {
41 AlarmTestHarness::SetUp();
42 cb_counter = 0;
43
44 semaphore = semaphore_new(0);
45 }
46
TearDown()47 virtual void TearDown() {
48 semaphore_free(semaphore);
49 AlarmTestHarness::TearDown();
50 }
51 };
52
cb(UNUSED_ATTR void * data)53 static void cb(UNUSED_ATTR void *data) {
54 ++cb_counter;
55 semaphore_post(semaphore);
56 }
57
TEST_F(AlarmTest,test_new_free_simple)58 TEST_F(AlarmTest, test_new_free_simple) {
59 alarm_t *alarm = alarm_new();
60 ASSERT_TRUE(alarm != NULL);
61 alarm_free(alarm);
62 }
63
TEST_F(AlarmTest,test_free_null)64 TEST_F(AlarmTest, test_free_null) {
65 alarm_free(NULL);
66 }
67
TEST_F(AlarmTest,test_simple_cancel)68 TEST_F(AlarmTest, test_simple_cancel) {
69 alarm_t *alarm = alarm_new();
70 alarm_cancel(alarm);
71 alarm_free(alarm);
72 }
73
TEST_F(AlarmTest,test_cancel)74 TEST_F(AlarmTest, test_cancel) {
75 alarm_t *alarm = alarm_new();
76 alarm_set(alarm, 10, cb, NULL);
77 alarm_cancel(alarm);
78
79 msleep(10 + EPSILON_MS);
80
81 EXPECT_EQ(cb_counter, 0);
82 EXPECT_EQ(lock_count, 0);
83 alarm_free(alarm);
84 }
85
TEST_F(AlarmTest,test_cancel_idempotent)86 TEST_F(AlarmTest, test_cancel_idempotent) {
87 alarm_t *alarm = alarm_new();
88 alarm_set(alarm, 10, cb, NULL);
89 alarm_cancel(alarm);
90 alarm_cancel(alarm);
91 alarm_cancel(alarm);
92 alarm_free(alarm);
93 }
94
TEST_F(AlarmTest,test_set_short)95 TEST_F(AlarmTest, test_set_short) {
96 alarm_t *alarm = alarm_new();
97 alarm_set(alarm, 10, cb, NULL);
98
99 EXPECT_EQ(cb_counter, 0);
100 EXPECT_EQ(lock_count, 1);
101
102 semaphore_wait(semaphore);
103
104 EXPECT_EQ(cb_counter, 1);
105 EXPECT_EQ(lock_count, 0);
106
107 alarm_free(alarm);
108 }
109
TEST_F(AlarmTest,test_set_long)110 TEST_F(AlarmTest, test_set_long) {
111 alarm_t *alarm = alarm_new();
112 alarm_set(alarm, TIMER_INTERVAL_FOR_WAKELOCK_IN_MS, cb, NULL);
113
114 EXPECT_EQ(cb_counter, 0);
115 EXPECT_EQ(lock_count, 0);
116
117 semaphore_wait(semaphore);
118
119 EXPECT_EQ(cb_counter, 1);
120 EXPECT_EQ(lock_count, 0);
121
122 alarm_free(alarm);
123 }
124
TEST_F(AlarmTest,test_set_short_short)125 TEST_F(AlarmTest, test_set_short_short) {
126 alarm_t *alarm[2] = {
127 alarm_new(),
128 alarm_new()
129 };
130
131 alarm_set(alarm[0], 10, cb, NULL);
132 alarm_set(alarm[1], 20, cb, NULL);
133
134 EXPECT_EQ(cb_counter, 0);
135 EXPECT_EQ(lock_count, 1);
136
137 semaphore_wait(semaphore);
138
139 EXPECT_EQ(cb_counter, 1);
140 EXPECT_EQ(lock_count, 1);
141
142 semaphore_wait(semaphore);
143
144 EXPECT_EQ(cb_counter, 2);
145 EXPECT_EQ(lock_count, 0);
146
147 alarm_free(alarm[0]);
148 alarm_free(alarm[1]);
149 }
150
TEST_F(AlarmTest,test_set_short_long)151 TEST_F(AlarmTest, test_set_short_long) {
152 alarm_t *alarm[2] = {
153 alarm_new(),
154 alarm_new()
155 };
156
157 alarm_set(alarm[0], 10, cb, NULL);
158 alarm_set(alarm[1], 10 + TIMER_INTERVAL_FOR_WAKELOCK_IN_MS + EPSILON_MS, cb, NULL);
159
160 EXPECT_EQ(cb_counter, 0);
161 EXPECT_EQ(lock_count, 1);
162
163 semaphore_wait(semaphore);
164
165 EXPECT_EQ(cb_counter, 1);
166 EXPECT_EQ(lock_count, 0);
167
168 semaphore_wait(semaphore);
169
170 EXPECT_EQ(cb_counter, 2);
171 EXPECT_EQ(lock_count, 0);
172
173 alarm_free(alarm[0]);
174 alarm_free(alarm[1]);
175 }
176
TEST_F(AlarmTest,test_set_long_long)177 TEST_F(AlarmTest, test_set_long_long) {
178 alarm_t *alarm[2] = {
179 alarm_new(),
180 alarm_new()
181 };
182
183 alarm_set(alarm[0], TIMER_INTERVAL_FOR_WAKELOCK_IN_MS, cb, NULL);
184 alarm_set(alarm[1], 2 * TIMER_INTERVAL_FOR_WAKELOCK_IN_MS + EPSILON_MS, cb, NULL);
185
186 EXPECT_EQ(cb_counter, 0);
187 EXPECT_EQ(lock_count, 0);
188
189 semaphore_wait(semaphore);
190
191 EXPECT_EQ(cb_counter, 1);
192 EXPECT_EQ(lock_count, 0);
193
194 semaphore_wait(semaphore);
195
196 EXPECT_EQ(cb_counter, 2);
197 EXPECT_EQ(lock_count, 0);
198
199 alarm_free(alarm[0]);
200 alarm_free(alarm[1]);
201 }
202
203 // Try to catch any race conditions between the timer callback and |alarm_free|.
TEST_F(AlarmTest,test_callback_free_race)204 TEST_F(AlarmTest, test_callback_free_race) {
205 for (int i = 0; i < 1000; ++i) {
206 alarm_t *alarm = alarm_new();
207 alarm_set(alarm, 0, cb, NULL);
208 alarm_free(alarm);
209 }
210 }
211