efl/src/tests/ecore/ecore_test_timer.c

429 lines
12 KiB
C

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <Ecore.h>
#include <math.h>
#include "ecore_suite.h"
#define TIMEOUT_1 0.01 // interval for timer1
#define TIMEOUT_2 0.02 // timer2
#define TIMEOUT_3 0.06 // timer3
#define TIMEOUT_4 0.1 // timer4
#define TIMEOUT_5 0.5 // timer5 - end ecore_main_loop_begin()
#define SIZE 3
static int freeze_thaw = 0; // 1 - freeze timer, 0 - thaw
struct _timers // timer struct
{
Ecore_Timer *timer1; // timer 1
Ecore_Timer *timer2;
Ecore_Timer *timer3;
Ecore_Timer *timer4;
Ecore_Timer *timer5;
int count_timer1;
int count_timer3; // check count timer 3
int add_timer2; // flag add timer 2
int check_freeze_thaw_timer3;
int num_elem;
double delay_1[3];
double interval_1[3];
double precision[3];
};
static Eina_Bool
_timer1_cb(void *data)
{
struct _timers *timer = data;
timer->count_timer1++;
return ECORE_CALLBACK_RENEW;
}
static Eina_Bool
_timer2_cb(void *data)
{
struct _timers *timer = (struct _timers*)data;
// choose next settings (delay, interval, precision) for timer 1
if (++timer->num_elem > 2)
timer->num_elem = 0;
// check add/delay timer 2
fail_if(timer->add_timer2 > 1, "Error add/delay timer");
// check set new delay for timer 1
ecore_timer_delay(timer->timer1, timer->delay_1[timer->num_elem]);
// check set new interval for timer 1
ecore_timer_interval_set(timer->timer1, timer->interval_1[timer->num_elem]);
fail_if(!EINA_DBL_EQ(timer->interval_1[timer->num_elem], ecore_timer_interval_get(timer->timer1)), "Error set new interval");
// check set new precision
ecore_timer_precision_set(timer->precision[timer->num_elem]);
fail_if(!EINA_DBL_EQ(timer->precision[timer->num_elem], ecore_timer_precision_get()), "Error set new precision");
// check removal timer 2
if (ecore_timer_del(timer->timer2))
{
timer->add_timer2 = 0;
timer->timer2 = NULL;
}
return ECORE_CALLBACK_RENEW;
}
static Eina_Bool
_timer3_cb(void *data)
{
struct _timers *timer = (struct _timers*)data;
timer->count_timer3++; // number of starts timer 3
// check add timer 2
if (!timer->timer2)
{
timer->add_timer2++; // amount of added timer
timer->timer2 = ecore_timer_add(TIMEOUT_2, _timer2_cb, timer);
}
return ECORE_CALLBACK_RENEW;
}
static Eina_Bool
_timer4_cb(void *data)
{
struct _timers *timer = (struct _timers*)data;
// check frezze/thaw timer 3
if (freeze_thaw)
{
fail_if(timer->check_freeze_thaw_timer3 != timer->count_timer3, "Error frezze/thaw timer");
ecore_timer_thaw(timer->timer3);
freeze_thaw = 0;
}
else
{
ecore_timer_freeze(timer->timer3);
freeze_thaw = 1;
timer->check_freeze_thaw_timer3 = timer->count_timer3;
}
return ECORE_CALLBACK_RENEW;
}
static Eina_Bool
_timer5_cb(void *data)
{
struct _timers *timer = (struct _timers*)data;
if (timer->timer2) timer->timer2 = NULL;
ecore_main_loop_quit();
return ECORE_CALLBACK_RENEW;
}
/*
Timer2 sets new parameters (delay, interval and precision) for Timer1 and checks them.
Timer3 creates and runs Timer2 and increases parameter add_timer2 to 1. Timer2 removes himself
and sets parameter add_timer2 to 0. Inside callback of Timer2 parameter add_timer2 should be
equal to 1 otherwise "Error add/delay timer".
Timer4 controls 'freezing' or 'thaw' for Timer3. Timer4 sets flag freeze_thaw to state: 'freeze' or 'thaw'.
When Timer3 is frozen counter of Timer3 saved in the parameter check_freeze_thaw_timer3.
Otherwise (thaw mode) check that parameter check_freeze_thaw_timer3 equals to counter Timer3.
If not equal then "Error frezze/thaw timer".
Timer 5 finishes testing.
*/
EFL_START_TEST(ecore_test_timers)
{
struct _timers timer = \
{
.num_elem = 0,
.delay_1 = {0.01, 0.05, 0.1},
.interval_1 = {0.01, 0.05, 0.1},
.precision = {0.01, 0.02, 0.03}
};
timer.timer1 = ecore_timer_add(TIMEOUT_1, _timer1_cb, &timer);
timer.timer2 = ecore_timer_add(TIMEOUT_2, _timer2_cb, &timer);
timer.add_timer2++;
timer.timer3 = ecore_timer_add(TIMEOUT_3, _timer3_cb, &timer);
timer.timer4 = ecore_timer_add(TIMEOUT_4, _timer4_cb, &timer);
timer.timer5 = ecore_timer_add(TIMEOUT_5, _timer5_cb, &timer);
fail_if((!timer.timer1 || !timer.timer2 || !timer.timer3 || !timer.timer4 || !timer.timer5), "Error add timer\n");
ecore_main_loop_begin();
if (timer.timer1)
ecore_timer_del(timer.timer1);
if (timer.timer2)
ecore_timer_del(timer.timer2);
if (timer.timer3)
ecore_timer_del(timer.timer3);
if (timer.timer4)
ecore_timer_del(timer.timer4);
if (timer.timer5)
ecore_timer_del(timer.timer5);
}
EFL_END_TEST
typedef struct _Test_Inside_Call
{
Ecore_Timer *t;
int it;
} Test_Inside_Call;
static Eina_Bool
_timeri_cb(void *data)
{
Test_Inside_Call *c = data;
ecore_timer_reset(c->t);
c->it--;
if (c->it > 0) return EINA_TRUE;
free(c);
ecore_main_loop_quit();
return EINA_FALSE;
}
static Eina_Bool
timeout_timer_cb()
{
ck_abort();
return EINA_FALSE;
}
EFL_START_TEST(ecore_test_timer_inside_call)
{
Test_Inside_Call *c;
c = malloc(sizeof(Test_Inside_Call));
c->it = 5;
c->t = ecore_timer_add(0.01, _timeri_cb, c);
ecore_timer_add(1.0, timeout_timer_cb, NULL);
fail_if(!c->t, "Error add timer\n");
ecore_main_loop_begin();
}
EFL_END_TEST
EFL_START_TEST(ecore_test_timer_valid_callbackfunc)
{
Ecore_Timer *t = NULL;
fail_if((t = ecore_timer_add(0.5, NULL, NULL)), "ERROR: Invalid callback func!\n");
}
EFL_END_TEST
static Eina_Bool
_quit_cb(void *data)
{
Eina_Bool *val = data;
if (val) *val = EINA_TRUE;
ecore_main_loop_quit();
return EINA_FALSE;
}
EFL_START_TEST(ecore_test_ecore_main_loop_timer)
{
Eina_Bool did = EINA_FALSE;
Ecore_Timer *timer;
double start, end, elapsed;
timer = ecore_timer_add(0.1, _quit_cb, &did);
fail_if(timer == NULL);
start = ecore_time_get();
ecore_main_loop_begin();
end = ecore_time_get();
elapsed = end - start;
fail_if(did == EINA_FALSE);
fail_if(elapsed < 0.05);
fail_if(elapsed > 0.15); /* .05 second "error margin" */
}
EFL_END_TEST
static int count = 0;
static Eina_Bool
_timer_cb(void *data)
{
count++;
int num = (intptr_t) data;
fail_if (num != count, "Error timer is called out of order");
if (count == 8) ecore_main_loop_quit();
return ECORE_CALLBACK_CANCEL;
}
EFL_START_TEST(ecore_test_timer_in_order)
{
Ecore_Timer *timer;
timer = ecore_timer_add(0.001, _timer_cb, (void *) 1);
fail_if(timer == NULL);
timer = ecore_timer_add(0.001, _timer_cb, (void *) 2);
fail_if(timer == NULL);
timer = ecore_timer_add(0.001, _timer_cb, (void *) 3);
fail_if(timer == NULL);
timer = ecore_timer_add(0.001, _timer_cb, (void *) 4);
fail_if(timer == NULL);
timer = ecore_timer_add(0.001, _timer_cb, (void *) 5);
fail_if(timer == NULL);
timer = ecore_timer_add(0.001, _timer_cb, (void *) 6);
fail_if(timer == NULL);
timer = ecore_timer_add(0.001, _timer_cb, (void *) 7);
fail_if(timer == NULL);
timer = ecore_timer_add(0.001, _timer_cb, (void *) 8);
fail_if(timer == NULL);
ecore_main_loop_begin();
}
EFL_END_TEST
EFL_START_TEST(ecore_test_timer_iteration)
{
Ecore_Timer *timer;
count = 0;
/* verify that timers expire after exactly one loop iteration */
ecore_timer_add(0, _timer_cb, (void *) 1);
ecore_main_loop_iterate();
/* timers should not expire for one loop iteration */
ck_assert_int_eq(count, 0);
ecore_main_loop_iterate();
/* timers should expire after one loop iteration */
ck_assert_int_eq(count, 1);
/* verify multiple timer expiration in single mainloop iteration */
ecore_timer_add(0, _timer_cb, (void *) 2);
ecore_timer_add(0, _timer_cb, (void *) 3);
ecore_main_loop_iterate();
/* timers should not expire for one loop iteration */
ck_assert_int_eq(count, 1);
ecore_timer_add(0, _timer_cb, (void *) 4);
ecore_main_loop_iterate();
/* all pending and instantiated timers should expire after exactly one loop iteration */
ck_assert_int_eq(count, 3);
ecore_main_loop_iterate();
/* this should not interfere with successive timer processing */
ck_assert_int_eq(count, 4);
/* verify out-of-order timer processing solely based on timer times */
timer = ecore_timer_add(1, _timer_cb, (void *) 6);
ecore_main_loop_iterate();
ck_assert_int_eq(count, 4);
ecore_timer_add(0, _timer_cb, (void *) 5);
ecore_main_loop_iterate();
ck_assert_int_eq(count, 4);
/* timer should expire after exactly 2 iterations */
ecore_main_loop_iterate();
ck_assert_int_eq(count, 5);
ecore_timer_interval_set(timer, 0);
ecore_timer_reset(timer);
/* timer should expire after exactly 2 iterations since it becomes un-instantiated now */
ecore_main_loop_iterate();
ecore_main_loop_iterate();
ck_assert_int_eq(count, 6);
}
EFL_END_TEST
static Eina_Bool
_recursion()
{
static unsigned int recurse = 0;
static Ecore_Timer *timer;
switch (recurse++)
{
case 0:
/* verify multiple timer expiration in single mainloop iteration */
ecore_timer_add(0, _timer_cb, (void *) 2);
ecore_timer_add(0, _timer_cb, (void *) 3);
ecore_main_loop_iterate();
ecore_main_loop_iterate();
ck_assert_int_eq(count, 6);
ecore_main_loop_quit();
break;
case 1:
/* timers should not expire for one loop iteration */
ck_assert_int_eq(count, 1);
ecore_timer_add(0, _timer_cb, (void *) 4);
ecore_main_loop_iterate();
ecore_main_loop_iterate();
break;
case 2:
/* all pending and instantiated timers should expire after exactly one loop iteration */
ck_assert_int_eq(count, 3);
ecore_main_loop_iterate();
ecore_main_loop_iterate();
break;
case 3:
/* this should not interfere with successive timer processing */
ck_assert_int_eq(count, 4);
/* verify out-of-order timer processing solely based on timer times */
timer = ecore_timer_add(1, _timer_cb, (void *) 6);
ecore_main_loop_iterate();
ecore_main_loop_iterate();
break;
case 4:
ck_assert_int_eq(count, 4);
ecore_timer_add(0, _timer_cb, (void *) 5);
ecore_main_loop_iterate();
ecore_main_loop_iterate();
break;
case 5:
ck_assert_int_eq(count, 4);
/* timer should expire after exactly 2 iterations */
ecore_main_loop_iterate();
ecore_main_loop_iterate();
break;
case 6:
ck_assert_int_eq(count, 5);
ecore_timer_interval_set(timer, 0);
ecore_timer_reset(timer);
/* timer should expire after exactly 2 iterations since it becomes un-instantiated now */
ecore_main_loop_iterate();
ecore_main_loop_iterate();
break;
case 7:
ecore_main_loop_iterate();
ecore_main_loop_iterate();
break;
}
return EINA_FALSE;
}
EFL_START_TEST(ecore_test_timer_recursion)
{
Eina_Bool crit = eina_log_abort_on_critical_get();
int critlevel = eina_log_abort_on_critical_level_get();
count = 1;
eina_log_abort_on_critical_set(1);
eina_log_abort_on_critical_level_set(1);
ecore_timer_add(0, _recursion, NULL);
ecore_main_loop_begin();
ck_assert_int_eq(count, 6);
eina_log_abort_on_critical_set(crit);
eina_log_abort_on_critical_level_set(critlevel);
}
EFL_END_TEST
void ecore_test_timer(TCase *tc)
{
tcase_add_test(tc, ecore_test_timers);
tcase_add_test(tc, ecore_test_timer_inside_call);
tcase_add_test(tc, ecore_test_timer_valid_callbackfunc);
tcase_add_test(tc, ecore_test_ecore_main_loop_timer);
tcase_add_test(tc, ecore_test_timer_in_order);
tcase_add_test(tc, ecore_test_timer_iteration);
tcase_add_test(tc, ecore_test_timer_recursion);
}