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 <[email protected]>
Signed-off-by: Peter Hutterer <[email protected]>
---
 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 <[email protected]>
  *
  * 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

_______________________________________________
wayland-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to