mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-06-18 22:28:24 +02:00
test: add a backtrace facility to litest
The check unit test framework isn't particularly suited to having ck_assert* calls in helper functions. A failed assertion in a helper function or the litest framework merely gives us a the failed line in litest.c. which doesn't tell us which test actually failed. Add a backtracing facility with litest_backtrace(). And since this requires wrapping all ck_assert macros with litest_assert() this patch ended up replacing/duplicating a bunch of ck_assert_* bits. So rather than ck_assert_int_eq() we now use litest_assert_int_eq(), etc. in the litest framework itself. The int comparison macros are more type-safe than ck_assert()'s macros which just cast all the ints to intmax_t. Backtrace is spewed to stderr, which is good enough for debugging. Example backtrace: FAILED COMPARISON: status != expected Resolved to: 0 != 0 in disable_button_scrolling() (pointer.c:115) Backtrace: 0: ./test/test-pointer (litest_fail_comparison_int+0xab) [0x40973b] 1: ./test/test-pointer (disable_button_scrolling+0x174) [0x40421b] 2: ./test/test-pointer (middlebutton_middleclick+0x40) [0x40829c] 3: /lib64/libcheck.so.0 (srunner_run+0x7f5) [0x7f0e8a277025] 4: ./test/test-pointer (litest_run+0x107) [0x40a42b] 5: ./test/test-pointer (main+0x2fa) [0x4090e7] 6: /lib64/libc.so.6 (__libc_start_main+0xf0) [0x7f0e88f5e790] 7: ./test/test-pointer (_start+0x29) [0x403ce9] 8: ? (?+0x29) [0x29] litest_backtrace() itself is copied from xserver/os/backtrace.c which git blame attributes to Marcin. CC: Marcin Slusarz <marcin.slusarz@gmail.com> Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
parent
c9ea9836f3
commit
84e6321f51
6 changed files with 537 additions and 70 deletions
10
configure.ac
10
configure.ac
|
|
@ -60,6 +60,15 @@ PKG_PROG_PKG_CONFIG()
|
|||
PKG_CHECK_MODULES(MTDEV, [mtdev >= 1.1.0])
|
||||
PKG_CHECK_MODULES(LIBUDEV, [libudev])
|
||||
PKG_CHECK_MODULES(LIBEVDEV, [libevdev >= 0.4])
|
||||
PKG_CHECK_MODULES(LIBUNWIND,
|
||||
[libunwind],
|
||||
[HAVE_LIBUNWIND=yes],
|
||||
[HAVE_LIBUNWIND=no])
|
||||
if test "x$HAVE_LIBUNWIND" = "xyes"; then
|
||||
AC_DEFINE(HAVE_LIBUNWIND, 1, [Have libunwind support])
|
||||
fi
|
||||
AM_CONDITIONAL(HAVE_LIBUNWIND, [test "x$HAVE_LIBUNWIND" = xyes])
|
||||
|
||||
AC_CHECK_LIB([m], [atan2])
|
||||
AC_CHECK_LIB([rt], [clock_gettime])
|
||||
|
||||
|
|
@ -190,5 +199,6 @@ AC_MSG_RESULT([
|
|||
Build documentation ${build_documentation}
|
||||
Build tests ${build_tests}
|
||||
Tests use valgrind ${VALGRIND}
|
||||
Tests use libunwind ${HAVE_LIBUNWIND}
|
||||
Build GUI event tool ${build_eventgui}
|
||||
])
|
||||
|
|
|
|||
|
|
@ -38,6 +38,11 @@ liblitest_la_SOURCES = \
|
|||
litest-vmware-virtual-usb-mouse.c \
|
||||
litest.c
|
||||
liblitest_la_LIBADD = $(top_builddir)/src/libinput-util.la
|
||||
liblitest_la_CFLAGS = $(AM_CFLAGS)
|
||||
if HAVE_LIBUNWIND
|
||||
liblitest_la_LIBADD += $(LIBUNWIND_LIBS) -ldl
|
||||
liblitest_la_CFLAGS += $(LIBUNWIND_CFLAGS)
|
||||
endif
|
||||
|
||||
run_tests = \
|
||||
test-touchpad \
|
||||
|
|
@ -49,7 +54,9 @@ run_tests = \
|
|||
test-path \
|
||||
test-log \
|
||||
test-misc \
|
||||
test-keyboard
|
||||
test-keyboard \
|
||||
test-litest-selftest
|
||||
|
||||
build_tests = \
|
||||
test-build-cxx \
|
||||
test-build-linker \
|
||||
|
|
@ -102,6 +109,11 @@ test_device_SOURCES = device.c
|
|||
test_device_LDADD = $(TEST_LIBS)
|
||||
test_device_LDFLAGS = -no-install
|
||||
|
||||
test_litest_selftest_SOURCES = litest-selftest.c litest.c litest-int.h litest.h
|
||||
test_litest_selftest_CFLAGS = -DLITEST_DISABLE_BACKTRACE_LOGGING
|
||||
test_litest_selftest_LDADD = $(TEST_LIBS)
|
||||
test_litest_selftest_LDFLAGS = -no-install
|
||||
|
||||
# build-test only
|
||||
test_build_pedantic_c99_SOURCES = build-pedantic.c
|
||||
test_build_pedantic_c99_CFLAGS = -std=c99 -pedantic -Werror
|
||||
|
|
@ -125,7 +137,7 @@ VALGRIND_FLAGS=--leak-check=full \
|
|||
--suppressions=$(srcdir)/valgrind.suppressions
|
||||
|
||||
valgrind:
|
||||
$(MAKE) check-TESTS LOG_COMPILER="$(VALGRIND)" LOG_FLAGS="$(VALGRIND_FLAGS)" CK_FORK=no
|
||||
$(MAKE) check-TESTS LOG_COMPILER="$(VALGRIND)" LOG_FLAGS="$(VALGRIND_FLAGS)" CK_FORK=no USING_VALGRIND=yes
|
||||
|
||||
check: valgrind
|
||||
|
||||
|
|
|
|||
228
test/litest-selftest.c
Normal file
228
test/litest-selftest.c
Normal file
|
|
@ -0,0 +1,228 @@
|
|||
#include <config.h>
|
||||
|
||||
#include <check.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "litest.h"
|
||||
|
||||
START_TEST(litest_assert_trigger)
|
||||
{
|
||||
litest_assert(1 == 2);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(litest_assert_notrigger)
|
||||
{
|
||||
litest_assert(1 == 1);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(litest_assert_msg_trigger)
|
||||
{
|
||||
litest_assert_msg(1 == 2, "1 is not 2\n");
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(litest_assert_msg_NULL_trigger)
|
||||
{
|
||||
litest_assert_msg(1 == 2, NULL);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(litest_assert_msg_notrigger)
|
||||
{
|
||||
litest_assert_msg(1 == 1, "1 is not 2\n");
|
||||
litest_assert_msg(1 == 1, NULL);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(litest_abort_msg_trigger)
|
||||
{
|
||||
litest_abort_msg("message\n");
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(litest_abort_msg_NULL_trigger)
|
||||
{
|
||||
litest_abort_msg(NULL);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(litest_int_eq_trigger)
|
||||
{
|
||||
int a = 10;
|
||||
int b = 20;
|
||||
litest_assert_int_eq(a, b);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(litest_int_eq_notrigger)
|
||||
{
|
||||
int a = 10;
|
||||
int b = 10;
|
||||
litest_assert_int_eq(a, b);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(litest_int_ne_trigger)
|
||||
{
|
||||
int a = 10;
|
||||
int b = 10;
|
||||
litest_assert_int_ne(a, b);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(litest_int_ne_notrigger)
|
||||
{
|
||||
int a = 10;
|
||||
int b = 20;
|
||||
litest_assert_int_ne(a, b);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(litest_int_lt_trigger_eq)
|
||||
{
|
||||
int a = 10;
|
||||
int b = 10;
|
||||
litest_assert_int_lt(a, b);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(litest_int_lt_trigger_gt)
|
||||
{
|
||||
int a = 11;
|
||||
int b = 10;
|
||||
litest_assert_int_lt(a, b);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(litest_int_lt_notrigger)
|
||||
{
|
||||
int a = 10;
|
||||
int b = 11;
|
||||
litest_assert_int_lt(a, b);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(litest_int_le_trigger)
|
||||
{
|
||||
int a = 11;
|
||||
int b = 10;
|
||||
litest_assert_int_le(a, b);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(litest_int_le_notrigger)
|
||||
{
|
||||
int a = 10;
|
||||
int b = 11;
|
||||
int c = 10;
|
||||
litest_assert_int_le(a, b);
|
||||
litest_assert_int_le(a, c);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(litest_int_gt_trigger_eq)
|
||||
{
|
||||
int a = 10;
|
||||
int b = 10;
|
||||
litest_assert_int_gt(a, b);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(litest_int_gt_trigger_lt)
|
||||
{
|
||||
int a = 9;
|
||||
int b = 10;
|
||||
litest_assert_int_gt(a, b);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(litest_int_gt_notrigger)
|
||||
{
|
||||
int a = 10;
|
||||
int b = 9;
|
||||
litest_assert_int_gt(a, b);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(litest_int_ge_trigger)
|
||||
{
|
||||
int a = 9;
|
||||
int b = 10;
|
||||
litest_assert_int_ge(a, b);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(litest_int_ge_notrigger)
|
||||
{
|
||||
int a = 10;
|
||||
int b = 9;
|
||||
int c = 10;
|
||||
litest_assert_int_ge(a, b);
|
||||
litest_assert_int_ge(a, c);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
static Suite *
|
||||
litest_assert_macros_suite(void)
|
||||
{
|
||||
TCase *tc;
|
||||
Suite *s;
|
||||
|
||||
s = suite_create("litest:assert macros");
|
||||
tc = tcase_create("assert");
|
||||
tcase_add_test_raise_signal(tc, litest_assert_trigger, SIGABRT);
|
||||
tcase_add_test(tc, litest_assert_notrigger);
|
||||
tcase_add_test_raise_signal(tc, litest_assert_msg_trigger, SIGABRT);
|
||||
tcase_add_test_raise_signal(tc, litest_assert_msg_NULL_trigger, SIGABRT);
|
||||
tcase_add_test(tc, litest_assert_msg_notrigger);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("abort");
|
||||
tcase_add_test_raise_signal(tc, litest_abort_msg_trigger, SIGABRT);
|
||||
tcase_add_test_raise_signal(tc, litest_abort_msg_NULL_trigger, SIGABRT);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("int comparison ");
|
||||
tcase_add_test_raise_signal(tc, litest_int_eq_trigger, SIGABRT);
|
||||
tcase_add_test(tc, litest_int_eq_notrigger);
|
||||
tcase_add_test_raise_signal(tc, litest_int_ne_trigger, SIGABRT);
|
||||
tcase_add_test(tc, litest_int_ne_notrigger);
|
||||
tcase_add_test_raise_signal(tc, litest_int_le_trigger, SIGABRT);
|
||||
tcase_add_test(tc, litest_int_le_notrigger);
|
||||
tcase_add_test_raise_signal(tc, litest_int_lt_trigger_gt, SIGABRT);
|
||||
tcase_add_test_raise_signal(tc, litest_int_lt_trigger_eq, SIGABRT);
|
||||
tcase_add_test(tc, litest_int_lt_notrigger);
|
||||
tcase_add_test_raise_signal(tc, litest_int_ge_trigger, SIGABRT);
|
||||
tcase_add_test(tc, litest_int_ge_notrigger);
|
||||
tcase_add_test_raise_signal(tc, litest_int_gt_trigger_eq, SIGABRT);
|
||||
tcase_add_test_raise_signal(tc, litest_int_gt_trigger_lt, SIGABRT);
|
||||
tcase_add_test(tc, litest_int_gt_notrigger);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int nfailed;
|
||||
Suite *s;
|
||||
SRunner *sr;
|
||||
|
||||
/* when running under valgrind we're using nofork mode, so a signal
|
||||
* raised by a test will fail in valgrind. There's nothing to
|
||||
* memcheck here anyway, so just skip the valgrind test */
|
||||
if (getenv("USING_VALGRIND"))
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
s = litest_assert_macros_suite();
|
||||
sr = srunner_create(s);
|
||||
|
||||
srunner_run_all(sr, CK_ENV);
|
||||
nfailed = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
|
||||
return (nfailed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
||||
272
test/litest.c
272
test/litest.c
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2013 Red Hat, Inc.
|
||||
* Copyright © 2013 Marcin Slusarz <marcin.slusarz@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
|
|
@ -51,6 +52,142 @@
|
|||
static int in_debugger = -1;
|
||||
static int verbose = 0;
|
||||
|
||||
#ifdef HAVE_LIBUNWIND
|
||||
#define UNW_LOCAL_ONLY
|
||||
#include <libunwind.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
/* defined for the litest selftest */
|
||||
#ifndef LITEST_DISABLE_BACKTRACE_LOGGING
|
||||
#define litest_log(...) fprintf(stderr, __VA_ARGS__)
|
||||
#define litest_vlog(format_, args_) vfprintf(stderr, format_, args_)
|
||||
#else
|
||||
#define litest_log(...) /* __VA_ARGS__ */
|
||||
#define litest_vlog(...) /* __VA_ARGS__ */
|
||||
#endif
|
||||
|
||||
static void
|
||||
litest_backtrace(void)
|
||||
{
|
||||
unw_cursor_t cursor;
|
||||
unw_context_t context;
|
||||
unw_word_t off;
|
||||
unw_proc_info_t pip;
|
||||
int ret;
|
||||
char procname[256];
|
||||
Dl_info dlinfo;
|
||||
/* filename and i are unused ifdef LITEST_SHUTUP */
|
||||
const char *filename __attribute__((unused));
|
||||
int i __attribute__((unused)) = 0;
|
||||
|
||||
pip.unwind_info = NULL;
|
||||
ret = unw_getcontext(&context);
|
||||
if (ret) {
|
||||
litest_log("unw_getcontext failed: %s [%d]\n",
|
||||
unw_strerror(ret),
|
||||
ret);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = unw_init_local(&cursor, &context);
|
||||
if (ret) {
|
||||
litest_log("unw_init_local failed: %s [%d]\n",
|
||||
unw_strerror(ret),
|
||||
ret);
|
||||
return;
|
||||
}
|
||||
|
||||
litest_log("\nBacktrace:\n");
|
||||
ret = unw_step(&cursor);
|
||||
while (ret > 0) {
|
||||
ret = unw_get_proc_info(&cursor, &pip);
|
||||
if (ret) {
|
||||
litest_log("unw_get_proc_info failed: %s [%d]\n",
|
||||
unw_strerror(ret),
|
||||
ret);
|
||||
break;
|
||||
}
|
||||
|
||||
ret = unw_get_proc_name(&cursor, procname, 256, &off);
|
||||
if (ret && ret != -UNW_ENOMEM) {
|
||||
if (ret != -UNW_EUNSPEC)
|
||||
litest_log("unw_get_proc_name failed: %s [%d]\n",
|
||||
unw_strerror(ret),
|
||||
ret);
|
||||
procname[0] = '?';
|
||||
procname[1] = 0;
|
||||
}
|
||||
|
||||
if (dladdr((void *)(pip.start_ip + off), &dlinfo) &&
|
||||
dlinfo.dli_fname &&
|
||||
*dlinfo.dli_fname)
|
||||
filename = dlinfo.dli_fname;
|
||||
else
|
||||
filename = "?";
|
||||
|
||||
litest_log("%u: %s (%s%s+%#x) [%p]\n",
|
||||
i++,
|
||||
filename,
|
||||
procname,
|
||||
ret == -UNW_ENOMEM ? "..." : "",
|
||||
(int)off,
|
||||
(void *)(pip.start_ip + off));
|
||||
|
||||
ret = unw_step(&cursor);
|
||||
if (ret < 0)
|
||||
litest_log("unw_step failed: %s [%d]\n",
|
||||
unw_strerror(ret),
|
||||
ret);
|
||||
}
|
||||
litest_log("\n");
|
||||
}
|
||||
#else /* HAVE_LIBUNWIND */
|
||||
static inline void
|
||||
litest_backtrace(void)
|
||||
{
|
||||
/* thou shall install libunwind */
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
litest_fail_condition(const char *file,
|
||||
int line,
|
||||
const char *func,
|
||||
const char *condition,
|
||||
const char *message,
|
||||
...)
|
||||
{
|
||||
litest_log("FAILED: %s\n", condition);
|
||||
|
||||
if (message) {
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
litest_vlog(message, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
litest_log("in %s() (%s:%d)\n", func, file, line);
|
||||
litest_backtrace();
|
||||
abort();
|
||||
}
|
||||
|
||||
void
|
||||
litest_fail_comparison_int(const char *file,
|
||||
int line,
|
||||
const char *func,
|
||||
const char *operator,
|
||||
int a,
|
||||
int b,
|
||||
const char *astr,
|
||||
const char *bstr)
|
||||
{
|
||||
litest_log("FAILED COMPARISON: %s %s %s\n", astr, operator, bstr);
|
||||
litest_log("Resolved to: %d %s %d\n", a, operator, b);
|
||||
litest_log("in %s() (%s:%d)\n", func, file, line);
|
||||
litest_backtrace();
|
||||
abort();
|
||||
}
|
||||
|
||||
struct test {
|
||||
struct list node;
|
||||
char *name;
|
||||
|
|
@ -370,7 +507,7 @@ litest_add_ranged_for_device(const char *name,
|
|||
dev++;
|
||||
}
|
||||
|
||||
ck_abort_msg("Invalid test device type");
|
||||
litest_abort_msg("Invalid test device type");
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -533,13 +670,13 @@ merge_absinfo(const struct input_absinfo *orig,
|
|||
return NULL;
|
||||
|
||||
abs = calloc(sz, sizeof(*abs));
|
||||
ck_assert(abs != NULL);
|
||||
litest_assert(abs != NULL);
|
||||
|
||||
nelem = 0;
|
||||
while (orig[nelem].value != -1) {
|
||||
abs[nelem] = orig[nelem];
|
||||
nelem++;
|
||||
ck_assert_int_lt(nelem, sz);
|
||||
litest_assert_int_lt(nelem, sz);
|
||||
}
|
||||
|
||||
/* just append, if the same axis is present twice, libevdev will
|
||||
|
|
@ -547,10 +684,10 @@ merge_absinfo(const struct input_absinfo *orig,
|
|||
i = 0;
|
||||
while (override && override[i].value != -1) {
|
||||
abs[nelem++] = override[i++];
|
||||
ck_assert_int_lt(nelem, sz);
|
||||
litest_assert_int_lt(nelem, sz);
|
||||
}
|
||||
|
||||
ck_assert_int_lt(nelem, sz);
|
||||
litest_assert_int_lt(nelem, sz);
|
||||
abs[nelem].value = -1;
|
||||
|
||||
return abs;
|
||||
|
|
@ -567,13 +704,13 @@ merge_events(const int *orig, const int *override)
|
|||
return NULL;
|
||||
|
||||
events = calloc(sz, sizeof(int));
|
||||
ck_assert(events != NULL);
|
||||
litest_assert(events != NULL);
|
||||
|
||||
nelem = 0;
|
||||
while (orig[nelem] != -1) {
|
||||
events[nelem] = orig[nelem];
|
||||
nelem++;
|
||||
ck_assert_int_lt(nelem, sz);
|
||||
litest_assert_int_lt(nelem, sz);
|
||||
}
|
||||
|
||||
/* just append, if the same axis is present twice, libevdev will
|
||||
|
|
@ -581,10 +718,10 @@ merge_events(const int *orig, const int *override)
|
|||
i = 0;
|
||||
while (override && override[i] != -1) {
|
||||
events[nelem++] = override[i++];
|
||||
ck_assert_int_le(nelem, sz);
|
||||
litest_assert_int_le(nelem, sz);
|
||||
}
|
||||
|
||||
ck_assert_int_lt(nelem, sz);
|
||||
litest_assert_int_lt(nelem, sz);
|
||||
events[nelem] = -1;
|
||||
|
||||
return events;
|
||||
|
|
@ -610,14 +747,14 @@ litest_init_udev_rules(struct litest_test_device *dev)
|
|||
UDEV_RULES_D,
|
||||
UDEV_RULE_PREFIX,
|
||||
dev->shortname);
|
||||
ck_assert_int_eq(rc,
|
||||
(int)(
|
||||
strlen(UDEV_RULES_D) +
|
||||
strlen(UDEV_RULE_PREFIX) +
|
||||
strlen(dev->shortname) + 7));
|
||||
litest_assert_int_eq(rc,
|
||||
(int)(
|
||||
strlen(UDEV_RULES_D) +
|
||||
strlen(UDEV_RULE_PREFIX) +
|
||||
strlen(dev->shortname) + 7));
|
||||
f = fopen(path, "w");
|
||||
ck_assert_notnull(f);
|
||||
ck_assert_int_ge(fputs(dev->udev_rule, f), 0);
|
||||
litest_assert_notnull(f);
|
||||
litest_assert_int_ge(fputs(dev->udev_rule, f), 0);
|
||||
fclose(f);
|
||||
|
||||
litest_reload_udev_rules();
|
||||
|
|
@ -651,7 +788,7 @@ litest_create(enum litest_device_type which,
|
|||
ck_abort_msg("Invalid device type %d\n", which);
|
||||
|
||||
d = zalloc(sizeof(*d));
|
||||
ck_assert(d != NULL);
|
||||
litest_assert(d != NULL);
|
||||
|
||||
udev_file = litest_init_udev_rules(*dev);
|
||||
|
||||
|
|
@ -661,8 +798,7 @@ litest_create(enum litest_device_type which,
|
|||
if (abs_override || events_override) {
|
||||
if (udev_file)
|
||||
unlink(udev_file);
|
||||
ck_abort_msg("Custom create cannot"
|
||||
"be overridden");
|
||||
litest_abort_msg("Custom create cannot be overridden");
|
||||
}
|
||||
|
||||
return d;
|
||||
|
|
@ -691,7 +827,7 @@ litest_create_context(void)
|
|||
{
|
||||
struct libinput *libinput =
|
||||
libinput_path_create_context(&interface, NULL);
|
||||
ck_assert_notnull(libinput);
|
||||
litest_assert_notnull(libinput);
|
||||
|
||||
libinput_log_set_handler(libinput, litest_log_handler);
|
||||
if (verbose)
|
||||
|
|
@ -732,16 +868,16 @@ litest_add_device_with_overrides(struct libinput *libinput,
|
|||
events_override);
|
||||
|
||||
path = libevdev_uinput_get_devnode(d->uinput);
|
||||
ck_assert(path != NULL);
|
||||
litest_assert(path != NULL);
|
||||
fd = open(path, O_RDWR|O_NONBLOCK);
|
||||
ck_assert_int_ne(fd, -1);
|
||||
litest_assert_int_ne(fd, -1);
|
||||
|
||||
rc = libevdev_new_from_fd(fd, &d->evdev);
|
||||
ck_assert_int_eq(rc, 0);
|
||||
litest_assert_int_eq(rc, 0);
|
||||
|
||||
d->libinput = libinput;
|
||||
d->libinput_device = libinput_path_add_device(d->libinput, path);
|
||||
ck_assert(d->libinput_device != NULL);
|
||||
litest_assert(d->libinput_device != NULL);
|
||||
libinput_device_ref(d->libinput_device);
|
||||
|
||||
if (d->interface) {
|
||||
|
|
@ -836,7 +972,7 @@ litest_event(struct litest_device *d, unsigned int type,
|
|||
return;
|
||||
|
||||
ret = libevdev_uinput_write_event(d->uinput, type, code, value);
|
||||
ck_assert_int_eq(ret, 0);
|
||||
litest_assert_int_eq(ret, 0);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -1169,9 +1305,9 @@ int
|
|||
litest_scale(const struct litest_device *d, unsigned int axis, double val)
|
||||
{
|
||||
int min, max;
|
||||
ck_assert_int_ge((int)val, 0);
|
||||
ck_assert_int_le((int)val, 100);
|
||||
ck_assert_int_le(axis, (unsigned int)ABS_Y);
|
||||
litest_assert_int_ge((int)val, 0);
|
||||
litest_assert_int_le((int)val, 100);
|
||||
litest_assert_int_le(axis, (unsigned int)ABS_Y);
|
||||
|
||||
min = d->interface->min[axis];
|
||||
max = d->interface->max[axis];
|
||||
|
|
@ -1352,7 +1488,7 @@ litest_assert_empty_queue(struct libinput *li)
|
|||
libinput_dispatch(li);
|
||||
}
|
||||
|
||||
ck_assert(empty_queue);
|
||||
litest_assert(empty_queue);
|
||||
}
|
||||
|
||||
struct libevdev_uinput *
|
||||
|
|
@ -1378,7 +1514,7 @@ litest_create_uinput_device_from_description(const char *name,
|
|||
const char *devnode;
|
||||
|
||||
dev = libevdev_new();
|
||||
ck_assert(dev != NULL);
|
||||
litest_assert(dev != NULL);
|
||||
|
||||
snprintf(buf, sizeof(buf), "litest %s", name);
|
||||
libevdev_set_name(dev, buf);
|
||||
|
|
@ -1393,7 +1529,7 @@ litest_create_uinput_device_from_description(const char *name,
|
|||
while (abs && abs->value != -1) {
|
||||
rc = libevdev_enable_event_code(dev, EV_ABS,
|
||||
abs->value, abs);
|
||||
ck_assert_int_eq(rc, 0);
|
||||
litest_assert_int_eq(rc, 0);
|
||||
abs++;
|
||||
}
|
||||
|
||||
|
|
@ -1406,7 +1542,7 @@ litest_create_uinput_device_from_description(const char *name,
|
|||
rc = libevdev_enable_event_code(dev, type, code,
|
||||
type == EV_ABS ? &default_abs : NULL);
|
||||
}
|
||||
ck_assert_int_eq(rc, 0);
|
||||
litest_assert_int_eq(rc, 0);
|
||||
}
|
||||
|
||||
rc = libevdev_uinput_create_from_device(dev,
|
||||
|
|
@ -1416,16 +1552,16 @@ litest_create_uinput_device_from_description(const char *name,
|
|||
http://cgit.freedesktop.org/libevdev/commit/?id=debe9b030c8069cdf78307888ef3b65830b25122 */
|
||||
if (rc == -EBADF)
|
||||
rc = -EACCES;
|
||||
ck_assert_msg(rc == 0, "Failed to create uinput device: %s", strerror(-rc));
|
||||
litest_assert_msg(rc == 0, "Failed to create uinput device: %s", strerror(-rc));
|
||||
|
||||
libevdev_free(dev);
|
||||
|
||||
devnode = libevdev_uinput_get_devnode(uinput);
|
||||
ck_assert_notnull(devnode);
|
||||
litest_assert_notnull(devnode);
|
||||
fd = open(devnode, O_RDONLY);
|
||||
ck_assert_int_gt(fd, -1);
|
||||
litest_assert_int_gt(fd, -1);
|
||||
rc = libevdev_new_from_fd(fd, &dev);
|
||||
ck_assert_int_eq(rc, 0);
|
||||
litest_assert_int_eq(rc, 0);
|
||||
|
||||
/* uinput does not yet support setting the resolution, so we set it
|
||||
* afterwards. This is of course racy as hell but the way we
|
||||
|
|
@ -1437,7 +1573,7 @@ litest_create_uinput_device_from_description(const char *name,
|
|||
rc = libevdev_kernel_set_abs_info(dev,
|
||||
abs->value,
|
||||
abs);
|
||||
ck_assert_int_eq(rc, 0);
|
||||
litest_assert_int_eq(rc, 0);
|
||||
}
|
||||
abs++;
|
||||
}
|
||||
|
|
@ -1461,7 +1597,7 @@ litest_create_uinput_abs_device_v(const char *name,
|
|||
(code = va_arg(args, int)) != -1) {
|
||||
*event++ = type;
|
||||
*event++ = code;
|
||||
ck_assert(event < &events[ARRAY_LENGTH(events) - 2]);
|
||||
litest_assert(event < &events[ARRAY_LENGTH(events) - 2]);
|
||||
}
|
||||
|
||||
*event++ = -1;
|
||||
|
|
@ -1508,13 +1644,13 @@ litest_is_button_event(struct libinput_event *event,
|
|||
struct libinput_event_pointer *ptrev;
|
||||
enum libinput_event_type type = LIBINPUT_EVENT_POINTER_BUTTON;
|
||||
|
||||
ck_assert(event != NULL);
|
||||
ck_assert_int_eq(libinput_event_get_type(event), type);
|
||||
litest_assert(event != NULL);
|
||||
litest_assert_int_eq(libinput_event_get_type(event), type);
|
||||
ptrev = libinput_event_get_pointer_event(event);
|
||||
ck_assert_int_eq(libinput_event_pointer_get_button(ptrev),
|
||||
button);
|
||||
ck_assert_int_eq(libinput_event_pointer_get_button_state(ptrev),
|
||||
state);
|
||||
litest_assert_int_eq(libinput_event_pointer_get_button(ptrev),
|
||||
button);
|
||||
litest_assert_int_eq(libinput_event_pointer_get_button_state(ptrev),
|
||||
state);
|
||||
|
||||
return ptrev;
|
||||
}
|
||||
|
|
@ -1527,14 +1663,14 @@ litest_is_axis_event(struct libinput_event *event,
|
|||
struct libinput_event_pointer *ptrev;
|
||||
enum libinput_event_type type = LIBINPUT_EVENT_POINTER_AXIS;
|
||||
|
||||
ck_assert(event != NULL);
|
||||
ck_assert_int_eq(libinput_event_get_type(event), type);
|
||||
litest_assert(event != NULL);
|
||||
litest_assert_int_eq(libinput_event_get_type(event), type);
|
||||
ptrev = libinput_event_get_pointer_event(event);
|
||||
ck_assert(libinput_event_pointer_has_axis(ptrev, axis));
|
||||
litest_assert(libinput_event_pointer_has_axis(ptrev, axis));
|
||||
|
||||
if (source != 0)
|
||||
ck_assert_int_eq(libinput_event_pointer_get_axis_source(ptrev),
|
||||
source);
|
||||
litest_assert_int_eq(libinput_event_pointer_get_axis_source(ptrev),
|
||||
source);
|
||||
|
||||
return ptrev;
|
||||
}
|
||||
|
|
@ -1546,8 +1682,8 @@ litest_is_motion_event(struct libinput_event *event)
|
|||
enum libinput_event_type type = LIBINPUT_EVENT_POINTER_MOTION;
|
||||
double x, y, ux, uy;
|
||||
|
||||
ck_assert(event != NULL);
|
||||
ck_assert_int_eq(libinput_event_get_type(event), type);
|
||||
litest_assert(event != NULL);
|
||||
litest_assert_int_eq(libinput_event_get_type(event), type);
|
||||
ptrev = libinput_event_get_pointer_event(event);
|
||||
|
||||
x = libinput_event_pointer_get_dx(ptrev);
|
||||
|
|
@ -1556,8 +1692,8 @@ litest_is_motion_event(struct libinput_event *event)
|
|||
uy = libinput_event_pointer_get_dy_unaccelerated(ptrev);
|
||||
|
||||
/* No 0 delta motion events */
|
||||
ck_assert(x != 0.0 || y != 0.0 ||
|
||||
ux != 0.0 || uy != 0.0);
|
||||
litest_assert(x != 0.0 || y != 0.0 ||
|
||||
ux != 0.0 || uy != 0.0);
|
||||
|
||||
return ptrev;
|
||||
}
|
||||
|
|
@ -1582,7 +1718,7 @@ litest_is_touch_event(struct libinput_event *event,
|
|||
{
|
||||
struct libinput_event_touch *touch;
|
||||
|
||||
ck_assert(event != NULL);
|
||||
litest_assert(event != NULL);
|
||||
|
||||
if (type == 0)
|
||||
type = libinput_event_get_type(event);
|
||||
|
|
@ -1592,7 +1728,7 @@ litest_is_touch_event(struct libinput_event *event,
|
|||
case LIBINPUT_EVENT_TOUCH_UP:
|
||||
case LIBINPUT_EVENT_TOUCH_MOTION:
|
||||
case LIBINPUT_EVENT_TOUCH_FRAME:
|
||||
ck_assert_int_eq(libinput_event_get_type(event), type);
|
||||
litest_assert_int_eq(libinput_event_get_type(event), type);
|
||||
break;
|
||||
default:
|
||||
ck_abort_msg("%s: invalid touch type %d\n", __func__, type);
|
||||
|
|
@ -1611,15 +1747,15 @@ litest_is_keyboard_event(struct libinput_event *event,
|
|||
struct libinput_event_keyboard *kevent;
|
||||
enum libinput_event_type type = LIBINPUT_EVENT_KEYBOARD_KEY;
|
||||
|
||||
ck_assert_notnull(event);
|
||||
ck_assert_int_eq(libinput_event_get_type(event), type);
|
||||
litest_assert(event != NULL);
|
||||
litest_assert_int_eq(libinput_event_get_type(event), type);
|
||||
|
||||
kevent = libinput_event_get_keyboard_event(event);
|
||||
ck_assert_notnull(kevent);
|
||||
litest_assert(kevent != NULL);
|
||||
|
||||
ck_assert_int_eq(libinput_event_keyboard_get_key(kevent), key);
|
||||
ck_assert_int_eq(libinput_event_keyboard_get_key_state(kevent),
|
||||
state);
|
||||
litest_assert_int_eq(libinput_event_keyboard_get_key(kevent), key);
|
||||
litest_assert_int_eq(libinput_event_keyboard_get_key_state(kevent),
|
||||
state);
|
||||
return kevent;
|
||||
}
|
||||
|
||||
|
|
@ -1634,7 +1770,7 @@ litest_assert_scroll(struct libinput *li,
|
|||
|
||||
event = libinput_get_event(li);
|
||||
next_event = libinput_get_event(li);
|
||||
ck_assert(next_event != NULL); /* At least 1 scroll + stop scroll */
|
||||
litest_assert(next_event != NULL); /* At least 1 scroll + stop scroll */
|
||||
|
||||
while (event) {
|
||||
ptrev = litest_is_axis_event(event, axis, 0);
|
||||
|
|
@ -1644,13 +1780,13 @@ litest_assert_scroll(struct libinput *li,
|
|||
axis);
|
||||
/* Normal scroll event, check dir */
|
||||
if (minimum_movement > 0) {
|
||||
ck_assert_int_ge(value, minimum_movement);
|
||||
litest_assert_int_ge(value, minimum_movement);
|
||||
} else {
|
||||
ck_assert_int_le(value, minimum_movement);
|
||||
litest_assert_int_le(value, minimum_movement);
|
||||
}
|
||||
} else {
|
||||
/* Last scroll event, must be 0 */
|
||||
ck_assert_int_eq(
|
||||
litest_assert_int_eq(
|
||||
libinput_event_pointer_get_axis_value(ptrev, axis),
|
||||
0);
|
||||
}
|
||||
|
|
@ -1670,11 +1806,11 @@ litest_assert_only_typed_events(struct libinput *li,
|
|||
|
||||
libinput_dispatch(li);
|
||||
event = libinput_get_event(li);
|
||||
ck_assert_notnull(event);
|
||||
litest_assert_notnull(event);
|
||||
|
||||
while (event) {
|
||||
ck_assert_int_eq(libinput_event_get_type(event),
|
||||
type);
|
||||
litest_assert_int_eq(libinput_event_get_type(event),
|
||||
type);
|
||||
libinput_event_destroy(event);
|
||||
libinput_dispatch(li);
|
||||
event = libinput_get_event(li);
|
||||
|
|
|
|||
|
|
@ -32,6 +32,62 @@
|
|||
#include <libevdev/libevdev.h>
|
||||
#include <libevdev/libevdev-uinput.h>
|
||||
#include <libinput.h>
|
||||
#include <math.h>
|
||||
|
||||
#define litest_assert(cond) \
|
||||
do { \
|
||||
if (!(cond)) \
|
||||
litest_fail_condition(__FILE__, __LINE__, __func__, \
|
||||
#cond, NULL); \
|
||||
} while(0)
|
||||
|
||||
#define litest_assert_msg(cond, ...) \
|
||||
do { \
|
||||
if (!(cond)) \
|
||||
litest_fail_condition(__FILE__, __LINE__, __func__, \
|
||||
#cond, __VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
#define litest_abort_msg(...) \
|
||||
litest_fail_condition(__FILE__, __LINE__, __func__, \
|
||||
"aborting", __VA_ARGS__); \
|
||||
|
||||
#define litest_assert_notnull(cond) \
|
||||
do { \
|
||||
if ((cond) == NULL) \
|
||||
litest_fail_condition(__FILE__, __LINE__, __func__, \
|
||||
#cond, " expected to be not NULL"); \
|
||||
} while(0)
|
||||
|
||||
#define litest_assert_comparison_int_(a_, op_, b_) \
|
||||
do { \
|
||||
__typeof__(a_) _a = a_; \
|
||||
__typeof__(b_) _b = b_; \
|
||||
if (trunc(_a) != _a || trunc(_b) != _b) \
|
||||
litest_abort_msg("litest_assert_int_* used for non-integer value\n"); \
|
||||
if (!((_a) op_ (_b))) \
|
||||
litest_fail_comparison_int(__FILE__, __LINE__, __func__,\
|
||||
#op_, _a, _b, \
|
||||
#a_, #b_); \
|
||||
} while(0)
|
||||
|
||||
#define litest_assert_int_eq(a_, b_) \
|
||||
litest_assert_comparison_int_(a_, ==, b_)
|
||||
|
||||
#define litest_assert_int_ne(a_, b_) \
|
||||
litest_assert_comparison_int_(a_, !=, b_)
|
||||
|
||||
#define litest_assert_int_lt(a_, b_) \
|
||||
litest_assert_comparison_int_(a_, <, b_)
|
||||
|
||||
#define litest_assert_int_le(a_, b_) \
|
||||
litest_assert_comparison_int_(a_, <=, b_)
|
||||
|
||||
#define litest_assert_int_ge(a_, b_) \
|
||||
litest_assert_comparison_int_(a_, >=, b_)
|
||||
|
||||
#define litest_assert_int_gt(a_, b_) \
|
||||
litest_assert_comparison_int_(a_, >, b_)
|
||||
|
||||
enum litest_device_type {
|
||||
LITEST_NO_DEVICE = -1,
|
||||
|
|
@ -109,6 +165,23 @@ struct libinput *litest_create_context(void);
|
|||
void litest_disable_log_handler(struct libinput *libinput);
|
||||
void litest_restore_log_handler(struct libinput *libinput);
|
||||
|
||||
void
|
||||
litest_fail_condition(const char *file,
|
||||
int line,
|
||||
const char *func,
|
||||
const char *condition,
|
||||
const char *message,
|
||||
...);
|
||||
void
|
||||
litest_fail_comparison_int(const char *file,
|
||||
int line,
|
||||
const char *func,
|
||||
const char *operator,
|
||||
int a,
|
||||
int b,
|
||||
const char *astr,
|
||||
const char *bstr);
|
||||
|
||||
void litest_add(const char *name, void *func,
|
||||
enum litest_device_feature required_feature,
|
||||
enum litest_device_feature excluded_feature);
|
||||
|
|
|
|||
|
|
@ -13,3 +13,11 @@
|
|||
...
|
||||
fun:mtdev_put_event
|
||||
}
|
||||
{
|
||||
libunwind:msync_uninitialized_bytes
|
||||
Memcheck:Param
|
||||
msync(start)
|
||||
fun:__msync_nocancel
|
||||
...
|
||||
fun:litest_backtrace
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue