/* Listed requirements are under requirement Trick-163 (3.7.5.2) */ /* Real-time control shall be able to use a system clock source */ #define protected public #define TOL 2e3 #include #include #include //#include #include #include "gtest/gtest.h" #include "sim_services/Timer/include/ITimer.hh" #include "sim_services/Clock/include/GetTimeOfDayClock.hh" #include "sim_services/SimObject/include/SimObject.hh" #include "trick_utils/reqs/include/RequirementScribe.hh" namespace Trick { class ITimerTest : public testing::Test { public: Trick::GetTimeOfDayClock dClk; Trick::RequirementScribe req; double sec; long long tim_st, tim_elap; ITimerTest() {} ~ITimerTest() {} virtual void SetUp() {} virtual void TearDown() {} }; /* Proper initialization of ITimer */ TEST_F(ITimerTest, Initialize) { req.add_requirement("timer"); //"The ITimer shall initialize with disabled and inactive status."); Trick::ITimer *iTim; iTim = new Trick::ITimer; iTim->init(); EXPECT_FALSE(iTim->get_enabled()); EXPECT_FALSE(iTim->active); iTim->enable(); EXPECT_TRUE(iTim->get_enabled()); iTim->disable(); EXPECT_FALSE(iTim->get_enabled()); delete iTim; } /* Timer not enabled; ensure no activity when starting, pausing, etc */ TEST_F(ITimerTest, TimerNotEnabled) { req.add_requirement("timer"); //"The ITimer shall start if and only if the ITimer is enabled to do so."); bool active_ch, enable_ch; Trick::ITimer *iTim; iTim = new Trick::ITimer; active_ch = iTim->active; enable_ch = iTim->get_enabled(); sec = 0.05; iTim->init(); iTim->start(sec); EXPECT_EQ(iTim->active, active_ch); iTim->set_active(~active_ch); active_ch = iTim->active; iTim->start(sec); EXPECT_EQ(iTim->active, active_ch); delete iTim; } /* Tolerance: 2 ms */ TEST_F(ITimerTest, TimerStartSuccess) { req.add_requirement("timer"); //"The ITimer shall sleep when commanded, thereby releasing the processor for a specified amount of time."); sec = 0.05; Trick::ITimer *iTim; iTim = new Trick::ITimer; iTim->init(); iTim->enable(); tim_st = dClk.wall_clock_time(); iTim->start(sec); ASSERT_TRUE(iTim->active); /* Cause simulation to wait until "sec" seconds have passed */ iTim->pause(); tim_elap = dClk.wall_clock_time() - tim_st; EXPECT_NEAR((tim_elap+2000), sec*1e6, TOL); delete iTim; } TEST_F(ITimerTest, TimerStartReset) { req.add_requirement("timer"); //"The ITimer shall reset to a new alarm time when commanded if the current time until alarm has not yet expired."); sec = 0.05; Trick::ITimer *iTim; iTim = new Trick::ITimer; iTim->init(); iTim->enable(); iTim->start(sec); usleep(40000); /* This is equivalent to saying start(2.0*sec), both are valid */ iTim->reset(2.0*sec); //iTim->start(2.0*sec); tim_st = dClk.wall_clock_time(); iTim->pause(); tim_elap = dClk.wall_clock_time() - tim_st; EXPECT_NEAR((tim_elap+2000), (2*sec*1e6), TOL); delete iTim; } TEST_F(ITimerTest, TimerStartStop) { req.add_requirement("timer"); //"The ITimer shall stop when commanded if the time until alarm has not yet expired."); sec = 0.05; Trick::ITimer *iTim; iTim = new Trick::ITimer; iTim->init(); iTim->enable(); tim_st = dClk.wall_clock_time(); iTim->start(sec); usleep(40000); iTim->stop(); tim_elap = dClk.wall_clock_time() - tim_st; EXPECT_NEAR((tim_elap+2000), 40000, (TOL+4000)); //std::cout << TOL+4000 << std::endl; EXPECT_FALSE(iTim->active); tim_st = dClk.wall_clock_time(); iTim->pause(); tim_elap = dClk.wall_clock_time() - tim_st; EXPECT_NEAR(tim_elap, 0, TOL); delete iTim; } TEST_F(ITimerTest, TimerStartFailure) { req.add_requirement("timer"); //"The ITimer shall not initiate with start times that are negative or less than 10 ms"); sec = 0.05; Trick::ITimer *iTim; iTim = new Trick::ITimer; iTim->init(); iTim->enable(); /*Passing negative time to elapse; expecting throw */ EXPECT_ANY_THROW(iTim->start(-sec)); /* Cannot activate timer with < 10 ms */ sec = 0.005; iTim->start(sec); EXPECT_FALSE(iTim->active); delete iTim; } }