mirror of
https://gitlab.freedesktop.org/libinput/libei.git
synced 2026-01-06 22:20:18 +01:00
test: add the ability to add offsets to ei_now()
Build a separate libei-eierpecken.so that is identical to libei.so but allows adding an offset to ei_now() for the eierpecken tests. That offset is added to the return value of ei_now(), removing the real-time dependency of the tests. In other words, we can call peck_ei_add_time_offset(peck, s2us(5)) to add 5 seconds to the time and continue the test as if that time has elapsed.
This commit is contained in:
parent
7999483a34
commit
4e634aa76c
8 changed files with 146 additions and 36 deletions
|
|
@ -113,6 +113,8 @@ struct ei {
|
|||
enum ei_log_priority priority;
|
||||
} log;
|
||||
|
||||
ei_clock_now_func clock_now;
|
||||
|
||||
bool is_sender;
|
||||
};
|
||||
|
||||
|
|
|
|||
25
src/libei.c
25
src/libei.c
|
|
@ -896,19 +896,30 @@ ei_configure_name(struct ei *ei, const char *name)
|
|||
ei->name = xstrdup(name);
|
||||
}
|
||||
|
||||
_public_ void
|
||||
ei_clock_set_now_func(struct ei *ei, ei_clock_now_func func)
|
||||
{
|
||||
ei->clock_now = func;
|
||||
}
|
||||
|
||||
_public_ uint64_t
|
||||
ei_now(struct ei *ei)
|
||||
{
|
||||
uint64_t ts = 0;
|
||||
int rc = now(&ts);
|
||||
|
||||
if (rc < 0) {
|
||||
/* We should probably disconnect here but the chances of this
|
||||
* happening are so slim it's not worth worrying about. Plus,
|
||||
* if this fails we're likely to be inside eis_device_frame()
|
||||
* so we should flush a frame event before disconnecting and... */
|
||||
log_error(ei, "clock_gettime failed: %s", strerror(-rc));
|
||||
if (ei->clock_now)
|
||||
ts = ei->clock_now(ei);
|
||||
else {
|
||||
int rc = now(&ts);
|
||||
if (rc < 0) {
|
||||
/* We should probably disconnect here but the chances of this
|
||||
* happening are so slim it's not worth worrying about. Plus,
|
||||
* if this fails we're likely to be inside eis_device_frame()
|
||||
* so we should flush a frame event before disconnecting and... */
|
||||
log_error(ei, "clock_gettime failed: %s", strerror(-rc));
|
||||
}
|
||||
}
|
||||
|
||||
return ts;
|
||||
}
|
||||
|
||||
|
|
|
|||
22
src/libei.h
22
src/libei.h
|
|
@ -693,6 +693,24 @@ ei_log_set_priority(struct ei *ei, enum ei_log_priority priority);
|
|||
enum ei_log_priority
|
||||
ei_log_get_priority(const struct ei *ei);
|
||||
|
||||
/**
|
||||
* Optional override function for ei_now().
|
||||
*
|
||||
* By default ei_now() returns the current timestamp in CLOCK_MONOTONIC. This
|
||||
* may be overridden by a caller to provide a different timestamp.
|
||||
*
|
||||
* There is rarely a need to override this function. It exists for the libei-internal test suite.
|
||||
*/
|
||||
typedef uint64_t (*ei_clock_now_func)(struct ei *ei);
|
||||
|
||||
/**
|
||||
* Override the function that returns the current time ei_now().
|
||||
*
|
||||
* There is rarely a need to override this function. It exists for the libei-internal test suite.
|
||||
*/
|
||||
void
|
||||
ei_clock_set_now_func(struct ei *, ei_clock_now_func func);
|
||||
|
||||
/**
|
||||
* Set the name for this client. This is a suggestion to the
|
||||
* server only and may not be honored.
|
||||
|
|
@ -802,8 +820,8 @@ ei_peek_event(struct ei *ei);
|
|||
* @returns a timestamp in microseconds for the current time to pass into
|
||||
* ei_device_frame().
|
||||
*
|
||||
* In the current implementation, the returned timestamp is CLOCK_MONOTONIC
|
||||
* for compatibility with evdev and libinput.
|
||||
* By default, the returned timestamp is CLOCK_MONOTONIC for compatibility with
|
||||
* evdev and libinput. This can be overridden with ei_clock_set_now_func().
|
||||
*/
|
||||
uint64_t
|
||||
ei_now(struct ei *ei);
|
||||
|
|
|
|||
|
|
@ -72,6 +72,8 @@ struct eis {
|
|||
enum eis_log_priority priority;
|
||||
} log;
|
||||
|
||||
eis_clock_now_func clock_now;
|
||||
|
||||
const struct eis_proto_requests *requests;
|
||||
};
|
||||
|
||||
|
|
|
|||
26
src/libeis.c
26
src/libeis.c
|
|
@ -424,18 +424,30 @@ eis_add_client(struct eis *eis, struct eis_client *client)
|
|||
list_append(&eis->clients, &client->link);
|
||||
}
|
||||
|
||||
_public_ void
|
||||
eis_clock_set_now_func(struct eis *eis, eis_clock_now_func func)
|
||||
{
|
||||
eis->clock_now = func;
|
||||
}
|
||||
|
||||
_public_ uint64_t
|
||||
eis_now(struct eis *eis)
|
||||
{
|
||||
uint64_t ts = 0;
|
||||
int rc = now(&ts);
|
||||
|
||||
if (rc < 0) {
|
||||
/* We should probably disconnect here but the chances of this
|
||||
* happening are so slim it's not worth worrying about. Plus,
|
||||
* if this fails we're likely to be inside ei_device_frame()
|
||||
* so we should flush a frame event before disconnecting and... */
|
||||
log_error(eis, "clock_gettime failed: %s", strerror(-rc));
|
||||
if (eis->clock_now)
|
||||
ts = eis->clock_now(eis);
|
||||
else {
|
||||
int rc = now(&ts);
|
||||
|
||||
if (rc < 0) {
|
||||
/* We should probably disconnect here but the chances of this
|
||||
* happening are so slim it's not worth worrying about. Plus,
|
||||
* if this fails we're likely to be inside ei_device_frame()
|
||||
* so we should flush a frame event before disconnecting and... */
|
||||
log_error(eis, "clock_gettime failed: %s", strerror(-rc));
|
||||
}
|
||||
}
|
||||
|
||||
return ts;
|
||||
}
|
||||
|
|
|
|||
24
src/libeis.h
24
src/libeis.h
|
|
@ -439,6 +439,24 @@ eis_log_set_priority(struct eis *eis, enum eis_log_priority priority);
|
|||
enum eis_log_priority
|
||||
eis_log_get_priority(const struct eis *eis);
|
||||
|
||||
/**
|
||||
* Optional override function for eis_now().
|
||||
*
|
||||
* By default eis_now() returns the current timestamp in CLOCK_MONOTONIC. This
|
||||
* may be overridden by a caller to provide a different timestamp.
|
||||
*
|
||||
* There is rarely a need to override this function. It exists for the libeis-internal test suite.
|
||||
*/
|
||||
typedef uint64_t (*eis_clock_now_func)(struct eis *eis);
|
||||
|
||||
/**
|
||||
* Override the function that returns the current time eis_now().
|
||||
*
|
||||
* There is rarely a need to override this function. It exists for the libeis-internal test suite.
|
||||
*/
|
||||
void
|
||||
eis_clock_set_now_func(struct eis *, eis_clock_now_func func);
|
||||
|
||||
struct eis *
|
||||
eis_ref(struct eis *eis);
|
||||
|
||||
|
|
@ -1594,11 +1612,11 @@ eis_event_touch_get_y(struct eis_event *event);
|
|||
* @returns a timestamp for the current time to pass into
|
||||
* eis_device_frame().
|
||||
*
|
||||
* In the current implementation, the returned timestamp is CLOCK_MONOTONIC
|
||||
* for compatibility with evdev and libinput.
|
||||
* By default, the returned timestamp is CLOCK_MONOTONIC for compatibility with
|
||||
* evdev and libinput. This can be overridden with eis_clock_set_now_func().
|
||||
*/
|
||||
uint64_t
|
||||
eis_now(struct eis *ei);
|
||||
eis_now(struct eis *eis);
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
|
|
|||
|
|
@ -86,6 +86,9 @@ struct peck {
|
|||
|
||||
bool ei_fatal_bugs;
|
||||
bool eis_fatal_bugs;
|
||||
|
||||
uint64_t ei_time_offset;
|
||||
uint64_t eis_time_offset;
|
||||
};
|
||||
|
||||
static const uint32_t INDENTATION = 4;
|
||||
|
|
@ -105,6 +108,40 @@ peck_dedent(struct peck *peck)
|
|||
static
|
||||
OBJECT_IMPLEMENT_GETTER(peck, indent, uint32_t);
|
||||
|
||||
static uint64_t
|
||||
peck_ei_now_func(struct ei *ei)
|
||||
{
|
||||
static uint64_t offset = 0;
|
||||
struct peck *peck = ei_get_user_data(ei);
|
||||
|
||||
if (peck->ei_time_offset != offset) {
|
||||
offset = peck->ei_time_offset;
|
||||
log_debug(peck, "Time is now offset by %" PRIu64"us\n", offset);
|
||||
}
|
||||
|
||||
uint64_t ts = 0;
|
||||
now(&ts);
|
||||
|
||||
return ts + peck->ei_time_offset;
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
peck_eis_now_func(struct eis *eis)
|
||||
{
|
||||
static uint64_t offset = 0;
|
||||
struct peck *peck = eis_get_user_data(eis);
|
||||
|
||||
if (peck->eis_time_offset != offset) {
|
||||
offset = peck->eis_time_offset;
|
||||
log_debug(peck, "Time is now offset by %" PRIu64"us\n", offset);
|
||||
}
|
||||
|
||||
uint64_t ts = 0;
|
||||
now(&ts);
|
||||
|
||||
return ts + peck->ei_time_offset;
|
||||
}
|
||||
|
||||
static void
|
||||
peck_destroy(struct peck *peck)
|
||||
{
|
||||
|
|
@ -147,6 +184,20 @@ peck_destroy(struct peck *peck)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
peck_ei_add_time_offset(struct peck *peck, uint64_t us)
|
||||
{
|
||||
log_debug(peck, "Adding ei time offset of %" PRIu64 "us\n", us);
|
||||
peck->ei_time_offset += us;
|
||||
}
|
||||
|
||||
void
|
||||
peck_eis_add_time_offset(struct peck *peck, uint64_t us)
|
||||
{
|
||||
log_debug(peck, "Adding EIS time offset of %" PRIu64 "us\n", us);
|
||||
peck->eis_time_offset += us;
|
||||
}
|
||||
|
||||
static
|
||||
OBJECT_IMPLEMENT_CREATE(peck);
|
||||
OBJECT_IMPLEMENT_UNREF(peck);
|
||||
|
|
@ -270,32 +321,20 @@ peck_ei_get_default_touch(struct peck *peck)
|
|||
};
|
||||
|
||||
/* Ensures that device frames in tests always have an ascending and fixed
|
||||
* interval. We start with 30 * interval in the past, every event then goes
|
||||
* forward by 10ms.
|
||||
*
|
||||
* Tests that have more than 30 events will run into the future with their
|
||||
* timestamps, shouldn't be an issue for the test suite though.
|
||||
* interval. Every time this is called it adds 10ms to the time offset.
|
||||
*/
|
||||
uint64_t
|
||||
peck_ei_now(struct peck *peck)
|
||||
{
|
||||
const uint32_t interval = ms2us(10);
|
||||
const uint32_t past_offset = interval * 30;
|
||||
|
||||
peck->now = peck->now == 0 ? ei_now(peck->ei) - past_offset : peck->now + interval;
|
||||
|
||||
return peck->now;
|
||||
peck_ei_add_time_offset(peck, ms2us(10));
|
||||
return ei_now(peck->ei);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
peck_eis_now(struct peck *peck)
|
||||
{
|
||||
const uint32_t interval = ms2us(10);
|
||||
const uint32_t past_offset = interval * 30;
|
||||
|
||||
peck->now = peck->now == 0 ? eis_now(peck->eis) - past_offset : peck->now + interval;
|
||||
|
||||
return peck->now;
|
||||
peck_eis_add_time_offset(peck, ms2us(10));
|
||||
return eis_now(peck->eis);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -439,6 +478,7 @@ new_context(enum peck_ei_mode ei_mode)
|
|||
struct eis *eis = eis_new(peck);
|
||||
eis_log_set_handler(eis, peck_eis_log_handler);
|
||||
eis_log_set_priority(eis, EIS_LOG_PRIORITY_DEBUG);
|
||||
eis_clock_set_now_func(eis, peck_eis_now_func);
|
||||
rc = eis_setup_backend_fd(eis);
|
||||
munit_assert_int(rc, ==, 0);
|
||||
fd = eis_backend_fd_add_client(eis);
|
||||
|
|
@ -451,6 +491,7 @@ new_context(enum peck_ei_mode ei_mode)
|
|||
ei_set_user_data(ei, peck);
|
||||
ei_log_set_handler(ei, peck_ei_log_handler);
|
||||
ei_log_set_priority(ei, EI_LOG_PRIORITY_DEBUG);
|
||||
ei_clock_set_now_func(ei, peck_ei_now_func);
|
||||
ei_configure_name(ei, "eierpecken test context");
|
||||
rc = ei_setup_backend_fd(ei, fd);
|
||||
munit_assert_int(rc, ==, 0);
|
||||
|
|
|
|||
|
|
@ -167,6 +167,12 @@ peck_eis_disable_fatal_bug(struct peck *peck);
|
|||
void
|
||||
peck_eis_enable_fatal_bug(struct peck *peck);
|
||||
|
||||
void
|
||||
peck_ei_add_time_offset(struct peck *peck, uint64_t us);
|
||||
|
||||
void
|
||||
peck_eis_add_time_offset(struct peck *peck, uint64_t us);
|
||||
|
||||
void
|
||||
peck_enable_eis_behavior(struct peck *peck, enum peck_eis_behavior behavior);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue