Merge branch 'litest-backtrace'

This commit is contained in:
Peter Hutterer 2015-05-21 11:05:45 +10:00
commit ed5d43da36
11 changed files with 833 additions and 101 deletions

View file

@ -60,6 +60,20 @@ 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_PATH_PROG(ADDR2LINE, [addr2line])
if test "x$ADDR2LINE" != "x"; then
AC_DEFINE_UNQUOTED(HAVE_ADDR2LINE, 1, [addr2line found])
AC_DEFINE_UNQUOTED(ADDR2LINE, ["$ADDR2LINE"], [Path to addr2line])
fi
AC_CHECK_LIB([m], [atan2])
AC_CHECK_LIB([rt], [clock_gettime])
@ -190,5 +204,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}
])

View file

@ -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
@ -127,7 +139,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

View file

@ -830,7 +830,7 @@ assert_device_ignored(struct libinput *li, struct input_absinfo *absinfo)
-1);
device = libinput_path_add_device(li,
libevdev_uinput_get_devnode(uinput));
ck_assert(device == NULL);
litest_assert_ptr_null(device);
libevdev_uinput_destroy(uinput);
}

369
test/litest-selftest.c Normal file
View file

@ -0,0 +1,369 @@
#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
START_TEST(litest_ptr_eq_notrigger)
{
int v = 10;
int *a = &v;
int *b = &v;
int c = NULL;
int d = NULL;
litest_assert_ptr_eq(a, b);
litest_assert_ptr_eq(c, d);
}
END_TEST
START_TEST(litest_ptr_eq_trigger)
{
int v = 10;
int v2 = 11;
int *a = &v;
int *b = &v2;
litest_assert_ptr_eq(a, b);
}
END_TEST
START_TEST(litest_ptr_eq_trigger_NULL)
{
int v = 10;
int *a = &v;
int *b = NULL;
litest_assert_ptr_eq(a, b);
}
END_TEST
START_TEST(litest_ptr_eq_trigger_NULL2)
{
int v = 10;
int *a = &v;
int *b = NULL;
litest_assert_ptr_eq(b, a);
}
END_TEST
START_TEST(litest_ptr_ne_trigger)
{
int v = 10;
int *a = &v;
int *b = &v;
litest_assert_ptr_ne(a, b);
}
END_TEST
START_TEST(litest_ptr_ne_trigger_NULL)
{
int *a = NULL;
litest_assert_ptr_ne(a, NULL);
}
END_TEST
START_TEST(litest_ptr_ne_trigger_NULL2)
{
int *a = NULL;
litest_assert_ptr_ne(NULL, a);
}
END_TEST
START_TEST(litest_ptr_ne_notrigger)
{
int v1 = 10;
int v2 = 10;
int *a = &v1;
int *b = &v2;
int *c = NULL;
litest_assert_ptr_ne(a, b);
litest_assert_ptr_ne(a, c);
litest_assert_ptr_ne(c, b);
}
END_TEST
START_TEST(litest_ptr_null_notrigger)
{
int *a = NULL;
litest_assert_ptr_null(a);
litest_assert_ptr_null(NULL);
}
END_TEST
START_TEST(litest_ptr_null_trigger)
{
int v;
int *a = &v;
litest_assert_ptr_null(a);
}
END_TEST
START_TEST(litest_ptr_notnull_notrigger)
{
int v;
int *a = &v;
litest_assert_ptr_notnull(a);
}
END_TEST
START_TEST(litest_ptr_notnull_trigger)
{
int *a = NULL;
litest_assert_ptr_notnull(a);
}
END_TEST
START_TEST(litest_ptr_notnull_trigger_NULL)
{
litest_assert_ptr_notnull(NULL);
}
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);
tc = tcase_create("pointer comparison ");
tcase_add_test_raise_signal(tc, litest_ptr_eq_trigger, SIGABRT);
tcase_add_test_raise_signal(tc, litest_ptr_eq_trigger_NULL, SIGABRT);
tcase_add_test_raise_signal(tc, litest_ptr_eq_trigger_NULL2, SIGABRT);
tcase_add_test(tc, litest_ptr_eq_notrigger);
tcase_add_test_raise_signal(tc, litest_ptr_ne_trigger, SIGABRT);
tcase_add_test_raise_signal(tc, litest_ptr_ne_trigger_NULL, SIGABRT);
tcase_add_test_raise_signal(tc, litest_ptr_ne_trigger_NULL2, SIGABRT);
tcase_add_test(tc, litest_ptr_ne_notrigger);
tcase_add_test_raise_signal(tc, litest_ptr_null_trigger, SIGABRT);
tcase_add_test(tc, litest_ptr_null_notrigger);
tcase_add_test_raise_signal(tc, litest_ptr_notnull_trigger, SIGABRT);
tcase_add_test_raise_signal(tc, litest_ptr_notnull_trigger_NULL, SIGABRT);
tcase_add_test(tc, litest_ptr_notnull_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;
}

