test: add logcapturing to litest

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1226>
This commit is contained in:
Peter Hutterer 2025-06-11 09:36:07 +10:00
parent 2dcfda2ebc
commit a0a2416d11
2 changed files with 131 additions and 0 deletions

View file

@ -1267,6 +1267,18 @@ _litest_add_parametrized_for_device(const char *filename,
litest_abort_msg("Invalid test device type");
}
static int
is_actual_error(const char *error, size_t index, void *data)
{
/* We don't want to abort on these errors */
if (((RUNNING_ON_VALGRIND || in_debugger) && strstr(error, "scheduled expiry is in the past")) ||
strstr(error, "event processing lagging behind")) {
return 0;
}
return 1;
}
LIBINPUT_ATTRIBUTE_PRINTF(3, 0)
static void
litest_log_handler(struct libinput *libinput,
@ -4741,6 +4753,93 @@ _litest_timeout(struct libinput *li, const char *func, int lineno, int millis)
_litest_dispatch(li, func, lineno);
}
void
_litest_assert_logcapture_no_errors(struct litest_logcapture *capture,
const char *file,
const char *func,
int line)
{
litest_assert_ptr_notnull(capture);
if (capture->errors && strv_for_each((const char **)capture->errors, is_actual_error, NULL)) {
_autofree_ char *errors = strv_join(capture->errors, "\n");
_litest_abort_msg(file, line, func,
"Unexpected errors in log capture:\n%s\n",
errors);
}
}
void
litest_logcapture_destroy(struct litest_logcapture *c)
{
strv_free(c->errors);
strv_free(c->infos);
strv_free(c->debugs);
free(c);
}
LIBINPUT_ATTRIBUTE_PRINTF(3, 0)
static void
litest_log_handler_msgcapture(struct libinput *libinput,
enum libinput_log_priority pri,
const char *format,
va_list args)
{
struct litest_user_data *user_data = libinput_get_user_data(libinput);
struct litest_logcapture *capture = user_data->private;
const char *priority = NULL;
const char *color = use_colors ? ANSI_RGB(255, 255, 70) ANSI_RGB_BG(40, 40, 40) : "";
switch (pri) {
case LIBINPUT_LOG_PRIORITY_ERROR:
priority = "error ";
break;
case LIBINPUT_LOG_PRIORITY_INFO:
priority = "info ";
break;
case LIBINPUT_LOG_PRIORITY_DEBUG:
priority = "debug ";
break;
}
_autofree_ char *message = strdup_vprintf(format, args);
fprintf(stderr, "%slitest captured: %-6s%s %s",
color,
priority,
use_colors ? ANSI_NORMAL : "",
message);
switch (pri) {
case LIBINPUT_LOG_PRIORITY_ERROR:
capture->errors = strv_append_take(capture->errors, &message);
break;
case LIBINPUT_LOG_PRIORITY_INFO:
capture->infos = strv_append_take(capture->infos, &message);
break;
case LIBINPUT_LOG_PRIORITY_DEBUG:
capture->debugs = strv_append_take(capture->debugs, &message);
break;
}
}
struct litest_logcapture *
litest_logcapture_setup(struct libinput *li)
{
struct litest_logcapture *c = zalloc(sizeof(*c));
litest_context_set_user_data(li, c);
libinput_log_set_handler(li, litest_log_handler_msgcapture);
return c;
}
struct litest_logcapture *
litest_logcapture_remove(struct libinput *li, struct litest_logcapture *capture)
{
litest_restore_log_handler(li);
litest_logcapture_destroy(capture);
return NULL;
}
void
litest_push_event_frame(struct litest_device *dev)
{

View file

@ -1340,6 +1340,38 @@ _litest_timeout(struct libinput *li, const char *func, int lineno, int millis);
#define litest_timeout_hysteresis(li_) litest_timeout(li_, 90)
#define litest_timeout_3fg_drag(li_) litest_timeout(li_, 800)
struct litest_logcapture {
char **errors;
char **infos;
char **debugs;
};
void
litest_logcapture_destroy(struct litest_logcapture *c);
DEFINE_DESTROY_CLEANUP_FUNC(litest_logcapture);
struct litest_logcapture *
litest_logcapture_setup(struct libinput *li);
struct litest_logcapture *
litest_logcapture_remove(struct libinput *li,
struct litest_logcapture *capture);
#define litest_with_logcapture(li_, capture_) \
for (struct litest_logcapture *capture_ = litest_logcapture_setup(li_); \
capture_ != NULL; \
capture_ = litest_logcapture_remove(li_, capture_))
void
_litest_assert_logcapture_no_errors(struct litest_logcapture *c,
const char *file,
const char *func,
int lineno);
#define litest_assert_logcapture_no_errors(c_) \
_litest_assert_logcapture_no_errors(c_, __FILE__, __func__, __LINE__)
#define litest_with_event_frame(dev_) \
for (bool _i = ({litest_push_event_frame(dev_); true; }); \
_i; \