| // Copyright (c) 2012 The Chromium OS Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <gtest/gtest.h> |
| #include <stdio.h> |
| |
| extern "C" { |
| #include "cras_tm.h" |
| #include "cras_types.h" |
| } |
| |
| namespace { |
| |
| class TimerTestSuite : public testing::Test { |
| protected: |
| virtual void SetUp() { |
| tm_ = cras_tm_init(); |
| ASSERT_TRUE(tm_); |
| } |
| |
| virtual void TearDown() { cras_tm_deinit(tm_); } |
| |
| struct cras_tm* tm_; |
| }; |
| |
| static struct timespec time_now; |
| static unsigned int test_cb_called; |
| static unsigned int test_cb2_called; |
| |
| void test_cb(struct cras_timer* t, void* data) { |
| test_cb_called++; |
| } |
| |
| void test_cb2(struct cras_timer* t, void* data) { |
| test_cb2_called++; |
| } |
| |
| TEST_F(TimerTestSuite, InitNoTimers) { |
| struct timespec ts; |
| int timers_active; |
| |
| timers_active = cras_tm_get_next_timeout(tm_, &ts); |
| EXPECT_FALSE(timers_active); |
| } |
| |
| TEST_F(TimerTestSuite, AddTimer) { |
| struct cras_timer* t; |
| |
| t = cras_tm_create_timer(tm_, 10, test_cb, this); |
| EXPECT_TRUE(t); |
| } |
| |
| TEST_F(TimerTestSuite, AddLongTimer) { |
| struct timespec ts; |
| struct cras_timer* t; |
| int timers_active; |
| |
| time_now.tv_sec = 0; |
| time_now.tv_nsec = 0; |
| t = cras_tm_create_timer(tm_, 10000, test_cb, this); |
| EXPECT_TRUE(t); |
| |
| timers_active = cras_tm_get_next_timeout(tm_, &ts); |
| ASSERT_TRUE(timers_active); |
| EXPECT_EQ(10, ts.tv_sec); |
| EXPECT_EQ(0, ts.tv_nsec); |
| |
| // All timers already fired. |
| time_now.tv_sec = 12; |
| time_now.tv_nsec = 0; |
| timers_active = cras_tm_get_next_timeout(tm_, &ts); |
| ASSERT_TRUE(timers_active); |
| EXPECT_EQ(0, ts.tv_sec); |
| EXPECT_EQ(0, ts.tv_nsec); |
| |
| cras_tm_cancel_timer(tm_, t); |
| timers_active = cras_tm_get_next_timeout(tm_, &ts); |
| EXPECT_FALSE(timers_active); |
| } |
| |
| TEST_F(TimerTestSuite, AddRemoveTimer) { |
| struct timespec ts; |
| struct cras_timer* t; |
| int timers_active; |
| |
| time_now.tv_sec = 0; |
| time_now.tv_nsec = 0; |
| t = cras_tm_create_timer(tm_, 10, test_cb, this); |
| EXPECT_TRUE(t); |
| |
| timers_active = cras_tm_get_next_timeout(tm_, &ts); |
| ASSERT_TRUE(timers_active); |
| EXPECT_EQ(0, ts.tv_sec); |
| EXPECT_EQ(10 * 1000000, ts.tv_nsec); |
| |
| // All timers already fired. |
| time_now.tv_sec = 1; |
| time_now.tv_nsec = 0; |
| timers_active = cras_tm_get_next_timeout(tm_, &ts); |
| ASSERT_TRUE(timers_active); |
| EXPECT_EQ(0, ts.tv_sec); |
| EXPECT_EQ(0, ts.tv_nsec); |
| |
| cras_tm_cancel_timer(tm_, t); |
| timers_active = cras_tm_get_next_timeout(tm_, &ts); |
| EXPECT_FALSE(timers_active); |
| } |
| |
| TEST_F(TimerTestSuite, AddTwoTimers) { |
| struct timespec ts; |
| struct cras_timer *t1, *t2; |
| int timers_active; |
| static const unsigned int t1_to = 10; |
| static const unsigned int t2_offset = 5; |
| static const unsigned int t2_to = 7; |
| |
| time_now.tv_sec = 0; |
| time_now.tv_nsec = 0; |
| t1 = cras_tm_create_timer(tm_, t1_to, test_cb, this); |
| ASSERT_TRUE(t1); |
| |
| time_now.tv_sec = 0; |
| time_now.tv_nsec = t2_offset; |
| t2 = cras_tm_create_timer(tm_, t2_to, test_cb2, this); |
| ASSERT_TRUE(t2); |
| |
| /* Check That the right calls are made at the right times. */ |
| test_cb_called = 0; |
| test_cb2_called = 0; |
| time_now.tv_sec = 0; |
| time_now.tv_nsec = t2_to * 1000000 + t2_offset; |
| cras_tm_call_callbacks(tm_); |
| EXPECT_EQ(0, test_cb_called); |
| EXPECT_EQ(1, test_cb2_called); |
| timers_active = cras_tm_get_next_timeout(tm_, &ts); |
| ASSERT_TRUE(timers_active); |
| |
| time_now.tv_sec = 0; |
| time_now.tv_nsec = t2_offset; |
| t2 = cras_tm_create_timer(tm_, t2_to, test_cb2, this); |
| ASSERT_TRUE(t2); |
| |
| test_cb_called = 0; |
| test_cb2_called = 0; |
| time_now.tv_sec = 0; |
| time_now.tv_nsec = t1_to * 1000000; |
| cras_tm_call_callbacks(tm_); |
| EXPECT_EQ(1, test_cb_called); |
| EXPECT_EQ(1, test_cb2_called); |
| timers_active = cras_tm_get_next_timeout(tm_, &ts); |
| EXPECT_FALSE(timers_active); |
| |
| time_now.tv_sec = 0; |
| time_now.tv_nsec = 0; |
| t1 = cras_tm_create_timer(tm_, t1_to, test_cb, this); |
| ASSERT_TRUE(t1); |
| |
| time_now.tv_sec = 0; |
| time_now.tv_nsec = t2_offset; |
| t2 = cras_tm_create_timer(tm_, t2_to, test_cb2, this); |
| ASSERT_TRUE(t2); |
| |
| /* Timeout values returned are correct. */ |
| time_now.tv_sec = 0; |
| time_now.tv_nsec = 50; |
| timers_active = cras_tm_get_next_timeout(tm_, &ts); |
| ASSERT_TRUE(timers_active); |
| EXPECT_EQ(0, ts.tv_sec); |
| EXPECT_EQ(t2_to * 1000000 + t2_offset - time_now.tv_nsec, ts.tv_nsec); |
| |
| cras_tm_cancel_timer(tm_, t2); |
| |
| time_now.tv_sec = 0; |
| time_now.tv_nsec = 60; |
| timers_active = cras_tm_get_next_timeout(tm_, &ts); |
| ASSERT_TRUE(timers_active); |
| EXPECT_EQ(0, ts.tv_sec); |
| EXPECT_EQ(t1_to * 1000000 - time_now.tv_nsec, ts.tv_nsec); |
| cras_tm_cancel_timer(tm_, t1); |
| } |
| |
| /* Stubs */ |
| extern "C" { |
| |
| int clock_gettime(clockid_t clk_id, struct timespec* tp) { |
| *tp = time_now; |
| return 0; |
| } |
| |
| } // extern "C" |
| |
| } // namespace |
| |
| int main(int argc, char** argv) { |
| ::testing::InitGoogleTest(&argc, argv); |
| return RUN_ALL_TESTS(); |
| } |