diff --git a/configure.ac b/configure.ac index cdde4fae..75951fda 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 0df89b2c..a36d3681 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 00000000..5ed20ffe --- /dev/null +++ b/test/litest-selftest.c @@ -0,0 +1,228 @@ +#include + +#include +#include + +#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 aae2663e..e91e499f 100644 --- a/test/litest.c +++ b/test/litest.c @@ -1,5 +1,6 @@ /* * Copyright © 2013 Red Hat, Inc. + * Copyright © 2013 Marcin Slusarz * * 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 +#include + +/* 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); diff --git a/test/litest.h b/test/litest.h index 38d3c1b6..80ced698 100644 --- a/test/litest.h +++ b/test/litest.h @@ -32,6 +32,62 @@ #include #include #include +#include + +#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); diff --git a/test/valgrind.suppressions b/test/valgrind.suppressions index 5aef8a41..50b5c58a 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 +}