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