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 23extern "C" { 24#include "alarm.h" 25#include "osi.h" 26#include "semaphore.h" 27} 28 29static semaphore_t *semaphore; 30static int cb_counter; 31 32static const uint64_t EPSILON_MS = 5; 33 34static void msleep(uint64_t ms) { 35 usleep(ms * 1000); 36} 37 38class AlarmTest : public AlarmTestHarness { 39 protected: 40 virtual void SetUp() { 41 AlarmTestHarness::SetUp(); 42 cb_counter = 0; 43 44 semaphore = semaphore_new(0); 45 } 46 47 virtual void TearDown() { 48 semaphore_free(semaphore); 49 AlarmTestHarness::TearDown(); 50 } 51}; 52 53static void cb(UNUSED_ATTR void *data) { 54 ++cb_counter; 55 semaphore_post(semaphore); 56} 57 58TEST_F(AlarmTest, test_new_free_simple) { 59 alarm_t *alarm = alarm_new(); 60 ASSERT_TRUE(alarm != NULL); 61 alarm_free(alarm); 62} 63 64TEST_F(AlarmTest, test_free_null) { 65 alarm_free(NULL); 66} 67 68TEST_F(AlarmTest, test_simple_cancel) { 69 alarm_t *alarm = alarm_new(); 70 alarm_cancel(alarm); 71 alarm_free(alarm); 72} 73 74TEST_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 86TEST_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 95TEST_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 110TEST_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 125TEST_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 151TEST_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 177TEST_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|. 204TEST_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