View file

@ -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,234 @@
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 char cwd[PATH_MAX];
static bool
litest_backtrace_get_lineno(const char *executable,
unw_word_t addr,
char *file_return,
int *line_return)
{
#if HAVE_ADDR2LINE
FILE* f;
char buffer[PATH_MAX];
char *s;
int i;
if (!cwd[0])
getcwd(cwd, sizeof(cwd));
sprintf (buffer,
ADDR2LINE " -C -e %s -i %lx",
executable,
(unsigned long) addr);
f = popen(buffer, "r");
if (f == NULL) {
litest_log("Failed to execute: %s\n", buffer);
return false;
}
buffer[0] = '?';
fgets(buffer, sizeof(buffer), f);
fclose(f);
if (buffer[0] == '?')
return false;
s = strrchr(buffer, ':');
if (!s)
return false;
*s = '\0';
s++;
sscanf(s, "%d", line_return);
/* now strip cwd from buffer */
s = buffer;
i = 0;
while(cwd[i] == *s) {
*s = '\0';
s++;
i++;
}
if (i > 0)
*(--s) = '.';
strcpy(file_return, s);
return true;
#else /* HAVE_ADDR2LINE */
return false;
#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) {
char file[PATH_MAX];
int line;
bool have_lineno = false;
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;
have_lineno = litest_backtrace_get_lineno(filename,
(pip.start_ip + off),
file,
&line);
} else {
filename = "?";
}
if (have_lineno) {
litest_log("%u: %s() (%s:%d)\n",
i,
procname,
file,
line);
} else {
litest_log("%u: %s (%s%s+%#x) [%p]\n",
i,
filename,
procname,
ret == -UNW_ENOMEM ? "..." : "",
(int)off,
(void *)(pip.start_ip + off));
}
i++;
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();
}
void
litest_fail_comparison_ptr(const char *file,
int line,
const char *func,
const char *comparison)
{
litest_log("FAILED COMPARISON: %s\n", comparison);
litest_log("in %s() (%s:%d)\n", func, file, line);
litest_backtrace();
abort();
}
struct test {
struct list node;
char *name;
@ -372,7 +601,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
@ -539,13 +768,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
@ -553,10 +782,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;
@ -573,13 +802,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
@ -587,10 +816,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;
@ -616,13 +845,14 @@ litest_init_udev_rules(struct litest_test_device *dev)
UDEV_RULES_D,
UDEV_RULE_PREFIX,
dev->shortname);
ck_assert_int_eq(rc,
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();
@ -656,7 +886,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);
@ -666,8 +896,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;
@ -696,7 +925,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)
@ -737,16 +966,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) {
@ -841,7 +1070,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
@ -1174,9 +1403,9 @@ int
litest_scale(const struct litest_device *d, unsigned int axis, double val)
{
int min, max;
ck_assert_int_ge(val, 0);
ck_assert_int_le(val, 100);
ck_assert_int_le(axis, 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];
@ -1357,7 +1586,7 @@ litest_assert_empty_queue(struct libinput *li)
libinput_dispatch(li);
}
ck_assert(empty_queue);
litest_assert(empty_queue);
}
struct libevdev_uinput *
@ -1383,7 +1612,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);
@ -1398,7 +1627,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++;
}
@ -1411,7 +1640,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,
@ -1421,16 +1650,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
@ -1442,7 +1671,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++;
}
@ -1466,7 +1695,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;
@ -1511,15 +1740,15 @@ litest_is_button_event(struct libinput_event *event,
enum libinput_button_state state)
{
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),
LIBINPUT_EVENT_POINTER_BUTTON);
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;
}
@ -1532,14 +1761,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;
}
@ -1551,8 +1780,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);
@ -1561,8 +1790,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;
}
@ -1587,7 +1816,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);
@ -1597,7 +1826,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);
@ -1616,15 +1845,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;
}
@ -1635,30 +1864,27 @@ litest_assert_scroll(struct libinput *li,
{
struct libinput_event *event, *next_event;
struct libinput_event_pointer *ptrev;
int value;
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);
if (next_event) {
value = libinput_event_pointer_get_axis_value(ptrev,
axis);
/* Normal scroll event, check dir */
if (minimum_movement > 0) {
ck_assert_int_ge(
libinput_event_pointer_get_axis_value(ptrev,
axis),
minimum_movement);
litest_assert_int_ge(value, minimum_movement);
} else {
ck_assert_int_le(
libinput_event_pointer_get_axis_value(ptrev,
axis),
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);
}
@ -1678,11 +1904,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);

View file

@ -32,6 +32,83 @@
#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_)
#define litest_assert_comparison_ptr_(a_, op_, b_) \
do { \
__typeof__(a_) _a = a_; \
__typeof__(b_) _b = b_; \
if (!((_a) op_ (_b))) \
litest_fail_comparison_ptr(__FILE__, __LINE__, __func__,\
#a_ " " #op_ " " #b_); \
} while(0)
#define litest_assert_ptr_eq(a_, b_) \
litest_assert_comparison_ptr_(a_, ==, b_)
#define litest_assert_ptr_ne(a_, b_) \
litest_assert_comparison_ptr_(a_, !=, b_)
#define litest_assert_ptr_null(a_) \
litest_assert_comparison_ptr_(a_, ==, NULL)
#define litest_assert_ptr_notnull(a_) \
litest_assert_comparison_ptr_(a_, !=, NULL)
enum litest_device_type {
LITEST_NO_DEVICE = -1,
@ -109,6 +186,28 @@ 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_fail_comparison_ptr(const char *file,
int line,
const char *func,
const char *comparison);
void litest_add(const char *name, void *func,
enum litest_device_feature required_feature,
enum litest_device_feature excluded_feature);

View file

@ -57,8 +57,8 @@ simple_log_handler(struct libinput *libinput,
{
log_handler_called++;
if (log_handler_context)
ck_assert(libinput == log_handler_context);
ck_assert(format != NULL);
litest_assert_ptr_eq(libinput, log_handler_context);
litest_assert_notnull(format);
}
START_TEST(log_default_priority)

View file

@ -64,7 +64,7 @@ create_simple_test_device(const char *name, ...)
};
evdev = libevdev_new();
ck_assert(evdev != NULL);
litest_assert_notnull(evdev);
libevdev_set_name(evdev, name);
va_start(args, name);
@ -82,7 +82,7 @@ create_simple_test_device(const char *name, ...)
rc = libevdev_uinput_create_from_device(evdev,
LIBEVDEV_UINPUT_OPEN_MANAGED,
&uinput);
ck_assert_int_eq(rc, 0);
litest_assert_int_eq(rc, 0);
libevdev_free(evdev);
return uinput;

View file

@ -53,7 +53,7 @@ get_accelerated_motion_event(struct libinput *li)
return ptrev;
}
ck_abort_msg("No accelerated pointer motion event found");
litest_abort_msg("No accelerated pointer motion event found");
return NULL;
}
@ -90,11 +90,11 @@ test_relative_event(struct litest_device *dev, int dx, int dy)
actual_dir = atan2(ev_dx, ev_dy);
/* Check the length of the motion vector (tolerate 1.0 indifference). */
ck_assert(fabs(expected_length) >= actual_length);
litest_assert(fabs(expected_length) >= actual_length);
/* Check the direction of the motion vector (tolerate 2π/4 radians
* indifference). */
ck_assert(fabs(expected_dir - actual_dir) < M_PI_2);
litest_assert(fabs(expected_dir - actual_dir) < M_PI_2);
libinput_event_destroy(libinput_event_pointer_get_base_event(ptrev));
@ -105,12 +105,14 @@ static void
disable_button_scrolling(struct litest_device *device)
{
struct libinput_device *dev = device->libinput_device;
enum libinput_config_status status;
enum libinput_config_status status,
expected;
status = libinput_device_config_scroll_set_method(dev,
LIBINPUT_CONFIG_SCROLL_NO_SCROLL);
ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
expected = LIBINPUT_CONFIG_STATUS_SUCCESS;
litest_assert_int_eq(status, expected);
}
START_TEST(pointer_motion_relative)
@ -138,22 +140,22 @@ test_absolute_event(struct litest_device *dev, double x, double y)
struct libinput_event *event;
struct libinput_event_pointer *ptrev;
double ex, ey;
enum libinput_event_type type = LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE;
litest_touch_down(dev, 0, x, y);
libinput_dispatch(li);
event = libinput_get_event(li);
ck_assert_notnull(event);
ck_assert_int_eq(libinput_event_get_type(event),
LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE);
litest_assert_notnull(event);
litest_assert_int_eq(libinput_event_get_type(event), type);
ptrev = libinput_event_get_pointer_event(event);
ck_assert(ptrev != NULL);
litest_assert(ptrev != NULL);
ex = libinput_event_pointer_get_absolute_x_transformed(ptrev, 100);
ey = libinput_event_pointer_get_absolute_y_transformed(ptrev, 100);
ck_assert_int_eq(ex + 0.5, x);
ck_assert_int_eq(ey + 0.5, y);
litest_assert_int_eq((int)(ex + 0.5), (int)x);
litest_assert_int_eq((int)(ey + 0.5), (int)y);
libinput_event_destroy(event);
}
@ -190,8 +192,8 @@ test_unaccel_event(struct litest_device *dev, int dx, int dy)
ev_dx = libinput_event_pointer_get_dx_unaccelerated(ptrev);
ev_dy = libinput_event_pointer_get_dy_unaccelerated(ptrev);
ck_assert_int_eq(dx, ev_dx);
ck_assert_int_eq(dy, ev_dy);
litest_assert_int_eq(dx, ev_dx);
litest_assert_int_eq(dy, ev_dy);
libinput_event_destroy(event);
@ -381,10 +383,10 @@ test_wheel_event(struct litest_device *dev, int which, int amount)
axis,
LIBINPUT_POINTER_AXIS_SOURCE_WHEEL);
ck_assert_int_eq(libinput_event_pointer_get_axis_value(ptrev, axis),
litest_assert_int_eq(libinput_event_pointer_get_axis_value(ptrev, axis),
expected);
ck_assert_int_eq(libinput_event_pointer_get_axis_value_discrete(ptrev, axis),
discrete);
litest_assert_int_eq(libinput_event_pointer_get_axis_value_discrete(ptrev, axis),
discrete);
libinput_event_destroy(event);
}

View file

@ -2936,13 +2936,14 @@ END_TEST
static void
enable_edge_scroll(struct litest_device *dev)
{
enum libinput_config_status status;
enum libinput_config_status status, expected;
struct libinput_device *device = dev->libinput_device;
status = libinput_device_config_scroll_set_method(device,
LIBINPUT_CONFIG_SCROLL_EDGE);
ck_assert_int_eq(status,
LIBINPUT_CONFIG_STATUS_SUCCESS);
expected = LIBINPUT_CONFIG_STATUS_SUCCESS;
litest_assert_int_eq(status, expected);
}
START_TEST(touchpad_edge_scroll)
@ -4268,7 +4269,7 @@ assert_btnevent_from_device(struct litest_device *device,
e = libinput_get_event(li);
litest_is_button_event(e, button, state);
ck_assert_ptr_eq(libinput_event_get_device(e), device->libinput_device);
litest_assert_ptr_eq(libinput_event_get_device(e), device->libinput_device);
libinput_event_destroy(e);
}

View file

@ -13,3 +13,11 @@
...
fun:mtdev_put_event
}
{
libunwind:msync_uninitialized_bytes
Memcheck:Param
msync(start)
fun:__msync_nocancel
...
fun:litest_backtrace
}