blob: 3f5521ebe69f8d125d3a2bae8876ce1b7f935c8b [file] [log] [blame]
// 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();
}