213 lines
5.6 KiB
C
213 lines
5.6 KiB
C
#include <check.h>
|
|
#include "ucore/timers.h"
|
|
#include "ucore/timers.h"
|
|
#include "ucore/clock.h"
|
|
|
|
struct TimerTest {
|
|
int cnt;
|
|
};
|
|
#define TEST_TIMER_START 1000000
|
|
static void timer_test_cb(struct UCTimers *timers, struct UCTimer *timer)
|
|
{
|
|
struct TimerTest *tt = timer->cookie_ptr;
|
|
(void)timers; //get rid of unused param warning
|
|
tt->cnt++;
|
|
}
|
|
|
|
static void timer_test_cb_add(struct UCTimers *timers, struct UCTimer *timer)
|
|
{
|
|
struct TimerTest *tt = timer->cookie_ptr;
|
|
tt->cnt++;
|
|
uc_timers_add(timers, timer, 10, 0);
|
|
}
|
|
|
|
static void timer_test_cb_remove(struct UCTimers *timers, struct UCTimer *timer)
|
|
{
|
|
struct UCTimer *timer2 = timer->cookie_ptr;
|
|
uc_timers_remove(timers, timer2);
|
|
}
|
|
|
|
static void common_init(struct UCoreSettableClock *clk,
|
|
struct TimerTest *tt,
|
|
struct UCTimers *timers,
|
|
struct UCTimer *timer)
|
|
{
|
|
uc_settable_clock_init(clk);
|
|
uc_settable_clock_set(clk, TEST_TIMER_START, 0);
|
|
uc_timers_init_ex(timers, &clk->clock);
|
|
|
|
|
|
tt->cnt = 0;
|
|
memset(timer, 0, sizeof *timer);
|
|
timer->cookie_ptr = tt;
|
|
}
|
|
|
|
START_TEST (test_timers_simple)
|
|
struct UCoreSettableClock clk;
|
|
struct TimerTest tt;
|
|
struct UCTimers timers;
|
|
struct UCTimer timer;
|
|
int t = TEST_TIMER_START;
|
|
int rc;
|
|
|
|
common_init(&clk, &tt, &timers, &timer);
|
|
|
|
timer.callback = timer_test_cb;
|
|
|
|
uc_timers_add(&timers, &timer, 10, 0);
|
|
|
|
//5 seconds into the future, no timer should fire
|
|
t += 5;
|
|
uc_settable_clock_set(&clk, t, 0);
|
|
rc = uc_timers_run(&timers);
|
|
fail_if(rc != 0);
|
|
fail_if(tt.cnt != 0);
|
|
ck_assert_int_eq(uc_timers_count(&timers), 1);
|
|
|
|
//10 seconds into the future, our timer should fire
|
|
t += 5;
|
|
uc_settable_clock_set(&clk, t, 0);
|
|
rc = uc_timers_run(&timers);
|
|
fail_if(rc != 1);
|
|
fail_if(tt.cnt != 1);
|
|
|
|
//20 seconds into the future, our oneshot timer shouldn't fire
|
|
t += 10;
|
|
uc_settable_clock_set(&clk, t, 0);
|
|
rc = uc_timers_run(&timers);
|
|
fail_if(rc != 0);
|
|
fail_if(tt.cnt != 1);
|
|
ck_assert_int_eq(uc_timers_count(&timers), 0);
|
|
fail_if(uc_timer_running(&timer) != 0);
|
|
|
|
END_TEST
|
|
|
|
START_TEST (test_timers_add_from_callback)
|
|
struct UCoreSettableClock clk;
|
|
struct TimerTest tt;
|
|
struct UCTimers timers;
|
|
struct UCTimer timer;
|
|
int t = TEST_TIMER_START;
|
|
int rc;
|
|
|
|
common_init(&clk, &tt, &timers, &timer);
|
|
|
|
timer.callback = timer_test_cb_add;
|
|
|
|
uc_timers_add(&timers, &timer, 10, 0);
|
|
|
|
//10 seconds into the future, our timer should fire
|
|
t += 10;
|
|
uc_settable_clock_set(&clk, t, 0);
|
|
rc = uc_timers_run(&timers);
|
|
fail_if(rc != 1);
|
|
fail_if(tt.cnt != 1);
|
|
|
|
|
|
//20 seconds into the future, our timer should fire again
|
|
t += 10;
|
|
uc_settable_clock_set(&clk, t, 0);
|
|
rc = uc_timers_run(&timers);
|
|
fail_if(rc != 1);
|
|
fail_if(tt.cnt != 2);
|
|
|
|
fail_if(uc_timer_running(&timer) == 0);
|
|
ck_assert_int_eq(uc_timers_count(&timers), 1);
|
|
|
|
END_TEST
|
|
|
|
START_TEST (test_timers_remove_from_callback)
|
|
struct UCoreSettableClock clk;
|
|
struct TimerTest tt;
|
|
struct UCTimers timers;
|
|
struct UCTimer timer;
|
|
struct UCTimer timer2;
|
|
int t = TEST_TIMER_START;
|
|
int rc;
|
|
struct timeval tv = {0, 0};
|
|
|
|
common_init(&clk, &tt, &timers, &timer);
|
|
|
|
timer.callback = timer_test_cb_remove;
|
|
timer.cookie_ptr = &timer2;
|
|
memset(&timer2, 0, sizeof timer2);
|
|
timer2.callback = timer_test_cb;
|
|
|
|
uc_timers_add(&timers, &timer, 5, 0);
|
|
uc_timers_add(&timers, &timer2, 10, 0);
|
|
|
|
ck_assert_int_eq(uc_timers_count(&timers), 2);
|
|
rc = uc_timers_first(&timers, &tv);
|
|
fail_if(rc != 0);
|
|
fail_if(tv.tv_sec != TEST_TIMER_START + 5);
|
|
fail_if(uc_timer_running(&timer) == 0);
|
|
fail_if(uc_timer_running(&timer2) == 0);
|
|
|
|
//5 seconds into the future, our timer should fire
|
|
t += 5;
|
|
uc_settable_clock_set(&clk, t, 0);
|
|
rc = uc_timers_run(&timers);
|
|
fail_if(rc != 1);
|
|
fail_if(tt.cnt != 0);
|
|
//and our timer2 should be removed, and timer has fired so it
|
|
//should be removed too
|
|
|
|
ck_assert_int_eq(uc_timers_count(&timers), 0);
|
|
fail_if(uc_timer_running(&timer) != 0);
|
|
fail_if(uc_timer_running(&timer2) != 0);
|
|
rc = uc_timers_first(&timers, &tv);
|
|
fail_if(rc == 0);
|
|
|
|
END_TEST
|
|
|
|
START_TEST (test_timers_add_remove)
|
|
struct UCoreSettableClock clk;
|
|
struct TimerTest tt;
|
|
struct UCTimers timers;
|
|
struct UCTimer timer[1023];
|
|
struct timeval first;
|
|
size_t i;
|
|
int toggle = 5;
|
|
|
|
common_init(&clk, &tt, &timers, &timer[0]);
|
|
memset(&timer, 0, sizeof timer);
|
|
for (i = 0; i < sizeof timer/sizeof timer[0]; i++) {
|
|
timer[i].callback = timer_test_cb_add;
|
|
|
|
uc_timers_add(&timers, &timer[i], toggle + i , 0);
|
|
if (i > 5) //just to add timeouts non-ascending order
|
|
toggle = 5 - toggle;
|
|
}
|
|
|
|
fail_if(uc_timers_first(&timers, &first) != 0);
|
|
fail_if(first.tv_sec != TEST_TIMER_START + 5);
|
|
fail_if(first.tv_usec != 0);
|
|
|
|
ck_assert_int_eq(uc_timers_count(&timers), sizeof timer/sizeof timer[0]);
|
|
|
|
for (i = 0; i < sizeof timer/sizeof timer[0]; i++) {
|
|
uc_timers_remove(&timers, &timer[i]);
|
|
}
|
|
|
|
|
|
ck_assert_int_eq(uc_timers_count(&timers), 0);
|
|
fail_if(uc_timers_first(&timers, &first) == 0);
|
|
|
|
END_TEST
|
|
|
|
|
|
Suite *timers_suite(void)
|
|
{
|
|
Suite *s = suite_create("timers");
|
|
TCase *tc = tcase_create("timers tests");
|
|
tcase_add_test(tc, test_timers_simple);
|
|
tcase_add_test(tc, test_timers_add_from_callback);
|
|
tcase_add_test(tc, test_timers_remove_from_callback);
|
|
tcase_add_test(tc, test_timers_add_remove);
|
|
|
|
suite_add_tcase(s, tc);
|
|
|
|
return s;
|
|
}
|
|
|