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