1 // Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <gtest/gtest.h>
6 #include <stdio.h>
7
8 extern "C" {
9 #include "cras_tm.h"
10 #include "cras_types.h"
11 }
12
13 namespace {
14
15 class TimerTestSuite : public testing::Test {
16 protected:
SetUp()17 virtual void SetUp() {
18 tm_ = cras_tm_init();
19 ASSERT_TRUE(tm_);
20 }
21
TearDown()22 virtual void TearDown() { cras_tm_deinit(tm_); }
23
24 struct cras_tm* tm_;
25 };
26
27 static struct timespec time_now;
28 static unsigned int test_cb_called;
29 static unsigned int test_cb2_called;
30
test_cb(struct cras_timer * t,void * data)31 void test_cb(struct cras_timer* t, void* data) {
32 test_cb_called++;
33 }
34
test_cb2(struct cras_timer * t,void * data)35 void test_cb2(struct cras_timer* t, void* data) {
36 test_cb2_called++;
37 }
38
TEST_F(TimerTestSuite,InitNoTimers)39 TEST_F(TimerTestSuite, InitNoTimers) {
40 struct timespec ts;
41 int timers_active;
42
43 timers_active = cras_tm_get_next_timeout(tm_, &ts);
44 EXPECT_FALSE(timers_active);
45 }
46
TEST_F(TimerTestSuite,AddTimer)47 TEST_F(TimerTestSuite, AddTimer) {
48 struct cras_timer* t;
49
50 t = cras_tm_create_timer(tm_, 10, test_cb, this);
51 EXPECT_TRUE(t);
52 }
53
TEST_F(TimerTestSuite,AddLongTimer)54 TEST_F(TimerTestSuite, AddLongTimer) {
55 struct timespec ts;
56 struct cras_timer* t;
57 int timers_active;
58
59 time_now.tv_sec = 0;
60 time_now.tv_nsec = 0;
61 t = cras_tm_create_timer(tm_, 10000, test_cb, this);
62 EXPECT_TRUE(t);
63
64 timers_active = cras_tm_get_next_timeout(tm_, &ts);
65 ASSERT_TRUE(timers_active);
66 EXPECT_EQ(10, ts.tv_sec);
67 EXPECT_EQ(0, ts.tv_nsec);
68
69 // All timers already fired.
70 time_now.tv_sec = 12;
71 time_now.tv_nsec = 0;
72 timers_active = cras_tm_get_next_timeout(tm_, &ts);
73 ASSERT_TRUE(timers_active);
74 EXPECT_EQ(0, ts.tv_sec);
75 EXPECT_EQ(0, ts.tv_nsec);
76
77 cras_tm_cancel_timer(tm_, t);
78 timers_active = cras_tm_get_next_timeout(tm_, &ts);
79 EXPECT_FALSE(timers_active);
80 }
81
TEST_F(TimerTestSuite,AddRemoveTimer)82 TEST_F(TimerTestSuite, AddRemoveTimer) {
83 struct timespec ts;
84 struct cras_timer* t;
85 int timers_active;
86
87 time_now.tv_sec = 0;
88 time_now.tv_nsec = 0;
89 t = cras_tm_create_timer(tm_, 10, test_cb, this);
90 EXPECT_TRUE(t);
91
92 timers_active = cras_tm_get_next_timeout(tm_, &ts);
93 ASSERT_TRUE(timers_active);
94 EXPECT_EQ(0, ts.tv_sec);
95 EXPECT_EQ(10 * 1000000, ts.tv_nsec);
96
97 // All timers already fired.
98 time_now.tv_sec = 1;
99 time_now.tv_nsec = 0;
100 timers_active = cras_tm_get_next_timeout(tm_, &ts);
101 ASSERT_TRUE(timers_active);
102 EXPECT_EQ(0, ts.tv_sec);
103 EXPECT_EQ(0, ts.tv_nsec);
104
105 cras_tm_cancel_timer(tm_, t);
106 timers_active = cras_tm_get_next_timeout(tm_, &ts);
107 EXPECT_FALSE(timers_active);
108 }
109
TEST_F(TimerTestSuite,AddTwoTimers)110 TEST_F(TimerTestSuite, AddTwoTimers) {
111 struct timespec ts;
112 struct cras_timer *t1, *t2;
113 int timers_active;
114 static const unsigned int t1_to = 10;
115 static const unsigned int t2_offset = 5;
116 static const unsigned int t2_to = 7;
117
118 time_now.tv_sec = 0;
119 time_now.tv_nsec = 0;
120 t1 = cras_tm_create_timer(tm_, t1_to, test_cb, this);
121 ASSERT_TRUE(t1);
122
123 time_now.tv_sec = 0;
124 time_now.tv_nsec = t2_offset;
125 t2 = cras_tm_create_timer(tm_, t2_to, test_cb2, this);
126 ASSERT_TRUE(t2);
127
128 /* Check That the right calls are made at the right times. */
129 test_cb_called = 0;
130 test_cb2_called = 0;
131 time_now.tv_sec = 0;
132 time_now.tv_nsec = t2_to * 1000000 + t2_offset;
133 cras_tm_call_callbacks(tm_);
134 EXPECT_EQ(0, test_cb_called);
135 EXPECT_EQ(1, test_cb2_called);
136 timers_active = cras_tm_get_next_timeout(tm_, &ts);
137 ASSERT_TRUE(timers_active);
138
139 time_now.tv_sec = 0;
140 time_now.tv_nsec = t2_offset;
141 t2 = cras_tm_create_timer(tm_, t2_to, test_cb2, this);
142 ASSERT_TRUE(t2);
143
144 test_cb_called = 0;
145 test_cb2_called = 0;
146 time_now.tv_sec = 0;
147 time_now.tv_nsec = t1_to * 1000000;
148 cras_tm_call_callbacks(tm_);
149 EXPECT_EQ(1, test_cb_called);
150 EXPECT_EQ(1, test_cb2_called);
151 timers_active = cras_tm_get_next_timeout(tm_, &ts);
152 EXPECT_FALSE(timers_active);
153
154 time_now.tv_sec = 0;
155 time_now.tv_nsec = 0;
156 t1 = cras_tm_create_timer(tm_, t1_to, test_cb, this);
157 ASSERT_TRUE(t1);
158
159 time_now.tv_sec = 0;
160 time_now.tv_nsec = t2_offset;
161 t2 = cras_tm_create_timer(tm_, t2_to, test_cb2, this);
162 ASSERT_TRUE(t2);
163
164 /* Timeout values returned are correct. */
165 time_now.tv_sec = 0;
166 time_now.tv_nsec = 50;
167 timers_active = cras_tm_get_next_timeout(tm_, &ts);
168 ASSERT_TRUE(timers_active);
169 EXPECT_EQ(0, ts.tv_sec);
170 EXPECT_EQ(t2_to * 1000000 + t2_offset - time_now.tv_nsec, ts.tv_nsec);
171
172 cras_tm_cancel_timer(tm_, t2);
173
174 time_now.tv_sec = 0;
175 time_now.tv_nsec = 60;
176 timers_active = cras_tm_get_next_timeout(tm_, &ts);
177 ASSERT_TRUE(timers_active);
178 EXPECT_EQ(0, ts.tv_sec);
179 EXPECT_EQ(t1_to * 1000000 - time_now.tv_nsec, ts.tv_nsec);
180 cras_tm_cancel_timer(tm_, t1);
181 }
182
183 /* Stubs */
184 extern "C" {
185
clock_gettime(clockid_t clk_id,struct timespec * tp)186 int clock_gettime(clockid_t clk_id, struct timespec* tp) {
187 *tp = time_now;
188 return 0;
189 }
190
191 } // extern "C"
192
193 } // namespace
194
main(int argc,char ** argv)195 int main(int argc, char** argv) {
196 ::testing::InitGoogleTest(&argc, argv);
197 return RUN_ALL_TESTS();
198 }
199