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