[PATCH 4/7] test: add a backtrace facility to litest
Peter Hutterer
peter.hutterer at who-t.net
Thu May 7 22:57:47 PDT 2015
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 at gmail.com>
Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
configure.ac | 10 ++
test/Makefile.am | 16 ++-
test/litest-selftest.c | 228 +++++++++++++++++++++++++++++++++++++
test/litest.c | 272 +++++++++++++++++++++++++++++++++------------
test/litest.h | 73 ++++++++++++
test/valgrind.suppressions | 8 ++
6 files changed, 537 insertions(+), 70 deletions(-)
create mode 100644 test/litest-selftest.c
diff --git a/configure.ac b/configure.ac
index cdde4fa..75951fd 100644
--- a/configure.ac
+++ b/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}
])
diff --git a/test/Makefile.am b/test/Makefile.am
index 0df89b2..a36d368 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -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
diff --git a/test/litest-selftest.c b/test/litest-selftest.c
new file mode 100644
index 0000000..5ed20ff
--- /dev/null
+++ b/test/litest-selftest.c
@@ -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;
+}
diff --git a/test/litest.c b/test/litest.c
index 355c591..f284d22 100644
--- a/test/litest.c
+++ b/test/litest.c
@@ -1,5 +1,6 @@
/*
* Copyright © 2013 Red Hat, Inc.
+ * Copyright © 2013 Marcin Slusarz <marcin.slusarz at 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;
@@ -326,7 +463,7 @@ litest_add_for_device(const char *name,
dev++;
}
- ck_abort_msg("Invalid test device type");
+ litest_abort_msg("Invalid test device type");
}
static int
@@ -489,13 +626,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
@@ -503,10 +640,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;
@@ -523,13 +660,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
@@ -537,10 +674,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;
@@ -566,14 +703,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();
@@ -607,7 +744,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);
@@ -617,8 +754,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;
@@ -647,7 +783,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)
@@ -688,16 +824,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) {
@@ -792,7 +928,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
@@ -1125,9 +1261,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];
@@ -1308,7 +1444,7 @@ litest_assert_empty_queue(struct libinput *li)
libinput_dispatch(li);
}
- ck_assert(empty_queue);
+ litest_assert(empty_queue);
}
struct libevdev_uinput *
@@ -1334,7 +1470,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);
@@ -1349,7 +1485,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++;
}
@@ -1362,7 +1498,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,
@@ -1372,16 +1508,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
@@ -1393,7 +1529,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++;
}
@@ -1417,7 +1553,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;
@@ -1464,13 +1600,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;
}
@@ -1483,14 +1619,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;
}
@@ -1502,8 +1638,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);
@@ -1512,8 +1648,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;
}
@@ -1538,7 +1674,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);
@@ -1548,7 +1684,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);
@@ -1567,15 +1703,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;
}
@@ -1590,7 +1726,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);
@@ -1600,13 +1736,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);
}
@@ -1626,11 +1762,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);
diff --git a/test/litest.h b/test/litest.h
index 664b49a..f13ea7e 100644
--- a/test/litest.h
+++ b/test/litest.h
@@ -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,
@@ -101,6 +157,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);
diff --git a/test/valgrind.suppressions b/test/valgrind.suppressions
index 5aef8a4..50b5c58 100644
--- a/test/valgrind.suppressions
+++ b/test/valgrind.suppressions
@@ -13,3 +13,11 @@
...
fun:mtdev_put_event
}
+{
+ libunwind:msync_uninitialized_bytes
+ Memcheck:Param
+ msync(start)
+ fun:__msync_nocancel
+ ...
+ fun:litest_backtrace
+}
--
2.3.5
More information about the wayland-devel
mailing list