/* Hanoh Haim Cisco Systems, Inc. */ /* Copyright (c) 2015-2015 Cisco Systems, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include #include #include "h_timer.h" class gt_r_timer : public testing::Test { protected: virtual void SetUp() { } virtual void TearDown() { } public: }; TEST_F(gt_r_timer, timer1) { CHTimerObj timer; timer.reset(); timer.Dump(stdout); } TEST_F(gt_r_timer, timer2) { CHTimerOneWheel timer; EXPECT_EQ( timer.Create(513),RC_HTW_ERR_NO_LOG2); } TEST_F(gt_r_timer, timer3) { CHTimerOneWheel timer; EXPECT_EQ( timer.Create(512),RC_HTW_OK); EXPECT_EQ( timer.Delete(),RC_HTW_OK); } void tw_on_tick_cb_test1(void *userdata, CHTimerObj *tmr){ //int tick=(int)((uintptr_t)userdata); printf(" action %lu \n",(ulong)tmr->m_pad[0]); } TEST_F(gt_r_timer, timer4) { CHTimerOneWheel timer; CHTimerObj tmr1; CHTimerObj tmr2; tmr1.reset(); tmr2.reset(); tmr1.m_ticks_left=0; tmr1.m_pad[0]=1; tmr2.m_ticks_left=0; tmr2.m_pad[0]=2; EXPECT_EQ( timer.Create(512),RC_HTW_OK); timer.timer_start(&tmr1,7); timer.timer_start(&tmr2,7); timer.dump_link_list(1,0,tw_on_tick_cb_test1,stdout); timer.dump_link_list(7,0,tw_on_tick_cb_test1,stdout); EXPECT_EQ( timer.Delete(),RC_HTW_OK); } TEST_F(gt_r_timer, timer5) { CHTimerOneWheel timer; CHTimerObj tmr1; CHTimerObj tmr2; tmr1.reset(); tmr2.reset(); tmr1.m_ticks_left=0; tmr1.m_pad[0]=1; tmr2.m_ticks_left=0; tmr2.m_pad[0]=2; EXPECT_EQ( timer.Create(512),RC_HTW_OK); timer.timer_start(&tmr1,7); timer.timer_start(&tmr2,7); timer.dump_link_list(1,0,tw_on_tick_cb_test1,stdout); timer.dump_link_list(7,0,tw_on_tick_cb_test1,stdout); assert( timer.pop_event()==0); int i; for (i=0; i<7; i++) { timer.timer_tick(); } CHTimerObj * obj=timer.pop_event(); assert(obj==&tmr1); timer.dump_link_list(7,0,tw_on_tick_cb_test1,stdout); obj=timer.pop_event(); assert(obj==&tmr2); EXPECT_EQ( timer.Delete(),RC_HTW_OK); } class CMyTestObject { public: CMyTestObject(){ m_id=0; m_d_tick=0; m_t_tick=0; m_timer.reset(); } uint32_t m_id; uint32_t m_d_tick; uint32_t m_t_tick; CHTimerObj m_timer; }; #define MY_OFFSET_OF(cls,member) ((uintptr_t)(&(cls *0)->member) ) void my_test_on_tick_cb(void *userdata,CHTimerObj *tmr){ CHTimerWheel * lp=(CHTimerWheel *)userdata; #pragma GCC diagnostic ignored "-Winvalid-offsetof" CMyTestObject *lpobj=(CMyTestObject *)((uint8_t*)tmr-offsetof (CMyTestObject,m_timer)); #pragma GCC diagnostic pop printf(" [event %d ]",lpobj->m_id); lp->timer_start(tmr,2); } TEST_F(gt_r_timer, timer6) { CHTimerWheel timer; CMyTestObject tmr1; tmr1.m_id=12; EXPECT_EQ( timer.Create(8,3),RC_HTW_OK); timer.timer_start(&tmr1.m_timer,3); int i; for (i=0; i<20; i++) { printf(" tick %d :",i); timer.on_tick((void *)&timer,my_test_on_tick_cb); printf(" \n"); } EXPECT_EQ( timer.Delete(),RC_HTW_OK); } void my_test_on_tick_cb7(void *userdata,CHTimerObj *tmr){ CHTimerWheel * lp=(CHTimerWheel *)userdata; #pragma GCC diagnostic ignored "-Winvalid-offsetof" CMyTestObject *lpobj=(CMyTestObject *)((uint8_t*)tmr-offsetof (CMyTestObject,m_timer)); #pragma GCC diagnostic pop printf(" [event %d ]",lpobj->m_id); lp->timer_start(tmr,9); } TEST_F(gt_r_timer, timer7) { CHTimerWheel timer; CMyTestObject tmr1; tmr1.m_id=12; EXPECT_EQ( timer.Create(4,4),RC_HTW_OK); timer.timer_start(&tmr1.m_timer,80); int i; for (i=0; i<150; i++) { printf(" tick %d :",i); timer.on_tick((void *)&timer,my_test_on_tick_cb7); printf(" \n"); } EXPECT_EQ( timer.Delete(),RC_HTW_OK); } class CHTimerWheelTest1Cfg { public: uint32_t m_wheel_size; uint32_t m_num_wheels; uint32_t m_start_tick; uint32_t m_restart_tick; uint32_t m_total_ticks; bool m_verbose; bool m_dont_assert; }; class CHTimerWheelBase { public: virtual void on_tick(CMyTestObject *lpobj)=0; }; class CHTimerWheelTest1 : public CHTimerWheelBase { public: bool Create(CHTimerWheelTest1Cfg & cfg); void Delete(); void start_test(); virtual void on_tick(CMyTestObject *lpobj); private: CHTimerWheelTest1Cfg m_cfg; CHTimerWheel m_timer; CMyTestObject m_event; uint32_t m_ticks; uint32_t m_total_ticks; uint32_t m_expected_total_ticks; uint32_t m_expect_tick; }; void my_test_on_tick_cb8(void *userdata,CHTimerObj *tmr){ CHTimerWheelBase * lp=(CHTimerWheelBase *)userdata; #pragma GCC diagnostic ignored "-Winvalid-offsetof" CMyTestObject *lpobj=(CMyTestObject *)((uint8_t*)tmr-offsetof (CMyTestObject,m_timer)); #pragma GCC diagnostic pop lp->on_tick(lpobj); } void CHTimerWheelTest1::on_tick(CMyTestObject *lpobj){ assert(lpobj->m_id==17); m_total_ticks++; if (m_cfg.m_verbose) { printf(" [event %d ]",lpobj->m_id); } if (!m_cfg.m_dont_assert){ assert( m_ticks == m_expect_tick); } m_timer.timer_start(&lpobj->m_timer,m_cfg.m_restart_tick); m_expect_tick+=m_cfg.m_restart_tick; } void CHTimerWheelTest1::start_test(){ if (m_cfg.m_verbose) { printf(" test start %d,restart: %d \n",m_cfg.m_start_tick,m_cfg.m_restart_tick); } int i; m_expected_total_ticks=0; uint32_t cnt=m_cfg.m_start_tick; for (i=0; im_id=i+1; if (m_cfg.m_random) { lp->m_d_tick = ((rand() % m_cfg.m_number_of_con_event)+1); if (m_cfg.m_verbose) { printf(" flow %d : %d \n",i,lp->m_d_tick); } }else{ lp->m_d_tick=i+1; } lp->m_t_tick=lp->m_d_tick; m_timer.timer_start(&lp->m_timer,lp->m_d_tick); } for (i=0; im_id==lp->m_d_tick); } if (m_cfg.m_verbose) { printf(" [event %d ]",lp->m_id); } m_timer.timer_start(&lp->m_timer,lp->m_d_tick); if (!m_cfg.m_dont_check){ assert(m_ticks == lp->m_t_tick); } lp->m_t_tick+=lp->m_d_tick; } TEST_F(gt_r_timer, timer13) { CHTimerWheelTest2 test; CHTimerWheelTest2Cfg cfg ={ .m_wheel_size = 4, .m_num_wheels = 4, .m_number_of_con_event = 10, .m_total_ticks =1000, .m_random=false, .m_verbose =false }; test.Create(cfg); test.start_test(); test.Delete(); } TEST_F(gt_r_timer, timer14) { CHTimerWheelTest2 test; CHTimerWheelTest2Cfg cfg ={ .m_wheel_size = 8, .m_num_wheels = 3, .m_number_of_con_event = 10, .m_total_ticks =1000, .m_random=false, .m_verbose =false }; test.Create(cfg); test.start_test(); test.Delete(); } TEST_F(gt_r_timer, timer15) { CHTimerWheelTest2 test; CHTimerWheelTest2Cfg cfg ={ .m_wheel_size = 1024, .m_num_wheels = 3, .m_number_of_con_event = 100, .m_total_ticks =10000, .m_random=false, .m_verbose =false }; test.Create(cfg); test.start_test(); test.Delete(); } TEST_F(gt_r_timer, timer16) { CHTimerWheelTest2 test; CHTimerWheelTest2Cfg cfg ={ .m_wheel_size = 32, .m_num_wheels = 4, .m_number_of_con_event = 111, .m_total_ticks =20000, .m_random=true, .m_verbose =false, .m_dont_check=false }; test.Create(cfg); test.start_test(); test.Delete(); }