Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
/*
|
|
|
|
|
* Copyright © 2013 Red Hat, Inc.
|
2015-05-04 09:13:22 +10:00
|
|
|
* Copyright © 2013 Marcin Slusarz <marcin.slusarz@gmail.com>
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
*
|
2015-06-11 12:09:18 +10:00
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
|
|
|
* to deal in the Software without restriction, including without limitation
|
|
|
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
|
|
|
* Software is furnished to do so, subject to the following conditions:
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
*
|
2015-06-11 12:09:18 +10:00
|
|
|
* The above copyright notice and this permission notice (including the next
|
|
|
|
|
* paragraph) shall be included in all copies or substantial portions of the
|
|
|
|
|
* Software.
|
|
|
|
|
*
|
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
|
|
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
|
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
|
|
|
* DEALINGS IN THE SOFTWARE.
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
|
2015-02-02 10:47:52 +10:00
|
|
|
#include <dirent.h>
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
#include <errno.h>
|
|
|
|
|
#include <fcntl.h>
|
2015-05-20 10:12:39 +10:00
|
|
|
#include <fnmatch.h>
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
#include <getopt.h>
|
2015-07-02 13:39:40 +10:00
|
|
|
#include <libudev.h>
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
#include <poll.h>
|
2016-07-20 08:43:05 +10:00
|
|
|
#include <signal.h>
|
2017-12-01 09:31:07 +10:00
|
|
|
#include <stdarg.h>
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
#include <stdint.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <sys/ptrace.h>
|
2017-05-08 13:35:07 +10:00
|
|
|
#include <sys/resource.h>
|
2015-08-20 12:51:37 +02:00
|
|
|
#include <sys/stat.h>
|
2019-10-28 15:12:22 +10:00
|
|
|
#include <sys/sysinfo.h>
|
2015-07-02 13:39:40 +10:00
|
|
|
#include <sys/timerfd.h>
|
2015-08-20 12:51:37 +02:00
|
|
|
#include <sys/types.h>
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
#include <sys/wait.h>
|
|
|
|
|
#include <time.h>
|
|
|
|
|
#include <unistd.h>
|
2025-07-01 16:30:11 +10:00
|
|
|
|
2015-07-02 13:39:40 +10:00
|
|
|
#include "linux/input.h"
|
2018-02-01 14:23:41 +10:00
|
|
|
#if HAVE_LIBSYSTEMD
|
|
|
|
|
#include <systemd/sd-bus.h>
|
|
|
|
|
#endif
|
2018-07-10 13:47:54 +03:00
|
|
|
#ifdef __FreeBSD__
|
|
|
|
|
#include <termios.h>
|
|
|
|
|
#endif
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
|
2025-07-01 16:38:45 +10:00
|
|
|
#include <libevdev/libevdev.h>
|
2018-04-05 15:04:51 +10:00
|
|
|
#include <linux/kd.h>
|
2019-04-30 13:10:42 +10:00
|
|
|
#include <valgrind/valgrind.h>
|
|
|
|
|
|
2024-10-21 09:16:04 +10:00
|
|
|
#include "util-backtrace.h"
|
2024-03-14 12:28:39 +10:00
|
|
|
#include "util-files.h"
|
2025-03-10 16:16:58 +10:00
|
|
|
#include "util-libinput.h"
|
2025-07-01 16:38:45 +10:00
|
|
|
#include "util-mem.h"
|
2024-10-21 09:16:04 +10:00
|
|
|
|
2019-03-05 15:51:06 +10:00
|
|
|
#include "builddir.h"
|
2018-04-05 15:04:51 +10:00
|
|
|
#include "libinput-util.h"
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
#include "litest-int.h"
|
2024-10-12 10:31:42 +10:00
|
|
|
#include "litest-runner.h"
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
#include "litest.h"
|
2018-05-24 16:52:42 +10:00
|
|
|
#include "quirks.h"
|
2018-04-05 15:04:51 +10:00
|
|
|
|
2020-09-11 08:43:58 +10:00
|
|
|
#define evbit(t, c) ((t) << 16U | (c & 0xffff))
|
|
|
|
|
|
2015-02-02 10:47:52 +10:00
|
|
|
#define UDEV_RULES_D "/run/udev/rules.d"
|
2019-06-26 11:29:31 +10:00
|
|
|
#define UDEV_FUZZ_OVERRIDE_RULE_FILE \
|
|
|
|
|
UDEV_RULES_D \
|
|
|
|
|
"/91-litest-fuzz-override-REMOVEME-XXXXXX.rules"
|
2015-07-27 16:08:04 +08:00
|
|
|
#define UDEV_TEST_DEVICE_RULE_FILE \
|
|
|
|
|
UDEV_RULES_D \
|
2017-06-02 16:59:09 +10:00
|
|
|
"/91-litest-test-device-REMOVEME-XXXXXXX.rules"
|
2017-05-11 11:39:55 +10:00
|
|
|
#define UDEV_DEVICE_GROUPS_FILE \
|
|
|
|
|
UDEV_RULES_D \
|
2017-06-02 16:59:09 +10:00
|
|
|
"/80-libinput-device-groups-litest-XXXXXX.rules"
|
2015-02-02 10:47:52 +10:00
|
|
|
|
2025-04-03 12:15:43 +10:00
|
|
|
bool verbose = false;
|
|
|
|
|
bool in_debugger = false;
|
|
|
|
|
bool run_deviceless = false;
|
2019-03-22 11:43:13 +10:00
|
|
|
static bool use_system_rules_quirks = false;
|
2024-10-15 15:28:56 +10:00
|
|
|
static bool exit_first = false;
|
2024-10-21 12:12:45 +10:00
|
|
|
static FILE *outfile = NULL;
|
2022-11-23 19:17:32 +01:00
|
|
|
static const char *filter_test = NULL;
|
|
|
|
|
static const char *filter_device = NULL;
|
|
|
|
|
static const char *filter_group = NULL;
|
2024-10-17 09:04:36 +10:00
|
|
|
static int filter_rangeval = INT_MIN;
|
2025-04-03 12:15:43 +10:00
|
|
|
bool use_colors = false;
|
test: implement support for parametrizing tests
litest supports ranged tests but they are not enough, doubly so with
tests where we want to parametrize across multiple options.
This patch adds support for just that, in clunky C style.
The typical invocation for a test is by giving the test parameter
a name, a number of values and then the values themselves:
struct litest_parameters *params = litest_parameters_new("axis", 's', 2, "ABS_X", "ABS_Y",
"enabled", 'b', '2', true, false,
"number", 'u', '2', 10, 11,
NULL);
litest_add_parametrized(sometest, LITEST_ANY, LITEST_ANY, params);
litest_parameters_unref(params);
Currently supported are u (uint32), i (int32), d (double), b (bool),
c (char) and s (string).
In the test itself, the `test_env->params` variable is available and
retrieval of the parameters works like this:
const char *axis;
uint32_t number;
bool enabled;
litest_test_param_fetch(test_env->params,
"axis", &axis,
"enabled", &enabled,
"number", &number,
NULL);
Note that since this is an effectively internal test-suite only
functionality we don't do type-checking here, it's assumed that if you
write the code to pass parameters into a test you remember the type
of said params when you write the test code.
Because we don't have hashmaps or anything useful other than lists the
implementation is a bit clunky: we copy the parameter into the test
during litest_add_*, permutate it for our test list which gives us yet
another linked list C struct, and finally copy the actual value into
the test and test environment as it's executed. Not pretty, but it
works.
A few tests are switched as simple demonstration. The name of the
test has the parameters with their names and values appended now, e.g.:
"pointer:pointer_scroll_wheel_hires_send_only_lores:ms-surface-cover:axis:ABS_X"
"pointer:pointer_motion_relative_min_decel:mouse-roccat:direction:NW"
Filtering by parameters can be done via globs of their string
representation:
libinput-test-suite --filter-params="axis:ABS_*,enabled:true,number:10*"
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1109>
2024-12-22 00:06:19 +10:00
|
|
|
|
|
|
|
|
struct param_filter {
|
|
|
|
|
char name[64];
|
|
|
|
|
char glob[64];
|
|
|
|
|
};
|
|
|
|
|
struct param_filter filter_params[8]; /* name=NULL terminated */
|
|
|
|
|
|
2018-05-24 16:52:42 +10:00
|
|
|
static struct quirks_context *quirks_context;
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
|
2016-07-22 13:23:35 +10:00
|
|
|
struct created_file {
|
|
|
|
|
struct list link;
|
|
|
|
|
char *path;
|
|
|
|
|
};
|
|
|
|
|
|
2024-10-15 11:46:58 +10:00
|
|
|
static void
|
|
|
|
|
created_file_destroy(struct created_file *f)
|
|
|
|
|
{
|
|
|
|
|
list_remove(&f->link);
|
|
|
|
|
free(f->path);
|
|
|
|
|
free(f);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
created_file_unlink(struct created_file *f)
|
|
|
|
|
{
|
|
|
|
|
unlink(f->path);
|
|
|
|
|
rmdir(f->path);
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-03 12:15:43 +10:00
|
|
|
struct suite *current_suite = NULL;
|
2016-07-20 08:43:05 +10:00
|
|
|
|
2016-07-22 13:23:35 +10:00
|
|
|
static void
|
|
|
|
|
litest_init_udev_rules(struct list *created_files_list);
|
|
|
|
|
static void
|
|
|
|
|
litest_remove_udev_rules(struct list *created_files_list);
|
2025-03-10 16:16:58 +10:00
|
|
|
static void
|
|
|
|
|
litest_print_event(struct libinput_event *event, const char *message);
|
2019-03-05 15:24:10 +10:00
|
|
|
|
|
|
|
|
enum quirks_setup_mode {
|
|
|
|
|
QUIRKS_SETUP_USE_SRCDIR,
|
|
|
|
|
QUIRKS_SETUP_ONLY_DEVICE,
|
|
|
|
|
QUIRKS_SETUP_FULL,
|
|
|
|
|
};
|
|
|
|
|
static void
|
|
|
|
|
litest_setup_quirks(struct list *created_files_list, enum quirks_setup_mode mode);
|
2015-06-05 10:52:04 +10:00
|
|
|
|
2015-05-04 09:13:22 +10:00
|
|
|
/* 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
|
2015-06-05 11:40:26 +10:00
|
|
|
#define litest_log(...) \
|
|
|
|
|
{ /* __VA_ARGS__ */ \
|
|
|
|
|
}
|
|
|
|
|
#define litest_vlog(...) \
|
|
|
|
|
{ /* __VA_ARGS__ */ \
|
|
|
|
|
}
|
2015-05-04 09:13:22 +10:00
|
|
|
#endif
|
|
|
|
|
|
2025-03-12 10:35:56 +10:00
|
|
|
LIBINPUT_ATTRIBUTE_PRINTF(4, 5)
|
2024-09-12 13:40:44 +10:00
|
|
|
void
|
|
|
|
|
_litest_checkpoint(const char *func,
|
|
|
|
|
int line,
|
2025-03-12 10:38:12 +10:00
|
|
|
const char *color,
|
2024-09-12 13:40:44 +10:00
|
|
|
const char *format,
|
|
|
|
|
...)
|
|
|
|
|
{
|
|
|
|
|
char buf[1024];
|
|
|
|
|
va_list args;
|
|
|
|
|
|
|
|
|
|
va_start(args, format);
|
|
|
|
|
if (verbose) {
|
|
|
|
|
vsnprintf(buf, sizeof(buf), format, args);
|
2025-01-07 13:52:46 +10:00
|
|
|
fprintf(stderr,
|
|
|
|
|
"%s%s():%d - %s%s%s\n",
|
|
|
|
|
use_colors ? ANSI_BRIGHT_BLUE : "",
|
|
|
|
|
func,
|
|
|
|
|
line,
|
2025-03-12 10:38:12 +10:00
|
|
|
use_colors ? color : "",
|
2025-01-07 13:52:46 +10:00
|
|
|
buf,
|
|
|
|
|
use_colors ? ANSI_NORMAL : "");
|
2024-09-12 13:40:44 +10:00
|
|
|
}
|
|
|
|
|
va_end(args);
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-12 10:35:29 +10:00
|
|
|
void
|
2025-03-14 09:51:01 +10:00
|
|
|
litest_backtrace(const char *func)
|
2015-05-04 09:13:22 +10:00
|
|
|
{
|
2024-10-21 09:16:04 +10:00
|
|
|
#ifndef LITEST_DISABLE_BACKTRACE_LOGGING
|
2019-04-12 10:00:12 +10:00
|
|
|
if (RUNNING_ON_VALGRIND) {
|
2024-10-21 09:16:04 +10:00
|
|
|
fprintf(stderr, "Using valgrind, omitting backtrace\n");
|
2019-04-12 10:00:12 +10:00
|
|
|
return;
|
|
|
|
|
}
|
2025-03-14 09:51:01 +10:00
|
|
|
char buf[256];
|
2019-04-12 10:00:12 +10:00
|
|
|
|
2025-03-14 09:51:01 +10:00
|
|
|
snprintf(buf, sizeof(buf), "in %s", func);
|
|
|
|
|
|
|
|
|
|
backtrace_print(stderr,
|
|
|
|
|
use_colors,
|
|
|
|
|
"in litest_backtrace",
|
|
|
|
|
"in litest_runner_test_run",
|
|
|
|
|
func ? buf : NULL);
|
2015-05-04 09:13:22 +10:00
|
|
|
#endif
|
2018-08-08 16:32:06 +10:00
|
|
|
}
|
2015-05-04 09:13:22 +10:00
|
|
|
|
2016-10-24 11:06:23 +10:00
|
|
|
LIBINPUT_ATTRIBUTE_PRINTF(5, 6)
|
2016-11-22 10:57:01 +10:00
|
|
|
__attribute__((noreturn)) void
|
2015-05-04 09:13:22 +10:00
|
|
|
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) {
|
2024-10-14 21:42:26 +10:00
|
|
|
char buf[1024];
|
2015-05-04 09:13:22 +10:00
|
|
|
va_list args;
|
|
|
|
|
va_start(args, message);
|
2024-10-14 21:42:26 +10:00
|
|
|
vsnprintf(buf, sizeof(buf), message, args);
|
2015-05-04 09:13:22 +10:00
|
|
|
va_end(args);
|
2024-10-14 21:42:26 +10:00
|
|
|
litest_log("%s\n", buf);
|
2015-05-04 09:13:22 +10:00
|
|
|
}
|
|
|
|
|
|
2025-03-31 14:10:26 +10:00
|
|
|
litest_log("in %s() (%s:%d)\n", func, file ? file : "???", line);
|
2025-03-14 09:51:01 +10:00
|
|
|
litest_backtrace(func);
|
2024-10-17 08:29:22 +10:00
|
|
|
litest_runner_abort();
|
2015-05-04 09:13:22 +10:00
|
|
|
}
|
|
|
|
|
|
2016-11-22 10:57:01 +10:00
|
|
|
__attribute__((noreturn)) void
|
2015-05-04 09:13:22 +10:00
|
|
|
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);
|
2025-03-14 09:51:01 +10:00
|
|
|
litest_backtrace(func);
|
2024-10-17 08:29:22 +10:00
|
|
|
litest_runner_abort();
|
2015-05-04 09:13:22 +10:00
|
|
|
}
|
|
|
|
|
|
2019-06-12 14:11:00 +10:00
|
|
|
__attribute__((noreturn)) void
|
|
|
|
|
litest_fail_comparison_double(const char *file,
|
|
|
|
|
int line,
|
|
|
|
|
const char *func,
|
|
|
|
|
const char *operator,
|
|
|
|
|
double a,
|
|
|
|
|
double b,
|
|
|
|
|
const char *astr,
|
|
|
|
|
const char *bstr)
|
|
|
|
|
{
|
|
|
|
|
litest_log("FAILED COMPARISON: %s %s %s\n", astr, operator, bstr);
|
|
|
|
|
litest_log("Resolved to: %.3f %s %.3f\n", a, operator, b);
|
|
|
|
|
litest_log("in %s() (%s:%d)\n", func, file, line);
|
2025-03-14 09:51:01 +10:00
|
|
|
litest_backtrace(func);
|
2024-10-17 08:29:22 +10:00
|
|
|
litest_runner_abort();
|
2019-06-12 14:11:00 +10:00
|
|
|
}
|
|
|
|
|
|
2016-11-22 10:57:01 +10:00
|
|
|
__attribute__((noreturn)) void
|
2015-05-08 08:16:39 +10:00
|
|
|
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);
|
2025-03-14 09:51:01 +10:00
|
|
|
litest_backtrace(func);
|
2024-10-17 08:29:22 +10:00
|
|
|
litest_runner_abort();
|
2015-05-08 08:16:39 +10:00
|
|
|
}
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
|
2024-09-16 16:13:44 +10:00
|
|
|
__attribute__((noreturn)) void
|
|
|
|
|
litest_fail_comparison_str(const char *file,
|
|
|
|
|
int line,
|
|
|
|
|
const char *func,
|
|
|
|
|
const char *comparison,
|
|
|
|
|
const char *operator,
|
|
|
|
|
const char *astr,
|
|
|
|
|
const char *bstr)
|
|
|
|
|
{
|
|
|
|
|
litest_log("FAILED COMPARISON: %s %s %s\n", astr, operator, bstr);
|
|
|
|
|
litest_log("Resolved to: %s %s %s\n", astr, operator, bstr);
|
|
|
|
|
litest_log("in %s() (%s:%d)\n", func, file, line);
|
2025-03-14 09:51:01 +10:00
|
|
|
litest_backtrace(func);
|
2024-10-17 08:29:22 +10:00
|
|
|
litest_runner_abort();
|
2024-09-16 16:13:44 +10:00
|
|
|
}
|
|
|
|
|
|
test: implement support for parametrizing tests
litest supports ranged tests but they are not enough, doubly so with
tests where we want to parametrize across multiple options.
This patch adds support for just that, in clunky C style.
The typical invocation for a test is by giving the test parameter
a name, a number of values and then the values themselves:
struct litest_parameters *params = litest_parameters_new("axis", 's', 2, "ABS_X", "ABS_Y",
"enabled", 'b', '2', true, false,
"number", 'u', '2', 10, 11,
NULL);
litest_add_parametrized(sometest, LITEST_ANY, LITEST_ANY, params);
litest_parameters_unref(params);
Currently supported are u (uint32), i (int32), d (double), b (bool),
c (char) and s (string).
In the test itself, the `test_env->params` variable is available and
retrieval of the parameters works like this:
const char *axis;
uint32_t number;
bool enabled;
litest_test_param_fetch(test_env->params,
"axis", &axis,
"enabled", &enabled,
"number", &number,
NULL);
Note that since this is an effectively internal test-suite only
functionality we don't do type-checking here, it's assumed that if you
write the code to pass parameters into a test you remember the type
of said params when you write the test code.
Because we don't have hashmaps or anything useful other than lists the
implementation is a bit clunky: we copy the parameter into the test
during litest_add_*, permutate it for our test list which gives us yet
another linked list C struct, and finally copy the actual value into
the test and test environment as it's executed. Not pretty, but it
works.
A few tests are switched as simple demonstration. The name of the
test has the parameters with their names and values appended now, e.g.:
"pointer:pointer_scroll_wheel_hires_send_only_lores:ms-surface-cover:axis:ABS_X"
"pointer:pointer_motion_relative_min_decel:mouse-roccat:direction:NW"
Filtering by parameters can be done via globs of their string
representation:
libinput-test-suite --filter-params="axis:ABS_*,enabled:true,number:10*"
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1109>
2024-12-22 00:06:19 +10:00
|
|
|
struct litest_parameter_value {
|
|
|
|
|
size_t refcnt;
|
|
|
|
|
struct list link; /* litest_parameter->values */
|
|
|
|
|
|
|
|
|
|
struct multivalue value;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct litest_parameter {
|
|
|
|
|
size_t refcnt;
|
|
|
|
|
struct list link; /* litest_parameters.params */
|
|
|
|
|
char name[128];
|
|
|
|
|
char type; /* One of u, i, d, c, s, b */
|
|
|
|
|
|
|
|
|
|
struct list values; /* litest_parameter_value */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct litest_parameters {
|
|
|
|
|
size_t refcnt;
|
|
|
|
|
struct list params; /* struct litest_parameter */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static struct litest_parameter_value *
|
|
|
|
|
litest_parameter_value_new(void)
|
|
|
|
|
{
|
|
|
|
|
struct litest_parameter_value *pv = zalloc(sizeof *pv);
|
|
|
|
|
|
|
|
|
|
list_init(&pv->link);
|
|
|
|
|
pv->refcnt = 1;
|
|
|
|
|
|
|
|
|
|
return pv;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
|
litest_parameter_add_string(struct litest_parameter *p, const char *s)
|
|
|
|
|
{
|
|
|
|
|
assert(p->type == 's');
|
|
|
|
|
|
|
|
|
|
struct litest_parameter_value *pv = litest_parameter_value_new();
|
|
|
|
|
pv->value = multivalue_new_string(s);
|
|
|
|
|
list_append(&p->values, &pv->link);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
|
litest_parameter_add_char(struct litest_parameter *p, char c)
|
|
|
|
|
{
|
|
|
|
|
assert(p->type == 'c');
|
|
|
|
|
|
|
|
|
|
struct litest_parameter_value *pv = litest_parameter_value_new();
|
|
|
|
|
pv->value = multivalue_new_char(c);
|
|
|
|
|
list_append(&p->values, &pv->link);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
|
litest_parameter_add_bool(struct litest_parameter *p, bool b)
|
|
|
|
|
{
|
|
|
|
|
assert(p->type == 'b');
|
|
|
|
|
|
|
|
|
|
struct litest_parameter_value *pv = litest_parameter_value_new();
|
|
|
|
|
pv->value = multivalue_new_bool(b);
|
|
|
|
|
list_append(&p->values, &pv->link);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
|
litest_parameter_add_u32(struct litest_parameter *p, uint32_t u)
|
|
|
|
|
{
|
|
|
|
|
assert(p->type == 'u');
|
|
|
|
|
|
|
|
|
|
struct litest_parameter_value *pv = litest_parameter_value_new();
|
|
|
|
|
pv->value = multivalue_new_u32(u);
|
|
|
|
|
list_append(&p->values, &pv->link);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
|
litest_parameter_add_i32(struct litest_parameter *p, int32_t i)
|
|
|
|
|
{
|
|
|
|
|
assert(p->type == 'i');
|
|
|
|
|
|
|
|
|
|
struct litest_parameter_value *pv = litest_parameter_value_new();
|
|
|
|
|
pv->value = multivalue_new_i32(i);
|
|
|
|
|
list_append(&p->values, &pv->link);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
litest_parameter_add_double(struct litest_parameter *p, double d)
|
|
|
|
|
{
|
|
|
|
|
assert(p->type == 'd');
|
|
|
|
|
|
|
|
|
|
struct litest_parameter_value *pv = litest_parameter_value_new();
|
|
|
|
|
pv->value = multivalue_new_double(d);
|
|
|
|
|
list_append(&p->values, &pv->link);
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-13 22:10:02 +01:00
|
|
|
static inline void
|
|
|
|
|
litest_parameter_add_named_i32(struct litest_parameter *p,
|
|
|
|
|
const struct litest_named_i32 i)
|
|
|
|
|
{
|
|
|
|
|
assert(p->type == 'I');
|
|
|
|
|
|
|
|
|
|
struct litest_parameter_value *pv = litest_parameter_value_new();
|
|
|
|
|
pv->value = multivalue_new_named_i32(i.value, i.name);
|
|
|
|
|
list_append(&p->values, &pv->link);
|
|
|
|
|
}
|
|
|
|
|
|
test: implement support for parametrizing tests
litest supports ranged tests but they are not enough, doubly so with
tests where we want to parametrize across multiple options.
This patch adds support for just that, in clunky C style.
The typical invocation for a test is by giving the test parameter
a name, a number of values and then the values themselves:
struct litest_parameters *params = litest_parameters_new("axis", 's', 2, "ABS_X", "ABS_Y",
"enabled", 'b', '2', true, false,
"number", 'u', '2', 10, 11,
NULL);
litest_add_parametrized(sometest, LITEST_ANY, LITEST_ANY, params);
litest_parameters_unref(params);
Currently supported are u (uint32), i (int32), d (double), b (bool),
c (char) and s (string).
In the test itself, the `test_env->params` variable is available and
retrieval of the parameters works like this:
const char *axis;
uint32_t number;
bool enabled;
litest_test_param_fetch(test_env->params,
"axis", &axis,
"enabled", &enabled,
"number", &number,
NULL);
Note that since this is an effectively internal test-suite only
functionality we don't do type-checking here, it's assumed that if you
write the code to pass parameters into a test you remember the type
of said params when you write the test code.
Because we don't have hashmaps or anything useful other than lists the
implementation is a bit clunky: we copy the parameter into the test
during litest_add_*, permutate it for our test list which gives us yet
another linked list C struct, and finally copy the actual value into
the test and test environment as it's executed. Not pretty, but it
works.
A few tests are switched as simple demonstration. The name of the
test has the parameters with their names and values appended now, e.g.:
"pointer:pointer_scroll_wheel_hires_send_only_lores:ms-surface-cover:axis:ABS_X"
"pointer:pointer_motion_relative_min_decel:mouse-roccat:direction:NW"
Filtering by parameters can be done via globs of their string
representation:
libinput-test-suite --filter-params="axis:ABS_*,enabled:true,number:10*"
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1109>
2024-12-22 00:06:19 +10:00
|
|
|
#if 0
|
|
|
|
|
static struct litest_parameter_value *
|
|
|
|
|
litest_parameter_value_ref(struct litest_parameter_value *pv) {
|
|
|
|
|
assert(pv);
|
|
|
|
|
assert(pv->refcnt > 0);
|
|
|
|
|
pv->refcnt++;
|
|
|
|
|
return pv;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
static struct litest_parameter_value *
|
|
|
|
|
litest_parameter_value_unref(struct litest_parameter_value *pv)
|
|
|
|
|
{
|
|
|
|
|
if (pv) {
|
|
|
|
|
assert(pv->refcnt > 0);
|
|
|
|
|
if (--pv->refcnt == 0) {
|
|
|
|
|
list_remove(&pv->link);
|
|
|
|
|
free(pv);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct litest_parameter *
|
|
|
|
|
litest_parameter_new(const char *name, char type)
|
|
|
|
|
{
|
|
|
|
|
struct litest_parameter *p = zalloc(sizeof *p);
|
|
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
|
case 'b':
|
|
|
|
|
case 'c':
|
|
|
|
|
case 'd':
|
|
|
|
|
case 'i':
|
2025-02-13 22:10:02 +01:00
|
|
|
case 'I':
|
test: implement support for parametrizing tests
litest supports ranged tests but they are not enough, doubly so with
tests where we want to parametrize across multiple options.
This patch adds support for just that, in clunky C style.
The typical invocation for a test is by giving the test parameter
a name, a number of values and then the values themselves:
struct litest_parameters *params = litest_parameters_new("axis", 's', 2, "ABS_X", "ABS_Y",
"enabled", 'b', '2', true, false,
"number", 'u', '2', 10, 11,
NULL);
litest_add_parametrized(sometest, LITEST_ANY, LITEST_ANY, params);
litest_parameters_unref(params);
Currently supported are u (uint32), i (int32), d (double), b (bool),
c (char) and s (string).
In the test itself, the `test_env->params` variable is available and
retrieval of the parameters works like this:
const char *axis;
uint32_t number;
bool enabled;
litest_test_param_fetch(test_env->params,
"axis", &axis,
"enabled", &enabled,
"number", &number,
NULL);
Note that since this is an effectively internal test-suite only
functionality we don't do type-checking here, it's assumed that if you
write the code to pass parameters into a test you remember the type
of said params when you write the test code.
Because we don't have hashmaps or anything useful other than lists the
implementation is a bit clunky: we copy the parameter into the test
during litest_add_*, permutate it for our test list which gives us yet
another linked list C struct, and finally copy the actual value into
the test and test environment as it's executed. Not pretty, but it
works.
A few tests are switched as simple demonstration. The name of the
test has the parameters with their names and values appended now, e.g.:
"pointer:pointer_scroll_wheel_hires_send_only_lores:ms-surface-cover:axis:ABS_X"
"pointer:pointer_motion_relative_min_decel:mouse-roccat:direction:NW"
Filtering by parameters can be done via globs of their string
representation:
libinput-test-suite --filter-params="axis:ABS_*,enabled:true,number:10*"
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1109>
2024-12-22 00:06:19 +10:00
|
|
|
case 's':
|
|
|
|
|
case 'u':
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
assert(!"Type not yet implemented");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
list_init(&p->link);
|
|
|
|
|
list_init(&p->values);
|
|
|
|
|
snprintf(p->name, sizeof(p->name), "%s", name);
|
|
|
|
|
p->type = type;
|
|
|
|
|
p->refcnt = 1;
|
|
|
|
|
|
|
|
|
|
return p;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct litest_parameter *
|
|
|
|
|
litest_parameter_ref(struct litest_parameter *p)
|
|
|
|
|
{
|
|
|
|
|
assert(p);
|
|
|
|
|
assert(p->refcnt > 0);
|
|
|
|
|
p->refcnt++;
|
|
|
|
|
return p;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct litest_parameter *
|
|
|
|
|
litest_parameter_unref(struct litest_parameter *p)
|
|
|
|
|
{
|
|
|
|
|
if (p) {
|
|
|
|
|
assert(p->refcnt > 0);
|
|
|
|
|
if (--p->refcnt == 0) {
|
|
|
|
|
struct litest_parameter_value *pv;
|
|
|
|
|
list_for_each_safe(pv, &p->values, link) {
|
|
|
|
|
litest_parameter_value_unref(pv);
|
|
|
|
|
}
|
|
|
|
|
list_remove(&p->link);
|
|
|
|
|
free(p);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-07 10:53:12 +10:00
|
|
|
DEFINE_UNREF_CLEANUP_FUNC(litest_parameter);
|
|
|
|
|
|
test: implement support for parametrizing tests
litest supports ranged tests but they are not enough, doubly so with
tests where we want to parametrize across multiple options.
This patch adds support for just that, in clunky C style.
The typical invocation for a test is by giving the test parameter
a name, a number of values and then the values themselves:
struct litest_parameters *params = litest_parameters_new("axis", 's', 2, "ABS_X", "ABS_Y",
"enabled", 'b', '2', true, false,
"number", 'u', '2', 10, 11,
NULL);
litest_add_parametrized(sometest, LITEST_ANY, LITEST_ANY, params);
litest_parameters_unref(params);
Currently supported are u (uint32), i (int32), d (double), b (bool),
c (char) and s (string).
In the test itself, the `test_env->params` variable is available and
retrieval of the parameters works like this:
const char *axis;
uint32_t number;
bool enabled;
litest_test_param_fetch(test_env->params,
"axis", &axis,
"enabled", &enabled,
"number", &number,
NULL);
Note that since this is an effectively internal test-suite only
functionality we don't do type-checking here, it's assumed that if you
write the code to pass parameters into a test you remember the type
of said params when you write the test code.
Because we don't have hashmaps or anything useful other than lists the
implementation is a bit clunky: we copy the parameter into the test
during litest_add_*, permutate it for our test list which gives us yet
another linked list C struct, and finally copy the actual value into
the test and test environment as it's executed. Not pretty, but it
works.
A few tests are switched as simple demonstration. The name of the
test has the parameters with their names and values appended now, e.g.:
"pointer:pointer_scroll_wheel_hires_send_only_lores:ms-surface-cover:axis:ABS_X"
"pointer:pointer_motion_relative_min_decel:mouse-roccat:direction:NW"
Filtering by parameters can be done via globs of their string
representation:
libinput-test-suite --filter-params="axis:ABS_*,enabled:true,number:10*"
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1109>
2024-12-22 00:06:19 +10:00
|
|
|
static void
|
|
|
|
|
litest_parameters_add(struct litest_parameters *ps, struct litest_parameter *param)
|
|
|
|
|
{
|
|
|
|
|
struct litest_parameter *p;
|
|
|
|
|
list_for_each(p, &ps->params, link) {
|
|
|
|
|
assert(!streq(p->name, param->name));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
litest_parameter_ref(param);
|
|
|
|
|
list_append(&ps->params, ¶m->link);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct litest_parameters *
|
|
|
|
|
_litest_parameters_new(const char *name, ...)
|
|
|
|
|
{
|
|
|
|
|
struct litest_parameters *ps = zalloc(sizeof *ps);
|
|
|
|
|
|
|
|
|
|
list_init(&ps->params);
|
|
|
|
|
ps->refcnt = 1;
|
|
|
|
|
|
|
|
|
|
va_list args;
|
|
|
|
|
va_start(args, name);
|
|
|
|
|
|
|
|
|
|
while (name) {
|
|
|
|
|
char type = va_arg(args, int);
|
|
|
|
|
|
2025-04-07 10:53:12 +10:00
|
|
|
_unref_(litest_parameter) *param = litest_parameter_new(name, type);
|
2025-01-08 15:00:20 +10:00
|
|
|
if (type == 'b') {
|
|
|
|
|
litest_parameter_add_bool(param, true);
|
|
|
|
|
litest_parameter_add_bool(param, false);
|
|
|
|
|
} else {
|
|
|
|
|
unsigned int nargs = va_arg(args, unsigned int);
|
|
|
|
|
for (unsigned int _ = 0; _ < nargs; _++) {
|
|
|
|
|
switch (type) {
|
|
|
|
|
case 'c': {
|
|
|
|
|
char b = va_arg(args, int);
|
|
|
|
|
litest_parameter_add_char(param, b);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 'u': {
|
|
|
|
|
uint32_t b = va_arg(args, uint32_t);
|
|
|
|
|
litest_parameter_add_u32(param, b);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 'i': {
|
|
|
|
|
int32_t b = va_arg(args, int32_t);
|
|
|
|
|
litest_parameter_add_i32(param, b);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 'd': {
|
|
|
|
|
double b = va_arg(args, double);
|
|
|
|
|
litest_parameter_add_double(param, b);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 's': {
|
|
|
|
|
const char *s = va_arg(args, const char *);
|
|
|
|
|
litest_parameter_add_string(param, s);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2025-02-13 22:10:02 +01:00
|
|
|
case 'I': {
|
|
|
|
|
struct litest_named_i32 p =
|
|
|
|
|
va_arg(args, struct litest_named_i32);
|
|
|
|
|
litest_parameter_add_named_i32(param, p);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2025-01-08 15:00:20 +10:00
|
|
|
default:
|
2025-05-20 11:18:44 +10:00
|
|
|
litest_abort_msg(
|
|
|
|
|
"Unhandled parameter type '%c'",
|
|
|
|
|
type);
|
2025-01-08 15:00:20 +10:00
|
|
|
break;
|
|
|
|
|
}
|
test: implement support for parametrizing tests
litest supports ranged tests but they are not enough, doubly so with
tests where we want to parametrize across multiple options.
This patch adds support for just that, in clunky C style.
The typical invocation for a test is by giving the test parameter
a name, a number of values and then the values themselves:
struct litest_parameters *params = litest_parameters_new("axis", 's', 2, "ABS_X", "ABS_Y",
"enabled", 'b', '2', true, false,
"number", 'u', '2', 10, 11,
NULL);
litest_add_parametrized(sometest, LITEST_ANY, LITEST_ANY, params);
litest_parameters_unref(params);
Currently supported are u (uint32), i (int32), d (double), b (bool),
c (char) and s (string).
In the test itself, the `test_env->params` variable is available and
retrieval of the parameters works like this:
const char *axis;
uint32_t number;
bool enabled;
litest_test_param_fetch(test_env->params,
"axis", &axis,
"enabled", &enabled,
"number", &number,
NULL);
Note that since this is an effectively internal test-suite only
functionality we don't do type-checking here, it's assumed that if you
write the code to pass parameters into a test you remember the type
of said params when you write the test code.
Because we don't have hashmaps or anything useful other than lists the
implementation is a bit clunky: we copy the parameter into the test
during litest_add_*, permutate it for our test list which gives us yet
another linked list C struct, and finally copy the actual value into
the test and test environment as it's executed. Not pretty, but it
works.
A few tests are switched as simple demonstration. The name of the
test has the parameters with their names and values appended now, e.g.:
"pointer:pointer_scroll_wheel_hires_send_only_lores:ms-surface-cover:axis:ABS_X"
"pointer:pointer_motion_relative_min_decel:mouse-roccat:direction:NW"
Filtering by parameters can be done via globs of their string
representation:
libinput-test-suite --filter-params="axis:ABS_*,enabled:true,number:10*"
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1109>
2024-12-22 00:06:19 +10:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
litest_parameters_add(ps, param);
|
|
|
|
|
name = va_arg(args, const char *);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
va_end(args);
|
|
|
|
|
|
|
|
|
|
return ps;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct litest_parameters *
|
|
|
|
|
litest_parameters_ref(struct litest_parameters *p)
|
|
|
|
|
{
|
|
|
|
|
assert(p);
|
|
|
|
|
assert(p->refcnt > 0);
|
|
|
|
|
p->refcnt++;
|
|
|
|
|
return p;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct litest_parameters *
|
|
|
|
|
litest_parameters_unref(struct litest_parameters *params)
|
|
|
|
|
{
|
|
|
|
|
if (params) {
|
|
|
|
|
assert(params->refcnt > 0);
|
|
|
|
|
if (--params->refcnt == 0) {
|
|
|
|
|
struct litest_parameter *p;
|
|
|
|
|
list_for_each_safe(p, ¶ms->params, link) {
|
|
|
|
|
litest_parameter_unref(p);
|
|
|
|
|
}
|
|
|
|
|
free(params);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline int
|
|
|
|
|
_permutate(struct litest_parameters_permutation *permutation,
|
|
|
|
|
struct list *next_param,
|
|
|
|
|
void *list_head,
|
|
|
|
|
litest_parameters_permutation_func_t func,
|
|
|
|
|
void *userdata)
|
|
|
|
|
{
|
|
|
|
|
if (next_param->next == list_head) {
|
|
|
|
|
func(permutation, userdata);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
struct litest_parameter_value *pv;
|
|
|
|
|
struct litest_parameter *param = list_first_entry(next_param, param, link);
|
|
|
|
|
list_for_each(pv, ¶m->values, link) {
|
|
|
|
|
struct litest_parameters_permutation_value v = {
|
|
|
|
|
.value = pv->value,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
memcpy(v.name, param->name, min(sizeof(v.name), sizeof(param->name)));
|
|
|
|
|
|
|
|
|
|
list_append(&permutation->values, &v.link);
|
|
|
|
|
int rc = _permutate(permutation,
|
|
|
|
|
¶m->link,
|
|
|
|
|
list_head,
|
|
|
|
|
func,
|
|
|
|
|
userdata);
|
|
|
|
|
if (rc)
|
|
|
|
|
return rc;
|
|
|
|
|
list_remove(&v.link);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Calls the given function func with each permutation of
|
|
|
|
|
* the given test parameters.
|
|
|
|
|
*/
|
|
|
|
|
int
|
|
|
|
|
litest_parameters_permutations(struct litest_parameters *params,
|
|
|
|
|
litest_parameters_permutation_func_t func,
|
|
|
|
|
void *userdata)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
struct litest_parameters_permutation permutation;
|
|
|
|
|
list_init(&permutation.values);
|
|
|
|
|
|
|
|
|
|
return _permutate(&permutation,
|
|
|
|
|
¶ms->params,
|
|
|
|
|
¶ms->params,
|
|
|
|
|
func,
|
|
|
|
|
userdata);
|
|
|
|
|
}
|
|
|
|
|
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
static struct litest_device *current_device;
|
|
|
|
|
|
2015-05-20 09:21:26 +10:00
|
|
|
struct litest_device *
|
|
|
|
|
litest_current_device(void)
|
|
|
|
|
{
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
return current_device;
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-13 15:13:38 +10:00
|
|
|
int
|
|
|
|
|
_litest_dispatch(struct libinput *li, const char *func, int line)
|
|
|
|
|
{
|
|
|
|
|
static int dispatch_counter = 0;
|
|
|
|
|
|
|
|
|
|
++dispatch_counter;
|
|
|
|
|
|
2025-03-12 10:38:12 +10:00
|
|
|
_litest_checkpoint(func,
|
|
|
|
|
line,
|
|
|
|
|
ANSI_MAGENTA,
|
2024-09-13 15:13:38 +10:00
|
|
|
"┌──────────────────── dispatch %3d ────────────────────┐",
|
|
|
|
|
dispatch_counter);
|
|
|
|
|
int rc = libinput_dispatch(li);
|
|
|
|
|
enum libinput_event_type type = libinput_next_event_type(li);
|
|
|
|
|
|
|
|
|
|
const char *evtype =
|
|
|
|
|
type == LIBINPUT_EVENT_NONE ? "NONE" : litest_event_type_str(type);
|
2025-03-12 10:38:12 +10:00
|
|
|
_litest_checkpoint(
|
|
|
|
|
func,
|
|
|
|
|
line,
|
|
|
|
|
ANSI_MAGENTA,
|
2024-09-13 15:13:38 +10:00
|
|
|
"└──────────────────── /dispatch %3d ────────────────────┘ pending %s",
|
|
|
|
|
dispatch_counter,
|
|
|
|
|
evtype);
|
|
|
|
|
return rc;
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-03 12:46:38 +10:00
|
|
|
static void
|
|
|
|
|
grab_device(struct litest_device *device, bool mode)
|
|
|
|
|
{
|
|
|
|
|
struct libinput *li = libinput_device_get_context(device->libinput_device);
|
|
|
|
|
struct litest_context *ctx = libinput_get_user_data(li);
|
2025-04-07 10:53:12 +10:00
|
|
|
_unref_(udev_device) * udev_device;
|
2020-07-03 12:46:38 +10:00
|
|
|
const char *devnode;
|
|
|
|
|
struct path *p;
|
|
|
|
|
|
|
|
|
|
udev_device = libinput_device_get_udev_device(device->libinput_device);
|
|
|
|
|
litest_assert_ptr_notnull(udev_device);
|
|
|
|
|
|
|
|
|
|
devnode = udev_device_get_devnode(udev_device);
|
|
|
|
|
|
|
|
|
|
/* Note: in some tests we create multiple devices for the same path.
|
|
|
|
|
* This will only grab the first device in the list but we're using
|
|
|
|
|
* list_insert() so the first device is the latest that was
|
|
|
|
|
* initialized, so we should be good.
|
|
|
|
|
*/
|
|
|
|
|
list_for_each(p, &ctx->paths, link) {
|
|
|
|
|
if (streq(p->path, devnode)) {
|
|
|
|
|
int rc = ioctl(p->fd, EVIOCGRAB, (void *)mode ? 1 : 0);
|
2024-10-16 11:27:27 +10:00
|
|
|
litest_assert_errno_success(rc);
|
2020-07-03 12:46:38 +10:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-10-14 21:42:26 +10:00
|
|
|
litest_abort_msg("Failed to find device %s to %sgrab",
|
2020-07-03 12:46:38 +10:00
|
|
|
devnode,
|
|
|
|
|
mode ? "" : "un");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
litest_grab_device(struct litest_device *device)
|
|
|
|
|
{
|
|
|
|
|
grab_device(device, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
litest_ungrab_device(struct litest_device *device)
|
|
|
|
|
{
|
|
|
|
|
grab_device(device, false);
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-20 09:21:26 +10:00
|
|
|
void
|
|
|
|
|
litest_set_current_device(struct litest_device *device)
|
|
|
|
|
{
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
current_device = device;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
litest_generic_device_teardown(void)
|
|
|
|
|
{
|
2025-04-07 15:12:51 +10:00
|
|
|
litest_device_destroy(current_device);
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
current_device = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-16 11:10:18 +10:00
|
|
|
static struct list devices = LIST_INIT(devices); /* struct litest_test_device */
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
|
2025-04-03 12:15:43 +10:00
|
|
|
void
|
|
|
|
|
litest_add_test_device(struct list *device)
|
|
|
|
|
{
|
|
|
|
|
list_append(&devices, device);
|
|
|
|
|
}
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
|
2015-06-05 10:52:04 +10:00
|
|
|
static inline void
|
|
|
|
|
litest_system(const char *command)
|
2015-02-02 10:47:52 +10:00
|
|
|
{
|
2015-06-05 10:52:04 +10:00
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
ret = system(command);
|
|
|
|
|
|
2015-06-01 18:04:59 -07:00
|
|
|
if (ret == -1) {
|
2015-06-05 10:52:04 +10:00
|
|
|
litest_abort_msg("Failed to execute: %s", command);
|
2015-06-01 18:04:59 -07:00
|
|
|
} else if (WIFEXITED(ret)) {
|
|
|
|
|
if (WEXITSTATUS(ret))
|
2015-06-05 10:52:04 +10:00
|
|
|
litest_abort_msg("'%s' failed with %d",
|
|
|
|
|
command,
|
2015-06-01 18:04:59 -07:00
|
|
|
WEXITSTATUS(ret));
|
|
|
|
|
} else if (WIFSIGNALED(ret)) {
|
2015-06-05 10:52:04 +10:00
|
|
|
litest_abort_msg("'%s' terminated with signal %d",
|
|
|
|
|
command,
|
2015-06-01 18:04:59 -07:00
|
|
|
WTERMSIG(ret));
|
|
|
|
|
}
|
2015-02-02 10:47:52 +10:00
|
|
|
}
|
|
|
|
|
|
2015-06-05 10:52:04 +10:00
|
|
|
static void
|
|
|
|
|
litest_reload_udev_rules(void)
|
|
|
|
|
{
|
|
|
|
|
litest_system("udevadm control --reload-rules");
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-17 09:04:36 +10:00
|
|
|
static bool
|
|
|
|
|
filter_for_rangeval(const struct range *range, int rangeval)
|
|
|
|
|
{
|
|
|
|
|
return !range || filter_rangeval == INT_MIN || filter_rangeval == rangeval;
|
|
|
|
|
}
|
|
|
|
|
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
static void
|
|
|
|
|
litest_add_tcase_for_device(struct suite *suite,
|
2015-05-20 10:12:39 +10:00
|
|
|
const char *funcname,
|
2020-01-03 18:06:54 -08:00
|
|
|
const void *func,
|
2015-05-06 08:09:50 +10:00
|
|
|
const struct litest_test_device *dev,
|
|
|
|
|
const struct range *range)
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
{
|
2024-10-12 10:31:42 +10:00
|
|
|
const struct range no_range = range_init_empty();
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
|
2024-10-16 11:21:29 +10:00
|
|
|
if (run_deviceless)
|
|
|
|
|
return;
|
|
|
|
|
|
2024-10-12 10:31:42 +10:00
|
|
|
if (!range)
|
|
|
|
|
range = &no_range;
|
2017-06-07 13:30:48 +10:00
|
|
|
|
2024-10-12 10:31:42 +10:00
|
|
|
int rangeval = range->lower;
|
|
|
|
|
do {
|
2024-10-17 09:04:36 +10:00
|
|
|
if (filter_for_rangeval(range, rangeval)) {
|
|
|
|
|
struct test *t;
|
|
|
|
|
|
|
|
|
|
t = zalloc(sizeof(*t));
|
|
|
|
|
t->name = safe_strdup(funcname);
|
|
|
|
|
t->devname = safe_strdup(dev->shortname);
|
|
|
|
|
t->func = func;
|
|
|
|
|
t->setup = dev->setup;
|
|
|
|
|
t->teardown = dev->teardown ? dev->teardown
|
|
|
|
|
: litest_generic_device_teardown;
|
|
|
|
|
if (range)
|
|
|
|
|
t->range = *range;
|
|
|
|
|
t->rangeval = rangeval;
|
|
|
|
|
|
|
|
|
|
list_append(&suite->tests, &t->node);
|
|
|
|
|
}
|
2024-10-12 10:31:42 +10:00
|
|
|
} while (++rangeval < range->upper);
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
}
|
|
|
|
|
|
test: implement support for parametrizing tests
litest supports ranged tests but they are not enough, doubly so with
tests where we want to parametrize across multiple options.
This patch adds support for just that, in clunky C style.
The typical invocation for a test is by giving the test parameter
a name, a number of values and then the values themselves:
struct litest_parameters *params = litest_parameters_new("axis", 's', 2, "ABS_X", "ABS_Y",
"enabled", 'b', '2', true, false,
"number", 'u', '2', 10, 11,
NULL);
litest_add_parametrized(sometest, LITEST_ANY, LITEST_ANY, params);
litest_parameters_unref(params);
Currently supported are u (uint32), i (int32), d (double), b (bool),
c (char) and s (string).
In the test itself, the `test_env->params` variable is available and
retrieval of the parameters works like this:
const char *axis;
uint32_t number;
bool enabled;
litest_test_param_fetch(test_env->params,
"axis", &axis,
"enabled", &enabled,
"number", &number,
NULL);
Note that since this is an effectively internal test-suite only
functionality we don't do type-checking here, it's assumed that if you
write the code to pass parameters into a test you remember the type
of said params when you write the test code.
Because we don't have hashmaps or anything useful other than lists the
implementation is a bit clunky: we copy the parameter into the test
during litest_add_*, permutate it for our test list which gives us yet
another linked list C struct, and finally copy the actual value into
the test and test environment as it's executed. Not pretty, but it
works.
A few tests are switched as simple demonstration. The name of the
test has the parameters with their names and values appended now, e.g.:
"pointer:pointer_scroll_wheel_hires_send_only_lores:ms-surface-cover:axis:ABS_X"
"pointer:pointer_motion_relative_min_decel:mouse-roccat:direction:NW"
Filtering by parameters can be done via globs of their string
representation:
libinput-test-suite --filter-params="axis:ABS_*,enabled:true,number:10*"
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1109>
2024-12-22 00:06:19 +10:00
|
|
|
struct permutation_userdata {
|
|
|
|
|
struct suite *suite;
|
|
|
|
|
const char *funcname;
|
|
|
|
|
const void *func;
|
|
|
|
|
const struct litest_test_device *dev;
|
|
|
|
|
char devname[64]; /* set if dev == NULL */
|
|
|
|
|
|
|
|
|
|
const struct param_filter *param_filters; /* name=NULL terminated */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
permutation_func(struct litest_parameters_permutation *permutation, void *userdata)
|
|
|
|
|
{
|
|
|
|
|
struct permutation_userdata *data = userdata;
|
|
|
|
|
|
|
|
|
|
struct litest_test_parameters *params = litest_test_parameters_new();
|
|
|
|
|
struct litest_parameters_permutation_value *pmv;
|
2025-01-08 14:29:07 +10:00
|
|
|
bool filtered = false;
|
test: implement support for parametrizing tests
litest supports ranged tests but they are not enough, doubly so with
tests where we want to parametrize across multiple options.
This patch adds support for just that, in clunky C style.
The typical invocation for a test is by giving the test parameter
a name, a number of values and then the values themselves:
struct litest_parameters *params = litest_parameters_new("axis", 's', 2, "ABS_X", "ABS_Y",
"enabled", 'b', '2', true, false,
"number", 'u', '2', 10, 11,
NULL);
litest_add_parametrized(sometest, LITEST_ANY, LITEST_ANY, params);
litest_parameters_unref(params);
Currently supported are u (uint32), i (int32), d (double), b (bool),
c (char) and s (string).
In the test itself, the `test_env->params` variable is available and
retrieval of the parameters works like this:
const char *axis;
uint32_t number;
bool enabled;
litest_test_param_fetch(test_env->params,
"axis", &axis,
"enabled", &enabled,
"number", &number,
NULL);
Note that since this is an effectively internal test-suite only
functionality we don't do type-checking here, it's assumed that if you
write the code to pass parameters into a test you remember the type
of said params when you write the test code.
Because we don't have hashmaps or anything useful other than lists the
implementation is a bit clunky: we copy the parameter into the test
during litest_add_*, permutate it for our test list which gives us yet
another linked list C struct, and finally copy the actual value into
the test and test environment as it's executed. Not pretty, but it
works.
A few tests are switched as simple demonstration. The name of the
test has the parameters with their names and values appended now, e.g.:
"pointer:pointer_scroll_wheel_hires_send_only_lores:ms-surface-cover:axis:ABS_X"
"pointer:pointer_motion_relative_min_decel:mouse-roccat:direction:NW"
Filtering by parameters can be done via globs of their string
representation:
libinput-test-suite --filter-params="axis:ABS_*,enabled:true,number:10*"
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1109>
2024-12-22 00:06:19 +10:00
|
|
|
list_for_each(pmv, &permutation->values, link) {
|
|
|
|
|
const struct param_filter *f = data->param_filters;
|
|
|
|
|
while (!filtered && strlen(f->name)) {
|
|
|
|
|
if (streq(pmv->name, f->name)) {
|
2025-04-07 10:53:12 +10:00
|
|
|
_autofree_ char *s = multivalue_as_str(&pmv->value);
|
test: implement support for parametrizing tests
litest supports ranged tests but they are not enough, doubly so with
tests where we want to parametrize across multiple options.
This patch adds support for just that, in clunky C style.
The typical invocation for a test is by giving the test parameter
a name, a number of values and then the values themselves:
struct litest_parameters *params = litest_parameters_new("axis", 's', 2, "ABS_X", "ABS_Y",
"enabled", 'b', '2', true, false,
"number", 'u', '2', 10, 11,
NULL);
litest_add_parametrized(sometest, LITEST_ANY, LITEST_ANY, params);
litest_parameters_unref(params);
Currently supported are u (uint32), i (int32), d (double), b (bool),
c (char) and s (string).
In the test itself, the `test_env->params` variable is available and
retrieval of the parameters works like this:
const char *axis;
uint32_t number;
bool enabled;
litest_test_param_fetch(test_env->params,
"axis", &axis,
"enabled", &enabled,
"number", &number,
NULL);
Note that since this is an effectively internal test-suite only
functionality we don't do type-checking here, it's assumed that if you
write the code to pass parameters into a test you remember the type
of said params when you write the test code.
Because we don't have hashmaps or anything useful other than lists the
implementation is a bit clunky: we copy the parameter into the test
during litest_add_*, permutate it for our test list which gives us yet
another linked list C struct, and finally copy the actual value into
the test and test environment as it's executed. Not pretty, but it
works.
A few tests are switched as simple demonstration. The name of the
test has the parameters with their names and values appended now, e.g.:
"pointer:pointer_scroll_wheel_hires_send_only_lores:ms-surface-cover:axis:ABS_X"
"pointer:pointer_motion_relative_min_decel:mouse-roccat:direction:NW"
Filtering by parameters can be done via globs of their string
representation:
libinput-test-suite --filter-params="axis:ABS_*,enabled:true,number:10*"
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1109>
2024-12-22 00:06:19 +10:00
|
|
|
if (fnmatch(f->glob, s, 0) != 0)
|
|
|
|
|
filtered = true;
|
|
|
|
|
}
|
|
|
|
|
f++;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-08 14:29:07 +10:00
|
|
|
if (filtered)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
struct litest_test_param *tp = zalloc(sizeof *tp);
|
|
|
|
|
snprintf(tp->name, sizeof(tp->name), "%s", pmv->name);
|
|
|
|
|
tp->value = multivalue_copy(&pmv->value);
|
|
|
|
|
list_append(¶ms->test_params, &tp->link);
|
test: implement support for parametrizing tests
litest supports ranged tests but they are not enough, doubly so with
tests where we want to parametrize across multiple options.
This patch adds support for just that, in clunky C style.
The typical invocation for a test is by giving the test parameter
a name, a number of values and then the values themselves:
struct litest_parameters *params = litest_parameters_new("axis", 's', 2, "ABS_X", "ABS_Y",
"enabled", 'b', '2', true, false,
"number", 'u', '2', 10, 11,
NULL);
litest_add_parametrized(sometest, LITEST_ANY, LITEST_ANY, params);
litest_parameters_unref(params);
Currently supported are u (uint32), i (int32), d (double), b (bool),
c (char) and s (string).
In the test itself, the `test_env->params` variable is available and
retrieval of the parameters works like this:
const char *axis;
uint32_t number;
bool enabled;
litest_test_param_fetch(test_env->params,
"axis", &axis,
"enabled", &enabled,
"number", &number,
NULL);
Note that since this is an effectively internal test-suite only
functionality we don't do type-checking here, it's assumed that if you
write the code to pass parameters into a test you remember the type
of said params when you write the test code.
Because we don't have hashmaps or anything useful other than lists the
implementation is a bit clunky: we copy the parameter into the test
during litest_add_*, permutate it for our test list which gives us yet
another linked list C struct, and finally copy the actual value into
the test and test environment as it's executed. Not pretty, but it
works.
A few tests are switched as simple demonstration. The name of the
test has the parameters with their names and values appended now, e.g.:
"pointer:pointer_scroll_wheel_hires_send_only_lores:ms-surface-cover:axis:ABS_X"
"pointer:pointer_motion_relative_min_decel:mouse-roccat:direction:NW"
Filtering by parameters can be done via globs of their string
representation:
libinput-test-suite --filter-params="axis:ABS_*,enabled:true,number:10*"
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1109>
2024-12-22 00:06:19 +10:00
|
|
|
}
|
|
|
|
|
|
2025-01-08 14:29:07 +10:00
|
|
|
if (filtered) {
|
|
|
|
|
litest_test_parameters_unref(params);
|
test: implement support for parametrizing tests
litest supports ranged tests but they are not enough, doubly so with
tests where we want to parametrize across multiple options.
This patch adds support for just that, in clunky C style.
The typical invocation for a test is by giving the test parameter
a name, a number of values and then the values themselves:
struct litest_parameters *params = litest_parameters_new("axis", 's', 2, "ABS_X", "ABS_Y",
"enabled", 'b', '2', true, false,
"number", 'u', '2', 10, 11,
NULL);
litest_add_parametrized(sometest, LITEST_ANY, LITEST_ANY, params);
litest_parameters_unref(params);
Currently supported are u (uint32), i (int32), d (double), b (bool),
c (char) and s (string).
In the test itself, the `test_env->params` variable is available and
retrieval of the parameters works like this:
const char *axis;
uint32_t number;
bool enabled;
litest_test_param_fetch(test_env->params,
"axis", &axis,
"enabled", &enabled,
"number", &number,
NULL);
Note that since this is an effectively internal test-suite only
functionality we don't do type-checking here, it's assumed that if you
write the code to pass parameters into a test you remember the type
of said params when you write the test code.
Because we don't have hashmaps or anything useful other than lists the
implementation is a bit clunky: we copy the parameter into the test
during litest_add_*, permutate it for our test list which gives us yet
another linked list C struct, and finally copy the actual value into
the test and test environment as it's executed. Not pretty, but it
works.
A few tests are switched as simple demonstration. The name of the
test has the parameters with their names and values appended now, e.g.:
"pointer:pointer_scroll_wheel_hires_send_only_lores:ms-surface-cover:axis:ABS_X"
"pointer:pointer_motion_relative_min_decel:mouse-roccat:direction:NW"
Filtering by parameters can be done via globs of their string
representation:
libinput-test-suite --filter-params="axis:ABS_*,enabled:true,number:10*"
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1109>
2024-12-22 00:06:19 +10:00
|
|
|
return 0;
|
2025-01-08 14:29:07 +10:00
|
|
|
}
|
test: implement support for parametrizing tests
litest supports ranged tests but they are not enough, doubly so with
tests where we want to parametrize across multiple options.
This patch adds support for just that, in clunky C style.
The typical invocation for a test is by giving the test parameter
a name, a number of values and then the values themselves:
struct litest_parameters *params = litest_parameters_new("axis", 's', 2, "ABS_X", "ABS_Y",
"enabled", 'b', '2', true, false,
"number", 'u', '2', 10, 11,
NULL);
litest_add_parametrized(sometest, LITEST_ANY, LITEST_ANY, params);
litest_parameters_unref(params);
Currently supported are u (uint32), i (int32), d (double), b (bool),
c (char) and s (string).
In the test itself, the `test_env->params` variable is available and
retrieval of the parameters works like this:
const char *axis;
uint32_t number;
bool enabled;
litest_test_param_fetch(test_env->params,
"axis", &axis,
"enabled", &enabled,
"number", &number,
NULL);
Note that since this is an effectively internal test-suite only
functionality we don't do type-checking here, it's assumed that if you
write the code to pass parameters into a test you remember the type
of said params when you write the test code.
Because we don't have hashmaps or anything useful other than lists the
implementation is a bit clunky: we copy the parameter into the test
during litest_add_*, permutate it for our test list which gives us yet
another linked list C struct, and finally copy the actual value into
the test and test environment as it's executed. Not pretty, but it
works.
A few tests are switched as simple demonstration. The name of the
test has the parameters with their names and values appended now, e.g.:
"pointer:pointer_scroll_wheel_hires_send_only_lores:ms-surface-cover:axis:ABS_X"
"pointer:pointer_motion_relative_min_decel:mouse-roccat:direction:NW"
Filtering by parameters can be done via globs of their string
representation:
libinput-test-suite --filter-params="axis:ABS_*,enabled:true,number:10*"
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1109>
2024-12-22 00:06:19 +10:00
|
|
|
|
|
|
|
|
struct test *t;
|
|
|
|
|
|
|
|
|
|
t = zalloc(sizeof(*t));
|
|
|
|
|
t->name = safe_strdup(data->funcname);
|
|
|
|
|
t->func = data->func;
|
|
|
|
|
if (data->dev) {
|
|
|
|
|
t->devname = safe_strdup(data->dev->shortname);
|
|
|
|
|
t->setup = data->dev->setup;
|
|
|
|
|
t->teardown = data->dev->teardown ? data->dev->teardown
|
|
|
|
|
: litest_generic_device_teardown;
|
|
|
|
|
} else {
|
|
|
|
|
t->devname = safe_strdup(data->devname);
|
|
|
|
|
t->setup = NULL;
|
|
|
|
|
t->teardown = NULL;
|
|
|
|
|
}
|
|
|
|
|
t->rangeval = 0;
|
|
|
|
|
t->params = params;
|
|
|
|
|
|
|
|
|
|
list_append(&data->suite->tests, &t->node);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
litest_add_tcase_for_device_with_params(struct suite *suite,
|
|
|
|
|
const char *funcname,
|
|
|
|
|
const void *func,
|
|
|
|
|
const struct litest_test_device *dev,
|
|
|
|
|
struct litest_parameters *params)
|
|
|
|
|
{
|
|
|
|
|
if (run_deviceless)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
struct permutation_userdata data = {
|
|
|
|
|
.suite = suite,
|
|
|
|
|
.funcname = funcname,
|
|
|
|
|
.func = func,
|
|
|
|
|
.dev = dev,
|
|
|
|
|
.param_filters = filter_params,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
litest_parameters_permutations(params, permutation_func, &data);
|
|
|
|
|
}
|
|
|
|
|
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
static void
|
2015-05-06 08:09:50 +10:00
|
|
|
litest_add_tcase_no_device(struct suite *suite,
|
2020-01-03 18:06:54 -08:00
|
|
|
const void *func,
|
2017-09-21 15:55:18 +10:00
|
|
|
const char *funcname,
|
2015-05-06 08:09:50 +10:00
|
|
|
const struct range *range)
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
{
|
2017-09-21 15:55:18 +10:00
|
|
|
const char *test_name = funcname;
|
2024-10-12 10:31:42 +10:00
|
|
|
const struct range no_range = range_init_empty();
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
|
2015-05-20 10:49:13 +10:00
|
|
|
if (filter_device && fnmatch(filter_device, test_name, 0) != 0)
|
|
|
|
|
return;
|
|
|
|
|
|
2024-10-16 11:21:29 +10:00
|
|
|
if (run_deviceless)
|
|
|
|
|
return;
|
|
|
|
|
|
2024-10-12 10:31:42 +10:00
|
|
|
if (!range)
|
|
|
|
|
range = &no_range;
|
2017-06-07 13:30:48 +10:00
|
|
|
|
2024-10-12 10:31:42 +10:00
|
|
|
int rangeval = range->lower;
|
|
|
|
|
do {
|
2024-10-17 09:04:36 +10:00
|
|
|
if (filter_for_rangeval(range, rangeval)) {
|
|
|
|
|
struct test *t;
|
|
|
|
|
|
|
|
|
|
t = zalloc(sizeof(*t));
|
|
|
|
|
t->name = safe_strdup(test_name);
|
|
|
|
|
t->devname = safe_strdup("no device");
|
|
|
|
|
t->func = func;
|
|
|
|
|
if (range)
|
|
|
|
|
t->range = *range;
|
|
|
|
|
t->rangeval = rangeval;
|
|
|
|
|
t->setup = NULL;
|
|
|
|
|
t->teardown = NULL;
|
|
|
|
|
|
|
|
|
|
list_append(&suite->tests, &t->node);
|
|
|
|
|
}
|
2024-10-12 10:31:42 +10:00
|
|
|
} while (++rangeval < range->upper);
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
}
|
|
|
|
|
|
test: implement support for parametrizing tests
litest supports ranged tests but they are not enough, doubly so with
tests where we want to parametrize across multiple options.
This patch adds support for just that, in clunky C style.
The typical invocation for a test is by giving the test parameter
a name, a number of values and then the values themselves:
struct litest_parameters *params = litest_parameters_new("axis", 's', 2, "ABS_X", "ABS_Y",
"enabled", 'b', '2', true, false,
"number", 'u', '2', 10, 11,
NULL);
litest_add_parametrized(sometest, LITEST_ANY, LITEST_ANY, params);
litest_parameters_unref(params);
Currently supported are u (uint32), i (int32), d (double), b (bool),
c (char) and s (string).
In the test itself, the `test_env->params` variable is available and
retrieval of the parameters works like this:
const char *axis;
uint32_t number;
bool enabled;
litest_test_param_fetch(test_env->params,
"axis", &axis,
"enabled", &enabled,
"number", &number,
NULL);
Note that since this is an effectively internal test-suite only
functionality we don't do type-checking here, it's assumed that if you
write the code to pass parameters into a test you remember the type
of said params when you write the test code.
Because we don't have hashmaps or anything useful other than lists the
implementation is a bit clunky: we copy the parameter into the test
during litest_add_*, permutate it for our test list which gives us yet
another linked list C struct, and finally copy the actual value into
the test and test environment as it's executed. Not pretty, but it
works.
A few tests are switched as simple demonstration. The name of the
test has the parameters with their names and values appended now, e.g.:
"pointer:pointer_scroll_wheel_hires_send_only_lores:ms-surface-cover:axis:ABS_X"
"pointer:pointer_motion_relative_min_decel:mouse-roccat:direction:NW"
Filtering by parameters can be done via globs of their string
representation:
libinput-test-suite --filter-params="axis:ABS_*,enabled:true,number:10*"
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1109>
2024-12-22 00:06:19 +10:00
|
|
|
static void
|
|
|
|
|
litest_add_tcase_no_device_with_params(struct suite *suite,
|
|
|
|
|
const void *func,
|
|
|
|
|
const char *funcname,
|
|
|
|
|
struct litest_parameters *params)
|
|
|
|
|
{
|
|
|
|
|
const char *test_name = funcname;
|
|
|
|
|
|
|
|
|
|
if (filter_device && fnmatch(filter_device, test_name, 0) != 0)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (run_deviceless)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
struct permutation_userdata data = {
|
|
|
|
|
.suite = suite,
|
|
|
|
|
.funcname = funcname,
|
|
|
|
|
.func = func,
|
|
|
|
|
.param_filters = filter_params,
|
|
|
|
|
};
|
|
|
|
|
snprintf(data.devname, sizeof(data.devname), "no device");
|
|
|
|
|
|
|
|
|
|
litest_parameters_permutations(params, permutation_func, &data);
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-21 17:05:30 +10:00
|
|
|
static void
|
|
|
|
|
litest_add_tcase_deviceless(struct suite *suite,
|
2020-01-03 18:06:54 -08:00
|
|
|
const void *func,
|
2018-06-21 17:05:30 +10:00
|
|
|
const char *funcname,
|
|
|
|
|
const struct range *range)
|
|
|
|
|
{
|
|
|
|
|
const char *test_name = funcname;
|
2024-10-12 10:31:42 +10:00
|
|
|
const struct range no_range = range_init_empty();
|
2018-06-21 17:05:30 +10:00
|
|
|
|
|
|
|
|
if (filter_device && fnmatch(filter_device, test_name, 0) != 0)
|
|
|
|
|
return;
|
|
|
|
|
|
2024-10-12 10:31:42 +10:00
|
|
|
if (!range)
|
|
|
|
|
range = &no_range;
|
|
|
|
|
|
|
|
|
|
int rangeval = range->lower;
|
|
|
|
|
do {
|
2024-10-17 09:04:36 +10:00
|
|
|
if (filter_for_rangeval(range, rangeval)) {
|
|
|
|
|
struct test *t;
|
|
|
|
|
|
|
|
|
|
t = zalloc(sizeof(*t));
|
|
|
|
|
t->deviceless = true;
|
|
|
|
|
t->name = safe_strdup(test_name);
|
|
|
|
|
t->devname = safe_strdup("deviceless");
|
|
|
|
|
t->func = func;
|
|
|
|
|
if (range)
|
|
|
|
|
t->range = *range;
|
|
|
|
|
t->rangeval = rangeval;
|
|
|
|
|
t->setup = NULL;
|
|
|
|
|
t->teardown = NULL;
|
|
|
|
|
|
|
|
|
|
list_append(&suite->tests, &t->node);
|
|
|
|
|
}
|
2024-10-12 10:31:42 +10:00
|
|
|
} while (++rangeval < range->upper);
|
2018-06-21 17:05:30 +10:00
|
|
|
}
|
|
|
|
|
|
test: implement support for parametrizing tests
litest supports ranged tests but they are not enough, doubly so with
tests where we want to parametrize across multiple options.
This patch adds support for just that, in clunky C style.
The typical invocation for a test is by giving the test parameter
a name, a number of values and then the values themselves:
struct litest_parameters *params = litest_parameters_new("axis", 's', 2, "ABS_X", "ABS_Y",
"enabled", 'b', '2', true, false,
"number", 'u', '2', 10, 11,
NULL);
litest_add_parametrized(sometest, LITEST_ANY, LITEST_ANY, params);
litest_parameters_unref(params);
Currently supported are u (uint32), i (int32), d (double), b (bool),
c (char) and s (string).
In the test itself, the `test_env->params` variable is available and
retrieval of the parameters works like this:
const char *axis;
uint32_t number;
bool enabled;
litest_test_param_fetch(test_env->params,
"axis", &axis,
"enabled", &enabled,
"number", &number,
NULL);
Note that since this is an effectively internal test-suite only
functionality we don't do type-checking here, it's assumed that if you
write the code to pass parameters into a test you remember the type
of said params when you write the test code.
Because we don't have hashmaps or anything useful other than lists the
implementation is a bit clunky: we copy the parameter into the test
during litest_add_*, permutate it for our test list which gives us yet
another linked list C struct, and finally copy the actual value into
the test and test environment as it's executed. Not pretty, but it
works.
A few tests are switched as simple demonstration. The name of the
test has the parameters with their names and values appended now, e.g.:
"pointer:pointer_scroll_wheel_hires_send_only_lores:ms-surface-cover:axis:ABS_X"
"pointer:pointer_motion_relative_min_decel:mouse-roccat:direction:NW"
Filtering by parameters can be done via globs of their string
representation:
libinput-test-suite --filter-params="axis:ABS_*,enabled:true,number:10*"
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1109>
2024-12-22 00:06:19 +10:00
|
|
|
static void
|
|
|
|
|
litest_add_tcase_deviceless_with_params(struct suite *suite,
|
|
|
|
|
const void *func,
|
|
|
|
|
const char *funcname,
|
|
|
|
|
struct litest_parameters *params)
|
|
|
|
|
{
|
|
|
|
|
const char *test_name = funcname;
|
|
|
|
|
|
|
|
|
|
if (filter_device && fnmatch(filter_device, test_name, 0) != 0)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
struct permutation_userdata data = {
|
|
|
|
|
.suite = suite,
|
|
|
|
|
.funcname = funcname,
|
|
|
|
|
.func = func,
|
|
|
|
|
.param_filters = filter_params,
|
|
|
|
|
};
|
|
|
|
|
snprintf(data.devname, sizeof(data.devname), "deviceless");
|
|
|
|
|
|
|
|
|
|
litest_parameters_permutations(params, permutation_func, &data);
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-05 14:51:02 +10:00
|
|
|
static void
|
|
|
|
|
litest_add_tcase(const char *filename,
|
2015-05-20 10:12:39 +10:00
|
|
|
const char *funcname,
|
2020-01-03 18:06:54 -08:00
|
|
|
const void *func,
|
2019-07-01 16:12:26 +10:00
|
|
|
int64_t required,
|
|
|
|
|
int64_t excluded,
|
test: implement support for parametrizing tests
litest supports ranged tests but they are not enough, doubly so with
tests where we want to parametrize across multiple options.
This patch adds support for just that, in clunky C style.
The typical invocation for a test is by giving the test parameter
a name, a number of values and then the values themselves:
struct litest_parameters *params = litest_parameters_new("axis", 's', 2, "ABS_X", "ABS_Y",
"enabled", 'b', '2', true, false,
"number", 'u', '2', 10, 11,
NULL);
litest_add_parametrized(sometest, LITEST_ANY, LITEST_ANY, params);
litest_parameters_unref(params);
Currently supported are u (uint32), i (int32), d (double), b (bool),
c (char) and s (string).
In the test itself, the `test_env->params` variable is available and
retrieval of the parameters works like this:
const char *axis;
uint32_t number;
bool enabled;
litest_test_param_fetch(test_env->params,
"axis", &axis,
"enabled", &enabled,
"number", &number,
NULL);
Note that since this is an effectively internal test-suite only
functionality we don't do type-checking here, it's assumed that if you
write the code to pass parameters into a test you remember the type
of said params when you write the test code.
Because we don't have hashmaps or anything useful other than lists the
implementation is a bit clunky: we copy the parameter into the test
during litest_add_*, permutate it for our test list which gives us yet
another linked list C struct, and finally copy the actual value into
the test and test environment as it's executed. Not pretty, but it
works.
A few tests are switched as simple demonstration. The name of the
test has the parameters with their names and values appended now, e.g.:
"pointer:pointer_scroll_wheel_hires_send_only_lores:ms-surface-cover:axis:ABS_X"
"pointer:pointer_motion_relative_min_decel:mouse-roccat:direction:NW"
Filtering by parameters can be done via globs of their string
representation:
libinput-test-suite --filter-params="axis:ABS_*,enabled:true,number:10*"
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1109>
2024-12-22 00:06:19 +10:00
|
|
|
const struct range *range,
|
|
|
|
|
struct litest_parameters *params)
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
{
|
2015-12-02 09:27:22 +10:00
|
|
|
bool added = false;
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
|
2018-06-21 17:05:30 +10:00
|
|
|
litest_assert(required >= LITEST_DEVICELESS);
|
|
|
|
|
litest_assert(excluded >= LITEST_DEVICELESS);
|
2014-08-04 12:49:59 +10:00
|
|
|
|
2015-05-20 10:12:39 +10:00
|
|
|
if (filter_test && fnmatch(filter_test, funcname, 0) != 0)
|
|
|
|
|
return;
|
|
|
|
|
|
2024-10-17 19:55:25 +10:00
|
|
|
struct suite *suite = current_suite;
|
2021-02-05 14:51:02 +10:00
|
|
|
|
2024-10-17 19:55:25 +10:00
|
|
|
if (filter_group && fnmatch(filter_group, suite->name, 0) != 0)
|
2015-05-20 11:00:37 +10:00
|
|
|
return;
|
|
|
|
|
|
2018-06-21 17:05:30 +10:00
|
|
|
if (required == LITEST_DEVICELESS && excluded == LITEST_DEVICELESS) {
|
test: implement support for parametrizing tests
litest supports ranged tests but they are not enough, doubly so with
tests where we want to parametrize across multiple options.
This patch adds support for just that, in clunky C style.
The typical invocation for a test is by giving the test parameter
a name, a number of values and then the values themselves:
struct litest_parameters *params = litest_parameters_new("axis", 's', 2, "ABS_X", "ABS_Y",
"enabled", 'b', '2', true, false,
"number", 'u', '2', 10, 11,
NULL);
litest_add_parametrized(sometest, LITEST_ANY, LITEST_ANY, params);
litest_parameters_unref(params);
Currently supported are u (uint32), i (int32), d (double), b (bool),
c (char) and s (string).
In the test itself, the `test_env->params` variable is available and
retrieval of the parameters works like this:
const char *axis;
uint32_t number;
bool enabled;
litest_test_param_fetch(test_env->params,
"axis", &axis,
"enabled", &enabled,
"number", &number,
NULL);
Note that since this is an effectively internal test-suite only
functionality we don't do type-checking here, it's assumed that if you
write the code to pass parameters into a test you remember the type
of said params when you write the test code.
Because we don't have hashmaps or anything useful other than lists the
implementation is a bit clunky: we copy the parameter into the test
during litest_add_*, permutate it for our test list which gives us yet
another linked list C struct, and finally copy the actual value into
the test and test environment as it's executed. Not pretty, but it
works.
A few tests are switched as simple demonstration. The name of the
test has the parameters with their names and values appended now, e.g.:
"pointer:pointer_scroll_wheel_hires_send_only_lores:ms-surface-cover:axis:ABS_X"
"pointer:pointer_motion_relative_min_decel:mouse-roccat:direction:NW"
Filtering by parameters can be done via globs of their string
representation:
libinput-test-suite --filter-params="axis:ABS_*,enabled:true,number:10*"
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1109>
2024-12-22 00:06:19 +10:00
|
|
|
if (params)
|
|
|
|
|
litest_add_tcase_deviceless_with_params(suite,
|
|
|
|
|
func,
|
|
|
|
|
funcname,
|
|
|
|
|
params);
|
|
|
|
|
else
|
|
|
|
|
litest_add_tcase_deviceless(suite, func, funcname, range);
|
2018-06-21 17:05:30 +10:00
|
|
|
added = true;
|
|
|
|
|
} else if (required == LITEST_DISABLE_DEVICE &&
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
excluded == LITEST_DISABLE_DEVICE) {
|
test: implement support for parametrizing tests
litest supports ranged tests but they are not enough, doubly so with
tests where we want to parametrize across multiple options.
This patch adds support for just that, in clunky C style.
The typical invocation for a test is by giving the test parameter
a name, a number of values and then the values themselves:
struct litest_parameters *params = litest_parameters_new("axis", 's', 2, "ABS_X", "ABS_Y",
"enabled", 'b', '2', true, false,
"number", 'u', '2', 10, 11,
NULL);
litest_add_parametrized(sometest, LITEST_ANY, LITEST_ANY, params);
litest_parameters_unref(params);
Currently supported are u (uint32), i (int32), d (double), b (bool),
c (char) and s (string).
In the test itself, the `test_env->params` variable is available and
retrieval of the parameters works like this:
const char *axis;
uint32_t number;
bool enabled;
litest_test_param_fetch(test_env->params,
"axis", &axis,
"enabled", &enabled,
"number", &number,
NULL);
Note that since this is an effectively internal test-suite only
functionality we don't do type-checking here, it's assumed that if you
write the code to pass parameters into a test you remember the type
of said params when you write the test code.
Because we don't have hashmaps or anything useful other than lists the
implementation is a bit clunky: we copy the parameter into the test
during litest_add_*, permutate it for our test list which gives us yet
another linked list C struct, and finally copy the actual value into
the test and test environment as it's executed. Not pretty, but it
works.
A few tests are switched as simple demonstration. The name of the
test has the parameters with their names and values appended now, e.g.:
"pointer:pointer_scroll_wheel_hires_send_only_lores:ms-surface-cover:axis:ABS_X"
"pointer:pointer_motion_relative_min_decel:mouse-roccat:direction:NW"
Filtering by parameters can be done via globs of their string
representation:
libinput-test-suite --filter-params="axis:ABS_*,enabled:true,number:10*"
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1109>
2024-12-22 00:06:19 +10:00
|
|
|
if (params)
|
|
|
|
|
litest_add_tcase_no_device_with_params(suite,
|
|
|
|
|
func,
|
|
|
|
|
funcname,
|
|
|
|
|
params);
|
|
|
|
|
else
|
|
|
|
|
litest_add_tcase_no_device(suite, func, funcname, range);
|
2015-12-02 09:27:22 +10:00
|
|
|
added = true;
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
} else if (required != LITEST_ANY || excluded != LITEST_ANY) {
|
2018-06-22 16:57:51 +10:00
|
|
|
struct litest_test_device *dev;
|
|
|
|
|
|
|
|
|
|
list_for_each(dev, &devices, node) {
|
|
|
|
|
if (dev->features & LITEST_IGNORED)
|
2017-08-17 01:25:24 +02:00
|
|
|
continue;
|
|
|
|
|
|
2015-05-20 10:49:13 +10:00
|
|
|
if (filter_device &&
|
2018-06-22 16:57:51 +10:00
|
|
|
fnmatch(filter_device, dev->shortname, 0) != 0)
|
2015-05-20 10:49:13 +10:00
|
|
|
continue;
|
2018-06-22 16:57:51 +10:00
|
|
|
if ((dev->features & required) != required ||
|
|
|
|
|
(dev->features & excluded) != 0)
|
2015-05-20 10:49:13 +10:00
|
|
|
continue;
|
|
|
|
|
|
test: implement support for parametrizing tests
litest supports ranged tests but they are not enough, doubly so with
tests where we want to parametrize across multiple options.
This patch adds support for just that, in clunky C style.
The typical invocation for a test is by giving the test parameter
a name, a number of values and then the values themselves:
struct litest_parameters *params = litest_parameters_new("axis", 's', 2, "ABS_X", "ABS_Y",
"enabled", 'b', '2', true, false,
"number", 'u', '2', 10, 11,
NULL);
litest_add_parametrized(sometest, LITEST_ANY, LITEST_ANY, params);
litest_parameters_unref(params);
Currently supported are u (uint32), i (int32), d (double), b (bool),
c (char) and s (string).
In the test itself, the `test_env->params` variable is available and
retrieval of the parameters works like this:
const char *axis;
uint32_t number;
bool enabled;
litest_test_param_fetch(test_env->params,
"axis", &axis,
"enabled", &enabled,
"number", &number,
NULL);
Note that since this is an effectively internal test-suite only
functionality we don't do type-checking here, it's assumed that if you
write the code to pass parameters into a test you remember the type
of said params when you write the test code.
Because we don't have hashmaps or anything useful other than lists the
implementation is a bit clunky: we copy the parameter into the test
during litest_add_*, permutate it for our test list which gives us yet
another linked list C struct, and finally copy the actual value into
the test and test environment as it's executed. Not pretty, but it
works.
A few tests are switched as simple demonstration. The name of the
test has the parameters with their names and values appended now, e.g.:
"pointer:pointer_scroll_wheel_hires_send_only_lores:ms-surface-cover:axis:ABS_X"
"pointer:pointer_motion_relative_min_decel:mouse-roccat:direction:NW"
Filtering by parameters can be done via globs of their string
representation:
libinput-test-suite --filter-params="axis:ABS_*,enabled:true,number:10*"
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1109>
2024-12-22 00:06:19 +10:00
|
|
|
if (params) {
|
|
|
|
|
litest_add_tcase_for_device_with_params(suite,
|
|
|
|
|
funcname,
|
|
|
|
|
func,
|
|
|
|
|
dev,
|
|
|
|
|
params);
|
|
|
|
|
} else {
|
|
|
|
|
litest_add_tcase_for_device(suite,
|
|
|
|
|
funcname,
|
|
|
|
|
func,
|
|
|
|
|
dev,
|
|
|
|
|
range);
|
|
|
|
|
}
|
2015-12-02 09:27:22 +10:00
|
|
|
added = true;
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
}
|
|
|
|
|
} else {
|
2018-06-22 16:57:51 +10:00
|
|
|
struct litest_test_device *dev;
|
|
|
|
|
|
|
|
|
|
list_for_each(dev, &devices, node) {
|
|
|
|
|
if (dev->features & LITEST_IGNORED)
|
2017-08-17 01:25:24 +02:00
|
|
|
continue;
|
|
|
|
|
|
2015-05-20 10:49:13 +10:00
|
|
|
if (filter_device &&
|
2018-06-22 16:57:51 +10:00
|
|
|
fnmatch(filter_device, dev->shortname, 0) != 0)
|
2015-05-20 10:49:13 +10:00
|
|
|
continue;
|
|
|
|
|
|
test: implement support for parametrizing tests
litest supports ranged tests but they are not enough, doubly so with
tests where we want to parametrize across multiple options.
This patch adds support for just that, in clunky C style.
The typical invocation for a test is by giving the test parameter
a name, a number of values and then the values themselves:
struct litest_parameters *params = litest_parameters_new("axis", 's', 2, "ABS_X", "ABS_Y",
"enabled", 'b', '2', true, false,
"number", 'u', '2', 10, 11,
NULL);
litest_add_parametrized(sometest, LITEST_ANY, LITEST_ANY, params);
litest_parameters_unref(params);
Currently supported are u (uint32), i (int32), d (double), b (bool),
c (char) and s (string).
In the test itself, the `test_env->params` variable is available and
retrieval of the parameters works like this:
const char *axis;
uint32_t number;
bool enabled;
litest_test_param_fetch(test_env->params,
"axis", &axis,
"enabled", &enabled,
"number", &number,
NULL);
Note that since this is an effectively internal test-suite only
functionality we don't do type-checking here, it's assumed that if you
write the code to pass parameters into a test you remember the type
of said params when you write the test code.
Because we don't have hashmaps or anything useful other than lists the
implementation is a bit clunky: we copy the parameter into the test
during litest_add_*, permutate it for our test list which gives us yet
another linked list C struct, and finally copy the actual value into
the test and test environment as it's executed. Not pretty, but it
works.
A few tests are switched as simple demonstration. The name of the
test has the parameters with their names and values appended now, e.g.:
"pointer:pointer_scroll_wheel_hires_send_only_lores:ms-surface-cover:axis:ABS_X"
"pointer:pointer_motion_relative_min_decel:mouse-roccat:direction:NW"
Filtering by parameters can be done via globs of their string
representation:
libinput-test-suite --filter-params="axis:ABS_*,enabled:true,number:10*"
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1109>
2024-12-22 00:06:19 +10:00
|
|
|
if (params) {
|
|
|
|
|
litest_add_tcase_for_device_with_params(suite,
|
|
|
|
|
funcname,
|
|
|
|
|
func,
|
|
|
|
|
dev,
|
|
|
|
|
params);
|
|
|
|
|
} else {
|
|
|
|
|
litest_add_tcase_for_device(suite,
|
|
|
|
|
funcname,
|
|
|
|
|
func,
|
|
|
|
|
dev,
|
|
|
|
|
range);
|
|
|
|
|
}
|
2015-12-02 09:27:22 +10:00
|
|
|
added = true;
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
}
|
|
|
|
|
}
|
2015-12-02 09:27:22 +10:00
|
|
|
|
2016-08-23 10:39:16 +10:00
|
|
|
if (!added && filter_test == NULL && filter_device == NULL &&
|
|
|
|
|
filter_group == NULL) {
|
2015-12-02 09:27:22 +10:00
|
|
|
fprintf(stderr,
|
|
|
|
|
"Test '%s' does not match any devices. Aborting.\n",
|
|
|
|
|
funcname);
|
|
|
|
|
abort();
|
|
|
|
|
}
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2020-01-03 18:06:54 -08:00
|
|
|
_litest_add_no_device(const char *name, const char *funcname, const void *func)
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
{
|
2015-05-20 10:12:39 +10:00
|
|
|
_litest_add(name, funcname, func, LITEST_DISABLE_DEVICE, LITEST_DISABLE_DEVICE);
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
}
|
|
|
|
|
|
test: implement support for parametrizing tests
litest supports ranged tests but they are not enough, doubly so with
tests where we want to parametrize across multiple options.
This patch adds support for just that, in clunky C style.
The typical invocation for a test is by giving the test parameter
a name, a number of values and then the values themselves:
struct litest_parameters *params = litest_parameters_new("axis", 's', 2, "ABS_X", "ABS_Y",
"enabled", 'b', '2', true, false,
"number", 'u', '2', 10, 11,
NULL);
litest_add_parametrized(sometest, LITEST_ANY, LITEST_ANY, params);
litest_parameters_unref(params);
Currently supported are u (uint32), i (int32), d (double), b (bool),
c (char) and s (string).
In the test itself, the `test_env->params` variable is available and
retrieval of the parameters works like this:
const char *axis;
uint32_t number;
bool enabled;
litest_test_param_fetch(test_env->params,
"axis", &axis,
"enabled", &enabled,
"number", &number,
NULL);
Note that since this is an effectively internal test-suite only
functionality we don't do type-checking here, it's assumed that if you
write the code to pass parameters into a test you remember the type
of said params when you write the test code.
Because we don't have hashmaps or anything useful other than lists the
implementation is a bit clunky: we copy the parameter into the test
during litest_add_*, permutate it for our test list which gives us yet
another linked list C struct, and finally copy the actual value into
the test and test environment as it's executed. Not pretty, but it
works.
A few tests are switched as simple demonstration. The name of the
test has the parameters with their names and values appended now, e.g.:
"pointer:pointer_scroll_wheel_hires_send_only_lores:ms-surface-cover:axis:ABS_X"
"pointer:pointer_motion_relative_min_decel:mouse-roccat:direction:NW"
Filtering by parameters can be done via globs of their string
representation:
libinput-test-suite --filter-params="axis:ABS_*,enabled:true,number:10*"
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1109>
2024-12-22 00:06:19 +10:00
|
|
|
void
|
|
|
|
|
_litest_add_parametrized_no_device(const char *name,
|
|
|
|
|
const char *funcname,
|
|
|
|
|
const void *func,
|
|
|
|
|
struct litest_parameters *params)
|
|
|
|
|
{
|
|
|
|
|
_litest_add_parametrized(name,
|
|
|
|
|
funcname,
|
|
|
|
|
func,
|
|
|
|
|
LITEST_DISABLE_DEVICE,
|
|
|
|
|
LITEST_DISABLE_DEVICE,
|
|
|
|
|
params);
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-06 08:09:50 +10:00
|
|
|
void
|
2015-05-20 10:12:39 +10:00
|
|
|
_litest_add_ranged_no_device(const char *name,
|
|
|
|
|
const char *funcname,
|
2020-01-03 18:06:54 -08:00
|
|
|
const void *func,
|
2015-05-20 10:12:39 +10:00
|
|
|
const struct range *range)
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
{
|
2015-05-20 10:12:39 +10:00
|
|
|
_litest_add_ranged(name,
|
|
|
|
|
funcname,
|
|
|
|
|
func,
|
|
|
|
|
LITEST_DISABLE_DEVICE,
|
|
|
|
|
LITEST_DISABLE_DEVICE,
|
|
|
|
|
range);
|
2014-07-14 00:01:10 +02:00
|
|
|
}
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
|
2018-06-21 17:05:30 +10:00
|
|
|
void
|
|
|
|
|
_litest_add_deviceless(const char *name, const char *funcname, const void *func)
|
|
|
|
|
{
|
|
|
|
|
_litest_add_ranged(name,
|
|
|
|
|
funcname,
|
|
|
|
|
func,
|
|
|
|
|
LITEST_DEVICELESS,
|
|
|
|
|
LITEST_DEVICELESS,
|
|
|
|
|
NULL);
|
|
|
|
|
}
|
|
|
|
|
|
test: implement support for parametrizing tests
litest supports ranged tests but they are not enough, doubly so with
tests where we want to parametrize across multiple options.
This patch adds support for just that, in clunky C style.
The typical invocation for a test is by giving the test parameter
a name, a number of values and then the values themselves:
struct litest_parameters *params = litest_parameters_new("axis", 's', 2, "ABS_X", "ABS_Y",
"enabled", 'b', '2', true, false,
"number", 'u', '2', 10, 11,
NULL);
litest_add_parametrized(sometest, LITEST_ANY, LITEST_ANY, params);
litest_parameters_unref(params);
Currently supported are u (uint32), i (int32), d (double), b (bool),
c (char) and s (string).
In the test itself, the `test_env->params` variable is available and
retrieval of the parameters works like this:
const char *axis;
uint32_t number;
bool enabled;
litest_test_param_fetch(test_env->params,
"axis", &axis,
"enabled", &enabled,
"number", &number,
NULL);
Note that since this is an effectively internal test-suite only
functionality we don't do type-checking here, it's assumed that if you
write the code to pass parameters into a test you remember the type
of said params when you write the test code.
Because we don't have hashmaps or anything useful other than lists the
implementation is a bit clunky: we copy the parameter into the test
during litest_add_*, permutate it for our test list which gives us yet
another linked list C struct, and finally copy the actual value into
the test and test environment as it's executed. Not pretty, but it
works.
A few tests are switched as simple demonstration. The name of the
test has the parameters with their names and values appended now, e.g.:
"pointer:pointer_scroll_wheel_hires_send_only_lores:ms-surface-cover:axis:ABS_X"
"pointer:pointer_motion_relative_min_decel:mouse-roccat:direction:NW"
Filtering by parameters can be done via globs of their string
representation:
libinput-test-suite --filter-params="axis:ABS_*,enabled:true,number:10*"
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1109>
2024-12-22 00:06:19 +10:00
|
|
|
void
|
|
|
|
|
_litest_add_parametrized_deviceless(const char *name,
|
|
|
|
|
const char *funcname,
|
|
|
|
|
const void *func,
|
|
|
|
|
struct litest_parameters *params)
|
|
|
|
|
{
|
|
|
|
|
_litest_add_parametrized(name,
|
|
|
|
|
funcname,
|
|
|
|
|
func,
|
|
|
|
|
LITEST_DISABLE_DEVICE,
|
|
|
|
|
LITEST_DISABLE_DEVICE,
|
|
|
|
|
params);
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-14 00:01:10 +02:00
|
|
|
void
|
2015-05-20 10:12:39 +10:00
|
|
|
_litest_add(const char *name,
|
|
|
|
|
const char *funcname,
|
2020-01-03 18:06:54 -08:00
|
|
|
const void *func,
|
2019-07-01 16:12:26 +10:00
|
|
|
int64_t required,
|
|
|
|
|
int64_t excluded)
|
2014-07-14 00:01:10 +02:00
|
|
|
{
|
2015-05-20 10:12:39 +10:00
|
|
|
_litest_add_ranged(name, funcname, func, required, excluded, NULL);
|
2015-05-06 08:09:50 +10:00
|
|
|
}
|
2014-07-14 00:01:10 +02:00
|
|
|
|
2015-05-06 08:09:50 +10:00
|
|
|
void
|
2015-05-20 10:12:39 +10:00
|
|
|
_litest_add_ranged(const char *name,
|
|
|
|
|
const char *funcname,
|
2020-01-03 18:06:54 -08:00
|
|
|
const void *func,
|
2019-07-01 16:12:26 +10:00
|
|
|
int64_t required,
|
|
|
|
|
int64_t excluded,
|
2015-05-20 10:12:39 +10:00
|
|
|
const struct range *range)
|
2015-05-06 08:09:50 +10:00
|
|
|
{
|
test: implement support for parametrizing tests
litest supports ranged tests but they are not enough, doubly so with
tests where we want to parametrize across multiple options.
This patch adds support for just that, in clunky C style.
The typical invocation for a test is by giving the test parameter
a name, a number of values and then the values themselves:
struct litest_parameters *params = litest_parameters_new("axis", 's', 2, "ABS_X", "ABS_Y",
"enabled", 'b', '2', true, false,
"number", 'u', '2', 10, 11,
NULL);
litest_add_parametrized(sometest, LITEST_ANY, LITEST_ANY, params);
litest_parameters_unref(params);
Currently supported are u (uint32), i (int32), d (double), b (bool),
c (char) and s (string).
In the test itself, the `test_env->params` variable is available and
retrieval of the parameters works like this:
const char *axis;
uint32_t number;
bool enabled;
litest_test_param_fetch(test_env->params,
"axis", &axis,
"enabled", &enabled,
"number", &number,
NULL);
Note that since this is an effectively internal test-suite only
functionality we don't do type-checking here, it's assumed that if you
write the code to pass parameters into a test you remember the type
of said params when you write the test code.
Because we don't have hashmaps or anything useful other than lists the
implementation is a bit clunky: we copy the parameter into the test
during litest_add_*, permutate it for our test list which gives us yet
another linked list C struct, and finally copy the actual value into
the test and test environment as it's executed. Not pretty, but it
works.
A few tests are switched as simple demonstration. The name of the
test has the parameters with their names and values appended now, e.g.:
"pointer:pointer_scroll_wheel_hires_send_only_lores:ms-surface-cover:axis:ABS_X"
"pointer:pointer_motion_relative_min_decel:mouse-roccat:direction:NW"
Filtering by parameters can be done via globs of their string
representation:
libinput-test-suite --filter-params="axis:ABS_*,enabled:true,number:10*"
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1109>
2024-12-22 00:06:19 +10:00
|
|
|
litest_add_tcase(name, funcname, func, required, excluded, range, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
_litest_add_parametrized(const char *name,
|
|
|
|
|
const char *funcname,
|
|
|
|
|
const void *func,
|
|
|
|
|
int64_t required,
|
|
|
|
|
int64_t excluded,
|
|
|
|
|
struct litest_parameters *params)
|
|
|
|
|
{
|
|
|
|
|
litest_add_tcase(name, funcname, func, required, excluded, NULL, params);
|
2014-07-14 00:01:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2015-05-20 10:12:39 +10:00
|
|
|
_litest_add_for_device(const char *name,
|
|
|
|
|
const char *funcname,
|
2020-01-03 18:06:54 -08:00
|
|
|
const void *func,
|
2015-05-20 10:12:39 +10:00
|
|
|
enum litest_device_type type)
|
2014-07-14 00:01:10 +02:00
|
|
|
{
|
2015-05-20 10:12:39 +10:00
|
|
|
_litest_add_ranged_for_device(name, funcname, func, type, NULL);
|
2014-07-14 00:01:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2021-02-05 14:51:02 +10:00
|
|
|
_litest_add_ranged_for_device(const char *filename,
|
2015-05-20 10:12:39 +10:00
|
|
|
const char *funcname,
|
2020-01-03 18:06:54 -08:00
|
|
|
const void *func,
|
2015-05-20 10:12:39 +10:00
|
|
|
enum litest_device_type type,
|
|
|
|
|
const struct range *range)
|
2014-07-14 00:01:10 +02:00
|
|
|
{
|
2018-06-22 16:57:51 +10:00
|
|
|
struct litest_test_device *dev;
|
2015-05-28 13:33:54 +10:00
|
|
|
bool device_filtered = false;
|
2014-07-14 00:01:10 +02:00
|
|
|
|
2016-11-25 14:56:52 +10:00
|
|
|
litest_assert(type < LITEST_NO_DEVICE);
|
2014-08-04 12:49:59 +10:00
|
|
|
|
2015-05-22 14:55:24 +10:00
|
|
|
if (filter_test && fnmatch(filter_test, funcname, 0) != 0)
|
|
|
|
|
return;
|
|
|
|
|
|
2024-10-17 19:55:25 +10:00
|
|
|
struct suite *s = current_suite;
|
2024-03-15 10:11:54 +10:00
|
|
|
|
2024-10-17 19:55:25 +10:00
|
|
|
if (filter_group && fnmatch(filter_group, s->name, 0) != 0)
|
2015-05-20 11:00:37 +10:00
|
|
|
return;
|
|
|
|
|
|
2018-06-22 16:57:51 +10:00
|
|
|
list_for_each(dev, &devices, node) {
|
|
|
|
|
if (filter_device && fnmatch(filter_device, dev->shortname, 0) != 0) {
|
2015-05-28 13:33:54 +10:00
|
|
|
device_filtered = true;
|
2015-05-20 10:49:13 +10:00
|
|
|
continue;
|
2015-05-28 13:33:54 +10:00
|
|
|
}
|
2015-05-20 10:49:13 +10:00
|
|
|
|
2018-06-22 16:57:51 +10:00
|
|
|
if (dev->type == type) {
|
2015-05-20 10:12:39 +10:00
|
|
|
litest_add_tcase_for_device(s, funcname, func, dev, range);
|
2014-07-14 00:01:10 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-28 13:33:54 +10:00
|
|
|
/* only abort if no filter was set, that's a bug */
|
|
|
|
|
if (!device_filtered)
|
2024-10-14 21:42:26 +10:00
|
|
|
litest_abort_msg("Invalid test device type");
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
}
|
|
|
|
|
|
test: implement support for parametrizing tests
litest supports ranged tests but they are not enough, doubly so with
tests where we want to parametrize across multiple options.
This patch adds support for just that, in clunky C style.
The typical invocation for a test is by giving the test parameter
a name, a number of values and then the values themselves:
struct litest_parameters *params = litest_parameters_new("axis", 's', 2, "ABS_X", "ABS_Y",
"enabled", 'b', '2', true, false,
"number", 'u', '2', 10, 11,
NULL);
litest_add_parametrized(sometest, LITEST_ANY, LITEST_ANY, params);
litest_parameters_unref(params);
Currently supported are u (uint32), i (int32), d (double), b (bool),
c (char) and s (string).
In the test itself, the `test_env->params` variable is available and
retrieval of the parameters works like this:
const char *axis;
uint32_t number;
bool enabled;
litest_test_param_fetch(test_env->params,
"axis", &axis,
"enabled", &enabled,
"number", &number,
NULL);
Note that since this is an effectively internal test-suite only
functionality we don't do type-checking here, it's assumed that if you
write the code to pass parameters into a test you remember the type
of said params when you write the test code.
Because we don't have hashmaps or anything useful other than lists the
implementation is a bit clunky: we copy the parameter into the test
during litest_add_*, permutate it for our test list which gives us yet
another linked list C struct, and finally copy the actual value into
the test and test environment as it's executed. Not pretty, but it
works.
A few tests are switched as simple demonstration. The name of the
test has the parameters with their names and values appended now, e.g.:
"pointer:pointer_scroll_wheel_hires_send_only_lores:ms-surface-cover:axis:ABS_X"
"pointer:pointer_motion_relative_min_decel:mouse-roccat:direction:NW"
Filtering by parameters can be done via globs of their string
representation:
libinput-test-suite --filter-params="axis:ABS_*,enabled:true,number:10*"
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1109>
2024-12-22 00:06:19 +10:00
|
|
|
void
|
|
|
|
|
_litest_add_parametrized_for_device(const char *filename,
|
|
|
|
|
const char *funcname,
|
|
|
|
|
const void *func,
|
|
|
|
|
enum litest_device_type type,
|
|
|
|
|
struct litest_parameters *params)
|
|
|
|
|
{
|
|
|
|
|
struct litest_test_device *dev;
|
|
|
|
|
bool device_filtered = false;
|
|
|
|
|
|
|
|
|
|
litest_assert(type < LITEST_NO_DEVICE);
|
|
|
|
|
|
|
|
|
|
if (filter_test && fnmatch(filter_test, funcname, 0) != 0)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
struct suite *s = current_suite;
|
|
|
|
|
|
|
|
|
|
if (filter_group && fnmatch(filter_group, s->name, 0) != 0)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
list_for_each(dev, &devices, node) {
|
|
|
|
|
if (filter_device && fnmatch(filter_device, dev->shortname, 0) != 0) {
|
|
|
|
|
device_filtered = true;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (dev->type == type) {
|
|
|
|
|
litest_add_tcase_for_device_with_params(s,
|
|
|
|
|
funcname,
|
|
|
|
|
func,
|
|
|
|
|
dev,
|
|
|
|
|
params);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* only abort if no filter was set, that's a bug */
|
|
|
|
|
if (!device_filtered)
|
|
|
|
|
litest_abort_msg("Invalid test device type");
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-11 09:36:07 +10:00
|
|
|
static int
|
|
|
|
|
is_actual_error(const char *error, size_t index, void *data)
|
|
|
|
|
{
|
|
|
|
|
/* We don't want to abort on these errors */
|
|
|
|
|
if (((RUNNING_ON_VALGRIND || in_debugger) &&
|
|
|
|
|
strstr(error, "scheduled expiry is in the past")) ||
|
|
|
|
|
strstr(error, "event processing lagging behind")) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-24 11:06:23 +10:00
|
|
|
LIBINPUT_ATTRIBUTE_PRINTF(3, 0)
|
2014-06-06 15:55:15 +10:00
|
|
|
static void
|
2014-06-18 19:51:19 +10:00
|
|
|
litest_log_handler(struct libinput *libinput,
|
|
|
|
|
enum libinput_log_priority pri,
|
2014-06-06 15:55:15 +10:00
|
|
|
const char *format,
|
|
|
|
|
va_list args)
|
|
|
|
|
{
|
|
|
|
|
const char *priority = NULL;
|
2025-06-17 11:09:33 +10:00
|
|
|
const char *color = "";
|
|
|
|
|
const char *color_reset = ANSI_NORMAL;
|
2017-03-28 11:31:16 +10:00
|
|
|
|
2014-06-06 15:55:15 +10:00
|
|
|
switch (pri) {
|
2017-03-28 11:31:16 +10:00
|
|
|
case LIBINPUT_LOG_PRIORITY_INFO:
|
|
|
|
|
priority = "info ";
|
2025-06-18 13:28:34 +10:00
|
|
|
color = ANSI_BOLD;
|
2017-03-28 11:31:16 +10:00
|
|
|
break;
|
|
|
|
|
case LIBINPUT_LOG_PRIORITY_ERROR:
|
|
|
|
|
priority = "error";
|
2017-03-28 11:48:52 +10:00
|
|
|
color = ANSI_BRIGHT_RED;
|
2017-03-28 11:31:16 +10:00
|
|
|
break;
|
|
|
|
|
case LIBINPUT_LOG_PRIORITY_DEBUG:
|
|
|
|
|
priority = "debug";
|
|
|
|
|
color = ANSI_NORMAL;
|
|
|
|
|
break;
|
2015-03-13 10:11:41 +10:00
|
|
|
default:
|
|
|
|
|
abort();
|
2014-06-06 15:55:15 +10:00
|
|
|
}
|
|
|
|
|
|
2025-06-17 11:09:33 +10:00
|
|
|
_autofree_ char *msg = strdup_vprintf(format, args);
|
|
|
|
|
|
2025-01-07 13:52:46 +10:00
|
|
|
if (!use_colors)
|
2025-06-17 11:09:33 +10:00
|
|
|
color_reset = "";
|
2025-06-18 12:52:29 +10:00
|
|
|
else if (strstr(format, "tap:"))
|
2017-03-28 11:48:52 +10:00
|
|
|
color = ANSI_BLUE;
|
2025-06-18 12:52:29 +10:00
|
|
|
else if (strstr(format, "thumb state:"))
|
2017-03-28 11:48:52 +10:00
|
|
|
color = ANSI_YELLOW;
|
2025-06-18 12:52:29 +10:00
|
|
|
else if (strstr(format, "button state:"))
|
2017-03-28 11:48:52 +10:00
|
|
|
color = ANSI_MAGENTA;
|
2025-06-18 12:52:29 +10:00
|
|
|
else if (strstr(format, "touch-size:") || strstr(format, "pressure:"))
|
2017-03-28 11:48:52 +10:00
|
|
|
color = ANSI_GREEN;
|
2025-06-18 12:52:29 +10:00
|
|
|
else if (strstr(format, "palm:") || strstr(format, "thumb:"))
|
2017-03-28 11:48:52 +10:00
|
|
|
color = ANSI_CYAN;
|
2025-06-18 12:52:29 +10:00
|
|
|
else if (strstr(format, "edge-scroll:"))
|
2017-03-28 11:48:52 +10:00
|
|
|
color = ANSI_BRIGHT_GREEN;
|
2025-06-18 12:52:29 +10:00
|
|
|
else if (strstr(format, "gesture:"))
|
2024-09-12 14:59:38 +10:00
|
|
|
color = ANSI_BRIGHT_YELLOW;
|
2025-06-18 14:55:16 +10:00
|
|
|
else if (strstr(msg, "Plugin:"))
|
|
|
|
|
color = ANSI_BRIGHT_CYAN;
|
2017-03-28 11:48:52 +10:00
|
|
|
|
2025-06-17 11:09:33 +10:00
|
|
|
fprintf(stderr, "%slitest %s %s%s", color, priority, msg, color_reset);
|
2017-03-28 11:31:16 +10:00
|
|
|
|
2025-06-17 11:09:33 +10:00
|
|
|
if (strstr(msg, "client bug: ") || strstr(msg, "libinput bug: ") ||
|
2025-06-18 14:55:16 +10:00
|
|
|
strstr(msg, "plugin bug: ")) {
|
2018-02-01 16:45:35 +10:00
|
|
|
/* valgrind is too slow and some of our offsets are too
|
|
|
|
|
* short, don't abort if during a valgrind run we get a
|
|
|
|
|
* negative offset */
|
2025-06-12 12:52:31 +10:00
|
|
|
if ((RUNNING_ON_VALGRIND || in_debugger) &&
|
2024-09-13 12:56:28 +10:00
|
|
|
strstr(format, "scheduled expiry is in the past")) {
|
2020-04-13 15:12:43 +10:00
|
|
|
/* noop */
|
2024-09-13 12:56:28 +10:00
|
|
|
} else if (strstr(format, "event processing lagging behind")) {
|
2020-04-13 15:12:43 +10:00
|
|
|
/* noop */
|
|
|
|
|
} else {
|
2024-10-14 21:42:26 +10:00
|
|
|
litest_abort_msg("libinput bug triggered, aborting.");
|
2020-04-13 15:12:43 +10:00
|
|
|
}
|
2018-02-01 16:45:35 +10:00
|
|
|
}
|
2018-08-28 10:00:12 +10:00
|
|
|
|
2025-06-17 11:09:33 +10:00
|
|
|
if (strstr(msg, "Touch jump detected and discarded")) {
|
2024-10-14 21:42:26 +10:00
|
|
|
litest_abort_msg("libinput touch jump triggered, aborting.");
|
2018-08-28 10:00:12 +10:00
|
|
|
}
|
2014-06-06 15:55:15 +10:00
|
|
|
}
|
|
|
|
|
|
2019-06-10 22:18:50 +10:00
|
|
|
static void
|
|
|
|
|
litest_init_device_udev_rules(struct litest_test_device *dev, FILE *f)
|
|
|
|
|
{
|
|
|
|
|
const struct key_value_str *kv;
|
|
|
|
|
static int count;
|
2020-02-12 18:04:41 +10:00
|
|
|
bool need_keyboard_builtin = false;
|
2019-06-10 22:18:50 +10:00
|
|
|
|
2019-07-08 09:53:49 +10:00
|
|
|
if (dev->udev_properties[0].key == NULL)
|
2019-06-10 22:18:50 +10:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
count++;
|
|
|
|
|
|
|
|
|
|
fprintf(f, "# %s\n", dev->shortname);
|
|
|
|
|
fprintf(f, "ACTION==\"remove\", GOTO=\"rule%d_end\"\n", count);
|
|
|
|
|
fprintf(f, "KERNEL!=\"event*\", GOTO=\"rule%d_end\"\n", count);
|
|
|
|
|
|
|
|
|
|
fprintf(f, "ATTRS{name}==\"litest %s*\"", dev->name);
|
|
|
|
|
|
|
|
|
|
kv = dev->udev_properties;
|
|
|
|
|
while (kv->key) {
|
|
|
|
|
fprintf(f, ", \\\n\tENV{%s}=\"%s\"", kv->key, kv->value);
|
2025-01-09 09:04:54 +10:00
|
|
|
if (strstartswith(kv->key, "EVDEV_ABS_"))
|
2020-02-12 18:04:41 +10:00
|
|
|
need_keyboard_builtin = true;
|
2019-06-10 22:18:50 +10:00
|
|
|
kv++;
|
|
|
|
|
}
|
|
|
|
|
fprintf(f, "\n");
|
2020-02-12 18:04:41 +10:00
|
|
|
|
|
|
|
|
/* Special case: the udev keyboard builtin is only run for hwdb
|
|
|
|
|
* matches but we don't set any up in litest. So instead scan the
|
|
|
|
|
* device's udev properties for any EVDEV_ABS properties and where
|
|
|
|
|
* they exist, force a (re-)run of the keyboard builtin to set up
|
|
|
|
|
* the evdev device correctly.
|
|
|
|
|
* This needs to be done as separate rule apparently, otherwise the
|
|
|
|
|
* ENV variables aren't set yet by the time the builtin runs.
|
|
|
|
|
*/
|
|
|
|
|
if (need_keyboard_builtin) {
|
|
|
|
|
fprintf(f,
|
|
|
|
|
""
|
|
|
|
|
"ATTRS{name}==\"litest %s*\","
|
2020-03-27 19:37:10 +10:00
|
|
|
" IMPORT{builtin}=\"keyboard\"\n",
|
2020-02-12 18:04:41 +10:00
|
|
|
dev->name);
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-10 22:18:50 +10:00
|
|
|
fprintf(f, "LABEL=\"rule%d_end\"\n\n", count);
|
2025-07-01 16:30:11 +10:00
|
|
|
;
|
2019-06-10 22:18:50 +10:00
|
|
|
}
|
2016-07-08 09:42:36 +10:00
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
litest_init_all_device_udev_rules(struct list *created_files)
|
|
|
|
|
{
|
2019-06-10 22:18:50 +10:00
|
|
|
struct created_file *file = zalloc(sizeof(*file));
|
2018-06-22 16:57:51 +10:00
|
|
|
struct litest_test_device *dev;
|
2019-06-10 22:18:50 +10:00
|
|
|
FILE *f;
|
|
|
|
|
int fd;
|
2016-07-08 09:42:36 +10:00
|
|
|
|
2025-04-02 15:37:23 +10:00
|
|
|
char *path = strdup_printf("%s/99-litest-XXXXXX.rules", UDEV_RULES_D);
|
|
|
|
|
litest_assert_ptr_notnull(path);
|
2016-07-08 09:42:36 +10:00
|
|
|
|
2019-06-10 22:18:50 +10:00
|
|
|
fd = mkstemps(path, 6);
|
2024-03-14 12:07:29 +10:00
|
|
|
litest_assert_errno_success(fd);
|
2019-06-10 22:18:50 +10:00
|
|
|
f = fdopen(fd, "w");
|
|
|
|
|
litest_assert_notnull(f);
|
|
|
|
|
|
|
|
|
|
list_for_each(dev, &devices, node)
|
|
|
|
|
litest_init_device_udev_rules(dev, f);
|
|
|
|
|
|
|
|
|
|
fclose(f);
|
|
|
|
|
|
|
|
|
|
file->path = path;
|
|
|
|
|
list_insert(created_files, &file->link);
|
2016-07-08 09:42:36 +10:00
|
|
|
}
|
|
|
|
|
|
2014-06-13 11:11:05 +10:00
|
|
|
static int
|
|
|
|
|
open_restricted(const char *path, int flags, void *userdata)
|
|
|
|
|
{
|
2020-07-03 12:29:16 +10:00
|
|
|
const char prefix[] = "/dev/input/event";
|
|
|
|
|
struct litest_context *ctx = userdata;
|
|
|
|
|
struct path *p;
|
|
|
|
|
int fd;
|
|
|
|
|
|
|
|
|
|
litest_assert_ptr_notnull(ctx);
|
|
|
|
|
|
|
|
|
|
fd = open(path, flags);
|
|
|
|
|
if (fd < 0)
|
|
|
|
|
return -errno;
|
|
|
|
|
|
2025-01-09 09:04:54 +10:00
|
|
|
if (strstartswith(path, prefix)) {
|
2020-07-03 12:29:16 +10:00
|
|
|
p = zalloc(sizeof *p);
|
|
|
|
|
p->path = safe_strdup(path);
|
|
|
|
|
p->fd = fd;
|
2020-07-03 12:46:38 +10:00
|
|
|
/* We specifically insert here so that the most-recently
|
|
|
|
|
* opened path is the first one in the list. This helps when
|
|
|
|
|
* we have multiple test devices with the same device path,
|
|
|
|
|
* the fd of the most recent device is the first one to get
|
|
|
|
|
* grabbed
|
|
|
|
|
*/
|
|
|
|
|
list_insert(&ctx->paths, &p->link);
|
2020-07-03 12:29:16 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return fd;
|
2014-06-13 11:11:05 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
close_restricted(int fd, void *userdata)
|
|
|
|
|
{
|
2020-07-03 12:29:16 +10:00
|
|
|
struct litest_context *ctx = userdata;
|
2021-02-22 19:52:40 +03:00
|
|
|
struct path *p;
|
2020-07-03 12:29:16 +10:00
|
|
|
|
2021-02-22 19:52:40 +03:00
|
|
|
list_for_each_safe(p, &ctx->paths, link) {
|
2020-07-03 12:29:16 +10:00
|
|
|
if (p->fd != fd)
|
|
|
|
|
continue;
|
|
|
|
|
list_remove(&p->link);
|
|
|
|
|
free(p->path);
|
|
|
|
|
free(p);
|
|
|
|
|
}
|
|
|
|
|
|
2014-06-13 11:11:05 +10:00
|
|
|
close(fd);
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-23 19:17:32 +01:00
|
|
|
static struct libinput_interface interface = {
|
2014-06-13 11:11:05 +10:00
|
|
|
.open_restricted = open_restricted,
|
|
|
|
|
.close_restricted = close_restricted,
|
|
|
|
|
};
|
|
|
|
|
|
2018-05-24 16:52:42 +10:00
|
|
|
LIBINPUT_ATTRIBUTE_PRINTF(3, 0)
|
|
|
|
|
static inline void
|
|
|
|
|
quirk_log_handler(struct libinput *unused,
|
|
|
|
|
enum libinput_log_priority priority,
|
|
|
|
|
const char *format,
|
|
|
|
|
va_list args)
|
|
|
|
|
{
|
|
|
|
|
if (priority < LIBINPUT_LOG_PRIORITY_ERROR)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
vfprintf(stderr, format, args);
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-16 18:31:51 +10:00
|
|
|
static enum litest_runner_result
|
|
|
|
|
init_quirks(void *userdata)
|
|
|
|
|
{
|
|
|
|
|
const char *data_path = getenv("LIBINPUT_QUIRKS_DIR");
|
|
|
|
|
if (!data_path)
|
|
|
|
|
data_path = LIBINPUT_QUIRKS_DIR;
|
|
|
|
|
|
|
|
|
|
quirks_context = quirks_init_subsystem(data_path,
|
|
|
|
|
NULL,
|
|
|
|
|
quirk_log_handler,
|
|
|
|
|
NULL,
|
|
|
|
|
QLOG_LIBINPUT_LOGGING);
|
|
|
|
|
|
|
|
|
|
return LITEST_PASS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
teardown_quirks(void *userdata)
|
|
|
|
|
{
|
|
|
|
|
quirks_context_unref(quirks_context);
|
|
|
|
|
}
|
|
|
|
|
|
2016-07-22 15:19:23 +10:00
|
|
|
static int
|
2024-10-12 10:31:42 +10:00
|
|
|
litest_run_suite(struct list *suites, int njobs)
|
2016-07-22 15:19:23 +10:00
|
|
|
{
|
2024-10-12 10:31:42 +10:00
|
|
|
size_t ntests = 0;
|
|
|
|
|
enum litest_runner_result result = LITEST_SKIP;
|
2016-07-22 15:19:23 +10:00
|
|
|
struct suite *s;
|
2025-04-07 10:53:12 +10:00
|
|
|
_destroy_(litest_runner) *runner = litest_runner_new();
|
2016-07-22 15:19:23 +10:00
|
|
|
|
2025-04-03 12:03:17 +10:00
|
|
|
litest_runner_set_num_parallel(runner, njobs > 0 ? njobs : 0);
|
2024-10-21 12:12:45 +10:00
|
|
|
if (outfile)
|
|
|
|
|
litest_runner_set_output_file(runner, outfile);
|
2024-10-12 10:31:42 +10:00
|
|
|
litest_runner_set_verbose(runner, verbose);
|
2025-01-07 13:52:46 +10:00
|
|
|
litest_runner_set_use_colors(runner, use_colors);
|
2024-10-12 10:31:42 +10:00
|
|
|
litest_runner_set_timeout(runner, 30);
|
2024-10-15 15:28:56 +10:00
|
|
|
litest_runner_set_exit_on_fail(runner, exit_first);
|
2024-10-16 18:31:51 +10:00
|
|
|
litest_runner_set_setup_funcs(runner, init_quirks, teardown_quirks, NULL);
|
2016-07-22 15:19:23 +10:00
|
|
|
|
2024-10-12 10:31:42 +10:00
|
|
|
list_for_each(s, suites, node) {
|
|
|
|
|
struct test *t;
|
|
|
|
|
list_for_each(t, &s->tests, node) {
|
test: implement support for parametrizing tests
litest supports ranged tests but they are not enough, doubly so with
tests where we want to parametrize across multiple options.
This patch adds support for just that, in clunky C style.
The typical invocation for a test is by giving the test parameter
a name, a number of values and then the values themselves:
struct litest_parameters *params = litest_parameters_new("axis", 's', 2, "ABS_X", "ABS_Y",
"enabled", 'b', '2', true, false,
"number", 'u', '2', 10, 11,
NULL);
litest_add_parametrized(sometest, LITEST_ANY, LITEST_ANY, params);
litest_parameters_unref(params);
Currently supported are u (uint32), i (int32), d (double), b (bool),
c (char) and s (string).
In the test itself, the `test_env->params` variable is available and
retrieval of the parameters works like this:
const char *axis;
uint32_t number;
bool enabled;
litest_test_param_fetch(test_env->params,
"axis", &axis,
"enabled", &enabled,
"number", &number,
NULL);
Note that since this is an effectively internal test-suite only
functionality we don't do type-checking here, it's assumed that if you
write the code to pass parameters into a test you remember the type
of said params when you write the test code.
Because we don't have hashmaps or anything useful other than lists the
implementation is a bit clunky: we copy the parameter into the test
during litest_add_*, permutate it for our test list which gives us yet
another linked list C struct, and finally copy the actual value into
the test and test environment as it's executed. Not pretty, but it
works.
A few tests are switched as simple demonstration. The name of the
test has the parameters with their names and values appended now, e.g.:
"pointer:pointer_scroll_wheel_hires_send_only_lores:ms-surface-cover:axis:ABS_X"
"pointer:pointer_motion_relative_min_decel:mouse-roccat:direction:NW"
Filtering by parameters can be done via globs of their string
representation:
libinput-test-suite --filter-params="axis:ABS_*,enabled:true,number:10*"
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1109>
2024-12-22 00:06:19 +10:00
|
|
|
struct litest_runner_test_description tdesc = { 0 };
|
2024-10-12 10:31:42 +10:00
|
|
|
|
|
|
|
|
if (range_is_valid(&t->range)) {
|
|
|
|
|
snprintf(tdesc.name,
|
|
|
|
|
sizeof(tdesc.name),
|
|
|
|
|
"%s:%s:%s:%d",
|
|
|
|
|
s->name,
|
|
|
|
|
t->name,
|
|
|
|
|
t->devname,
|
|
|
|
|
t->rangeval);
|
test: implement support for parametrizing tests
litest supports ranged tests but they are not enough, doubly so with
tests where we want to parametrize across multiple options.
This patch adds support for just that, in clunky C style.
The typical invocation for a test is by giving the test parameter
a name, a number of values and then the values themselves:
struct litest_parameters *params = litest_parameters_new("axis", 's', 2, "ABS_X", "ABS_Y",
"enabled", 'b', '2', true, false,
"number", 'u', '2', 10, 11,
NULL);
litest_add_parametrized(sometest, LITEST_ANY, LITEST_ANY, params);
litest_parameters_unref(params);
Currently supported are u (uint32), i (int32), d (double), b (bool),
c (char) and s (string).
In the test itself, the `test_env->params` variable is available and
retrieval of the parameters works like this:
const char *axis;
uint32_t number;
bool enabled;
litest_test_param_fetch(test_env->params,
"axis", &axis,
"enabled", &enabled,
"number", &number,
NULL);
Note that since this is an effectively internal test-suite only
functionality we don't do type-checking here, it's assumed that if you
write the code to pass parameters into a test you remember the type
of said params when you write the test code.
Because we don't have hashmaps or anything useful other than lists the
implementation is a bit clunky: we copy the parameter into the test
during litest_add_*, permutate it for our test list which gives us yet
another linked list C struct, and finally copy the actual value into
the test and test environment as it's executed. Not pretty, but it
works.
A few tests are switched as simple demonstration. The name of the
test has the parameters with their names and values appended now, e.g.:
"pointer:pointer_scroll_wheel_hires_send_only_lores:ms-surface-cover:axis:ABS_X"
"pointer:pointer_motion_relative_min_decel:mouse-roccat:direction:NW"
Filtering by parameters can be done via globs of their string
representation:
libinput-test-suite --filter-params="axis:ABS_*,enabled:true,number:10*"
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1109>
2024-12-22 00:06:19 +10:00
|
|
|
} else if (t->params) {
|
|
|
|
|
char buf[256] = { 0 };
|
|
|
|
|
|
|
|
|
|
struct litest_test_param *tp;
|
|
|
|
|
bool is_first = true;
|
|
|
|
|
list_for_each(tp, &t->params->test_params, link) {
|
2025-04-07 10:53:12 +10:00
|
|
|
_autofree_ char *val =
|
|
|
|
|
multivalue_as_str(&tp->value);
|
test: implement support for parametrizing tests
litest supports ranged tests but they are not enough, doubly so with
tests where we want to parametrize across multiple options.
This patch adds support for just that, in clunky C style.
The typical invocation for a test is by giving the test parameter
a name, a number of values and then the values themselves:
struct litest_parameters *params = litest_parameters_new("axis", 's', 2, "ABS_X", "ABS_Y",
"enabled", 'b', '2', true, false,
"number", 'u', '2', 10, 11,
NULL);
litest_add_parametrized(sometest, LITEST_ANY, LITEST_ANY, params);
litest_parameters_unref(params);
Currently supported are u (uint32), i (int32), d (double), b (bool),
c (char) and s (string).
In the test itself, the `test_env->params` variable is available and
retrieval of the parameters works like this:
const char *axis;
uint32_t number;
bool enabled;
litest_test_param_fetch(test_env->params,
"axis", &axis,
"enabled", &enabled,
"number", &number,
NULL);
Note that since this is an effectively internal test-suite only
functionality we don't do type-checking here, it's assumed that if you
write the code to pass parameters into a test you remember the type
of said params when you write the test code.
Because we don't have hashmaps or anything useful other than lists the
implementation is a bit clunky: we copy the parameter into the test
during litest_add_*, permutate it for our test list which gives us yet
another linked list C struct, and finally copy the actual value into
the test and test environment as it's executed. Not pretty, but it
works.
A few tests are switched as simple demonstration. The name of the
test has the parameters with their names and values appended now, e.g.:
"pointer:pointer_scroll_wheel_hires_send_only_lores:ms-surface-cover:axis:ABS_X"
"pointer:pointer_motion_relative_min_decel:mouse-roccat:direction:NW"
Filtering by parameters can be done via globs of their string
representation:
libinput-test-suite --filter-params="axis:ABS_*,enabled:true,number:10*"
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1109>
2024-12-22 00:06:19 +10:00
|
|
|
snprintf(buf + strlen(buf),
|
|
|
|
|
sizeof(buf) - strlen(buf),
|
|
|
|
|
"%s%s:%s",
|
|
|
|
|
is_first ? "" : ",",
|
|
|
|
|
tp->name,
|
|
|
|
|
val);
|
|
|
|
|
is_first = false;
|
|
|
|
|
}
|
|
|
|
|
snprintf(tdesc.name,
|
|
|
|
|
sizeof(tdesc.name),
|
|
|
|
|
"%s:%s:%s:%s",
|
|
|
|
|
s->name,
|
|
|
|
|
t->name,
|
|
|
|
|
t->devname,
|
|
|
|
|
buf);
|
2024-10-12 10:31:42 +10:00
|
|
|
} else {
|
|
|
|
|
snprintf(tdesc.name,
|
|
|
|
|
sizeof(tdesc.name),
|
|
|
|
|
"%s:%s:%s",
|
|
|
|
|
s->name,
|
|
|
|
|
t->name,
|
|
|
|
|
t->devname);
|
|
|
|
|
}
|
|
|
|
|
tdesc.func = t->func;
|
|
|
|
|
tdesc.setup = t->setup;
|
|
|
|
|
tdesc.teardown = t->teardown;
|
|
|
|
|
tdesc.args.range = t->range;
|
|
|
|
|
tdesc.rangeval = t->rangeval;
|
test: implement support for parametrizing tests
litest supports ranged tests but they are not enough, doubly so with
tests where we want to parametrize across multiple options.
This patch adds support for just that, in clunky C style.
The typical invocation for a test is by giving the test parameter
a name, a number of values and then the values themselves:
struct litest_parameters *params = litest_parameters_new("axis", 's', 2, "ABS_X", "ABS_Y",
"enabled", 'b', '2', true, false,
"number", 'u', '2', 10, 11,
NULL);
litest_add_parametrized(sometest, LITEST_ANY, LITEST_ANY, params);
litest_parameters_unref(params);
Currently supported are u (uint32), i (int32), d (double), b (bool),
c (char) and s (string).
In the test itself, the `test_env->params` variable is available and
retrieval of the parameters works like this:
const char *axis;
uint32_t number;
bool enabled;
litest_test_param_fetch(test_env->params,
"axis", &axis,
"enabled", &enabled,
"number", &number,
NULL);
Note that since this is an effectively internal test-suite only
functionality we don't do type-checking here, it's assumed that if you
write the code to pass parameters into a test you remember the type
of said params when you write the test code.
Because we don't have hashmaps or anything useful other than lists the
implementation is a bit clunky: we copy the parameter into the test
during litest_add_*, permutate it for our test list which gives us yet
another linked list C struct, and finally copy the actual value into
the test and test environment as it's executed. Not pretty, but it
works.
A few tests are switched as simple demonstration. The name of the
test has the parameters with their names and values appended now, e.g.:
"pointer:pointer_scroll_wheel_hires_send_only_lores:ms-surface-cover:axis:ABS_X"
"pointer:pointer_motion_relative_min_decel:mouse-roccat:direction:NW"
Filtering by parameters can be done via globs of their string
representation:
libinput-test-suite --filter-params="axis:ABS_*,enabled:true,number:10*"
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1109>
2024-12-22 00:06:19 +10:00
|
|
|
tdesc.params = t->params;
|
2024-10-12 10:31:42 +10:00
|
|
|
litest_runner_add_test(runner, &tdesc);
|
|
|
|
|
ntests++;
|
2016-07-22 15:19:23 +10:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-16 11:18:24 +10:00
|
|
|
if (ntests > 0)
|
2024-10-12 10:31:42 +10:00
|
|
|
result = litest_runner_run_tests(runner);
|
2016-07-22 15:19:23 +10:00
|
|
|
|
2024-10-12 10:31:42 +10:00
|
|
|
return result;
|
2016-07-22 15:19:23 +10:00
|
|
|
}
|
|
|
|
|
|
2018-02-01 14:23:41 +10:00
|
|
|
static inline int
|
|
|
|
|
inhibit(void)
|
|
|
|
|
{
|
|
|
|
|
int lock_fd = -1;
|
|
|
|
|
#if HAVE_LIBSYSTEMD
|
2025-04-07 10:53:12 +10:00
|
|
|
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
|
|
|
|
_unref_(sd_bus_message) *m = NULL;
|
|
|
|
|
_unref_(sd_bus) *bus = NULL;
|
2018-02-01 14:23:41 +10:00
|
|
|
int rc;
|
|
|
|
|
|
2018-08-10 11:39:04 +10:00
|
|
|
if (run_deviceless)
|
|
|
|
|
return -1;
|
|
|
|
|
|
2018-02-01 14:23:41 +10:00
|
|
|
rc = sd_bus_open_system(&bus);
|
|
|
|
|
if (rc != 0) {
|
|
|
|
|
fprintf(stderr, "Warning: inhibit failed: %s\n", strerror(-rc));
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rc = sd_bus_call_method(
|
|
|
|
|
bus,
|
|
|
|
|
"org.freedesktop.login1",
|
|
|
|
|
"/org/freedesktop/login1",
|
|
|
|
|
"org.freedesktop.login1.Manager",
|
|
|
|
|
"Inhibit",
|
|
|
|
|
&error,
|
|
|
|
|
&m,
|
|
|
|
|
"ssss",
|
2020-07-03 10:28:53 +10:00
|
|
|
"sleep:shutdown:handle-lid-switch:handle-power-key:handle-suspend-key:"
|
|
|
|
|
"handle-hibernate-key",
|
2018-02-01 14:23:41 +10:00
|
|
|
"libinput test-suite runner",
|
|
|
|
|
"testing in progress",
|
|
|
|
|
"block");
|
|
|
|
|
if (rc < 0) {
|
|
|
|
|
fprintf(stderr, "Warning: inhibit failed: %s\n", error.message);
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rc = sd_bus_message_read(m, "h", &lock_fd);
|
|
|
|
|
if (rc < 0) {
|
|
|
|
|
fprintf(stderr, "Warning: inhibit failed: %s\n", strerror(-rc));
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lock_fd = dup(lock_fd);
|
|
|
|
|
out:
|
|
|
|
|
sd_bus_close(bus);
|
|
|
|
|
#endif
|
|
|
|
|
return lock_fd;
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-16 11:02:21 +10:00
|
|
|
static int
|
|
|
|
|
disable_tty(void)
|
|
|
|
|
{
|
|
|
|
|
int tty_mode = -1;
|
|
|
|
|
|
|
|
|
|
if (isatty(STDIN_FILENO) && ioctl(STDIN_FILENO, KDGKBMODE, &tty_mode) == 0) {
|
|
|
|
|
#ifdef __linux__
|
|
|
|
|
ioctl(STDIN_FILENO, KDSKBMODE, K_OFF);
|
|
|
|
|
#elif __FreeBSD__
|
|
|
|
|
ioctl(STDIN_FILENO, KDSKBMODE, K_RAW);
|
|
|
|
|
|
|
|
|
|
/* Put the tty into raw mode */
|
|
|
|
|
struct termios tios;
|
|
|
|
|
if (tcgetattr(STDIN_FILENO, &tios))
|
|
|
|
|
fprintf(stderr,
|
|
|
|
|
"Failed to get terminal attribute: %d - %s\n",
|
|
|
|
|
errno,
|
|
|
|
|
strerror(errno));
|
|
|
|
|
cfmakeraw(&tios);
|
|
|
|
|
if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &tios))
|
|
|
|
|
fprintf(stderr,
|
|
|
|
|
"Failed to set terminal attribute: %d - %s\n",
|
|
|
|
|
errno,
|
|
|
|
|
strerror(errno));
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return tty_mode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
restore_tty(int tty_mode)
|
|
|
|
|
{
|
|
|
|
|
if (tty_mode != -1) {
|
|
|
|
|
ioctl(STDIN_FILENO, KDSKBMODE, tty_mode);
|
|
|
|
|
#ifdef __FreeBSD__
|
|
|
|
|
/* Put the tty into "sane" mode */
|
|
|
|
|
struct termios tios;
|
|
|
|
|
if (tcgetattr(STDIN_FILENO, &tios))
|
|
|
|
|
fprintf(stderr,
|
|
|
|
|
"Failed to get terminal attribute: %d - %s\n",
|
|
|
|
|
errno,
|
|
|
|
|
strerror(errno));
|
|
|
|
|
cfmakesane(&tios);
|
|
|
|
|
if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &tios))
|
|
|
|
|
fprintf(stderr,
|
|
|
|
|
"Failed to set terminal attribute: %d - %s\n",
|
|
|
|
|
errno,
|
|
|
|
|
strerror(errno));
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-03 12:15:43 +10:00
|
|
|
enum litest_runner_result
|
|
|
|
|
litest_run(struct list *suites, int njobs)
|
2016-07-22 15:19:23 +10:00
|
|
|
{
|
2024-10-16 11:04:08 +10:00
|
|
|
const struct rlimit corelimit = { 0, 0 };
|
2018-02-01 14:23:41 +10:00
|
|
|
int inhibit_lock_fd;
|
2024-10-16 11:02:21 +10:00
|
|
|
int tty_mode = -1;
|
2016-07-22 15:19:23 +10:00
|
|
|
|
2024-10-16 11:04:08 +10:00
|
|
|
setenv("LIBINPUT_RUNNING_TEST_SUITE", "1", 1);
|
|
|
|
|
|
|
|
|
|
if (setrlimit(RLIMIT_CORE, &corelimit) != 0)
|
|
|
|
|
perror("WARNING: Core dumps not disabled");
|
|
|
|
|
|
2024-10-16 11:08:41 +10:00
|
|
|
struct list created_files_list = LIST_INIT(created_files_list);
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
|
2018-08-10 11:39:04 +10:00
|
|
|
if (run_deviceless) {
|
2019-03-05 15:24:10 +10:00
|
|
|
litest_setup_quirks(&created_files_list, QUIRKS_SETUP_USE_SRCDIR);
|
2018-08-10 11:39:04 +10:00
|
|
|
} else {
|
2019-03-05 15:24:10 +10:00
|
|
|
enum quirks_setup_mode mode;
|
2018-08-10 11:39:04 +10:00
|
|
|
litest_init_udev_rules(&created_files_list);
|
2019-03-05 15:24:10 +10:00
|
|
|
|
2019-03-22 11:43:13 +10:00
|
|
|
mode = use_system_rules_quirks ? QUIRKS_SETUP_ONLY_DEVICE
|
2019-03-05 15:24:10 +10:00
|
|
|
: QUIRKS_SETUP_FULL;
|
|
|
|
|
litest_setup_quirks(&created_files_list, mode);
|
2018-08-10 11:39:04 +10:00
|
|
|
}
|
2015-07-22 10:44:44 +10:00
|
|
|
|
2024-10-16 11:02:21 +10:00
|
|
|
/* If we're running 'normally' on the VT, disable the keyboard to
|
|
|
|
|
* avoid messing up our host. But if we're inside gdb or running
|
|
|
|
|
* without forking, leave it as-is.
|
|
|
|
|
*/
|
2025-04-03 12:15:43 +10:00
|
|
|
if (!run_deviceless && njobs > 1 && !in_debugger)
|
2024-10-16 11:02:21 +10:00
|
|
|
tty_mode = disable_tty();
|
|
|
|
|
|
2018-02-01 14:23:41 +10:00
|
|
|
inhibit_lock_fd = inhibit();
|
|
|
|
|
|
2025-04-03 12:15:43 +10:00
|
|
|
enum litest_runner_result result = litest_run_suite(suites, njobs);
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
|
2018-02-01 14:23:41 +10:00
|
|
|
close(inhibit_lock_fd);
|
|
|
|
|
|
2024-10-16 11:02:21 +10:00
|
|
|
restore_tty(tty_mode);
|
|
|
|
|
|
2016-07-22 13:23:35 +10:00
|
|
|
litest_remove_udev_rules(&created_files_list);
|
2015-07-22 10:44:44 +10:00
|
|
|
|
2024-10-12 10:31:42 +10:00
|
|
|
return result;
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
}
|
|
|
|
|
|
test: allow partial overriding the test devices
For specific tests we need something that e.g. looks like a touchpad, but has
a different name, a different number of slots, etc. In this case, the
following code will do exactly that:
struct input_absinfo overrides[] = {
{ .value = ABS_MT_SLOT, .minimum = 0, .maximum = 100 },
{ .value = -1 },
};
litest_create_device_with_overrides(LITEST_SYNAPTICS_CLICKPAD,
NULL, NULL, &overrides, NULL);
For general event codes, overrides can only add to the set of events, they
can't remove.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2014-03-31 14:54:46 +10:00
|
|
|
static struct input_absinfo *
|
|
|
|
|
merge_absinfo(const struct input_absinfo *orig, const struct input_absinfo *override)
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
{
|
test: allow partial overriding the test devices
For specific tests we need something that e.g. looks like a touchpad, but has
a different name, a different number of slots, etc. In this case, the
following code will do exactly that:
struct input_absinfo overrides[] = {
{ .value = ABS_MT_SLOT, .minimum = 0, .maximum = 100 },
{ .value = -1 },
};
litest_create_device_with_overrides(LITEST_SYNAPTICS_CLICKPAD,
NULL, NULL, &overrides, NULL);
For general event codes, overrides can only add to the set of events, they
can't remove.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2014-03-31 14:54:46 +10:00
|
|
|
struct input_absinfo *abs;
|
2014-07-03 11:00:54 +10:00
|
|
|
unsigned int nelem, i;
|
test: allow partial overriding the test devices
For specific tests we need something that e.g. looks like a touchpad, but has
a different name, a different number of slots, etc. In this case, the
following code will do exactly that:
struct input_absinfo overrides[] = {
{ .value = ABS_MT_SLOT, .minimum = 0, .maximum = 100 },
{ .value = -1 },
};
litest_create_device_with_overrides(LITEST_SYNAPTICS_CLICKPAD,
NULL, NULL, &overrides, NULL);
For general event codes, overrides can only add to the set of events, they
can't remove.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2014-03-31 14:54:46 +10:00
|
|
|
size_t sz = ABS_MAX + 1;
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
|
test: allow partial overriding the test devices
For specific tests we need something that e.g. looks like a touchpad, but has
a different name, a different number of slots, etc. In this case, the
following code will do exactly that:
struct input_absinfo overrides[] = {
{ .value = ABS_MT_SLOT, .minimum = 0, .maximum = 100 },
{ .value = -1 },
};
litest_create_device_with_overrides(LITEST_SYNAPTICS_CLICKPAD,
NULL, NULL, &overrides, NULL);
For general event codes, overrides can only add to the set of events, they
can't remove.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2014-03-31 14:54:46 +10:00
|
|
|
if (!orig)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
2017-07-07 11:18:40 +10:00
|
|
|
abs = zalloc(sz * sizeof(*abs));
|
2019-06-11 08:24:10 +10:00
|
|
|
litest_assert_ptr_notnull(abs);
|
test: allow partial overriding the test devices
For specific tests we need something that e.g. looks like a touchpad, but has
a different name, a different number of slots, etc. In this case, the
following code will do exactly that:
struct input_absinfo overrides[] = {
{ .value = ABS_MT_SLOT, .minimum = 0, .maximum = 100 },
{ .value = -1 },
};
litest_create_device_with_overrides(LITEST_SYNAPTICS_CLICKPAD,
NULL, NULL, &overrides, NULL);
For general event codes, overrides can only add to the set of events, they
can't remove.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2014-03-31 14:54:46 +10:00
|
|
|
|
|
|
|
|
nelem = 0;
|
|
|
|
|
while (orig[nelem].value != -1) {
|
|
|
|
|
abs[nelem] = orig[nelem];
|
|
|
|
|
nelem++;
|
2015-05-04 09:13:22 +10:00
|
|
|
litest_assert_int_lt(nelem, sz);
|
test: allow partial overriding the test devices
For specific tests we need something that e.g. looks like a touchpad, but has
a different name, a different number of slots, etc. In this case, the
following code will do exactly that:
struct input_absinfo overrides[] = {
{ .value = ABS_MT_SLOT, .minimum = 0, .maximum = 100 },
{ .value = -1 },
};
litest_create_device_with_overrides(LITEST_SYNAPTICS_CLICKPAD,
NULL, NULL, &overrides, NULL);
For general event codes, overrides can only add to the set of events, they
can't remove.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2014-03-31 14:54:46 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* just append, if the same axis is present twice, libevdev will
|
|
|
|
|
only use the last value anyway */
|
|
|
|
|
i = 0;
|
|
|
|
|
while (override && override[i].value != -1) {
|
|
|
|
|
abs[nelem++] = override[i++];
|
2015-05-04 09:13:22 +10:00
|
|
|
litest_assert_int_lt(nelem, sz);
|
test: allow partial overriding the test devices
For specific tests we need something that e.g. looks like a touchpad, but has
a different name, a different number of slots, etc. In this case, the
following code will do exactly that:
struct input_absinfo overrides[] = {
{ .value = ABS_MT_SLOT, .minimum = 0, .maximum = 100 },
{ .value = -1 },
};
litest_create_device_with_overrides(LITEST_SYNAPTICS_CLICKPAD,
NULL, NULL, &overrides, NULL);
For general event codes, overrides can only add to the set of events, they
can't remove.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2014-03-31 14:54:46 +10:00
|
|
|
}
|
|
|
|
|
|
2015-05-04 09:13:22 +10:00
|
|
|
litest_assert_int_lt(nelem, sz);
|
test: allow partial overriding the test devices
For specific tests we need something that e.g. looks like a touchpad, but has
a different name, a different number of slots, etc. In this case, the
following code will do exactly that:
struct input_absinfo overrides[] = {
{ .value = ABS_MT_SLOT, .minimum = 0, .maximum = 100 },
{ .value = -1 },
};
litest_create_device_with_overrides(LITEST_SYNAPTICS_CLICKPAD,
NULL, NULL, &overrides, NULL);
For general event codes, overrides can only add to the set of events, they
can't remove.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2014-03-31 14:54:46 +10:00
|
|
|
abs[nelem].value = -1;
|
|
|
|
|
|
|
|
|
|
return abs;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int *
|
|
|
|
|
merge_events(const int *orig, const int *override)
|
|
|
|
|
{
|
|
|
|
|
int *events;
|
2014-07-03 11:00:54 +10:00
|
|
|
unsigned int nelem, i;
|
test: allow partial overriding the test devices
For specific tests we need something that e.g. looks like a touchpad, but has
a different name, a different number of slots, etc. In this case, the
following code will do exactly that:
struct input_absinfo overrides[] = {
{ .value = ABS_MT_SLOT, .minimum = 0, .maximum = 100 },
{ .value = -1 },
};
litest_create_device_with_overrides(LITEST_SYNAPTICS_CLICKPAD,
NULL, NULL, &overrides, NULL);
For general event codes, overrides can only add to the set of events, they
can't remove.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2014-03-31 14:54:46 +10:00
|
|
|
size_t sz = KEY_MAX * 3;
|
|
|
|
|
|
|
|
|
|
if (!orig)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
2017-07-07 11:18:40 +10:00
|
|
|
events = zalloc(sz * sizeof(int));
|
2019-06-11 08:24:10 +10:00
|
|
|
litest_assert_ptr_notnull(events);
|
test: allow partial overriding the test devices
For specific tests we need something that e.g. looks like a touchpad, but has
a different name, a different number of slots, etc. In this case, the
following code will do exactly that:
struct input_absinfo overrides[] = {
{ .value = ABS_MT_SLOT, .minimum = 0, .maximum = 100 },
{ .value = -1 },
};
litest_create_device_with_overrides(LITEST_SYNAPTICS_CLICKPAD,
NULL, NULL, &overrides, NULL);
For general event codes, overrides can only add to the set of events, they
can't remove.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2014-03-31 14:54:46 +10:00
|
|
|
|
|
|
|
|
nelem = 0;
|
|
|
|
|
while (orig[nelem] != -1) {
|
|
|
|
|
events[nelem] = orig[nelem];
|
|
|
|
|
nelem++;
|
2015-05-04 09:13:22 +10:00
|
|
|
litest_assert_int_lt(nelem, sz);
|
test: allow partial overriding the test devices
For specific tests we need something that e.g. looks like a touchpad, but has
a different name, a different number of slots, etc. In this case, the
following code will do exactly that:
struct input_absinfo overrides[] = {
{ .value = ABS_MT_SLOT, .minimum = 0, .maximum = 100 },
{ .value = -1 },
};
litest_create_device_with_overrides(LITEST_SYNAPTICS_CLICKPAD,
NULL, NULL, &overrides, NULL);
For general event codes, overrides can only add to the set of events, they
can't remove.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2014-03-31 14:54:46 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* just append, if the same axis is present twice, libevdev will
|
|
|
|
|
* ignore the double definition anyway */
|
|
|
|
|
i = 0;
|
|
|
|
|
while (override && override[i] != -1) {
|
|
|
|
|
events[nelem++] = override[i++];
|
2015-05-04 09:13:22 +10:00
|
|
|
litest_assert_int_le(nelem, sz);
|
test: allow partial overriding the test devices
For specific tests we need something that e.g. looks like a touchpad, but has
a different name, a different number of slots, etc. In this case, the
following code will do exactly that:
struct input_absinfo overrides[] = {
{ .value = ABS_MT_SLOT, .minimum = 0, .maximum = 100 },
{ .value = -1 },
};
litest_create_device_with_overrides(LITEST_SYNAPTICS_CLICKPAD,
NULL, NULL, &overrides, NULL);
For general event codes, overrides can only add to the set of events, they
can't remove.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2014-03-31 14:54:46 +10:00
|
|
|
}
|
|
|
|
|
|
2015-05-04 09:13:22 +10:00
|
|
|
litest_assert_int_lt(nelem, sz);
|
test: allow partial overriding the test devices
For specific tests we need something that e.g. looks like a touchpad, but has
a different name, a different number of slots, etc. In this case, the
following code will do exactly that:
struct input_absinfo overrides[] = {
{ .value = ABS_MT_SLOT, .minimum = 0, .maximum = 100 },
{ .value = -1 },
};
litest_create_device_with_overrides(LITEST_SYNAPTICS_CLICKPAD,
NULL, NULL, &overrides, NULL);
For general event codes, overrides can only add to the set of events, they
can't remove.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2014-03-31 14:54:46 +10:00
|
|
|
events[nelem] = -1;
|
|
|
|
|
|
|
|
|
|
return events;
|
|
|
|
|
}
|
|
|
|
|
|
2016-07-22 13:23:35 +10:00
|
|
|
static inline struct created_file *
|
2019-03-05 15:14:12 +10:00
|
|
|
litest_copy_file(const char *dest, const char *src, const char *header, bool is_file)
|
2015-06-05 10:52:04 +10:00
|
|
|
{
|
2015-09-04 13:35:01 +02:00
|
|
|
int in, out, length;
|
2016-07-22 13:23:35 +10:00
|
|
|
struct created_file *file;
|
|
|
|
|
|
|
|
|
|
file = zalloc(sizeof(*file));
|
2017-07-07 09:47:06 +10:00
|
|
|
file->path = safe_strdup(dest);
|
2015-06-05 10:52:04 +10:00
|
|
|
|
2018-05-24 14:47:30 +10:00
|
|
|
if (strstr(dest, "XXXXXX")) {
|
|
|
|
|
int suffixlen;
|
|
|
|
|
|
|
|
|
|
suffixlen = file->path + strlen(file->path) - rindex(file->path, '.');
|
|
|
|
|
out = mkstemps(file->path, suffixlen);
|
|
|
|
|
} else {
|
2018-06-18 13:41:18 +10:00
|
|
|
out = open(file->path, O_CREAT | O_WRONLY, 0644);
|
2018-05-24 14:47:30 +10:00
|
|
|
}
|
2017-05-15 09:02:32 +10:00
|
|
|
if (out == -1)
|
2024-10-14 21:42:26 +10:00
|
|
|
litest_abort_msg("Failed to write to file %s (%s)",
|
2017-06-02 16:59:09 +10:00
|
|
|
file->path,
|
2017-05-15 09:02:32 +10:00
|
|
|
strerror(errno));
|
2024-10-16 11:27:27 +10:00
|
|
|
litest_assert_errno_success(chmod(file->path, 0644));
|
2015-06-05 10:52:04 +10:00
|
|
|
|
2015-09-04 13:35:01 +02:00
|
|
|
if (header) {
|
|
|
|
|
length = strlen(header);
|
|
|
|
|
litest_assert_int_eq(write(out, header, length), length);
|
|
|
|
|
}
|
2015-06-05 10:52:04 +10:00
|
|
|
|
2019-03-05 15:14:12 +10:00
|
|
|
if (is_file) {
|
|
|
|
|
in = open(src, O_RDONLY);
|
|
|
|
|
if (in == -1)
|
2024-10-14 21:42:26 +10:00
|
|
|
litest_abort_msg("Failed to open file %s (%s)",
|
2019-03-05 15:14:12 +10:00
|
|
|
src,
|
|
|
|
|
strerror(errno));
|
|
|
|
|
/* lazy, just check for error and empty file copy */
|
|
|
|
|
litest_assert_int_gt(litest_send_file(out, in), 0);
|
|
|
|
|
close(in);
|
|
|
|
|
} else {
|
|
|
|
|
size_t written = write(out, src, strlen(src));
|
|
|
|
|
litest_assert_int_eq(written, strlen(src));
|
|
|
|
|
}
|
2015-06-05 10:52:04 +10:00
|
|
|
close(out);
|
2016-07-22 13:23:35 +10:00
|
|
|
|
|
|
|
|
return file;
|
2015-06-05 10:52:04 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void
|
2016-07-22 13:23:35 +10:00
|
|
|
litest_install_model_quirks(struct list *created_files_list)
|
2015-06-05 10:52:04 +10:00
|
|
|
{
|
2015-07-01 10:55:23 +10:00
|
|
|
const char *warning =
|
2015-06-05 10:52:04 +10:00
|
|
|
"#################################################################\n"
|
|
|
|
|
"# WARNING: REMOVE THIS FILE\n"
|
2015-07-01 10:55:23 +10:00
|
|
|
"# This is a run-time file for the libinput test suite and\n"
|
2015-06-05 10:52:04 +10:00
|
|
|
"# should be removed on exit. If the test-suite is not currently \n"
|
2019-02-13 14:33:35 +10:00
|
|
|
"# running, remove this file\n"
|
2015-07-01 10:55:23 +10:00
|
|
|
"#################################################################\n\n";
|
2016-07-22 13:23:35 +10:00
|
|
|
struct created_file *file;
|
2019-03-05 15:14:12 +10:00
|
|
|
const char *test_device_udev_rule =
|
|
|
|
|
"KERNELS==\"*input*\", "
|
|
|
|
|
"ATTRS{name}==\"litest *\", "
|
|
|
|
|
"ENV{LIBINPUT_TEST_DEVICE}=\"1\"";
|
2016-07-22 13:23:35 +10:00
|
|
|
|
|
|
|
|
file = litest_copy_file(UDEV_TEST_DEVICE_RULE_FILE,
|
2019-03-05 15:14:12 +10:00
|
|
|
test_device_udev_rule,
|
|
|
|
|
warning,
|
|
|
|
|
false);
|
2016-07-22 13:23:35 +10:00
|
|
|
list_insert(created_files_list, &file->link);
|
2017-05-11 11:39:55 +10:00
|
|
|
|
2020-08-27 19:52:34 +02:00
|
|
|
/* Only install the litest device rule when we're running as system
|
2019-03-22 11:43:13 +10:00
|
|
|
* test suite, we expect the others to be in place already */
|
|
|
|
|
if (use_system_rules_quirks)
|
|
|
|
|
return;
|
|
|
|
|
|
2017-05-11 11:39:55 +10:00
|
|
|
file = litest_copy_file(UDEV_DEVICE_GROUPS_FILE,
|
|
|
|
|
LIBINPUT_DEVICE_GROUPS_RULES_FILE,
|
2019-03-05 15:14:12 +10:00
|
|
|
warning,
|
|
|
|
|
true);
|
2017-05-11 11:39:55 +10:00
|
|
|
list_insert(created_files_list, &file->link);
|
2018-09-10 15:16:49 +10:00
|
|
|
|
2019-06-26 11:29:31 +10:00
|
|
|
file = litest_copy_file(UDEV_FUZZ_OVERRIDE_RULE_FILE,
|
|
|
|
|
LIBINPUT_FUZZ_OVERRIDE_UDEV_RULES_FILE,
|
2019-03-05 15:14:12 +10:00
|
|
|
warning,
|
|
|
|
|
true);
|
2018-09-10 15:16:49 +10:00
|
|
|
list_insert(created_files_list, &file->link);
|
2015-06-05 10:52:04 +10:00
|
|
|
}
|
|
|
|
|
|
2018-05-24 15:36:22 +10:00
|
|
|
static char *
|
|
|
|
|
litest_init_device_quirk_file(const char *data_dir, struct litest_test_device *dev)
|
|
|
|
|
{
|
|
|
|
|
int fd;
|
|
|
|
|
FILE *f;
|
|
|
|
|
char path[PATH_MAX];
|
|
|
|
|
static int count;
|
|
|
|
|
|
|
|
|
|
if (!dev->quirk_file)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
snprintf(path,
|
|
|
|
|
sizeof(path),
|
|
|
|
|
"%s/99-%03d-%s.quirks",
|
|
|
|
|
data_dir,
|
|
|
|
|
++count,
|
|
|
|
|
dev->shortname);
|
|
|
|
|
fd = open(path, O_CREAT | O_WRONLY, 0644);
|
2024-10-16 11:27:27 +10:00
|
|
|
litest_assert_errno_success(fd);
|
2018-05-24 15:36:22 +10:00
|
|
|
f = fdopen(fd, "w");
|
|
|
|
|
litest_assert_notnull(f);
|
|
|
|
|
litest_assert_int_ge(fputs(dev->quirk_file, f), 0);
|
|
|
|
|
fclose(f);
|
|
|
|
|
|
|
|
|
|
return safe_strdup(path);
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-17 09:43:54 +10:00
|
|
|
static int
|
|
|
|
|
is_quirks_file(const struct dirent *dir)
|
|
|
|
|
{
|
|
|
|
|
return strendswith(dir->d_name, ".quirks");
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-06 12:03:33 +10:00
|
|
|
/**
|
|
|
|
|
* Install the quirks from the quirks/ source directory.
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
litest_install_source_quirks(struct list *created_files_list, const char *dirname)
|
2018-05-24 15:36:22 +10:00
|
|
|
{
|
2025-04-07 10:53:12 +10:00
|
|
|
_autofree_ struct dirent **namelist;
|
2020-06-17 09:43:54 +10:00
|
|
|
int ndev;
|
2018-05-24 15:36:22 +10:00
|
|
|
|
2020-06-17 09:43:54 +10:00
|
|
|
ndev = scandir(LIBINPUT_QUIRKS_SRCDIR, &namelist, is_quirks_file, versionsort);
|
|
|
|
|
litest_assert_int_ge(ndev, 0);
|
2018-05-24 15:36:22 +10:00
|
|
|
|
2020-06-17 09:43:54 +10:00
|
|
|
for (int idx = 0; idx < ndev; idx++) {
|
2019-03-06 12:03:33 +10:00
|
|
|
struct created_file *file;
|
2018-05-24 15:36:22 +10:00
|
|
|
char *filename;
|
|
|
|
|
char dest[PATH_MAX];
|
|
|
|
|
char src[PATH_MAX];
|
|
|
|
|
|
2025-04-07 10:53:12 +10:00
|
|
|
_autofree_ struct dirent *entry = namelist[idx];
|
|
|
|
|
filename = entry->d_name;
|
2018-07-13 12:57:02 +10:00
|
|
|
snprintf(src, sizeof(src), "%s/%s", LIBINPUT_QUIRKS_SRCDIR, filename);
|
2018-05-24 15:36:22 +10:00
|
|
|
snprintf(dest, sizeof(dest), "%s/%s", dirname, filename);
|
2019-03-05 15:14:12 +10:00
|
|
|
file = litest_copy_file(dest, src, NULL, true);
|
2018-05-24 15:36:22 +10:00
|
|
|
list_append(created_files_list, &file->link);
|
|
|
|
|
}
|
2019-03-06 12:03:33 +10:00
|
|
|
}
|
2018-05-24 15:36:22 +10:00
|
|
|
|
2019-03-06 12:03:33 +10:00
|
|
|
/**
|
|
|
|
|
* Install the quirks from the various litest test devices
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
litest_install_device_quirks(struct list *created_files_list, const char *dirname)
|
|
|
|
|
{
|
|
|
|
|
struct litest_test_device *dev;
|
2018-05-24 15:36:22 +10:00
|
|
|
|
2018-06-22 16:57:51 +10:00
|
|
|
list_for_each(dev, &devices, node) {
|
2018-05-24 15:36:22 +10:00
|
|
|
char *path;
|
|
|
|
|
|
2018-06-22 16:57:51 +10:00
|
|
|
path = litest_init_device_quirk_file(dirname, dev);
|
2018-05-24 15:36:22 +10:00
|
|
|
if (path) {
|
|
|
|
|
struct created_file *file = zalloc(sizeof(*file));
|
|
|
|
|
file->path = path;
|
|
|
|
|
list_insert(created_files_list, &file->link);
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-03-06 12:03:33 +10:00
|
|
|
}
|
|
|
|
|
|
2019-03-05 15:24:10 +10:00
|
|
|
static void
|
|
|
|
|
litest_setup_quirks(struct list *created_files_list, enum quirks_setup_mode mode)
|
2019-03-06 12:03:33 +10:00
|
|
|
{
|
2019-03-05 15:24:10 +10:00
|
|
|
struct created_file *file = NULL;
|
|
|
|
|
const char *dirname;
|
|
|
|
|
char tmpdir[] = "/run/litest-XXXXXX";
|
2019-03-06 12:03:33 +10:00
|
|
|
|
2019-03-05 15:24:10 +10:00
|
|
|
switch (mode) {
|
|
|
|
|
case QUIRKS_SETUP_USE_SRCDIR:
|
|
|
|
|
dirname = LIBINPUT_QUIRKS_SRCDIR;
|
|
|
|
|
break;
|
|
|
|
|
case QUIRKS_SETUP_ONLY_DEVICE:
|
|
|
|
|
dirname = LIBINPUT_QUIRKS_DIR;
|
|
|
|
|
litest_install_device_quirks(created_files_list, dirname);
|
|
|
|
|
break;
|
|
|
|
|
case QUIRKS_SETUP_FULL:
|
|
|
|
|
litest_assert_notnull(mkdtemp(tmpdir));
|
2024-10-16 11:27:27 +10:00
|
|
|
litest_assert_errno_success(chmod(tmpdir, 0755));
|
2019-03-05 15:24:10 +10:00
|
|
|
file = zalloc(sizeof *file);
|
|
|
|
|
file->path = safe_strdup(tmpdir);
|
|
|
|
|
dirname = tmpdir;
|
|
|
|
|
|
|
|
|
|
litest_install_source_quirks(created_files_list, dirname);
|
|
|
|
|
litest_install_device_quirks(created_files_list, dirname);
|
|
|
|
|
list_append(created_files_list, &file->link);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2018-05-24 15:36:22 +10:00
|
|
|
|
2019-03-05 15:24:10 +10:00
|
|
|
setenv("LIBINPUT_QUIRKS_DIR", dirname, 1);
|
2018-05-24 15:36:22 +10:00
|
|
|
}
|
|
|
|
|
|
2018-06-21 17:05:30 +10:00
|
|
|
static inline void
|
2017-11-01 14:12:01 +10:00
|
|
|
litest_init_udev_rules(struct list *created_files)
|
|
|
|
|
{
|
2024-03-14 12:28:39 +10:00
|
|
|
litest_assert_neg_errno_success(mkdir_p(UDEV_RULES_D));
|
2015-06-05 10:52:04 +10:00
|
|
|
|
2016-07-22 13:23:35 +10:00
|
|
|
litest_install_model_quirks(created_files);
|
2016-07-08 09:42:36 +10:00
|
|
|
litest_init_all_device_udev_rules(created_files);
|
2016-07-22 13:23:35 +10:00
|
|
|
litest_reload_udev_rules();
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-21 17:05:30 +10:00
|
|
|
static inline void
|
2016-07-22 13:23:35 +10:00
|
|
|
litest_remove_udev_rules(struct list *created_files_list)
|
|
|
|
|
{
|
2021-02-22 19:52:40 +03:00
|
|
|
struct created_file *f;
|
2018-06-22 15:47:18 +10:00
|
|
|
bool reload_udev;
|
|
|
|
|
|
|
|
|
|
reload_udev = !list_empty(created_files_list);
|
2016-07-22 13:23:35 +10:00
|
|
|
|
2021-02-22 19:52:40 +03:00
|
|
|
list_for_each_safe(f, created_files_list, link) {
|
2024-10-15 11:46:58 +10:00
|
|
|
created_file_unlink(f);
|
|
|
|
|
created_file_destroy(f);
|
2016-07-22 13:23:35 +10:00
|
|
|
}
|
|
|
|
|
|
2018-06-22 15:47:18 +10:00
|
|
|
if (reload_udev)
|
|
|
|
|
litest_reload_udev_rules();
|
2015-07-22 10:44:44 +10:00
|
|
|
}
|
|
|
|
|
|
2017-08-17 02:07:18 +02:00
|
|
|
/**
|
|
|
|
|
* Creates a uinput device but does not add it to a libinput context
|
|
|
|
|
*/
|
|
|
|
|
struct litest_device *
|
test: allow partial overriding the test devices
For specific tests we need something that e.g. looks like a touchpad, but has
a different name, a different number of slots, etc. In this case, the
following code will do exactly that:
struct input_absinfo overrides[] = {
{ .value = ABS_MT_SLOT, .minimum = 0, .maximum = 100 },
{ .value = -1 },
};
litest_create_device_with_overrides(LITEST_SYNAPTICS_CLICKPAD,
NULL, NULL, &overrides, NULL);
For general event codes, overrides can only add to the set of events, they
can't remove.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2014-03-31 14:54:46 +10:00
|
|
|
litest_create(enum litest_device_type which,
|
|
|
|
|
const char *name_override,
|
|
|
|
|
struct input_id *id_override,
|
|
|
|
|
const struct input_absinfo *abs_override,
|
|
|
|
|
const int *events_override)
|
|
|
|
|
{
|
|
|
|
|
struct litest_device *d = NULL;
|
2018-06-22 16:57:51 +10:00
|
|
|
struct litest_test_device *dev;
|
test: allow partial overriding the test devices
For specific tests we need something that e.g. looks like a touchpad, but has
a different name, a different number of slots, etc. In this case, the
following code will do exactly that:
struct input_absinfo overrides[] = {
{ .value = ABS_MT_SLOT, .minimum = 0, .maximum = 100 },
{ .value = -1 },
};
litest_create_device_with_overrides(LITEST_SYNAPTICS_CLICKPAD,
NULL, NULL, &overrides, NULL);
For general event codes, overrides can only add to the set of events, they
can't remove.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2014-03-31 14:54:46 +10:00
|
|
|
const char *name;
|
|
|
|
|
const struct input_id *id;
|
2025-04-07 10:53:12 +10:00
|
|
|
_autofree_ struct input_absinfo *abs;
|
|
|
|
|
_autofree_ int *events;
|
|
|
|
|
int *e;
|
2017-08-17 02:07:18 +02:00
|
|
|
const char *path;
|
|
|
|
|
int fd, rc;
|
2018-06-22 16:57:51 +10:00
|
|
|
bool found = false;
|
2019-03-22 15:44:32 +10:00
|
|
|
bool create_device = true;
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
|
2018-06-22 16:57:51 +10:00
|
|
|
list_for_each(dev, &devices, node) {
|
|
|
|
|
if (dev->type == which) {
|
|
|
|
|
found = true;
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
break;
|
2018-06-22 16:57:51 +10:00
|
|
|
}
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
}
|
|
|
|
|
|
2018-06-22 16:57:51 +10:00
|
|
|
if (!found)
|
2024-10-14 21:42:26 +10:00
|
|
|
litest_abort_msg("Invalid device type %d", which);
|
test: allow partial overriding the test devices
For specific tests we need something that e.g. looks like a touchpad, but has
a different name, a different number of slots, etc. In this case, the
following code will do exactly that:
struct input_absinfo overrides[] = {
{ .value = ABS_MT_SLOT, .minimum = 0, .maximum = 100 },
{ .value = -1 },
};
litest_create_device_with_overrides(LITEST_SYNAPTICS_CLICKPAD,
NULL, NULL, &overrides, NULL);
For general event codes, overrides can only add to the set of events, they
can't remove.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2014-03-31 14:54:46 +10:00
|
|
|
|
|
|
|
|
d = zalloc(sizeof(*d));
|
2019-01-04 14:44:38 +10:00
|
|
|
d->which = which;
|
test: allow partial overriding the test devices
For specific tests we need something that e.g. looks like a touchpad, but has
a different name, a different number of slots, etc. In this case, the
following code will do exactly that:
struct input_absinfo overrides[] = {
{ .value = ABS_MT_SLOT, .minimum = 0, .maximum = 100 },
{ .value = -1 },
};
litest_create_device_with_overrides(LITEST_SYNAPTICS_CLICKPAD,
NULL, NULL, &overrides, NULL);
For general event codes, overrides can only add to the set of events, they
can't remove.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2014-03-31 14:54:46 +10:00
|
|
|
|
|
|
|
|
/* device has custom create method */
|
2018-06-22 16:57:51 +10:00
|
|
|
if (dev->create) {
|
2019-03-22 15:44:32 +10:00
|
|
|
create_device = dev->create(d);
|
2015-02-02 10:47:52 +10:00
|
|
|
if (abs_override || events_override) {
|
2015-05-04 09:13:22 +10:00
|
|
|
litest_abort_msg("Custom create cannot be overridden");
|
2015-02-02 10:47:52 +10:00
|
|
|
}
|
2019-03-22 15:44:32 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
abs = merge_absinfo(dev->absinfo, abs_override);
|
|
|
|
|
events = merge_events(dev->events, events_override);
|
|
|
|
|
name = name_override ? name_override : dev->name;
|
|
|
|
|
id = id_override ? id_override : dev->id;
|
2017-08-17 02:07:18 +02:00
|
|
|
|
2019-03-22 15:44:32 +10:00
|
|
|
if (create_device) {
|
2017-08-17 02:07:18 +02:00
|
|
|
d->uinput = litest_create_uinput_device_from_description(name,
|
|
|
|
|
id,
|
|
|
|
|
abs,
|
|
|
|
|
events);
|
2018-06-22 16:57:51 +10:00
|
|
|
d->interface = dev->interface;
|
2017-08-17 02:07:18 +02:00
|
|
|
|
|
|
|
|
for (e = events; *e != -1; e += 2) {
|
|
|
|
|
unsigned int type = *e, code = *(e + 1);
|
|
|
|
|
|
|
|
|
|
if (type == INPUT_PROP_MAX && code == INPUT_PROP_SEMI_MT) {
|
|
|
|
|
d->semi_mt.is_semi_mt = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
}
|
|
|
|
|
|
2017-08-17 02:07:18 +02:00
|
|
|
path = libevdev_uinput_get_devnode(d->uinput);
|
2019-06-11 08:24:10 +10:00
|
|
|
litest_assert_ptr_notnull(path);
|
2017-08-17 02:07:18 +02:00
|
|
|
fd = open(path, O_RDWR | O_NONBLOCK);
|
2024-10-16 11:27:27 +10:00
|
|
|
litest_assert_errno_success(fd);
|
2017-01-19 15:58:13 +10:00
|
|
|
|
2017-08-17 02:07:18 +02:00
|
|
|
rc = libevdev_new_from_fd(fd, &d->evdev);
|
2024-03-14 12:07:29 +10:00
|
|
|
litest_assert_neg_errno_success(rc);
|
test: allow partial overriding the test devices
For specific tests we need something that e.g. looks like a touchpad, but has
a different name, a different number of slots, etc. In this case, the
following code will do exactly that:
struct input_absinfo overrides[] = {
{ .value = ABS_MT_SLOT, .minimum = 0, .maximum = 100 },
{ .value = -1 },
};
litest_create_device_with_overrides(LITEST_SYNAPTICS_CLICKPAD,
NULL, NULL, &overrides, NULL);
For general event codes, overrides can only add to the set of events, they
can't remove.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2014-03-31 14:54:46 +10:00
|
|
|
|
|
|
|
|
return d;
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-22 15:06:34 +01:00
|
|
|
struct libinput *
|
|
|
|
|
litest_create_context(void)
|
|
|
|
|
{
|
2020-07-03 12:29:16 +10:00
|
|
|
struct libinput *libinput;
|
|
|
|
|
struct litest_context *ctx;
|
|
|
|
|
|
|
|
|
|
ctx = zalloc(sizeof *ctx);
|
|
|
|
|
list_init(&ctx->paths);
|
|
|
|
|
|
|
|
|
|
libinput = libinput_path_create_context(&interface, ctx);
|
2015-05-04 09:13:22 +10:00
|
|
|
litest_assert_notnull(libinput);
|
2014-06-18 19:51:19 +10:00
|
|
|
|
|
|
|
|
libinput_log_set_handler(libinput, litest_log_handler);
|
|
|
|
|
if (verbose)
|
|
|
|
|
libinput_log_set_priority(libinput, LIBINPUT_LOG_PRIORITY_DEBUG);
|
|
|
|
|
|
2014-02-22 15:06:34 +01:00
|
|
|
return libinput;
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-03 10:47:13 +10:00
|
|
|
void
|
|
|
|
|
litest_destroy_context(struct libinput *li)
|
|
|
|
|
{
|
2025-04-07 13:15:28 +10:00
|
|
|
if (li) {
|
|
|
|
|
_autofree_ struct litest_context *ctx = libinput_get_user_data(li);
|
|
|
|
|
litest_assert_ptr_notnull(ctx);
|
|
|
|
|
libinput_unref(li);
|
|
|
|
|
|
|
|
|
|
struct path *p;
|
|
|
|
|
list_for_each_safe(p, &ctx->paths, link) {
|
|
|
|
|
litest_abort_msg("Device paths should be removed by now");
|
|
|
|
|
}
|
2020-07-03 12:29:16 +10:00
|
|
|
}
|
2020-07-03 10:47:13 +10:00
|
|
|
}
|
|
|
|
|
|
2025-05-08 11:34:28 +10:00
|
|
|
void
|
|
|
|
|
litest_context_set_user_data(struct libinput *li, void *data)
|
|
|
|
|
{
|
|
|
|
|
struct litest_user_data *litest_data = libinput_get_user_data(li);
|
|
|
|
|
litest_assert_ptr_notnull(litest_data);
|
|
|
|
|
litest_data->private = data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void *
|
|
|
|
|
litest_context_get_user_data(struct libinput *li)
|
|
|
|
|
{
|
|
|
|
|
struct litest_user_data *litest_data = libinput_get_user_data(li);
|
|
|
|
|
litest_assert_ptr_notnull(litest_data);
|
|
|
|
|
return litest_data->private;
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-13 09:32:37 +10:00
|
|
|
void
|
|
|
|
|
litest_disable_log_handler(struct libinput *libinput)
|
|
|
|
|
{
|
|
|
|
|
libinput_log_set_handler(libinput, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
litest_restore_log_handler(struct libinput *libinput)
|
|
|
|
|
{
|
|
|
|
|
libinput_log_set_handler(libinput, litest_log_handler);
|
2017-08-17 01:28:52 +02:00
|
|
|
if (verbose)
|
|
|
|
|
libinput_log_set_priority(libinput, LIBINPUT_LOG_PRIORITY_DEBUG);
|
2015-03-13 09:32:37 +10:00
|
|
|
}
|
|
|
|
|
|
2017-01-13 11:44:28 +10:00
|
|
|
LIBINPUT_ATTRIBUTE_PRINTF(3, 0)
|
|
|
|
|
static void
|
|
|
|
|
litest_bug_log_handler(struct libinput *libinput,
|
|
|
|
|
enum libinput_log_priority pri,
|
|
|
|
|
const char *format,
|
|
|
|
|
va_list args)
|
|
|
|
|
{
|
2025-06-26 15:31:35 +10:00
|
|
|
if (pri != LIBINPUT_LOG_PRIORITY_ERROR || strstr(format, "client bug: ") ||
|
2021-09-24 17:50:53 +02:00
|
|
|
strstr(format, "libinput bug: ") || strstr(format, "kernel bug: "))
|
2017-01-13 11:44:28 +10:00
|
|
|
return;
|
|
|
|
|
|
2025-06-18 14:55:16 +10:00
|
|
|
/* messages from plugins don't have the string in the format, it's one of the
|
|
|
|
|
* args... */
|
|
|
|
|
_autofree_ char *msg = strdup_vprintf(format, args);
|
|
|
|
|
if (strstr(msg, "plugin bug:"))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
litest_abort_msg("Expected bug statement in log msg ('%s'), aborting.", msg);
|
2017-01-13 11:44:28 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
litest_set_log_handler_bug(struct libinput *libinput)
|
|
|
|
|
{
|
|
|
|
|
libinput_log_set_handler(libinput, litest_bug_log_handler);
|
|
|
|
|
}
|
|
|
|
|
|
test: allow partial overriding the test devices
For specific tests we need something that e.g. looks like a touchpad, but has
a different name, a different number of slots, etc. In this case, the
following code will do exactly that:
struct input_absinfo overrides[] = {
{ .value = ABS_MT_SLOT, .minimum = 0, .maximum = 100 },
{ .value = -1 },
};
litest_create_device_with_overrides(LITEST_SYNAPTICS_CLICKPAD,
NULL, NULL, &overrides, NULL);
For general event codes, overrides can only add to the set of events, they
can't remove.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2014-03-31 14:54:46 +10:00
|
|
|
struct litest_device *
|
2014-02-22 15:06:34 +01:00
|
|
|
litest_add_device_with_overrides(struct libinput *libinput,
|
|
|
|
|
enum litest_device_type which,
|
|
|
|
|
const char *name_override,
|
|
|
|
|
struct input_id *id_override,
|
|
|
|
|
const struct input_absinfo *abs_override,
|
|
|
|
|
const int *events_override)
|
test: allow partial overriding the test devices
For specific tests we need something that e.g. looks like a touchpad, but has
a different name, a different number of slots, etc. In this case, the
following code will do exactly that:
struct input_absinfo overrides[] = {
{ .value = ABS_MT_SLOT, .minimum = 0, .maximum = 100 },
{ .value = -1 },
};
litest_create_device_with_overrides(LITEST_SYNAPTICS_CLICKPAD,
NULL, NULL, &overrides, NULL);
For general event codes, overrides can only add to the set of events, they
can't remove.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2014-03-31 14:54:46 +10:00
|
|
|
{
|
|
|
|
|
struct litest_device *d;
|
|
|
|
|
const char *path;
|
|
|
|
|
|
|
|
|
|
d = litest_create(which,
|
|
|
|
|
name_override,
|
|
|
|
|
id_override,
|
|
|
|
|
abs_override,
|
|
|
|
|
events_override);
|
|
|
|
|
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
path = libevdev_uinput_get_devnode(d->uinput);
|
2019-06-11 08:24:10 +10:00
|
|
|
litest_assert_ptr_notnull(path);
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
|
2014-02-22 15:06:34 +01:00
|
|
|
d->libinput = libinput;
|
2014-01-29 15:38:48 +10:00
|
|
|
d->libinput_device = libinput_path_add_device(d->libinput, path);
|
2019-06-06 14:40:11 +10:00
|
|
|
litest_assert_ptr_notnull(d->libinput_device);
|
2025-04-07 10:53:12 +10:00
|
|
|
_unref_(udev_device) *ud = libinput_device_get_udev_device(d->libinput_device);
|
2018-07-26 10:25:52 +10:00
|
|
|
d->quirks = quirks_fetch_for_device(quirks_context, ud);
|
2018-05-24 16:52:42 +10:00
|
|
|
|
2014-01-29 15:38:48 +10:00
|
|
|
libinput_device_ref(d->libinput_device);
|
|
|
|
|
|
2014-03-31 10:00:16 +10:00
|
|
|
if (d->interface) {
|
2018-09-27 15:07:53 +10:00
|
|
|
unsigned int code;
|
|
|
|
|
|
|
|
|
|
code = ABS_X;
|
|
|
|
|
if (!libevdev_has_event_code(d->evdev, EV_ABS, code))
|
|
|
|
|
code = ABS_MT_POSITION_X;
|
|
|
|
|
if (libevdev_has_event_code(d->evdev, EV_ABS, code)) {
|
|
|
|
|
d->interface->min[ABS_X] =
|
|
|
|
|
libevdev_get_abs_minimum(d->evdev, code);
|
|
|
|
|
d->interface->max[ABS_X] =
|
|
|
|
|
libevdev_get_abs_maximum(d->evdev, code);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
code = ABS_Y;
|
|
|
|
|
if (!libevdev_has_event_code(d->evdev, EV_ABS, code))
|
|
|
|
|
code = ABS_MT_POSITION_Y;
|
|
|
|
|
if (libevdev_has_event_code(d->evdev, EV_ABS, code)) {
|
|
|
|
|
d->interface->min[ABS_Y] =
|
|
|
|
|
libevdev_get_abs_minimum(d->evdev, code);
|
|
|
|
|
d->interface->max[ABS_Y] =
|
|
|
|
|
libevdev_get_abs_maximum(d->evdev, code);
|
|
|
|
|
}
|
2020-09-11 08:43:58 +10:00
|
|
|
d->interface->tool_type = BTN_TOOL_PEN;
|
2014-03-31 10:00:16 +10:00
|
|
|
}
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
return d;
|
|
|
|
|
}
|
|
|
|
|
|
2014-08-29 14:08:46 +10:00
|
|
|
struct litest_device *
|
|
|
|
|
litest_add_device(struct libinput *libinput, enum litest_device_type which)
|
|
|
|
|
{
|
|
|
|
|
return litest_add_device_with_overrides(libinput,
|
|
|
|
|
which,
|
|
|
|
|
NULL,
|
|
|
|
|
NULL,
|
|
|
|
|
NULL,
|
|
|
|
|
NULL);
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-22 15:06:34 +01:00
|
|
|
struct litest_device *
|
|
|
|
|
litest_create_device_with_overrides(enum litest_device_type which,
|
|
|
|
|
const char *name_override,
|
|
|
|
|
struct input_id *id_override,
|
|
|
|
|
const struct input_absinfo *abs_override,
|
|
|
|
|
const int *events_override)
|
|
|
|
|
{
|
|
|
|
|
struct litest_device *dev =
|
|
|
|
|
litest_add_device_with_overrides(litest_create_context(),
|
|
|
|
|
which,
|
|
|
|
|
name_override,
|
|
|
|
|
id_override,
|
|
|
|
|
abs_override,
|
|
|
|
|
events_override);
|
|
|
|
|
dev->owns_context = true;
|
|
|
|
|
return dev;
|
|
|
|
|
}
|
|
|
|
|
|
test: allow partial overriding the test devices
For specific tests we need something that e.g. looks like a touchpad, but has
a different name, a different number of slots, etc. In this case, the
following code will do exactly that:
struct input_absinfo overrides[] = {
{ .value = ABS_MT_SLOT, .minimum = 0, .maximum = 100 },
{ .value = -1 },
};
litest_create_device_with_overrides(LITEST_SYNAPTICS_CLICKPAD,
NULL, NULL, &overrides, NULL);
For general event codes, overrides can only add to the set of events, they
can't remove.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2014-03-31 14:54:46 +10:00
|
|
|
struct litest_device *
|
|
|
|
|
litest_create_device(enum litest_device_type which)
|
|
|
|
|
{
|
|
|
|
|
return litest_create_device_with_overrides(which, NULL, NULL, NULL, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-18 11:05:46 +10:00
|
|
|
static struct udev_monitor *
|
|
|
|
|
udev_setup_monitor(void)
|
|
|
|
|
{
|
2025-04-07 10:53:12 +10:00
|
|
|
_unref_(udev) *udev = udev_new();
|
|
|
|
|
_unref_(udev_monitor) *udev_monitor = NULL;
|
2018-04-18 11:05:46 +10:00
|
|
|
int rc;
|
|
|
|
|
|
|
|
|
|
litest_assert_notnull(udev);
|
|
|
|
|
udev_monitor = udev_monitor_new_from_netlink(udev, "udev");
|
|
|
|
|
litest_assert_notnull(udev_monitor);
|
|
|
|
|
udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "input", NULL);
|
|
|
|
|
|
|
|
|
|
/* remove O_NONBLOCK */
|
|
|
|
|
rc = fcntl(udev_monitor_get_fd(udev_monitor), F_SETFL, 0);
|
2024-10-16 11:27:27 +10:00
|
|
|
litest_assert_errno_success(rc);
|
2018-04-18 11:05:46 +10:00
|
|
|
litest_assert_int_eq(udev_monitor_enable_receiving(udev_monitor), 0);
|
|
|
|
|
|
2025-04-07 10:53:12 +10:00
|
|
|
return steal(&udev_monitor);
|
2018-04-18 11:05:46 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct udev_device *
|
|
|
|
|
udev_wait_for_device_event(struct udev_monitor *udev_monitor,
|
|
|
|
|
const char *udev_event,
|
|
|
|
|
const char *syspath)
|
|
|
|
|
{
|
|
|
|
|
/* blocking, we don't want to continue until udev is ready */
|
|
|
|
|
while (1) {
|
2025-04-07 10:53:12 +10:00
|
|
|
_unref_(udev_device) *udev_device = NULL;
|
2018-04-18 11:05:46 +10:00
|
|
|
const char *udev_syspath = NULL;
|
|
|
|
|
const char *udev_action;
|
|
|
|
|
|
|
|
|
|
udev_device = udev_monitor_receive_device(udev_monitor);
|
2025-07-02 15:29:23 +10:00
|
|
|
if (!udev_device) {
|
2025-07-02 16:38:39 +10:00
|
|
|
if (errno == EAGAIN)
|
|
|
|
|
continue;
|
|
|
|
|
|
2025-07-02 15:29:23 +10:00
|
|
|
litest_abort_msg(
|
|
|
|
|
"Failed to receive udev device from monitor: %s (%d)",
|
|
|
|
|
strerror(errno),
|
|
|
|
|
errno);
|
|
|
|
|
}
|
2018-04-18 11:05:46 +10:00
|
|
|
udev_action = udev_device_get_action(udev_device);
|
2021-01-06 17:46:14 +08:00
|
|
|
if (!udev_action || !streq(udev_action, udev_event)) {
|
2018-04-18 11:05:46 +10:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
udev_syspath = udev_device_get_syspath(udev_device);
|
2025-01-09 09:04:54 +10:00
|
|
|
if (strstartswith(udev_syspath, syspath))
|
2025-04-07 10:53:12 +10:00
|
|
|
return steal(&udev_device);
|
2018-04-18 11:05:46 +10:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
void
|
2025-04-07 15:12:51 +10:00
|
|
|
litest_device_destroy(struct litest_device *d)
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
{
|
2018-04-18 11:05:46 +10:00
|
|
|
|
2025-04-07 10:53:12 +10:00
|
|
|
_unref_(udev_monitor) *udev_monitor = NULL;
|
|
|
|
|
_unref_(udev_device) *udev_device = NULL;
|
2018-04-18 11:05:46 +10:00
|
|
|
char path[PATH_MAX];
|
|
|
|
|
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
if (!d)
|
|
|
|
|
return;
|
|
|
|
|
|
2018-04-18 11:05:46 +10:00
|
|
|
udev_monitor = udev_setup_monitor();
|
|
|
|
|
snprintf(path,
|
|
|
|
|
sizeof(path),
|
|
|
|
|
"%s/event",
|
|
|
|
|
libevdev_uinput_get_syspath(d->uinput));
|
|
|
|
|
|
2017-01-19 17:20:19 +10:00
|
|
|
litest_assert_int_eq(d->skip_ev_syn, 0);
|
|
|
|
|
|
2018-05-24 16:52:42 +10:00
|
|
|
quirks_unref(d->quirks);
|
|
|
|
|
|
2017-08-17 02:07:18 +02:00
|
|
|
if (d->libinput_device) {
|
|
|
|
|
libinput_path_remove_device(d->libinput_device);
|
2017-10-17 16:55:27 +10:00
|
|
|
libinput_device_unref(d->libinput_device);
|
2017-08-17 02:07:18 +02:00
|
|
|
}
|
2019-01-30 14:26:31 +10:00
|
|
|
if (d->owns_context) {
|
|
|
|
|
libinput_dispatch(d->libinput);
|
2020-07-03 10:47:13 +10:00
|
|
|
litest_destroy_context(d->libinput);
|
2019-01-30 14:26:31 +10:00
|
|
|
}
|
2016-02-04 21:08:30 +10:00
|
|
|
close(libevdev_get_fd(d->evdev));
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
libevdev_free(d->evdev);
|
|
|
|
|
libevdev_uinput_destroy(d->uinput);
|
2014-07-24 13:18:56 +10:00
|
|
|
free(d->private);
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
memset(d, 0, sizeof(*d));
|
|
|
|
|
free(d);
|
2018-04-18 11:05:46 +10:00
|
|
|
|
2025-04-07 10:53:12 +10:00
|
|
|
udev_device =
|
|
|
|
|
udev_wait_for_device_event(udev_monitor, // NOLINT: deadcode.DeadStores
|
2018-04-18 11:05:46 +10:00
|
|
|
"remove",
|
|
|
|
|
path);
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
litest_event(struct litest_device *d, unsigned int type, unsigned int code, int value)
|
|
|
|
|
{
|
2019-04-05 15:57:48 +10:00
|
|
|
if (!libevdev_has_event_code(d->evdev, type, code))
|
|
|
|
|
return;
|
|
|
|
|
|
2025-04-09 17:50:42 +10:00
|
|
|
if (type == EV_SYN && code == SYN_REPORT) {
|
|
|
|
|
if (d->skip_ev_syn)
|
|
|
|
|
return;
|
2014-09-17 10:07:38 +10:00
|
|
|
|
2025-04-09 17:50:42 +10:00
|
|
|
for (size_t i = 0; i < d->frame.nevents; i++) {
|
|
|
|
|
struct input_event *e = &d->frame.events[i];
|
|
|
|
|
int ret = libevdev_uinput_write_event(d->uinput,
|
|
|
|
|
e->type,
|
|
|
|
|
e->code,
|
|
|
|
|
e->value);
|
|
|
|
|
litest_assert_neg_errno_success(ret);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int ret = libevdev_uinput_write_event(d->uinput,
|
|
|
|
|
EV_SYN,
|
|
|
|
|
SYN_REPORT,
|
|
|
|
|
value);
|
|
|
|
|
litest_assert_neg_errno_success(ret);
|
|
|
|
|
|
|
|
|
|
d->frame.nevents = 0;
|
|
|
|
|
} else {
|
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
|
|
if (type == EV_SYN || (type == EV_ABS && code >= ABS_MT_SLOT)) {
|
|
|
|
|
i = d->frame.nevents;
|
|
|
|
|
} else {
|
|
|
|
|
for (i = 0; i < d->frame.nevents; i++) {
|
|
|
|
|
if (d->frame.events[i].type == type &&
|
|
|
|
|
d->frame.events[i].code == code)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
litest_assert_int_lt(i, ARRAY_LENGTH(d->frame.events));
|
|
|
|
|
d->frame.events[i] = (struct input_event){
|
|
|
|
|
.type = type,
|
|
|
|
|
.code = code,
|
|
|
|
|
.value = value,
|
|
|
|
|
};
|
|
|
|
|
if (i >= d->frame.nevents)
|
|
|
|
|
d->frame.nevents++;
|
|
|
|
|
}
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
}
|
|
|
|
|
|
2015-07-06 16:26:21 +10:00
|
|
|
static bool
|
2015-12-10 16:05:37 +10:00
|
|
|
axis_replacement_value(struct litest_device *d,
|
|
|
|
|
struct axis_replacement *axes,
|
2015-07-06 16:26:21 +10:00
|
|
|
int32_t evcode,
|
|
|
|
|
int32_t *value)
|
2015-06-22 12:48:04 +02:00
|
|
|
{
|
|
|
|
|
struct axis_replacement *axis = axes;
|
|
|
|
|
|
2015-07-22 12:22:33 +10:00
|
|
|
if (!axes)
|
|
|
|
|
return false;
|
|
|
|
|
|
2015-06-22 12:48:04 +02:00
|
|
|
while (axis->evcode != -1) {
|
2015-07-06 16:26:21 +10:00
|
|
|
if (axis->evcode == evcode) {
|
2018-07-13 16:24:04 +10:00
|
|
|
switch (evcode) {
|
|
|
|
|
case ABS_MT_SLOT:
|
|
|
|
|
case ABS_MT_TRACKING_ID:
|
|
|
|
|
case ABS_MT_TOOL_TYPE:
|
|
|
|
|
*value = axis->value;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
*value = litest_scale(d, evcode, axis->value);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2015-07-06 16:26:21 +10:00
|
|
|
return true;
|
|
|
|
|
}
|
2015-06-22 12:48:04 +02:00
|
|
|
axis++;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-06 16:26:21 +10:00
|
|
|
return false;
|
2015-06-22 12:48:04 +02:00
|
|
|
}
|
|
|
|
|
|
2014-07-24 13:18:56 +10:00
|
|
|
int
|
|
|
|
|
litest_auto_assign_value(struct litest_device *d,
|
|
|
|
|
const struct input_event *ev,
|
2015-05-06 19:41:25 -04:00
|
|
|
int slot,
|
|
|
|
|
double x,
|
|
|
|
|
double y,
|
2015-06-22 12:48:04 +02:00
|
|
|
struct axis_replacement *axes,
|
2015-05-06 19:41:25 -04:00
|
|
|
bool touching)
|
2014-03-31 10:00:16 +10:00
|
|
|
{
|
|
|
|
|
static int tracking_id;
|
|
|
|
|
int value = ev->value;
|
|
|
|
|
|
|
|
|
|
if (value != LITEST_AUTO_ASSIGN || ev->type != EV_ABS)
|
|
|
|
|
return value;
|
|
|
|
|
|
|
|
|
|
switch (ev->code) {
|
|
|
|
|
case ABS_X:
|
|
|
|
|
case ABS_MT_POSITION_X:
|
|
|
|
|
value = litest_scale(d, ABS_X, x);
|
|
|
|
|
break;
|
|
|
|
|
case ABS_Y:
|
|
|
|
|
case ABS_MT_POSITION_Y:
|
|
|
|
|
value = litest_scale(d, ABS_Y, y);
|
|
|
|
|
break;
|
|
|
|
|
case ABS_MT_TRACKING_ID:
|
|
|
|
|
value = ++tracking_id;
|
|
|
|
|
break;
|
|
|
|
|
case ABS_MT_SLOT:
|
|
|
|
|
value = slot;
|
|
|
|
|
break;
|
2015-05-06 19:41:25 -04:00
|
|
|
case ABS_MT_DISTANCE:
|
|
|
|
|
value = touching ? 0 : 1;
|
|
|
|
|
break;
|
2018-07-13 16:24:04 +10:00
|
|
|
case ABS_MT_TOOL_TYPE:
|
|
|
|
|
if (!axis_replacement_value(d, axes, ev->code, &value))
|
|
|
|
|
value = MT_TOOL_FINGER;
|
|
|
|
|
break;
|
2015-06-22 12:48:04 +02:00
|
|
|
default:
|
2015-12-10 16:05:37 +10:00
|
|
|
if (!axis_replacement_value(d, axes, ev->code, &value) &&
|
2019-04-10 12:41:40 -07:00
|
|
|
d->interface->get_axis_default) {
|
|
|
|
|
int error = d->interface->get_axis_default(d, ev->code, &value);
|
|
|
|
|
if (error) {
|
2024-10-14 21:42:26 +10:00
|
|
|
litest_abort_msg(
|
|
|
|
|
"Failed to get default axis value for %s (%d)",
|
2019-04-10 12:41:40 -07:00
|
|
|
libevdev_event_code_get_name(EV_ABS, ev->code),
|
|
|
|
|
ev->code);
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-06-22 12:48:04 +02:00
|
|
|
break;
|
2014-03-31 10:00:16 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-21 12:30:40 +10:00
|
|
|
static void
|
2015-12-02 09:48:01 +10:00
|
|
|
send_btntool(struct litest_device *d, bool hover)
|
2014-07-21 12:30:40 +10:00
|
|
|
{
|
2015-12-02 09:48:01 +10:00
|
|
|
litest_event(d, EV_KEY, BTN_TOUCH, d->ntouches_down != 0 && !hover);
|
2014-07-21 12:30:40 +10:00
|
|
|
litest_event(d, EV_KEY, BTN_TOOL_FINGER, d->ntouches_down == 1);
|
|
|
|
|
litest_event(d, EV_KEY, BTN_TOOL_DOUBLETAP, d->ntouches_down == 2);
|
|
|
|
|
litest_event(d, EV_KEY, BTN_TOOL_TRIPLETAP, d->ntouches_down == 3);
|
|
|
|
|
litest_event(d, EV_KEY, BTN_TOOL_QUADTAP, d->ntouches_down == 4);
|
|
|
|
|
litest_event(d, EV_KEY, BTN_TOOL_QUINTTAP, d->ntouches_down == 5);
|
|
|
|
|
}
|
2014-03-31 10:00:16 +10:00
|
|
|
|
2015-05-06 19:41:25 -04:00
|
|
|
static void
|
2017-01-19 15:58:13 +10:00
|
|
|
slot_start(struct litest_device *d,
|
|
|
|
|
unsigned int slot,
|
|
|
|
|
double x,
|
|
|
|
|
double y,
|
|
|
|
|
struct axis_replacement *axes,
|
|
|
|
|
bool touching,
|
|
|
|
|
bool filter_abs_xy)
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
{
|
2014-03-31 10:00:16 +10:00
|
|
|
struct input_event *ev;
|
|
|
|
|
|
2019-06-11 08:24:10 +10:00
|
|
|
litest_assert_int_ge(d->ntouches_down, 0);
|
2015-02-19 07:22:59 +10:00
|
|
|
d->ntouches_down++;
|
2014-07-21 12:30:40 +10:00
|
|
|
|
2015-12-02 09:48:01 +10:00
|
|
|
send_btntool(d, !touching);
|
2014-07-21 12:30:40 +10:00
|
|
|
|
2020-01-09 09:48:29 +10:00
|
|
|
/* If the test device overrides touch_down and says it didn't
|
|
|
|
|
* handle the event, let's continue normally */
|
|
|
|
|
if (d->interface->touch_down && d->interface->touch_down(d, slot, x, y))
|
|
|
|
|
return;
|
2014-03-31 10:00:16 +10:00
|
|
|
|
2017-01-19 16:52:04 +10:00
|
|
|
for (ev = d->interface->touch_down_events;
|
|
|
|
|
ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1;
|
|
|
|
|
ev++) {
|
2015-05-06 19:41:25 -04:00
|
|
|
int value = litest_auto_assign_value(d, ev, slot, x, y, axes, touching);
|
2017-01-19 16:52:04 +10:00
|
|
|
if (value == LITEST_AUTO_ASSIGN)
|
|
|
|
|
continue;
|
|
|
|
|
|
2017-01-19 15:58:13 +10:00
|
|
|
if (filter_abs_xy && ev->type == EV_ABS &&
|
|
|
|
|
(ev->code == ABS_X || ev->code == ABS_Y))
|
|
|
|
|
continue;
|
|
|
|
|
|
2017-01-19 16:52:04 +10:00
|
|
|
litest_event(d, ev->type, ev->code, value);
|
2014-03-31 10:00:16 +10:00
|
|
|
}
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
}
|
|
|
|
|
|
2017-01-19 15:58:13 +10:00
|
|
|
static void
|
|
|
|
|
slot_move(struct litest_device *d,
|
|
|
|
|
unsigned int slot,
|
|
|
|
|
double x,
|
|
|
|
|
double y,
|
|
|
|
|
struct axis_replacement *axes,
|
|
|
|
|
bool touching,
|
|
|
|
|
bool filter_abs_xy)
|
2015-05-06 19:41:25 -04:00
|
|
|
{
|
2017-01-19 15:58:13 +10:00
|
|
|
struct input_event *ev;
|
2015-06-22 12:48:04 +02:00
|
|
|
|
2020-01-09 09:48:29 +10:00
|
|
|
if (d->interface->touch_move && d->interface->touch_move(d, slot, x, y))
|
2017-01-19 15:58:13 +10:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
for (ev = d->interface->touch_move_events;
|
|
|
|
|
ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1;
|
|
|
|
|
ev++) {
|
|
|
|
|
int value = litest_auto_assign_value(d, ev, slot, x, y, axes, touching);
|
|
|
|
|
if (value == LITEST_AUTO_ASSIGN)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (filter_abs_xy && ev->type == EV_ABS &&
|
|
|
|
|
(ev->code == ABS_X || ev->code == ABS_Y))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
litest_event(d, ev->type, ev->code, value);
|
|
|
|
|
}
|
2015-05-06 19:41:25 -04:00
|
|
|
}
|
|
|
|
|
|
2017-01-19 15:58:13 +10:00
|
|
|
static void
|
|
|
|
|
touch_up(struct litest_device *d, unsigned int slot)
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
{
|
|
|
|
|
struct input_event *ev;
|
|
|
|
|
struct input_event up[] = {
|
2014-03-31 10:00:16 +10:00
|
|
|
{ .type = EV_ABS, .code = ABS_MT_SLOT, .value = LITEST_AUTO_ASSIGN },
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
{ .type = EV_ABS, .code = ABS_MT_TRACKING_ID, .value = -1 },
|
2017-01-23 12:04:20 +10:00
|
|
|
{ .type = EV_ABS, .code = ABS_MT_PRESSURE, .value = 0 },
|
2017-03-28 11:22:27 +10:00
|
|
|
{ .type = EV_ABS, .code = ABS_MT_TOUCH_MAJOR, .value = 0 },
|
|
|
|
|
{ .type = EV_ABS, .code = ABS_MT_TOUCH_MINOR, .value = 0 },
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
{ .type = EV_SYN, .code = SYN_REPORT, .value = 0 },
|
2014-03-31 10:00:16 +10:00
|
|
|
{ .type = -1, .code = -1 }
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
};
|
|
|
|
|
|
2015-06-17 11:21:23 +10:00
|
|
|
litest_assert_int_gt(d->ntouches_down, 0);
|
2015-02-19 07:22:59 +10:00
|
|
|
d->ntouches_down--;
|
2014-07-21 12:30:40 +10:00
|
|
|
|
2015-12-02 09:48:01 +10:00
|
|
|
send_btntool(d, false);
|
2014-07-21 12:30:40 +10:00
|
|
|
|
2020-01-09 09:48:29 +10:00
|
|
|
if (d->interface->touch_up && d->interface->touch_up(d, slot)) {
|
2014-03-31 10:00:16 +10:00
|
|
|
return;
|
|
|
|
|
} else if (d->interface->touch_up_events) {
|
|
|
|
|
ev = d->interface->touch_up_events;
|
|
|
|
|
} else
|
|
|
|
|
ev = up;
|
|
|
|
|
|
2017-01-19 16:52:04 +10:00
|
|
|
for (/* */; ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1; ev++) {
|
2015-05-06 19:41:25 -04:00
|
|
|
int value = litest_auto_assign_value(d, ev, slot, 0, 0, NULL, false);
|
2014-03-31 10:00:16 +10:00
|
|
|
litest_event(d, ev->type, ev->code, value);
|
2014-03-24 15:25:32 +10:00
|
|
|
}
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
}
|
|
|
|
|
|
2017-01-19 15:58:13 +10:00
|
|
|
static void
|
|
|
|
|
litest_slot_start(struct litest_device *d,
|
|
|
|
|
unsigned int slot,
|
|
|
|
|
double x,
|
|
|
|
|
double y,
|
|
|
|
|
struct axis_replacement *axes,
|
|
|
|
|
bool touching)
|
|
|
|
|
{
|
|
|
|
|
double t, l, r = 0, b = 0; /* top, left, right, bottom */
|
|
|
|
|
bool filter_abs_xy = false;
|
|
|
|
|
|
|
|
|
|
if (!d->semi_mt.is_semi_mt) {
|
|
|
|
|
slot_start(d, slot, x, y, axes, touching, filter_abs_xy);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (d->ntouches_down >= 2 || slot > 1)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
slot = d->ntouches_down;
|
|
|
|
|
|
|
|
|
|
if (d->ntouches_down == 0) {
|
|
|
|
|
l = x;
|
|
|
|
|
t = y;
|
|
|
|
|
} else {
|
|
|
|
|
int other = (slot + 1) % 2;
|
|
|
|
|
l = min(x, d->semi_mt.touches[other].x);
|
|
|
|
|
t = min(y, d->semi_mt.touches[other].y);
|
|
|
|
|
r = max(x, d->semi_mt.touches[other].x);
|
|
|
|
|
b = max(y, d->semi_mt.touches[other].y);
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-15 13:29:39 +10:00
|
|
|
litest_with_event_frame(d) {
|
|
|
|
|
if (d->ntouches_down == 0)
|
|
|
|
|
slot_start(d, 0, l, t, axes, touching, filter_abs_xy);
|
|
|
|
|
else
|
|
|
|
|
slot_move(d, 0, l, t, axes, touching, filter_abs_xy);
|
2017-01-19 15:58:13 +10:00
|
|
|
|
2025-04-15 13:29:39 +10:00
|
|
|
if (slot == 1) {
|
|
|
|
|
filter_abs_xy = true;
|
|
|
|
|
slot_start(d, 1, r, b, axes, touching, filter_abs_xy);
|
|
|
|
|
}
|
2017-01-19 15:58:13 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
d->semi_mt.touches[slot].x = x;
|
|
|
|
|
d->semi_mt.touches[slot].y = y;
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-28 11:47:32 +10:00
|
|
|
void
|
|
|
|
|
litest_touch_sequence(struct litest_device *d,
|
|
|
|
|
unsigned int slot,
|
|
|
|
|
double x_from,
|
|
|
|
|
double y_from,
|
|
|
|
|
double x_to,
|
|
|
|
|
double y_to,
|
|
|
|
|
int steps)
|
|
|
|
|
{
|
|
|
|
|
litest_touch_down(d, slot, x_from, y_from);
|
|
|
|
|
litest_touch_move_to(d, slot, x_from, y_from, x_to, y_to, steps);
|
|
|
|
|
litest_touch_up(d, slot);
|
|
|
|
|
}
|
|
|
|
|
|
2017-01-19 15:58:13 +10:00
|
|
|
void
|
|
|
|
|
litest_touch_down(struct litest_device *d, unsigned int slot, double x, double y)
|
|
|
|
|
{
|
|
|
|
|
litest_slot_start(d, slot, x, y, NULL, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
litest_touch_down_extended(struct litest_device *d,
|
|
|
|
|
unsigned int slot,
|
|
|
|
|
double x,
|
|
|
|
|
double y,
|
|
|
|
|
struct axis_replacement *axes)
|
|
|
|
|
{
|
|
|
|
|
litest_slot_start(d, slot, x, y, axes, true);
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-06 19:41:25 -04:00
|
|
|
static void
|
2015-06-22 12:48:04 +02:00
|
|
|
litest_slot_move(struct litest_device *d,
|
|
|
|
|
unsigned int slot,
|
|
|
|
|
double x,
|
|
|
|
|
double y,
|
|
|
|
|
struct axis_replacement *axes,
|
|
|
|
|
bool touching)
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
{
|
2017-01-19 15:58:13 +10:00
|
|
|
double t, l, r = 0, b = 0; /* top, left, right, bottom */
|
|
|
|
|
bool filter_abs_xy = false;
|
2014-03-31 10:00:16 +10:00
|
|
|
|
2017-01-19 15:58:13 +10:00
|
|
|
if (!d->semi_mt.is_semi_mt) {
|
|
|
|
|
slot_move(d, slot, x, y, axes, touching, filter_abs_xy);
|
2014-03-31 10:00:16 +10:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2017-01-19 15:58:13 +10:00
|
|
|
if (d->ntouches_down > 2 || slot > 1)
|
|
|
|
|
return;
|
2017-01-19 16:52:04 +10:00
|
|
|
|
2017-01-19 15:58:13 +10:00
|
|
|
if (d->ntouches_down == 1) {
|
|
|
|
|
l = x;
|
|
|
|
|
t = y;
|
|
|
|
|
} else {
|
|
|
|
|
int other = (slot + 1) % 2;
|
|
|
|
|
l = min(x, d->semi_mt.touches[other].x);
|
|
|
|
|
t = min(y, d->semi_mt.touches[other].y);
|
|
|
|
|
r = max(x, d->semi_mt.touches[other].x);
|
|
|
|
|
b = max(y, d->semi_mt.touches[other].y);
|
2014-03-31 10:00:16 +10:00
|
|
|
}
|
2017-01-19 15:58:13 +10:00
|
|
|
|
2025-04-15 13:29:39 +10:00
|
|
|
litest_with_event_frame(d) {
|
|
|
|
|
slot_move(d, 0, l, t, axes, touching, filter_abs_xy);
|
2017-01-19 15:58:13 +10:00
|
|
|
|
2025-04-15 13:29:39 +10:00
|
|
|
if (d->ntouches_down == 2) {
|
|
|
|
|
filter_abs_xy = true;
|
|
|
|
|
slot_move(d, 1, r, b, axes, touching, filter_abs_xy);
|
|
|
|
|
}
|
2014-03-31 10:00:16 +10:00
|
|
|
}
|
2017-01-19 15:58:13 +10:00
|
|
|
|
|
|
|
|
d->semi_mt.touches[slot].x = x;
|
|
|
|
|
d->semi_mt.touches[slot].y = y;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
litest_touch_up(struct litest_device *d, unsigned int slot)
|
|
|
|
|
{
|
|
|
|
|
if (!d->semi_mt.is_semi_mt) {
|
|
|
|
|
touch_up(d, slot);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (d->ntouches_down > 2 || slot > 1)
|
|
|
|
|
return;
|
|
|
|
|
|
2025-04-15 13:29:39 +10:00
|
|
|
litest_with_event_frame(d) {
|
|
|
|
|
touch_up(d, d->ntouches_down - 1);
|
|
|
|
|
|
|
|
|
|
/* if we have one finger left, send x/y coords for that finger left.
|
|
|
|
|
this is likely to happen with a real touchpad */
|
|
|
|
|
if (d->ntouches_down == 1) {
|
|
|
|
|
bool touching = true;
|
|
|
|
|
bool filter_abs_xy = false;
|
|
|
|
|
|
|
|
|
|
int other = (slot + 1) % 2;
|
|
|
|
|
slot_move(d,
|
|
|
|
|
0,
|
|
|
|
|
d->semi_mt.touches[other].x,
|
|
|
|
|
d->semi_mt.touches[other].y,
|
|
|
|
|
NULL,
|
|
|
|
|
touching,
|
|
|
|
|
filter_abs_xy);
|
|
|
|
|
}
|
2017-01-19 15:58:13 +10:00
|
|
|
}
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
}
|
|
|
|
|
|
2015-05-06 19:41:25 -04:00
|
|
|
void
|
2015-06-22 12:48:04 +02:00
|
|
|
litest_touch_move(struct litest_device *d, unsigned int slot, double x, double y)
|
|
|
|
|
{
|
|
|
|
|
litest_slot_move(d, slot, x, y, NULL, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
litest_touch_move_extended(struct litest_device *d,
|
|
|
|
|
unsigned int slot,
|
|
|
|
|
double x,
|
|
|
|
|
double y,
|
|
|
|
|
struct axis_replacement *axes)
|
2015-05-06 19:41:25 -04:00
|
|
|
{
|
2015-06-22 12:48:04 +02:00
|
|
|
litest_slot_move(d, slot, x, y, axes, true);
|
2015-05-06 19:41:25 -04:00
|
|
|
}
|
|
|
|
|
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
void
|
2016-06-16 16:10:21 +10:00
|
|
|
litest_touch_move_to(struct litest_device *d,
|
|
|
|
|
unsigned int slot,
|
|
|
|
|
double x_from,
|
|
|
|
|
double y_from,
|
|
|
|
|
double x_to,
|
|
|
|
|
double y_to,
|
test: drop the sleep_ms argument
This forces events for every ~10ms now. If we want a slower movement, we need
more steps - just like a real touchpad does it.
Cocinelle spatch files were variants of:
@@
expression A, B, C, D, E, F, G, H, I, J, K;
@@
- litest_touch_move_two_touches(A, B, C, D, E, F, G, H, I)
+ litest_touch_move_two_touches(A, B, C, D, E, F, G, H)
The only test that needed a real fix was touchpad_no_palm_detect_2fg_scroll,
it used 12ms before, now it's using 10ms so on the bcm5974 touchpad the second
finger was a speed-thumb. Increasing the events and thus slowing down the
pointer means it's a normal finger and the test succeeds again.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-08-28 09:16:52 +10:00
|
|
|
int steps)
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
{
|
2018-08-27 13:26:04 +10:00
|
|
|
litest_touch_move_to_extended(d, slot, x_from, y_from, x_to, y_to, NULL, steps);
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
}
|
|
|
|
|
|
2017-01-11 14:48:11 +10:00
|
|
|
void
|
|
|
|
|
litest_touch_move_to_extended(struct litest_device *d,
|
|
|
|
|
unsigned int slot,
|
|
|
|
|
double x_from,
|
|
|
|
|
double y_from,
|
|
|
|
|
double x_to,
|
|
|
|
|
double y_to,
|
|
|
|
|
struct axis_replacement *axes,
|
test: drop the sleep_ms argument
This forces events for every ~10ms now. If we want a slower movement, we need
more steps - just like a real touchpad does it.
Cocinelle spatch files were variants of:
@@
expression A, B, C, D, E, F, G, H, I, J, K;
@@
- litest_touch_move_two_touches(A, B, C, D, E, F, G, H, I)
+ litest_touch_move_two_touches(A, B, C, D, E, F, G, H)
The only test that needed a real fix was touchpad_no_palm_detect_2fg_scroll,
it used 12ms before, now it's using 10ms so on the bcm5974 touchpad the second
finger was a speed-thumb. Increasing the events and thus slowing down the
pointer means it's a normal finger and the test succeeds again.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-08-28 09:16:52 +10:00
|
|
|
int steps)
|
2017-01-11 14:48:11 +10:00
|
|
|
{
|
test: drop the sleep_ms argument
This forces events for every ~10ms now. If we want a slower movement, we need
more steps - just like a real touchpad does it.
Cocinelle spatch files were variants of:
@@
expression A, B, C, D, E, F, G, H, I, J, K;
@@
- litest_touch_move_two_touches(A, B, C, D, E, F, G, H, I)
+ litest_touch_move_two_touches(A, B, C, D, E, F, G, H)
The only test that needed a real fix was touchpad_no_palm_detect_2fg_scroll,
it used 12ms before, now it's using 10ms so on the bcm5974 touchpad the second
finger was a speed-thumb. Increasing the events and thus slowing down the
pointer means it's a normal finger and the test succeeds again.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-08-28 09:16:52 +10:00
|
|
|
int sleep_ms = 10;
|
2018-08-27 13:22:24 +10:00
|
|
|
|
2018-08-27 13:26:04 +10:00
|
|
|
for (int i = 1; i < steps; i++) {
|
2017-01-11 14:48:11 +10:00
|
|
|
litest_touch_move_extended(d,
|
|
|
|
|
slot,
|
|
|
|
|
x_from + (x_to - x_from) / steps * i,
|
|
|
|
|
y_from + (y_to - y_from) / steps * i,
|
|
|
|
|
axes);
|
2018-08-27 13:22:24 +10:00
|
|
|
libinput_dispatch(d->libinput);
|
|
|
|
|
msleep(sleep_ms);
|
|
|
|
|
libinput_dispatch(d->libinput);
|
2017-01-11 14:48:11 +10:00
|
|
|
}
|
|
|
|
|
litest_touch_move_extended(d, slot, x_to, y_to, axes);
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-21 19:11:27 +02:00
|
|
|
static int
|
|
|
|
|
auto_assign_tablet_value(struct litest_device *d,
|
|
|
|
|
const struct input_event *ev,
|
|
|
|
|
int x,
|
|
|
|
|
int y,
|
|
|
|
|
struct axis_replacement *axes)
|
|
|
|
|
{
|
2018-09-14 14:03:09 +10:00
|
|
|
static int tracking_id;
|
2014-04-21 19:11:27 +02:00
|
|
|
int value = ev->value;
|
|
|
|
|
|
|
|
|
|
if (value != LITEST_AUTO_ASSIGN || ev->type != EV_ABS)
|
|
|
|
|
return value;
|
|
|
|
|
|
|
|
|
|
switch (ev->code) {
|
2018-09-14 14:03:09 +10:00
|
|
|
case ABS_MT_TRACKING_ID:
|
|
|
|
|
value = ++tracking_id;
|
|
|
|
|
break;
|
2014-04-21 19:11:27 +02:00
|
|
|
case ABS_X:
|
2018-09-14 14:03:09 +10:00
|
|
|
case ABS_MT_POSITION_X:
|
2014-04-21 19:11:27 +02:00
|
|
|
value = litest_scale(d, ABS_X, x);
|
|
|
|
|
break;
|
|
|
|
|
case ABS_Y:
|
2018-09-14 14:03:09 +10:00
|
|
|
case ABS_MT_POSITION_Y:
|
2014-04-21 19:11:27 +02:00
|
|
|
value = litest_scale(d, ABS_Y, y);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
2015-12-11 17:39:57 +10:00
|
|
|
if (!axis_replacement_value(d, axes, ev->code, &value) &&
|
2019-04-10 12:41:40 -07:00
|
|
|
d->interface->get_axis_default) {
|
|
|
|
|
int error = d->interface->get_axis_default(d, ev->code, &value);
|
|
|
|
|
if (error) {
|
2024-10-14 21:42:26 +10:00
|
|
|
litest_abort_msg(
|
|
|
|
|
"Failed to get default axis value for %s (%d)",
|
2019-04-10 12:41:40 -07:00
|
|
|
libevdev_event_code_get_name(EV_ABS, ev->code),
|
|
|
|
|
ev->code);
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-04-21 19:11:27 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
tablet_ignore_event(const struct input_event *ev, int value)
|
|
|
|
|
{
|
|
|
|
|
return value == -1 && (ev->code == ABS_PRESSURE || ev->code == ABS_DISTANCE);
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-11 08:43:58 +10:00
|
|
|
void
|
|
|
|
|
litest_tablet_set_tool_type(struct litest_device *d, unsigned int code)
|
|
|
|
|
{
|
|
|
|
|
switch (code) {
|
|
|
|
|
case BTN_TOOL_PEN:
|
|
|
|
|
case BTN_TOOL_RUBBER:
|
|
|
|
|
case BTN_TOOL_BRUSH:
|
|
|
|
|
case BTN_TOOL_PENCIL:
|
|
|
|
|
case BTN_TOOL_AIRBRUSH:
|
|
|
|
|
case BTN_TOOL_MOUSE:
|
|
|
|
|
case BTN_TOOL_LENS:
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
abort();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
d->interface->tool_type = code;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
litest_tool_event(struct litest_device *d, int value)
|
|
|
|
|
{
|
|
|
|
|
unsigned int tool = d->interface->tool_type;
|
|
|
|
|
|
|
|
|
|
litest_event(d, EV_KEY, tool, value);
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-21 19:11:27 +02:00
|
|
|
void
|
2023-05-11 13:45:25 +10:00
|
|
|
litest_tablet_proximity_in(struct litest_device *d,
|
|
|
|
|
double x,
|
|
|
|
|
double y,
|
|
|
|
|
struct axis_replacement *axes)
|
2014-04-21 19:11:27 +02:00
|
|
|
{
|
|
|
|
|
struct input_event *ev;
|
|
|
|
|
|
2020-09-11 09:54:24 +10:00
|
|
|
/* If the test device overrides proximity_in and says it didn't
|
|
|
|
|
* handle the event, let's continue normally */
|
|
|
|
|
if (d->interface->tablet_proximity_in &&
|
2023-05-11 13:45:25 +10:00
|
|
|
d->interface->tablet_proximity_in(d, d->interface->tool_type, &x, &y, axes))
|
2020-09-11 09:54:24 +10:00
|
|
|
return;
|
|
|
|
|
|
2014-04-21 19:11:27 +02:00
|
|
|
ev = d->interface->tablet_proximity_in_events;
|
|
|
|
|
while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
|
2020-09-11 08:43:58 +10:00
|
|
|
int value;
|
|
|
|
|
|
|
|
|
|
switch (evbit(ev->type, ev->code)) {
|
|
|
|
|
case evbit(EV_KEY, LITEST_BTN_TOOL_AUTO):
|
|
|
|
|
litest_tool_event(d, ev->value);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
value = auto_assign_tablet_value(d, ev, x, y, axes);
|
|
|
|
|
if (!tablet_ignore_event(ev, value))
|
|
|
|
|
litest_event(d, ev->type, ev->code, value);
|
|
|
|
|
}
|
2014-04-21 19:11:27 +02:00
|
|
|
ev++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
litest_tablet_proximity_out(struct litest_device *d)
|
|
|
|
|
{
|
|
|
|
|
struct input_event *ev;
|
|
|
|
|
|
2020-09-11 09:54:24 +10:00
|
|
|
/* If the test device overrides proximity_out and says it didn't
|
|
|
|
|
* handle the event, let's continue normally */
|
|
|
|
|
if (d->interface->tablet_proximity_out &&
|
|
|
|
|
d->interface->tablet_proximity_out(d, d->interface->tool_type))
|
|
|
|
|
return;
|
|
|
|
|
|
2014-04-21 19:11:27 +02:00
|
|
|
ev = d->interface->tablet_proximity_out_events;
|
|
|
|
|
while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
|
2020-09-11 08:43:58 +10:00
|
|
|
int value;
|
|
|
|
|
|
|
|
|
|
switch (evbit(ev->type, ev->code)) {
|
|
|
|
|
case evbit(EV_KEY, LITEST_BTN_TOOL_AUTO):
|
|
|
|
|
litest_tool_event(d, ev->value);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
value = auto_assign_tablet_value(d, ev, -1, -1, NULL);
|
|
|
|
|
if (!tablet_ignore_event(ev, value))
|
|
|
|
|
litest_event(d, ev->type, ev->code, value);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2014-04-21 19:11:27 +02:00
|
|
|
ev++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2023-05-11 13:45:25 +10:00
|
|
|
litest_tablet_motion(struct litest_device *d,
|
|
|
|
|
double x,
|
|
|
|
|
double y,
|
|
|
|
|
struct axis_replacement *axes)
|
2014-04-21 19:11:27 +02:00
|
|
|
{
|
|
|
|
|
struct input_event *ev;
|
|
|
|
|
|
2023-05-11 13:51:25 +10:00
|
|
|
/* If the test device overrides proximity_out and says it didn't
|
|
|
|
|
* handle the event, let's continue normally */
|
|
|
|
|
if (d->interface->tablet_motion && d->interface->tablet_motion(d, &x, &y, axes))
|
|
|
|
|
return;
|
|
|
|
|
|
2014-04-21 19:11:27 +02:00
|
|
|
ev = d->interface->tablet_motion_events;
|
|
|
|
|
while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
|
|
|
|
|
int value = auto_assign_tablet_value(d, ev, x, y, axes);
|
|
|
|
|
if (!tablet_ignore_event(ev, value))
|
|
|
|
|
litest_event(d, ev->type, ev->code, value);
|
|
|
|
|
ev++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-17 14:46:07 +10:00
|
|
|
void
|
|
|
|
|
litest_tablet_tip_down(struct litest_device *d,
|
2023-05-11 13:45:25 +10:00
|
|
|
double x,
|
|
|
|
|
double y,
|
2021-11-17 14:46:07 +10:00
|
|
|
struct axis_replacement *axes)
|
|
|
|
|
{
|
|
|
|
|
/* If the test device overrides tip_down and says it didn't
|
|
|
|
|
* handle the event, let's continue normally */
|
|
|
|
|
if (d->interface->tablet_tip_down &&
|
2023-05-11 13:45:25 +10:00
|
|
|
d->interface->tablet_tip_down(d, &x, &y, axes))
|
2021-11-17 14:46:07 +10:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
litest_event(d, EV_KEY, BTN_TOUCH, 1);
|
|
|
|
|
litest_tablet_motion(d, x, y, axes);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
litest_tablet_tip_up(struct litest_device *d,
|
2023-05-11 13:45:25 +10:00
|
|
|
double x,
|
|
|
|
|
double y,
|
2021-11-17 14:46:07 +10:00
|
|
|
struct axis_replacement *axes)
|
|
|
|
|
{
|
|
|
|
|
/* If the test device overrides tip_down and says it didn't
|
|
|
|
|
* handle the event, let's continue normally */
|
2023-05-11 13:45:25 +10:00
|
|
|
if (d->interface->tablet_tip_up && d->interface->tablet_tip_up(d, &x, &y, axes))
|
2021-11-17 14:46:07 +10:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
litest_event(d, EV_KEY, BTN_TOUCH, 0);
|
|
|
|
|
litest_tablet_motion(d, x, y, axes);
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-12 20:05:25 +01:00
|
|
|
void
|
|
|
|
|
litest_touch_move_two_touches(struct litest_device *d,
|
|
|
|
|
double x0,
|
|
|
|
|
double y0,
|
|
|
|
|
double x1,
|
|
|
|
|
double y1,
|
|
|
|
|
double dx,
|
|
|
|
|
double dy,
|
test: drop the sleep_ms argument
This forces events for every ~10ms now. If we want a slower movement, we need
more steps - just like a real touchpad does it.
Cocinelle spatch files were variants of:
@@
expression A, B, C, D, E, F, G, H, I, J, K;
@@
- litest_touch_move_two_touches(A, B, C, D, E, F, G, H, I)
+ litest_touch_move_two_touches(A, B, C, D, E, F, G, H)
The only test that needed a real fix was touchpad_no_palm_detect_2fg_scroll,
it used 12ms before, now it's using 10ms so on the bcm5974 touchpad the second
finger was a speed-thumb. Increasing the events and thus slowing down the
pointer means it's a normal finger and the test succeeds again.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-08-28 09:16:52 +10:00
|
|
|
int steps)
|
2015-03-12 20:05:25 +01:00
|
|
|
{
|
test: drop the sleep_ms argument
This forces events for every ~10ms now. If we want a slower movement, we need
more steps - just like a real touchpad does it.
Cocinelle spatch files were variants of:
@@
expression A, B, C, D, E, F, G, H, I, J, K;
@@
- litest_touch_move_two_touches(A, B, C, D, E, F, G, H, I)
+ litest_touch_move_two_touches(A, B, C, D, E, F, G, H)
The only test that needed a real fix was touchpad_no_palm_detect_2fg_scroll,
it used 12ms before, now it's using 10ms so on the bcm5974 touchpad the second
finger was a speed-thumb. Increasing the events and thus slowing down the
pointer means it's a normal finger and the test succeeds again.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-08-28 09:16:52 +10:00
|
|
|
int sleep_ms = 10;
|
2018-08-27 13:22:24 +10:00
|
|
|
|
2016-11-21 11:03:58 +10:00
|
|
|
for (int i = 1; i < steps; i++) {
|
2025-04-15 13:29:39 +10:00
|
|
|
litest_with_event_frame(d) {
|
|
|
|
|
litest_touch_move(d,
|
|
|
|
|
0,
|
|
|
|
|
x0 + dx / steps * i,
|
|
|
|
|
y0 + dy / steps * i);
|
|
|
|
|
litest_touch_move(d,
|
|
|
|
|
1,
|
|
|
|
|
x1 + dx / steps * i,
|
|
|
|
|
y1 + dy / steps * i);
|
|
|
|
|
}
|
2018-08-27 13:22:24 +10:00
|
|
|
libinput_dispatch(d->libinput);
|
|
|
|
|
msleep(sleep_ms);
|
2015-12-07 11:39:52 +10:00
|
|
|
libinput_dispatch(d->libinput);
|
2015-03-12 20:05:25 +01:00
|
|
|
}
|
2025-04-15 13:29:39 +10:00
|
|
|
litest_with_event_frame(d) {
|
|
|
|
|
litest_touch_move(d, 0, x0 + dx, y0 + dy);
|
|
|
|
|
litest_touch_move(d, 1, x1 + dx, y1 + dy);
|
|
|
|
|
}
|
2015-03-12 20:05:25 +01:00
|
|
|
}
|
|
|
|
|
|
2015-07-07 11:52:05 +10:00
|
|
|
void
|
|
|
|
|
litest_touch_move_three_touches(struct litest_device *d,
|
|
|
|
|
double x0,
|
|
|
|
|
double y0,
|
|
|
|
|
double x1,
|
|
|
|
|
double y1,
|
|
|
|
|
double x2,
|
|
|
|
|
double y2,
|
|
|
|
|
double dx,
|
|
|
|
|
double dy,
|
test: drop the sleep_ms argument
This forces events for every ~10ms now. If we want a slower movement, we need
more steps - just like a real touchpad does it.
Cocinelle spatch files were variants of:
@@
expression A, B, C, D, E, F, G, H, I, J, K;
@@
- litest_touch_move_two_touches(A, B, C, D, E, F, G, H, I)
+ litest_touch_move_two_touches(A, B, C, D, E, F, G, H)
The only test that needed a real fix was touchpad_no_palm_detect_2fg_scroll,
it used 12ms before, now it's using 10ms so on the bcm5974 touchpad the second
finger was a speed-thumb. Increasing the events and thus slowing down the
pointer means it's a normal finger and the test succeeds again.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-08-28 09:16:52 +10:00
|
|
|
int steps)
|
2015-07-07 11:52:05 +10:00
|
|
|
{
|
test: drop the sleep_ms argument
This forces events for every ~10ms now. If we want a slower movement, we need
more steps - just like a real touchpad does it.
Cocinelle spatch files were variants of:
@@
expression A, B, C, D, E, F, G, H, I, J, K;
@@
- litest_touch_move_two_touches(A, B, C, D, E, F, G, H, I)
+ litest_touch_move_two_touches(A, B, C, D, E, F, G, H)
The only test that needed a real fix was touchpad_no_palm_detect_2fg_scroll,
it used 12ms before, now it's using 10ms so on the bcm5974 touchpad the second
finger was a speed-thumb. Increasing the events and thus slowing down the
pointer means it's a normal finger and the test succeeds again.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-08-28 09:16:52 +10:00
|
|
|
int sleep_ms = 10;
|
2018-08-27 13:22:24 +10:00
|
|
|
|
2021-03-15 16:56:23 +10:00
|
|
|
for (int i = 1; i <= steps; i++) {
|
|
|
|
|
double step_x = dx / steps * i;
|
|
|
|
|
double step_y = dy / steps * i;
|
|
|
|
|
|
2025-04-15 13:29:39 +10:00
|
|
|
litest_with_event_frame(d) {
|
|
|
|
|
litest_touch_move(d, 0, x0 + step_x, y0 + step_y);
|
|
|
|
|
litest_touch_move(d, 1, x1 + step_x, y1 + step_y);
|
|
|
|
|
litest_touch_move(d, 2, x2 + step_x, y2 + step_y);
|
|
|
|
|
}
|
2018-08-27 13:22:24 +10:00
|
|
|
|
|
|
|
|
libinput_dispatch(d->libinput);
|
|
|
|
|
msleep(sleep_ms);
|
2015-07-07 11:52:05 +10:00
|
|
|
}
|
2021-03-15 16:56:23 +10:00
|
|
|
libinput_dispatch(d->libinput);
|
2015-07-07 11:52:05 +10:00
|
|
|
}
|
|
|
|
|
|
2015-05-06 19:41:25 -04:00
|
|
|
void
|
2015-06-22 12:48:04 +02:00
|
|
|
litest_hover_start(struct litest_device *d, unsigned int slot, double x, double y)
|
2015-05-06 19:41:25 -04:00
|
|
|
{
|
2017-01-11 09:49:37 +10:00
|
|
|
struct axis_replacement axes[] = {
|
|
|
|
|
{ ABS_MT_PRESSURE, 0 },
|
|
|
|
|
{ ABS_PRESSURE, 0 },
|
|
|
|
|
{ -1, -1 },
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
litest_slot_start(d, slot, x, y, axes, 0);
|
2015-05-06 19:41:25 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
litest_hover_end(struct litest_device *d, unsigned int slot)
|
|
|
|
|
{
|
|
|
|
|
struct input_event *ev;
|
|
|
|
|
struct input_event up[] = {
|
|
|
|
|
{ .type = EV_ABS, .code = ABS_MT_SLOT, .value = LITEST_AUTO_ASSIGN },
|
|
|
|
|
{ .type = EV_ABS, .code = ABS_MT_DISTANCE, .value = 1 },
|
|
|
|
|
{ .type = EV_ABS, .code = ABS_MT_TRACKING_ID, .value = -1 },
|
|
|
|
|
{ .type = EV_SYN, .code = SYN_REPORT, .value = 0 },
|
|
|
|
|
{ .type = -1, .code = -1 }
|
|
|
|
|
};
|
|
|
|
|
|
2015-06-17 11:21:23 +10:00
|
|
|
litest_assert_int_gt(d->ntouches_down, 0);
|
2015-05-06 19:41:25 -04:00
|
|
|
d->ntouches_down--;
|
|
|
|
|
|
2015-12-02 09:48:01 +10:00
|
|
|
send_btntool(d, true);
|
2015-05-06 19:41:25 -04:00
|
|
|
|
|
|
|
|
if (d->interface->touch_up) {
|
|
|
|
|
d->interface->touch_up(d, slot);
|
|
|
|
|
return;
|
|
|
|
|
} else if (d->interface->touch_up_events) {
|
|
|
|
|
ev = d->interface->touch_up_events;
|
|
|
|
|
} else
|
|
|
|
|
ev = up;
|
|
|
|
|
|
|
|
|
|
while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
|
2015-06-22 12:48:04 +02:00
|
|
|
int value = litest_auto_assign_value(d, ev, slot, 0, 0, NULL, false);
|
2015-05-06 19:41:25 -04:00
|
|
|
litest_event(d, ev->type, ev->code, value);
|
|
|
|
|
ev++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
litest_hover_move(struct litest_device *d, unsigned int slot, double x, double y)
|
|
|
|
|
{
|
2017-01-11 09:49:37 +10:00
|
|
|
struct axis_replacement axes[] = {
|
|
|
|
|
{ ABS_MT_PRESSURE, 0 },
|
|
|
|
|
{ ABS_PRESSURE, 0 },
|
|
|
|
|
{ -1, -1 },
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
litest_slot_move(d, slot, x, y, axes, false);
|
2015-05-06 19:41:25 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
litest_hover_move_to(struct litest_device *d,
|
|
|
|
|
unsigned int slot,
|
|
|
|
|
double x_from,
|
|
|
|
|
double y_from,
|
|
|
|
|
double x_to,
|
|
|
|
|
double y_to,
|
test: drop the sleep_ms argument
This forces events for every ~10ms now. If we want a slower movement, we need
more steps - just like a real touchpad does it.
Cocinelle spatch files were variants of:
@@
expression A, B, C, D, E, F, G, H, I, J, K;
@@
- litest_touch_move_two_touches(A, B, C, D, E, F, G, H, I)
+ litest_touch_move_two_touches(A, B, C, D, E, F, G, H)
The only test that needed a real fix was touchpad_no_palm_detect_2fg_scroll,
it used 12ms before, now it's using 10ms so on the bcm5974 touchpad the second
finger was a speed-thumb. Increasing the events and thus slowing down the
pointer means it's a normal finger and the test succeeds again.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-08-28 09:16:52 +10:00
|
|
|
int steps)
|
2015-05-06 19:41:25 -04:00
|
|
|
{
|
test: drop the sleep_ms argument
This forces events for every ~10ms now. If we want a slower movement, we need
more steps - just like a real touchpad does it.
Cocinelle spatch files were variants of:
@@
expression A, B, C, D, E, F, G, H, I, J, K;
@@
- litest_touch_move_two_touches(A, B, C, D, E, F, G, H, I)
+ litest_touch_move_two_touches(A, B, C, D, E, F, G, H)
The only test that needed a real fix was touchpad_no_palm_detect_2fg_scroll,
it used 12ms before, now it's using 10ms so on the bcm5974 touchpad the second
finger was a speed-thumb. Increasing the events and thus slowing down the
pointer means it's a normal finger and the test succeeds again.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-08-28 09:16:52 +10:00
|
|
|
int sleep_ms = 10;
|
2018-08-27 13:22:24 +10:00
|
|
|
|
2015-05-06 19:41:25 -04:00
|
|
|
for (int i = 0; i < steps - 1; i++) {
|
|
|
|
|
litest_hover_move(d,
|
|
|
|
|
slot,
|
|
|
|
|
x_from + (x_to - x_from) / steps * i,
|
|
|
|
|
y_from + (y_to - y_from) / steps * i);
|
2018-08-27 13:22:24 +10:00
|
|
|
libinput_dispatch(d->libinput);
|
|
|
|
|
msleep(sleep_ms);
|
|
|
|
|
libinput_dispatch(d->libinput);
|
2015-05-06 19:41:25 -04:00
|
|
|
}
|
|
|
|
|
litest_hover_move(d, slot, x_to, y_to);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
litest_hover_move_two_touches(struct litest_device *d,
|
|
|
|
|
double x0,
|
|
|
|
|
double y0,
|
|
|
|
|
double x1,
|
|
|
|
|
double y1,
|
|
|
|
|
double dx,
|
|
|
|
|
double dy,
|
test: drop the sleep_ms argument
This forces events for every ~10ms now. If we want a slower movement, we need
more steps - just like a real touchpad does it.
Cocinelle spatch files were variants of:
@@
expression A, B, C, D, E, F, G, H, I, J, K;
@@
- litest_touch_move_two_touches(A, B, C, D, E, F, G, H, I)
+ litest_touch_move_two_touches(A, B, C, D, E, F, G, H)
The only test that needed a real fix was touchpad_no_palm_detect_2fg_scroll,
it used 12ms before, now it's using 10ms so on the bcm5974 touchpad the second
finger was a speed-thumb. Increasing the events and thus slowing down the
pointer means it's a normal finger and the test succeeds again.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-08-28 09:16:52 +10:00
|
|
|
int steps)
|
2015-05-06 19:41:25 -04:00
|
|
|
{
|
test: drop the sleep_ms argument
This forces events for every ~10ms now. If we want a slower movement, we need
more steps - just like a real touchpad does it.
Cocinelle spatch files were variants of:
@@
expression A, B, C, D, E, F, G, H, I, J, K;
@@
- litest_touch_move_two_touches(A, B, C, D, E, F, G, H, I)
+ litest_touch_move_two_touches(A, B, C, D, E, F, G, H)
The only test that needed a real fix was touchpad_no_palm_detect_2fg_scroll,
it used 12ms before, now it's using 10ms so on the bcm5974 touchpad the second
finger was a speed-thumb. Increasing the events and thus slowing down the
pointer means it's a normal finger and the test succeeds again.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-08-28 09:16:52 +10:00
|
|
|
int sleep_ms = 10;
|
2018-08-27 13:22:24 +10:00
|
|
|
|
2015-05-06 19:41:25 -04:00
|
|
|
for (int i = 0; i < steps - 1; i++) {
|
2025-04-15 13:29:39 +10:00
|
|
|
litest_with_event_frame(d) {
|
|
|
|
|
litest_hover_move(d,
|
|
|
|
|
0,
|
|
|
|
|
x0 + dx / steps * i,
|
|
|
|
|
y0 + dy / steps * i);
|
|
|
|
|
litest_hover_move(d,
|
|
|
|
|
1,
|
|
|
|
|
x1 + dx / steps * i,
|
|
|
|
|
y1 + dy / steps * i);
|
|
|
|
|
}
|
2018-08-27 13:22:24 +10:00
|
|
|
libinput_dispatch(d->libinput);
|
|
|
|
|
msleep(sleep_ms);
|
|
|
|
|
libinput_dispatch(d->libinput);
|
2015-05-06 19:41:25 -04:00
|
|
|
}
|
2025-04-15 13:29:39 +10:00
|
|
|
litest_with_event_frame(d) {
|
|
|
|
|
litest_hover_move(d, 0, x0 + dx, y0 + dy);
|
|
|
|
|
litest_hover_move(d, 1, x1 + dx, y1 + dy);
|
|
|
|
|
}
|
2015-05-06 19:41:25 -04:00
|
|
|
}
|
|
|
|
|
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
void
|
2017-11-20 10:49:08 +10:00
|
|
|
litest_button_click(struct litest_device *d, unsigned int button, bool is_press)
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
{
|
|
|
|
|
struct input_event click[] = {
|
|
|
|
|
{ .type = EV_KEY, .code = button, .value = is_press ? 1 : 0 },
|
|
|
|
|
{ .type = EV_SYN, .code = SYN_REPORT, .value = 0 },
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
ARRAY_FOR_EACH(click, ev)
|
|
|
|
|
litest_event(d, ev->type, ev->code, ev->value);
|
2017-11-20 10:49:08 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
litest_button_click_debounced(struct litest_device *d,
|
|
|
|
|
struct libinput *li,
|
|
|
|
|
unsigned int button,
|
|
|
|
|
bool is_press)
|
|
|
|
|
{
|
|
|
|
|
litest_button_click(d, button, is_press);
|
2025-04-01 09:23:10 +10:00
|
|
|
litest_timeout_debounce(li);
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
}
|
|
|
|
|
|
2014-11-06 16:32:53 +01:00
|
|
|
void
|
|
|
|
|
litest_button_scroll(struct litest_device *dev,
|
|
|
|
|
unsigned int button,
|
|
|
|
|
double dx,
|
|
|
|
|
double dy)
|
|
|
|
|
{
|
|
|
|
|
struct libinput *li = dev->libinput;
|
|
|
|
|
|
2017-11-14 08:44:47 +10:00
|
|
|
litest_button_click_debounced(dev, li, button, 1);
|
2014-11-06 16:32:53 +01:00
|
|
|
|
2025-04-01 09:23:10 +10:00
|
|
|
litest_timeout_buttonscroll(li);
|
2014-11-06 16:32:53 +01:00
|
|
|
|
|
|
|
|
litest_event(dev, EV_REL, REL_X, dx);
|
|
|
|
|
litest_event(dev, EV_REL, REL_Y, dy);
|
|
|
|
|
litest_event(dev, EV_SYN, SYN_REPORT, 0);
|
|
|
|
|
|
2017-11-14 08:44:47 +10:00
|
|
|
litest_button_click_debounced(dev, li, button, 0);
|
2014-11-06 16:32:53 +01:00
|
|
|
|
|
|
|
|
libinput_dispatch(li);
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-20 10:56:51 +10:00
|
|
|
void
|
|
|
|
|
litest_button_scroll_locked(struct litest_device *dev,
|
|
|
|
|
unsigned int button,
|
|
|
|
|
double dx,
|
|
|
|
|
double dy)
|
|
|
|
|
{
|
|
|
|
|
struct libinput *li = dev->libinput;
|
|
|
|
|
|
|
|
|
|
litest_button_click_debounced(dev, li, button, 1);
|
|
|
|
|
litest_button_click_debounced(dev, li, button, 0);
|
|
|
|
|
|
2025-04-01 09:23:10 +10:00
|
|
|
litest_timeout_buttonscroll(li);
|
2019-03-20 10:56:51 +10:00
|
|
|
|
|
|
|
|
litest_event(dev, EV_REL, REL_X, dx);
|
|
|
|
|
litest_event(dev, EV_REL, REL_Y, dy);
|
|
|
|
|
litest_event(dev, EV_SYN, SYN_REPORT, 0);
|
|
|
|
|
|
|
|
|
|
libinput_dispatch(li);
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-01 22:24:10 +02:00
|
|
|
void
|
|
|
|
|
litest_keyboard_key(struct litest_device *d, unsigned int key, bool is_press)
|
|
|
|
|
{
|
2017-11-14 08:44:47 +10:00
|
|
|
struct input_event click[] = {
|
|
|
|
|
{ .type = EV_KEY, .code = key, .value = is_press ? 1 : 0 },
|
|
|
|
|
{ .type = EV_SYN, .code = SYN_REPORT, .value = 0 },
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
ARRAY_FOR_EACH(click, ev)
|
|
|
|
|
litest_event(d, ev->type, ev->code, ev->value);
|
2014-04-01 22:24:10 +02:00
|
|
|
}
|
|
|
|
|
|
2017-01-20 16:54:16 +11:00
|
|
|
void
|
2017-04-21 16:33:02 +10:00
|
|
|
litest_switch_action(struct litest_device *dev,
|
|
|
|
|
enum libinput_switch sw,
|
|
|
|
|
enum libinput_switch_state state)
|
2017-01-20 16:54:16 +11:00
|
|
|
{
|
2017-04-21 16:33:02 +10:00
|
|
|
unsigned int code;
|
|
|
|
|
|
|
|
|
|
switch (sw) {
|
|
|
|
|
case LIBINPUT_SWITCH_LID:
|
|
|
|
|
code = SW_LID;
|
|
|
|
|
break;
|
2017-04-21 17:52:37 +10:00
|
|
|
case LIBINPUT_SWITCH_TABLET_MODE:
|
|
|
|
|
code = SW_TABLET_MODE;
|
|
|
|
|
break;
|
2017-04-21 16:33:02 +10:00
|
|
|
default:
|
|
|
|
|
litest_abort_msg("Invalid switch %d", sw);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
litest_event(dev, EV_SW, code, state);
|
2017-01-20 16:54:16 +11:00
|
|
|
litest_event(dev, EV_SYN, SYN_REPORT, 0);
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-10 16:05:37 +10:00
|
|
|
static int
|
|
|
|
|
litest_scale_axis(const struct litest_device *d, unsigned int axis, double val)
|
|
|
|
|
{
|
|
|
|
|
const struct input_absinfo *abs;
|
|
|
|
|
|
|
|
|
|
litest_assert_double_ge(val, 0.0);
|
2017-03-29 12:31:12 +10:00
|
|
|
/* major/minor must be able to beyond 100% for large fingers */
|
|
|
|
|
if (axis != ABS_MT_TOUCH_MAJOR && axis != ABS_MT_TOUCH_MINOR) {
|
|
|
|
|
litest_assert_double_le(val, 100.0);
|
|
|
|
|
}
|
2015-12-10 16:05:37 +10:00
|
|
|
|
|
|
|
|
abs = libevdev_get_abs_info(d->evdev, axis);
|
|
|
|
|
litest_assert_notnull(abs);
|
|
|
|
|
|
|
|
|
|
return (abs->maximum - abs->minimum) * val / 100.0 + abs->minimum;
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-05 10:57:37 +10:00
|
|
|
static inline int
|
|
|
|
|
litest_scale_range(int min, int max, double val)
|
|
|
|
|
{
|
|
|
|
|
litest_assert_int_ge((int)val, 0);
|
|
|
|
|
litest_assert_int_le((int)val, 100);
|
|
|
|
|
|
|
|
|
|
return (max - min) * val / 100.0 + min;
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-18 16:01:10 +10:00
|
|
|
int
|
|
|
|
|
litest_scale(const struct litest_device *d, unsigned int axis, double val)
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
{
|
|
|
|
|
int min, max;
|
2017-03-29 12:31:12 +10:00
|
|
|
|
2015-12-01 15:26:48 +10:00
|
|
|
litest_assert_double_ge(val, 0.0);
|
2017-03-29 12:31:12 +10:00
|
|
|
/* major/minor must be able to beyond 100% for large fingers */
|
|
|
|
|
if (axis != ABS_MT_TOUCH_MAJOR && axis != ABS_MT_TOUCH_MINOR)
|
|
|
|
|
litest_assert_double_le(val, 100.0);
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
|
2015-12-10 16:05:37 +10:00
|
|
|
if (axis <= ABS_Y) {
|
2015-12-10 16:05:37 +10:00
|
|
|
min = d->interface->min[axis];
|
|
|
|
|
max = d->interface->max[axis];
|
2016-02-05 10:57:37 +10:00
|
|
|
|
|
|
|
|
return litest_scale_range(min, max, val);
|
2015-12-10 16:05:37 +10:00
|
|
|
} else {
|
|
|
|
|
return litest_scale_axis(d, axis, val);
|
|
|
|
|
}
|
Add a device test suite
A rather large commit, copied from a similar (almost identical) suite in
libtouchpad and ported for libinput.
The goal here is to make testing for various devices easy, so the litest
("libinput test") wrappers do that. The idea is that each device has some
features, and tests are likely to exercise some features or won't work with
other features.
Each test case takes a list of required features and a list of excluded
features. The test suite will create a new test case for each device in the
suite that matches that set.
For example, the set of required LITEST_TOUCHPAD, excluded LITEST_BUTTON would
run on clickpads only, not on touchpads with buttons.
check supports suites and test cases, both named. We wrap that so that each
named set of cases we add are a test suite, with the set of devices being the
test cases. i.e.
litest_add("foo:bar", some_test_function, LITEST_ANY, LITEST_ANY);
adds a suite named "foo:bar" and test cases for both devices given, with their
shortnames as test case name, resulting in:
"foo:bar", "trackpoint"
"foo:bar", "clickpad"
...
Multiple test functions can be added to a suite. For tests without a device
requirement there is litest_add_no_device_test(...).
The environment variables CK_RUN_SUITE and CK_RUN_CASE can be used to narrow
the set of test cases. The test suite detects when run inside a debugger and
disables fork mode (the default).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-12-06 15:02:11 +10:00
|
|
|
}
|
2014-01-22 11:20:50 +10:00
|
|
|
|
2016-02-05 10:57:37 +10:00
|
|
|
static inline int
|
|
|
|
|
auto_assign_pad_value(struct litest_device *dev, struct input_event *ev, double value)
|
|
|
|
|
{
|
|
|
|
|
const struct input_absinfo *abs;
|
|
|
|
|
|
2024-01-30 14:43:59 +10:00
|
|
|
if (ev->value != LITEST_AUTO_ASSIGN)
|
2016-02-05 10:57:37 +10:00
|
|
|
return value;
|
|
|
|
|
|
2024-01-30 14:43:59 +10:00
|
|
|
if (ev->type == EV_REL) {
|
|
|
|
|
switch (ev->code) {
|
|
|
|
|
case REL_WHEEL:
|
|
|
|
|
case REL_HWHEEL:
|
|
|
|
|
case REL_DIAL:
|
|
|
|
|
assert(fmod(value, 120.0) ==
|
|
|
|
|
0.0); /* Fractions not supported yet */
|
|
|
|
|
return value / 120.0;
|
|
|
|
|
default:
|
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
} else if (ev->type != EV_ABS) {
|
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-05 10:57:37 +10:00
|
|
|
abs = libevdev_get_abs_info(dev->evdev, ev->code);
|
|
|
|
|
litest_assert_notnull(abs);
|
|
|
|
|
|
|
|
|
|
if (ev->code == ABS_RX || ev->code == ABS_RY) {
|
|
|
|
|
double min = abs->minimum != 0 ? log2(abs->minimum) : 0,
|
|
|
|
|
max = abs->maximum != 0 ? log2(abs->maximum) : 0;
|
|
|
|
|
|
|
|
|
|
/* Value 0 is reserved for finger up, so a value of 0% is
|
|
|
|
|
* actually 1 */
|
|
|
|
|
if (value == 0.0) {
|
|
|
|
|
return 1;
|
|
|
|
|
} else {
|
|
|
|
|
value = litest_scale_range(min, max, value);
|
|
|
|
|
return pow(2, value);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
return litest_scale_range(abs->minimum, abs->maximum, value);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-02 10:54:38 +10:00
|
|
|
static void
|
|
|
|
|
litest_pad_events(struct litest_device *d, struct input_event *evs, double value)
|
|
|
|
|
{
|
|
|
|
|
while (evs && (int16_t)evs->type != -1 && (int16_t)evs->code != -1) {
|
|
|
|
|
value = auto_assign_pad_value(d, evs, value);
|
|
|
|
|
litest_event(d, evs->type, evs->code, value);
|
|
|
|
|
evs++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-05 10:57:37 +10:00
|
|
|
void
|
|
|
|
|
litest_pad_ring_start(struct litest_device *d, double value)
|
|
|
|
|
{
|
2025-07-02 10:54:38 +10:00
|
|
|
litest_pad_events(d, d->interface->pad_ring_start_events, value);
|
2016-02-05 10:57:37 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
litest_pad_ring_change(struct litest_device *d, double value)
|
|
|
|
|
{
|
2025-07-02 10:54:38 +10:00
|
|
|
litest_pad_events(d, d->interface->pad_ring_change_events, value);
|
2016-02-05 10:57:37 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
litest_pad_ring_end(struct litest_device *d)
|
|
|
|
|
{
|
|
|
|
|
struct input_event *ev;
|
|
|
|
|
|
|
|
|
|
ev = d->interface->pad_ring_end_events;
|
|
|
|
|
while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
|
|
|
|
|
litest_event(d, ev->type, ev->code, ev->value);
|
|
|
|
|
ev++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
litest_pad_strip_start(struct litest_device *d, double value)
|
|
|
|
|
{
|
2025-07-02 10:54:38 +10:00
|
|
|
litest_pad_events(d, d->interface->pad_strip_start_events, value);
|
2016-02-05 10:57:37 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
litest_pad_strip_change(struct litest_device *d, double value)
|
|
|
|
|
{
|
2025-07-02 10:54:38 +10:00
|
|
|
litest_pad_events(d, d->interface->pad_strip_change_events, value);
|
2016-02-05 10:57:37 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
litest_pad_strip_end(struct litest_device *d)
|
|
|
|
|
{
|
|
|
|
|
struct input_event *ev;
|
|
|
|
|
|
|
|
|
|
ev = d->interface->pad_strip_end_events;
|
|
|
|
|
while (ev && (int16_t)ev->type != -1 && (int16_t)ev->code != -1) {
|
|
|
|
|
litest_event(d, ev->type, ev->code, ev->value);
|
|
|
|
|
ev++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-08-20 17:15:50 +10:00
|
|
|
void
|
|
|
|
|
litest_wait_for_event(struct libinput *li)
|
|
|
|
|
{
|
|
|
|
|
return litest_wait_for_event_of_type(li, -1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2025-03-14 10:12:24 +10:00
|
|
|
_litest_wait_for_event_of_type(struct libinput *li, const char *func, int lineno, ...)
|
2014-08-20 17:15:50 +10:00
|
|
|
{
|
|
|
|
|
va_list args;
|
|
|
|
|
enum libinput_event_type types[32] = { LIBINPUT_EVENT_NONE };
|
|
|
|
|
size_t ntypes = 0;
|
|
|
|
|
enum libinput_event_type type;
|
2015-07-02 14:22:05 +10:00
|
|
|
struct pollfd fds;
|
2014-08-20 17:15:50 +10:00
|
|
|
|
2025-03-14 10:12:24 +10:00
|
|
|
va_start(args, lineno);
|
2014-08-20 17:15:50 +10:00
|
|
|
type = va_arg(args, int);
|
|
|
|
|
while ((int)type != -1) {
|
2019-06-11 08:24:10 +10:00
|
|
|
litest_assert_int_gt(type, 0U);
|
|
|
|
|
litest_assert_int_lt(ntypes, ARRAY_LENGTH(types));
|
2014-08-20 17:15:50 +10:00
|
|
|
types[ntypes++] = type;
|
2014-09-01 12:39:38 +10:00
|
|
|
type = va_arg(args, int);
|
2014-08-20 17:15:50 +10:00
|
|
|
}
|
|
|
|
|
va_end(args);
|
|
|
|
|
|
2015-07-02 14:22:05 +10:00
|
|
|
fds.fd = libinput_get_fd(li);
|
|
|
|
|
fds.events = POLLIN;
|
|
|
|
|
fds.revents = 0;
|
|
|
|
|
|
2025-03-31 12:06:45 +10:00
|
|
|
const int timeout = 2000;
|
|
|
|
|
uint64_t expiry = 0;
|
|
|
|
|
int rc = now_in_us(&expiry);
|
|
|
|
|
expiry += ms2us(timeout);
|
|
|
|
|
litest_assert_errno_success(rc);
|
|
|
|
|
|
2014-08-20 17:15:50 +10:00
|
|
|
while (1) {
|
|
|
|
|
size_t i;
|
2025-03-31 12:06:45 +10:00
|
|
|
enum libinput_event_type type;
|
2014-08-20 17:15:50 +10:00
|
|
|
|
|
|
|
|
while ((type = libinput_next_event_type(li)) == LIBINPUT_EVENT_NONE) {
|
2025-03-31 12:06:45 +10:00
|
|
|
int rc = poll(&fds, 1, timeout);
|
2024-03-14 12:07:29 +10:00
|
|
|
litest_assert_errno_success(rc);
|
2017-06-01 15:43:14 +10:00
|
|
|
litest_assert_int_gt(rc, 0);
|
2025-04-16 19:03:51 +10:00
|
|
|
litest_dispatch(li);
|
2014-08-20 17:15:50 +10:00
|
|
|
}
|
|
|
|
|
|
2025-03-31 12:06:45 +10:00
|
|
|
if (type == LIBINPUT_EVENT_NONE) {
|
|
|
|
|
uint64_t now;
|
|
|
|
|
now_in_us(&now);
|
|
|
|
|
if (now > expiry) {
|
2025-03-31 14:10:26 +10:00
|
|
|
_litest_abort_msg(
|
|
|
|
|
NULL,
|
|
|
|
|
lineno,
|
|
|
|
|
func,
|
|
|
|
|
"Waited >%dms for events, but no events are pending",
|
|
|
|
|
timeout);
|
2025-03-31 12:06:45 +10:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-08-20 17:15:50 +10:00
|
|
|
/* no event mask means wait for any event */
|
|
|
|
|
if (ntypes == 0)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < ntypes; i++) {
|
|
|
|
|
if (type == types[i])
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-07 10:53:12 +10:00
|
|
|
_destroy_(libinput_event) *event = libinput_get_event(li);
|
2025-03-07 10:07:37 +10:00
|
|
|
if (verbose) {
|
2025-03-10 16:16:58 +10:00
|
|
|
litest_print_event(event, "Discarding event while waiting: ");
|
2025-03-07 10:07:37 +10:00
|
|
|
}
|
2014-08-20 17:15:50 +10:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-22 11:20:50 +10:00
|
|
|
void
|
|
|
|
|
litest_drain_events(struct libinput *li)
|
|
|
|
|
{
|
2025-04-07 10:53:12 +10:00
|
|
|
do {
|
|
|
|
|
libinput_dispatch(li);
|
|
|
|
|
|
|
|
|
|
_destroy_(libinput_event) *event = libinput_get_event(li);
|
|
|
|
|
if (!event)
|
|
|
|
|
break;
|
2014-01-22 11:20:50 +10:00
|
|
|
|
2024-01-16 17:02:51 +10:00
|
|
|
if (verbose) {
|
2025-03-10 16:16:58 +10:00
|
|
|
litest_print_event(event, "litest: draining event: ");
|
2024-01-16 17:02:51 +10:00
|
|
|
}
|
2025-04-07 10:53:12 +10:00
|
|
|
} while (true);
|
2014-01-22 11:20:50 +10:00
|
|
|
}
|
test: add litest helper functions for creating uinput devices
Both functions accept a series of event types/codes tuples, terminated by -1.
For the even type INPUT_PROP_MAX (an invalid type otherwise) the code is used
as a property to enable.
The _abs function als takes an array of absinfo, with absinfo.value
determining the axis to change. If none are given, abs axes are initialized
with default settings.
Both functions abort on failure, so the caller does not need to check the
return value.
Example code for creating a rel device:
struct libevdev_uinput *uinput;
struct input_id id = { ... };
uinput = litest_create_uinput_device("foo", &id,
EV_REL, REL_X,
EV_REL, REL_Y,
EV_KEY, BTN_LEFT,
INPUT_PROP_MAX, INPUT_PROP_BUTTONPAD,
-1);
libevdev_uinput_write_event(uinput, EV_REL, REL_X, -1);
libevdev_uinput_write_event(uinput, EV_SYN, SYN_REPORT, 0);
...
libevdev_uinput_destroy(uinput);
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2014-03-26 20:09:42 +10:00
|
|
|
|
2019-02-12 11:59:09 +10:00
|
|
|
void
|
2024-09-11 16:19:33 +10:00
|
|
|
_litest_drain_events_of_type(struct libinput *li, ...)
|
2019-02-12 11:59:09 +10:00
|
|
|
{
|
|
|
|
|
enum libinput_event_type type;
|
|
|
|
|
enum libinput_event_type types[32] = { LIBINPUT_EVENT_NONE };
|
|
|
|
|
size_t ntypes = 0;
|
|
|
|
|
va_list args;
|
|
|
|
|
|
|
|
|
|
va_start(args, li);
|
|
|
|
|
type = va_arg(args, int);
|
|
|
|
|
while ((int)type != -1) {
|
2019-06-11 08:24:10 +10:00
|
|
|
litest_assert_int_gt(type, 0U);
|
|
|
|
|
litest_assert_int_lt(ntypes, ARRAY_LENGTH(types));
|
2019-02-12 11:59:09 +10:00
|
|
|
types[ntypes++] = type;
|
|
|
|
|
type = va_arg(args, int);
|
|
|
|
|
}
|
|
|
|
|
va_end(args);
|
|
|
|
|
|
|
|
|
|
libinput_dispatch(li);
|
|
|
|
|
type = libinput_next_event_type(li);
|
2024-09-11 16:19:33 +10:00
|
|
|
while (type != LIBINPUT_EVENT_NONE) {
|
2019-02-12 11:59:09 +10:00
|
|
|
bool found = false;
|
|
|
|
|
|
|
|
|
|
type = libinput_next_event_type(li);
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < ntypes; i++) {
|
|
|
|
|
if (type == types[i]) {
|
|
|
|
|
found = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!found)
|
|
|
|
|
return;
|
|
|
|
|
|
2025-04-07 10:53:12 +10:00
|
|
|
_destroy_(libinput_event) *event = libinput_get_event(li);
|
2025-03-31 12:08:13 +10:00
|
|
|
if (verbose)
|
|
|
|
|
litest_print_event(event, "litest: draining typed event: ");
|
2019-02-12 11:59:09 +10:00
|
|
|
libinput_dispatch(li);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-13 15:13:38 +10:00
|
|
|
const char *
|
2016-08-23 08:11:11 +10:00
|
|
|
litest_event_type_str(enum libinput_event_type type)
|
2014-12-11 14:02:37 +10:00
|
|
|
{
|
|
|
|
|
const char *str = NULL;
|
|
|
|
|
|
2016-08-23 08:11:11 +10:00
|
|
|
switch (type) {
|
2014-12-11 14:02:37 +10:00
|
|
|
case LIBINPUT_EVENT_NONE:
|
|
|
|
|
abort();
|
|
|
|
|
case LIBINPUT_EVENT_DEVICE_ADDED:
|
|
|
|
|
str = "ADDED";
|
|
|
|
|
break;
|
|
|
|
|
case LIBINPUT_EVENT_DEVICE_REMOVED:
|
|
|
|
|
str = "REMOVED";
|
|
|
|
|
break;
|
|
|
|
|
case LIBINPUT_EVENT_KEYBOARD_KEY:
|
|
|
|
|
str = "KEY";
|
|
|
|
|
break;
|
|
|
|
|
case LIBINPUT_EVENT_POINTER_MOTION:
|
|
|
|
|
str = "MOTION";
|
|
|
|
|
break;
|
|
|
|
|
case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
|
|
|
|
|
str = "ABSOLUTE";
|
|
|
|
|
break;
|
|
|
|
|
case LIBINPUT_EVENT_POINTER_BUTTON:
|
|
|
|
|
str = "BUTTON";
|
|
|
|
|
break;
|
|
|
|
|
case LIBINPUT_EVENT_POINTER_AXIS:
|
|
|
|
|
str = "AXIS";
|
|
|
|
|
break;
|
2018-11-22 10:24:54 +10:00
|
|
|
case LIBINPUT_EVENT_POINTER_SCROLL_WHEEL:
|
|
|
|
|
str = "SCROLL_WHEEL";
|
|
|
|
|
break;
|
|
|
|
|
case LIBINPUT_EVENT_POINTER_SCROLL_FINGER:
|
|
|
|
|
str = "SCROLL_FINGER";
|
|
|
|
|
break;
|
|
|
|
|
case LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS:
|
|
|
|
|
str = "SCROLL_CONTINUOUS";
|
|
|
|
|
break;
|
2014-12-11 14:02:37 +10:00
|
|
|
case LIBINPUT_EVENT_TOUCH_DOWN:
|
|
|
|
|
str = "TOUCH DOWN";
|
|
|
|
|
break;
|
|
|
|
|
case LIBINPUT_EVENT_TOUCH_UP:
|
|
|
|
|
str = "TOUCH UP";
|
|
|
|
|
break;
|
|
|
|
|
case LIBINPUT_EVENT_TOUCH_MOTION:
|
|
|
|
|
str = "TOUCH MOTION";
|
|
|
|
|
break;
|
|
|
|
|
case LIBINPUT_EVENT_TOUCH_CANCEL:
|
|
|
|
|
str = "TOUCH CANCEL";
|
|
|
|
|
break;
|
|
|
|
|
case LIBINPUT_EVENT_TOUCH_FRAME:
|
|
|
|
|
str = "TOUCH FRAME";
|
|
|
|
|
break;
|
2015-01-22 16:41:50 +01:00
|
|
|
case LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN:
|
2021-03-15 16:42:11 +10:00
|
|
|
str = "GESTURE SWIPE BEGIN";
|
2015-01-22 16:41:50 +01:00
|
|
|
break;
|
|
|
|
|
case LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE:
|
|
|
|
|
str = "GESTURE SWIPE UPDATE";
|
|
|
|
|
break;
|
|
|
|
|
case LIBINPUT_EVENT_GESTURE_SWIPE_END:
|
|
|
|
|
str = "GESTURE SWIPE END";
|
|
|
|
|
break;
|
2015-03-04 15:24:04 +01:00
|
|
|
case LIBINPUT_EVENT_GESTURE_PINCH_BEGIN:
|
2021-03-15 16:42:11 +10:00
|
|
|
str = "GESTURE PINCH BEGIN";
|
2015-03-04 15:24:04 +01:00
|
|
|
break;
|
|
|
|
|
case LIBINPUT_EVENT_GESTURE_PINCH_UPDATE:
|
|
|
|
|
str = "GESTURE PINCH UPDATE";
|
|
|
|
|
break;
|
|
|
|
|
case LIBINPUT_EVENT_GESTURE_PINCH_END:
|
|
|
|
|
str = "GESTURE PINCH END";
|
|
|
|
|
break;
|
2021-05-27 19:19:38 +02:00
|
|
|
case LIBINPUT_EVENT_GESTURE_HOLD_BEGIN:
|
|
|
|
|
str = "GESTURE HOLD BEGIN";
|
|
|
|
|
break;
|
|
|
|
|
case LIBINPUT_EVENT_GESTURE_HOLD_END:
|
|
|
|
|
str = "GESTURE HOLD END";
|
|
|
|
|
break;
|
2015-11-16 16:27:46 +10:00
|
|
|
case LIBINPUT_EVENT_TABLET_TOOL_AXIS:
|
2016-02-03 17:11:42 +10:00
|
|
|
str = "TABLET TOOL AXIS";
|
2014-12-18 09:39:46 +10:00
|
|
|
break;
|
2015-11-16 16:27:46 +10:00
|
|
|
case LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY:
|
2016-02-03 17:11:42 +10:00
|
|
|
str = "TABLET TOOL PROX";
|
2014-12-18 09:39:46 +10:00
|
|
|
break;
|
2015-11-16 16:27:46 +10:00
|
|
|
case LIBINPUT_EVENT_TABLET_TOOL_TIP:
|
2016-02-03 17:11:42 +10:00
|
|
|
str = "TABLET TOOL TIP";
|
2015-11-11 13:39:43 +10:00
|
|
|
break;
|
2015-11-16 16:27:46 +10:00
|
|
|
case LIBINPUT_EVENT_TABLET_TOOL_BUTTON:
|
2016-02-03 17:11:42 +10:00
|
|
|
str = "TABLET TOOL BUTTON";
|
2014-12-18 09:39:46 +10:00
|
|
|
break;
|
2016-01-21 12:35:11 +10:00
|
|
|
case LIBINPUT_EVENT_TABLET_PAD_BUTTON:
|
|
|
|
|
str = "TABLET PAD BUTTON";
|
|
|
|
|
break;
|
|
|
|
|
case LIBINPUT_EVENT_TABLET_PAD_RING:
|
|
|
|
|
str = "TABLET PAD RING";
|
|
|
|
|
break;
|
|
|
|
|
case LIBINPUT_EVENT_TABLET_PAD_STRIP:
|
|
|
|
|
str = "TABLET PAD STRIP";
|
|
|
|
|
break;
|
2019-01-17 11:08:27 +10:00
|
|
|
case LIBINPUT_EVENT_TABLET_PAD_KEY:
|
|
|
|
|
str = "TABLET PAD KEY";
|
|
|
|
|
break;
|
2024-01-30 14:43:59 +10:00
|
|
|
case LIBINPUT_EVENT_TABLET_PAD_DIAL:
|
|
|
|
|
str = "TABLET PAD DIAL";
|
|
|
|
|
break;
|
2017-01-20 16:54:13 +11:00
|
|
|
case LIBINPUT_EVENT_SWITCH_TOGGLE:
|
|
|
|
|
str = "SWITCH TOGGLE";
|
|
|
|
|
break;
|
2014-12-11 14:02:37 +10:00
|
|
|
}
|
|
|
|
|
return str;
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-23 08:11:11 +10:00
|
|
|
static const char *
|
|
|
|
|
litest_event_get_type_str(struct libinput_event *event)
|
|
|
|
|
{
|
|
|
|
|
return litest_event_type_str(libinput_event_get_type(event));
|
|
|
|
|
}
|
|
|
|
|
|
2014-06-06 10:58:11 +10:00
|
|
|
static void
|
2025-03-10 16:16:58 +10:00
|
|
|
litest_print_event(struct libinput_event *event, const char *message)
|
2014-06-06 10:58:11 +10:00
|
|
|
{
|
2025-04-07 10:53:12 +10:00
|
|
|
_autofree_ char *event_str = libinput_event_to_str(event, 0, NULL);
|
2025-03-10 16:16:58 +10:00
|
|
|
fprintf(stderr, "litest: %s %s\n", message, event_str);
|
2014-06-06 10:58:11 +10:00
|
|
|
}
|
|
|
|
|
|
2025-03-14 10:12:24 +10:00
|
|
|
void
|
|
|
|
|
_litest_assert_event_type_is_one_of(struct libinput_event *event,
|
|
|
|
|
const char *func,
|
|
|
|
|
int lineno,
|
|
|
|
|
...)
|
2016-08-23 08:11:11 +10:00
|
|
|
{
|
2021-07-24 13:54:24 +02:00
|
|
|
va_list args;
|
|
|
|
|
enum libinput_event_type expected_type;
|
|
|
|
|
enum libinput_event_type actual_type = libinput_event_get_type(event);
|
|
|
|
|
bool match = false;
|
|
|
|
|
|
2025-03-14 10:12:24 +10:00
|
|
|
va_start(args, lineno);
|
2021-07-24 13:54:24 +02:00
|
|
|
expected_type = va_arg(args, int);
|
|
|
|
|
while ((int)expected_type != -1 && !match) {
|
|
|
|
|
match = (actual_type == expected_type);
|
|
|
|
|
expected_type = va_arg(args, int);
|
|
|
|
|
}
|
|
|
|
|
va_end(args);
|
|
|
|
|
|
|
|
|
|
if (match)
|
2016-08-23 08:11:11 +10:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
fprintf(stderr,
|
2021-07-24 13:54:24 +02:00
|
|
|
"FAILED EVENT TYPE: %s: have %s (%d) but want ",
|
2018-04-17 18:02:14 +10:00
|
|
|
libinput_device_get_name(libinput_event_get_device(event)),
|
2016-08-23 08:11:11 +10:00
|
|
|
litest_event_get_type_str(event),
|
2021-07-24 13:54:24 +02:00
|
|
|
libinput_event_get_type(event));
|
|
|
|
|
|
2025-03-14 10:12:24 +10:00
|
|
|
va_start(args, lineno);
|
2021-07-24 13:54:24 +02:00
|
|
|
expected_type = va_arg(args, int);
|
|
|
|
|
while ((int)expected_type != -1) {
|
|
|
|
|
fprintf(stderr,
|
|
|
|
|
"%s (%d)",
|
|
|
|
|
litest_event_type_str(expected_type),
|
|
|
|
|
expected_type);
|
|
|
|
|
expected_type = va_arg(args, int);
|
|
|
|
|
|
|
|
|
|
if ((int)expected_type != -1)
|
|
|
|
|
fprintf(stderr, " || ");
|
|
|
|
|
}
|
2024-10-14 18:56:05 +10:00
|
|
|
va_end(args);
|
2025-03-10 16:16:58 +10:00
|
|
|
fprintf(stderr, "\n");
|
2021-07-24 13:54:24 +02:00
|
|
|
|
2025-03-10 16:16:58 +10:00
|
|
|
litest_print_event(event, "Wrong event is:");
|
2025-03-14 10:12:24 +10:00
|
|
|
litest_backtrace(func);
|
2024-10-17 08:29:22 +10:00
|
|
|
litest_runner_abort();
|
2016-08-23 08:11:11 +10:00
|
|
|
}
|
|
|
|
|
|
2021-07-24 13:54:24 +02:00
|
|
|
void
|
2025-03-14 10:12:24 +10:00
|
|
|
_litest_assert_event_type(struct libinput_event *event,
|
|
|
|
|
enum libinput_event_type want,
|
|
|
|
|
const char *func,
|
|
|
|
|
int lineno)
|
2021-07-24 13:54:24 +02:00
|
|
|
{
|
2025-03-14 10:12:24 +10:00
|
|
|
_litest_assert_event_type_is_one_of(event, func, lineno, want, -1);
|
2021-07-24 13:54:24 +02:00
|
|
|
}
|
|
|
|
|
|
2024-10-14 18:58:24 +10:00
|
|
|
void
|
2025-03-14 10:12:24 +10:00
|
|
|
_litest_assert_event_type_not_one_of(struct libinput_event *event,
|
|
|
|
|
const char *func,
|
|
|
|
|
int lineno,
|
|
|
|
|
...)
|
2024-10-14 18:58:24 +10:00
|
|
|
{
|
|
|
|
|
va_list args;
|
|
|
|
|
enum libinput_event_type not_expected_type;
|
|
|
|
|
enum libinput_event_type actual_type = libinput_event_get_type(event);
|
|
|
|
|
bool match = false;
|
|
|
|
|
|
2025-03-14 10:12:24 +10:00
|
|
|
va_start(args, lineno);
|
2024-10-14 18:58:24 +10:00
|
|
|
not_expected_type = va_arg(args, int);
|
|
|
|
|
while ((int)not_expected_type != -1 && !match) {
|
|
|
|
|
match = (actual_type == not_expected_type);
|
|
|
|
|
not_expected_type = va_arg(args, int);
|
|
|
|
|
}
|
|
|
|
|
va_end(args);
|
|
|
|
|
|
|
|
|
|
if (!match)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
fprintf(stderr,
|
|
|
|
|
"FAILED EVENT TYPE: %s: have %s (%d) but didn't want that\n",
|
|
|
|
|
libinput_device_get_name(libinput_event_get_device(event)),
|
|
|
|
|
litest_event_get_type_str(event),
|
|
|
|
|
libinput_event_get_type(event));
|
|
|
|
|
|
2025-03-10 16:16:58 +10:00
|
|
|
litest_print_event(event, "\nWrong event is: ");
|
2025-03-14 10:12:24 +10:00
|
|
|
litest_backtrace(func);
|
2024-10-17 08:29:22 +10:00
|
|
|
litest_runner_abort();
|
2024-10-14 18:58:24 +10:00
|
|
|
}
|
|
|
|
|
|
2014-06-06 10:58:11 +10:00
|
|
|
void
|
2024-09-12 13:40:44 +10:00
|
|
|
_litest_assert_empty_queue(struct libinput *li, const char *func, int line)
|
2014-06-06 10:58:11 +10:00
|
|
|
{
|
|
|
|
|
bool empty_queue = true;
|
|
|
|
|
struct libinput_event *event;
|
|
|
|
|
|
2025-03-12 10:38:12 +10:00
|
|
|
_litest_checkpoint(func, line, ANSI_BRIGHT_CYAN, "asserting empty queue");
|
2024-09-12 13:40:44 +10:00
|
|
|
|
2014-06-06 10:58:11 +10:00
|
|
|
libinput_dispatch(li);
|
|
|
|
|
while ((event = libinput_get_event(li))) {
|
|
|
|
|
empty_queue = false;
|
2025-03-10 16:16:58 +10:00
|
|
|
litest_print_event(event, "Unexpected event: ");
|
2014-06-06 10:58:11 +10:00
|
|
|
libinput_event_destroy(event);
|
|
|
|
|
libinput_dispatch(li);
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-04 09:13:22 +10:00
|
|
|
litest_assert(empty_queue);
|
2014-06-06 10:58:11 +10:00
|
|
|
}
|
|
|
|
|
|
2015-07-02 13:39:40 +10:00
|
|
|
static struct libevdev_uinput *
|
|
|
|
|
litest_create_uinput(const char *name,
|
|
|
|
|
const struct input_id *id,
|
|
|
|
|
const struct input_absinfo *abs_info,
|
|
|
|
|
const int *events)
|
test: add litest helper functions for creating uinput devices
Both functions accept a series of event types/codes tuples, terminated by -1.
For the even type INPUT_PROP_MAX (an invalid type otherwise) the code is used
as a property to enable.
The _abs function als takes an array of absinfo, with absinfo.value
determining the axis to change. If none are given, abs axes are initialized
with default settings.
Both functions abort on failure, so the caller does not need to check the
return value.
Example code for creating a rel device:
struct libevdev_uinput *uinput;
struct input_id id = { ... };
uinput = litest_create_uinput_device("foo", &id,
EV_REL, REL_X,
EV_REL, REL_Y,
EV_KEY, BTN_LEFT,
INPUT_PROP_MAX, INPUT_PROP_BUTTONPAD,
-1);
libevdev_uinput_write_event(uinput, EV_REL, REL_X, -1);
libevdev_uinput_write_event(uinput, EV_SYN, SYN_REPORT, 0);
...
libevdev_uinput_destroy(uinput);
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2014-03-26 20:09:42 +10:00
|
|
|
{
|
|
|
|
|
struct libevdev_uinput *uinput;
|
2025-04-07 10:53:12 +10:00
|
|
|
_free_(libevdev) *dev = libevdev_new();
|
test: add litest helper functions for creating uinput devices
Both functions accept a series of event types/codes tuples, terminated by -1.
For the even type INPUT_PROP_MAX (an invalid type otherwise) the code is used
as a property to enable.
The _abs function als takes an array of absinfo, with absinfo.value
determining the axis to change. If none are given, abs axes are initialized
with default settings.
Both functions abort on failure, so the caller does not need to check the
return value.
Example code for creating a rel device:
struct libevdev_uinput *uinput;
struct input_id id = { ... };
uinput = litest_create_uinput_device("foo", &id,
EV_REL, REL_X,
EV_REL, REL_Y,
EV_KEY, BTN_LEFT,
INPUT_PROP_MAX, INPUT_PROP_BUTTONPAD,
-1);
libevdev_uinput_write_event(uinput, EV_REL, REL_X, -1);
libevdev_uinput_write_event(uinput, EV_SYN, SYN_REPORT, 0);
...
libevdev_uinput_destroy(uinput);
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2014-03-26 20:09:42 +10:00
|
|
|
int type, code;
|
2024-03-18 09:51:49 +10:00
|
|
|
int rc;
|
2014-07-15 15:35:20 +10:00
|
|
|
const struct input_absinfo *abs;
|
test: add litest helper functions for creating uinput devices
Both functions accept a series of event types/codes tuples, terminated by -1.
For the even type INPUT_PROP_MAX (an invalid type otherwise) the code is used
as a property to enable.
The _abs function als takes an array of absinfo, with absinfo.value
determining the axis to change. If none are given, abs axes are initialized
with default settings.
Both functions abort on failure, so the caller does not need to check the
return value.
Example code for creating a rel device:
struct libevdev_uinput *uinput;
struct input_id id = { ... };
uinput = litest_create_uinput_device("foo", &id,
EV_REL, REL_X,
EV_REL, REL_Y,
EV_KEY, BTN_LEFT,
INPUT_PROP_MAX, INPUT_PROP_BUTTONPAD,
-1);
libevdev_uinput_write_event(uinput, EV_REL, REL_X, -1);
libevdev_uinput_write_event(uinput, EV_SYN, SYN_REPORT, 0);
...
libevdev_uinput_destroy(uinput);
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2014-03-26 20:09:42 +10:00
|
|
|
const struct input_absinfo default_abs = { .value = 0,
|
|
|
|
|
.minimum = 0,
|
2016-04-07 15:44:23 +10:00
|
|
|
.maximum = 100,
|
test: add litest helper functions for creating uinput devices
Both functions accept a series of event types/codes tuples, terminated by -1.
For the even type INPUT_PROP_MAX (an invalid type otherwise) the code is used
as a property to enable.
The _abs function als takes an array of absinfo, with absinfo.value
determining the axis to change. If none are given, abs axes are initialized
with default settings.
Both functions abort on failure, so the caller does not need to check the
return value.
Example code for creating a rel device:
struct libevdev_uinput *uinput;
struct input_id id = { ... };
uinput = litest_create_uinput_device("foo", &id,
EV_REL, REL_X,
EV_REL, REL_Y,
EV_KEY, BTN_LEFT,
INPUT_PROP_MAX, INPUT_PROP_BUTTONPAD,
-1);
libevdev_uinput_write_event(uinput, EV_REL, REL_X, -1);
libevdev_uinput_write_event(uinput, EV_SYN, SYN_REPORT, 0);
...
libevdev_uinput_destroy(uinput);
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2014-03-26 20:09:42 +10:00
|
|
|
.fuzz = 0,
|
|
|
|
|
.flat = 0,
|
|
|
|
|
.resolution = 100 };
|
2024-10-14 19:29:15 +10:00
|
|
|
/* See kernel commit 206f533a0a7c ("Input: uinput - reject requests with
|
|
|
|
|
* unreasonable number of slots") */
|
|
|
|
|
const struct input_absinfo default_abs_mt_slot = { .value = 0,
|
|
|
|
|
.minimum = 0,
|
|
|
|
|
.maximum = 64,
|
|
|
|
|
.fuzz = 0,
|
|
|
|
|
.flat = 0,
|
|
|
|
|
.resolution = 100 };
|
2014-06-24 16:23:12 +02:00
|
|
|
char buf[512];
|
test: add litest helper functions for creating uinput devices
Both functions accept a series of event types/codes tuples, terminated by -1.
For the even type INPUT_PROP_MAX (an invalid type otherwise) the code is used
as a property to enable.
The _abs function als takes an array of absinfo, with absinfo.value
determining the axis to change. If none are given, abs axes are initialized
with default settings.
Both functions abort on failure, so the caller does not need to check the
return value.
Example code for creating a rel device:
struct libevdev_uinput *uinput;
struct input_id id = { ... };
uinput = litest_create_uinput_device("foo", &id,
EV_REL, REL_X,
EV_REL, REL_Y,
EV_KEY, BTN_LEFT,
INPUT_PROP_MAX, INPUT_PROP_BUTTONPAD,
-1);
libevdev_uinput_write_event(uinput, EV_REL, REL_X, -1);
libevdev_uinput_write_event(uinput, EV_SYN, SYN_REPORT, 0);
...
libevdev_uinput_destroy(uinput);
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2014-03-26 20:09:42 +10:00
|
|
|
|
2019-06-11 08:24:10 +10:00
|
|
|
litest_assert_ptr_notnull(dev);
|
test: add litest helper functions for creating uinput devices
Both functions accept a series of event types/codes tuples, terminated by -1.
For the even type INPUT_PROP_MAX (an invalid type otherwise) the code is used
as a property to enable.
The _abs function als takes an array of absinfo, with absinfo.value
determining the axis to change. If none are given, abs axes are initialized
with default settings.
Both functions abort on failure, so the caller does not need to check the
return value.
Example code for creating a rel device:
struct libevdev_uinput *uinput;
struct input_id id = { ... };
uinput = litest_create_uinput_device("foo", &id,
EV_REL, REL_X,
EV_REL, REL_Y,
EV_KEY, BTN_LEFT,
INPUT_PROP_MAX, INPUT_PROP_BUTTONPAD,
-1);
libevdev_uinput_write_event(uinput, EV_REL, REL_X, -1);
libevdev_uinput_write_event(uinput, EV_SYN, SYN_REPORT, 0);
...
libevdev_uinput_destroy(uinput);
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2014-03-26 20:09:42 +10:00
|
|
|
|
2014-06-24 16:23:12 +02:00
|
|
|
snprintf(buf, sizeof(buf), "litest %s", name);
|
|
|
|
|
libevdev_set_name(dev, buf);
|
test: add litest helper functions for creating uinput devices
Both functions accept a series of event types/codes tuples, terminated by -1.
For the even type INPUT_PROP_MAX (an invalid type otherwise) the code is used
as a property to enable.
The _abs function als takes an array of absinfo, with absinfo.value
determining the axis to change. If none are given, abs axes are initialized
with default settings.
Both functions abort on failure, so the caller does not need to check the
return value.
Example code for creating a rel device:
struct libevdev_uinput *uinput;
struct input_id id = { ... };
uinput = litest_create_uinput_device("foo", &id,
EV_REL, REL_X,
EV_REL, REL_Y,
EV_KEY, BTN_LEFT,
INPUT_PROP_MAX, INPUT_PROP_BUTTONPAD,
-1);
libevdev_uinput_write_event(uinput, EV_REL, REL_X, -1);
libevdev_uinput_write_event(uinput, EV_SYN, SYN_REPORT, 0);
...
libevdev_uinput_destroy(uinput);
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2014-03-26 20:09:42 +10:00
|
|
|
if (id) {
|
|
|
|
|
libevdev_set_id_bustype(dev, id->bustype);
|
|
|
|
|
libevdev_set_id_vendor(dev, id->vendor);
|
|
|
|
|
libevdev_set_id_product(dev, id->product);
|
2015-01-28 15:59:03 +10:00
|
|
|
libevdev_set_id_version(dev, id->version);
|
test: add litest helper functions for creating uinput devices
Both functions accept a series of event types/codes tuples, terminated by -1.
For the even type INPUT_PROP_MAX (an invalid type otherwise) the code is used
as a property to enable.
The _abs function als takes an array of absinfo, with absinfo.value
determining the axis to change. If none are given, abs axes are initialized
with default settings.
Both functions abort on failure, so the caller does not need to check the
return value.
Example code for creating a rel device:
struct libevdev_uinput *uinput;
struct input_id id = { ... };
uinput = litest_create_uinput_device("foo", &id,
EV_REL, REL_X,
EV_REL, REL_Y,
EV_KEY, BTN_LEFT,
INPUT_PROP_MAX, INPUT_PROP_BUTTONPAD,
-1);
libevdev_uinput_write_event(uinput, EV_REL, REL_X, -1);
libevdev_uinput_write_event(uinput, EV_SYN, SYN_REPORT, 0);
...
libevdev_uinput_destroy(uinput);
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2014-03-26 20:09:42 +10:00
|
|
|
}
|
|
|
|
|
|
2014-07-15 15:35:20 +10:00
|
|
|
abs = abs_info;
|
test: add litest helper functions for creating uinput devices
Both functions accept a series of event types/codes tuples, terminated by -1.
For the even type INPUT_PROP_MAX (an invalid type otherwise) the code is used
as a property to enable.
The _abs function als takes an array of absinfo, with absinfo.value
determining the axis to change. If none are given, abs axes are initialized
with default settings.
Both functions abort on failure, so the caller does not need to check the
return value.
Example code for creating a rel device:
struct libevdev_uinput *uinput;
struct input_id id = { ... };
uinput = litest_create_uinput_device("foo", &id,
EV_REL, REL_X,
EV_REL, REL_Y,
EV_KEY, BTN_LEFT,
INPUT_PROP_MAX, INPUT_PROP_BUTTONPAD,
-1);
libevdev_uinput_write_event(uinput, EV_REL, REL_X, -1);
libevdev_uinput_write_event(uinput, EV_SYN, SYN_REPORT, 0);
...
libevdev_uinput_destroy(uinput);
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2014-03-26 20:09:42 +10:00
|
|
|
while (abs && abs->value != -1) {
|
2016-06-16 09:42:56 +10:00
|
|
|
struct input_absinfo a = *abs;
|
|
|
|
|
|
|
|
|
|
/* abs_info->value is used for the code and may be outside
|
|
|
|
|
of [min, max] */
|
|
|
|
|
a.value = abs->minimum;
|
|
|
|
|
rc = libevdev_enable_event_code(dev, EV_ABS, abs->value, &a);
|
2015-05-04 09:13:22 +10:00
|
|
|
litest_assert_int_eq(rc, 0);
|
test: add litest helper functions for creating uinput devices
Both functions accept a series of event types/codes tuples, terminated by -1.
For the even type INPUT_PROP_MAX (an invalid type otherwise) the code is used
as a property to enable.
The _abs function als takes an array of absinfo, with absinfo.value
determining the axis to change. If none are given, abs axes are initialized
with default settings.
Both functions abort on failure, so the caller does not need to check the
return value.
Example code for creating a rel device:
struct libevdev_uinput *uinput;
struct input_id id = { ... };
uinput = litest_create_uinput_device("foo", &id,
EV_REL, REL_X,
EV_REL, REL_Y,
EV_KEY, BTN_LEFT,
INPUT_PROP_MAX, INPUT_PROP_BUTTONPAD,
-1);
libevdev_uinput_write_event(uinput, EV_REL, REL_X, -1);
libevdev_uinput_write_event(uinput, EV_SYN, SYN_REPORT, 0);
...
libevdev_uinput_destroy(uinput);
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2014-03-26 20:09:42 +10:00
|
|
|
abs++;
|
|
|
|
|
}
|
|
|
|
|
|
2014-03-31 10:00:16 +10:00
|
|
|
while (events && (type = *events++) != -1 && (code = *events++) != -1) {
|
test: add litest helper functions for creating uinput devices
Both functions accept a series of event types/codes tuples, terminated by -1.
For the even type INPUT_PROP_MAX (an invalid type otherwise) the code is used
as a property to enable.
The _abs function als takes an array of absinfo, with absinfo.value
determining the axis to change. If none are given, abs axes are initialized
with default settings.
Both functions abort on failure, so the caller does not need to check the
return value.
Example code for creating a rel device:
struct libevdev_uinput *uinput;
struct input_id id = { ... };
uinput = litest_create_uinput_device("foo", &id,
EV_REL, REL_X,
EV_REL, REL_Y,
EV_KEY, BTN_LEFT,
INPUT_PROP_MAX, INPUT_PROP_BUTTONPAD,
-1);
libevdev_uinput_write_event(uinput, EV_REL, REL_X, -1);
libevdev_uinput_write_event(uinput, EV_SYN, SYN_REPORT, 0);
...
libevdev_uinput_destroy(uinput);
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2014-03-26 20:09:42 +10:00
|
|
|
if (type == INPUT_PROP_MAX) {
|
|
|
|
|
rc = libevdev_enable_property(dev, code);
|
|
|
|
|
} else {
|
2024-10-14 19:29:15 +10:00
|
|
|
const struct input_absinfo *abs = (code == ABS_MT_SLOT)
|
|
|
|
|
? &default_abs_mt_slot
|
|
|
|
|
: &default_abs;
|
test: add litest helper functions for creating uinput devices
Both functions accept a series of event types/codes tuples, terminated by -1.
For the even type INPUT_PROP_MAX (an invalid type otherwise) the code is used
as a property to enable.
The _abs function als takes an array of absinfo, with absinfo.value
determining the axis to change. If none are given, abs axes are initialized
with default settings.
Both functions abort on failure, so the caller does not need to check the
return value.
Example code for creating a rel device:
struct libevdev_uinput *uinput;
struct input_id id = { ... };
uinput = litest_create_uinput_device("foo", &id,
EV_REL, REL_X,
EV_REL, REL_Y,
EV_KEY, BTN_LEFT,
INPUT_PROP_MAX, INPUT_PROP_BUTTONPAD,
-1);
libevdev_uinput_write_event(uinput, EV_REL, REL_X, -1);
libevdev_uinput_write_event(uinput, EV_SYN, SYN_REPORT, 0);
...
libevdev_uinput_destroy(uinput);
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2014-03-26 20:09:42 +10:00
|
|
|
rc = libevdev_enable_event_code(dev,
|
|
|
|
|
type,
|
|
|
|
|
code,
|
2024-10-14 19:29:15 +10:00
|
|
|
type == EV_ABS ? abs : NULL);
|
test: add litest helper functions for creating uinput devices
Both functions accept a series of event types/codes tuples, terminated by -1.
For the even type INPUT_PROP_MAX (an invalid type otherwise) the code is used
as a property to enable.
The _abs function als takes an array of absinfo, with absinfo.value
determining the axis to change. If none are given, abs axes are initialized
with default settings.
Both functions abort on failure, so the caller does not need to check the
return value.
Example code for creating a rel device:
struct libevdev_uinput *uinput;
struct input_id id = { ... };
uinput = litest_create_uinput_device("foo", &id,
EV_REL, REL_X,
EV_REL, REL_Y,
EV_KEY, BTN_LEFT,
INPUT_PROP_MAX, INPUT_PROP_BUTTONPAD,
-1);
libevdev_uinput_write_event(uinput, EV_REL, REL_X, -1);
libevdev_uinput_write_event(uinput, EV_SYN, SYN_REPORT, 0);
...
libevdev_uinput_destroy(uinput);
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2014-03-26 20:09:42 +10:00
|
|
|
}
|
2015-05-04 09:13:22 +10:00
|
|
|
litest_assert_int_eq(rc, 0);
|
test: add litest helper functions for creating uinput devices
Both functions accept a series of event types/codes tuples, terminated by -1.
For the even type INPUT_PROP_MAX (an invalid type otherwise) the code is used
as a property to enable.
The _abs function als takes an array of absinfo, with absinfo.value
determining the axis to change. If none are given, abs axes are initialized
with default settings.
Both functions abort on failure, so the caller does not need to check the
return value.
Example code for creating a rel device:
struct libevdev_uinput *uinput;
struct input_id id = { ... };
uinput = litest_create_uinput_device("foo", &id,
EV_REL, REL_X,
EV_REL, REL_Y,
EV_KEY, BTN_LEFT,
INPUT_PROP_MAX, INPUT_PROP_BUTTONPAD,
-1);
libevdev_uinput_write_event(uinput, EV_REL, REL_X, -1);
libevdev_uinput_write_event(uinput, EV_SYN, SYN_REPORT, 0);
...
libevdev_uinput_destroy(uinput);
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2014-03-26 20:09:42 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rc = libevdev_uinput_create_from_device(dev,
|
|
|
|
|
LIBEVDEV_UINPUT_OPEN_MANAGED,
|
|
|
|
|
&uinput);
|
2017-03-14 12:24:36 +10:00
|
|
|
litest_assert_msg(rc == 0,
|
|
|
|
|
"Failed to create uinput device: %s\n",
|
|
|
|
|
strerror(-rc));
|
test: add litest helper functions for creating uinput devices
Both functions accept a series of event types/codes tuples, terminated by -1.
For the even type INPUT_PROP_MAX (an invalid type otherwise) the code is used
as a property to enable.
The _abs function als takes an array of absinfo, with absinfo.value
determining the axis to change. If none are given, abs axes are initialized
with default settings.
Both functions abort on failure, so the caller does not need to check the
return value.
Example code for creating a rel device:
struct libevdev_uinput *uinput;
struct input_id id = { ... };
uinput = litest_create_uinput_device("foo", &id,
EV_REL, REL_X,
EV_REL, REL_Y,
EV_KEY, BTN_LEFT,
INPUT_PROP_MAX, INPUT_PROP_BUTTONPAD,
-1);
libevdev_uinput_write_event(uinput, EV_REL, REL_X, -1);
libevdev_uinput_write_event(uinput, EV_SYN, SYN_REPORT, 0);
...
libevdev_uinput_destroy(uinput);
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2014-03-26 20:09:42 +10:00
|
|
|
|
|
|
|
|
return uinput;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-02 13:39:40 +10:00
|
|
|
struct libevdev_uinput *
|
|
|
|
|
litest_create_uinput_device_from_description(const char *name,
|
|
|
|
|
const struct input_id *id,
|
|
|
|
|
const struct input_absinfo *abs_info,
|
|
|
|
|
const int *events)
|
|
|
|
|
{
|
|
|
|
|
struct libevdev_uinput *uinput;
|
|
|
|
|
const char *syspath;
|
2017-05-31 12:01:16 +10:00
|
|
|
char path[PATH_MAX];
|
2015-07-02 13:39:40 +10:00
|
|
|
|
2025-04-07 10:53:12 +10:00
|
|
|
_unref_(udev_monitor) *udev_monitor = udev_setup_monitor();
|
|
|
|
|
_unref_(udev_device) *udev_device = NULL;
|
2015-07-02 13:39:40 +10:00
|
|
|
|
|
|
|
|
uinput = litest_create_uinput(name, id, abs_info, events);
|
|
|
|
|
|
|
|
|
|
syspath = libevdev_uinput_get_syspath(uinput);
|
2017-05-31 12:01:16 +10:00
|
|
|
snprintf(path, sizeof(path), "%s/event", syspath);
|
2015-07-02 13:39:40 +10:00
|
|
|
|
2018-04-18 11:05:46 +10:00
|
|
|
udev_device = udev_wait_for_device_event(udev_monitor, "add", path);
|
2015-07-02 13:39:40 +10:00
|
|
|
|
|
|
|
|
litest_assert(udev_device_get_property_value(udev_device, "ID_INPUT"));
|
|
|
|
|
|
|
|
|
|
return uinput;
|
|
|
|
|
}
|
|
|
|
|
|
2014-03-31 10:00:16 +10:00
|
|
|
static struct libevdev_uinput *
|
|
|
|
|
litest_create_uinput_abs_device_v(const char *name,
|
|
|
|
|
struct input_id *id,
|
|
|
|
|
const struct input_absinfo *abs,
|
|
|
|
|
va_list args)
|
|
|
|
|
{
|
|
|
|
|
int events[KEY_MAX * 2 + 2]; /* increase this if not sufficient */
|
|
|
|
|
int *event = events;
|
|
|
|
|
int type, code;
|
|
|
|
|
|
|
|
|
|
while ((type = va_arg(args, int)) != -1 && (code = va_arg(args, int)) != -1) {
|
|
|
|
|
*event++ = type;
|
|
|
|
|
*event++ = code;
|
2015-05-04 09:13:22 +10:00
|
|
|
litest_assert(event < &events[ARRAY_LENGTH(events) - 2]);
|
2014-03-31 10:00:16 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*event++ = -1;
|
|
|
|
|
*event++ = -1;
|
|
|
|
|
|
|
|
|
|
return litest_create_uinput_device_from_description(name, id, abs, events);
|
|
|
|
|
}
|
|
|
|
|
|
test: add litest helper functions for creating uinput devices
Both functions accept a series of event types/codes tuples, terminated by -1.
For the even type INPUT_PROP_MAX (an invalid type otherwise) the code is used
as a property to enable.
The _abs function als takes an array of absinfo, with absinfo.value
determining the axis to change. If none are given, abs axes are initialized
with default settings.
Both functions abort on failure, so the caller does not need to check the
return value.
Example code for creating a rel device:
struct libevdev_uinput *uinput;
struct input_id id = { ... };
uinput = litest_create_uinput_device("foo", &id,
EV_REL, REL_X,
EV_REL, REL_Y,
EV_KEY, BTN_LEFT,
INPUT_PROP_MAX, INPUT_PROP_BUTTONPAD,
-1);
libevdev_uinput_write_event(uinput, EV_REL, REL_X, -1);
libevdev_uinput_write_event(uinput, EV_SYN, SYN_REPORT, 0);
...
libevdev_uinput_destroy(uinput);
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2014-03-26 20:09:42 +10:00
|
|
|
struct libevdev_uinput *
|
|
|
|
|
litest_create_uinput_abs_device(const char *name,
|
|
|
|
|
struct input_id *id,
|
|
|
|
|
const struct input_absinfo *abs,
|
|
|
|
|
...)
|
|
|
|
|
{
|
|
|
|
|
struct libevdev_uinput *uinput;
|
|
|
|
|
va_list args;
|
|
|
|
|
|
|
|
|
|
va_start(args, abs);
|
|
|
|
|
uinput = litest_create_uinput_abs_device_v(name, id, abs, args);
|
|
|
|
|
va_end(args);
|
|
|
|
|
|
|
|
|
|
return uinput;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct libevdev_uinput *
|
|
|
|
|
litest_create_uinput_device(const char *name, struct input_id *id, ...)
|
|
|
|
|
{
|
|
|
|
|
struct libevdev_uinput *uinput;
|
|
|
|
|
va_list args;
|
|
|
|
|
|
|
|
|
|
va_start(args, id);
|
|
|
|
|
uinput = litest_create_uinput_abs_device_v(name, id, NULL, args);
|
|
|
|
|
va_end(args);
|
|
|
|
|
|
|
|
|
|
return uinput;
|
|
|
|
|
}
|
2014-09-03 10:53:00 +10:00
|
|
|
|
2015-04-16 10:42:16 +10:00
|
|
|
struct libinput_event_pointer *
|
|
|
|
|
litest_is_button_event(struct libinput_event *event,
|
2015-05-04 09:30:51 +10:00
|
|
|
unsigned int button,
|
2015-04-16 10:42:16 +10:00
|
|
|
enum libinput_button_state state)
|
2014-09-03 10:53:00 +10:00
|
|
|
{
|
|
|
|
|
struct libinput_event_pointer *ptrev;
|
2015-05-04 11:29:49 +10:00
|
|
|
enum libinput_event_type type = LIBINPUT_EVENT_POINTER_BUTTON;
|
2014-09-03 10:53:00 +10:00
|
|
|
|
2019-06-11 08:24:10 +10:00
|
|
|
litest_assert_ptr_notnull(event);
|
2016-08-23 08:11:11 +10:00
|
|
|
litest_assert_event_type(event, type);
|
2014-09-03 10:53:00 +10:00
|
|
|
ptrev = libinput_event_get_pointer_event(event);
|
2015-05-04 09:13:22 +10:00
|
|
|
litest_assert_int_eq(libinput_event_pointer_get_button(ptrev), button);
|
|
|
|
|
litest_assert_int_eq(libinput_event_pointer_get_button_state(ptrev), state);
|
2015-04-16 10:42:16 +10:00
|
|
|
|
|
|
|
|
return ptrev;
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-04 13:11:21 +10:00
|
|
|
struct libinput_event_pointer *
|
|
|
|
|
litest_is_axis_event(struct libinput_event *event,
|
2018-11-22 10:24:54 +10:00
|
|
|
enum libinput_event_type axis_type,
|
2015-05-04 13:11:21 +10:00
|
|
|
enum libinput_pointer_axis axis,
|
|
|
|
|
enum libinput_pointer_axis_source source)
|
|
|
|
|
{
|
|
|
|
|
struct libinput_event_pointer *ptrev;
|
2018-11-22 10:24:54 +10:00
|
|
|
|
|
|
|
|
litest_assert(axis_type == LIBINPUT_EVENT_POINTER_SCROLL_WHEEL ||
|
|
|
|
|
axis_type == LIBINPUT_EVENT_POINTER_SCROLL_FINGER ||
|
|
|
|
|
axis_type == LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS);
|
2015-05-04 13:11:21 +10:00
|
|
|
|
2019-06-11 08:24:10 +10:00
|
|
|
litest_assert_ptr_notnull(event);
|
2018-11-22 10:24:54 +10:00
|
|
|
litest_assert_event_type_is_one_of(event,
|
|
|
|
|
LIBINPUT_EVENT_POINTER_AXIS,
|
|
|
|
|
axis_type);
|
2015-05-04 13:11:21 +10:00
|
|
|
ptrev = libinput_event_get_pointer_event(event);
|
2015-05-04 09:13:22 +10:00
|
|
|
litest_assert(libinput_event_pointer_has_axis(ptrev, axis));
|
2015-05-04 13:11:21 +10:00
|
|
|
|
|
|
|
|
if (source != 0)
|
2018-11-22 10:24:54 +10:00
|
|
|
litest_assert_int_eq(litest_event_pointer_get_axis_source(ptrev),
|
2015-05-04 09:13:22 +10:00
|
|
|
source);
|
2015-05-04 13:11:21 +10:00
|
|
|
|
|
|
|
|
return ptrev;
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-22 10:24:54 +10:00
|
|
|
bool
|
|
|
|
|
litest_is_high_res_axis_event(struct libinput_event *event)
|
|
|
|
|
{
|
|
|
|
|
litest_assert_event_type_is_one_of(event,
|
|
|
|
|
LIBINPUT_EVENT_POINTER_AXIS,
|
|
|
|
|
LIBINPUT_EVENT_POINTER_SCROLL_WHEEL,
|
|
|
|
|
LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
|
|
|
|
|
LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS);
|
|
|
|
|
|
|
|
|
|
return (libinput_event_get_type(event) != LIBINPUT_EVENT_POINTER_AXIS);
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-04 13:17:27 +10:00
|
|
|
struct libinput_event_pointer *
|
|
|
|
|
litest_is_motion_event(struct libinput_event *event)
|
|
|
|
|
{
|
|
|
|
|
struct libinput_event_pointer *ptrev;
|
|
|
|
|
enum libinput_event_type type = LIBINPUT_EVENT_POINTER_MOTION;
|
|
|
|
|
double x, y, ux, uy;
|
|
|
|
|
|
2019-06-11 08:24:10 +10:00
|
|
|
litest_assert_ptr_notnull(event);
|
2016-08-23 08:11:11 +10:00
|
|
|
litest_assert_event_type(event, type);
|
2015-05-04 13:17:27 +10:00
|
|
|
ptrev = libinput_event_get_pointer_event(event);
|
|
|
|
|
|
|
|
|
|
x = libinput_event_pointer_get_dx(ptrev);
|
|
|
|
|
y = libinput_event_pointer_get_dy(ptrev);
|
|
|
|
|
ux = libinput_event_pointer_get_dx_unaccelerated(ptrev);
|
|
|
|
|
uy = libinput_event_pointer_get_dy_unaccelerated(ptrev);
|
|
|
|
|
|
|
|
|
|
/* No 0 delta motion events */
|
2015-05-04 09:13:22 +10:00
|
|
|
litest_assert(x != 0.0 || y != 0.0 || ux != 0.0 || uy != 0.0);
|
2015-05-04 13:17:27 +10:00
|
|
|
|
|
|
|
|
return ptrev;
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-19 15:51:09 +10:00
|
|
|
void
|
2025-03-14 10:12:24 +10:00
|
|
|
_litest_assert_key_event(struct libinput *li,
|
|
|
|
|
unsigned int key,
|
|
|
|
|
enum libinput_key_state state,
|
|
|
|
|
const char *func,
|
|
|
|
|
int lineno)
|
2017-09-19 15:51:09 +10:00
|
|
|
{
|
|
|
|
|
litest_wait_for_event(li);
|
2025-04-07 10:53:12 +10:00
|
|
|
_destroy_(libinput_event) *event = libinput_get_event(li);
|
2017-09-19 15:51:09 +10:00
|
|
|
litest_is_keyboard_event(event, key, state);
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-03 10:53:00 +10:00
|
|
|
void
|
2024-09-12 13:40:44 +10:00
|
|
|
_litest_assert_button_event(struct libinput *li,
|
|
|
|
|
unsigned int button,
|
|
|
|
|
enum libinput_button_state state,
|
|
|
|
|
const char *func,
|
|
|
|
|
int line)
|
2014-09-03 10:53:00 +10:00
|
|
|
{
|
2024-09-12 13:40:44 +10:00
|
|
|
_litest_checkpoint(func,
|
|
|
|
|
line,
|
2025-03-12 10:38:12 +10:00
|
|
|
ANSI_CYAN,
|
2024-09-12 13:40:44 +10:00
|
|
|
"asserting button event %s (%d) state %d",
|
|
|
|
|
libevdev_event_code_get_name(EV_KEY, button),
|
|
|
|
|
button,
|
|
|
|
|
state);
|
|
|
|
|
|
2014-09-03 10:57:25 +10:00
|
|
|
litest_wait_for_event(li);
|
2025-04-07 10:53:12 +10:00
|
|
|
_destroy_(libinput_event) *event = libinput_get_event(li);
|
2015-04-16 10:42:16 +10:00
|
|
|
litest_is_button_event(event, button, state);
|
2014-09-03 10:53:00 +10:00
|
|
|
}
|
2014-09-17 15:35:31 +02:00
|
|
|
|
2015-05-04 13:51:39 +10:00
|
|
|
struct libinput_event_touch *
|
|
|
|
|
litest_is_touch_event(struct libinput_event *event, enum libinput_event_type type)
|
|
|
|
|
{
|
|
|
|
|
struct libinput_event_touch *touch;
|
|
|
|
|
|
2019-06-11 08:24:10 +10:00
|
|
|
litest_assert_ptr_notnull(event);
|
2015-05-04 13:51:39 +10:00
|
|
|
|
|
|
|
|
if (type == 0)
|
|
|
|
|
type = libinput_event_get_type(event);
|
|
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
|
case LIBINPUT_EVENT_TOUCH_DOWN:
|
|
|
|
|
case LIBINPUT_EVENT_TOUCH_UP:
|
|
|
|
|
case LIBINPUT_EVENT_TOUCH_MOTION:
|
|
|
|
|
case LIBINPUT_EVENT_TOUCH_FRAME:
|
2018-07-13 16:04:35 +10:00
|
|
|
case LIBINPUT_EVENT_TOUCH_CANCEL:
|
2016-08-23 08:11:11 +10:00
|
|
|
litest_assert_event_type(event, type);
|
2015-05-04 13:51:39 +10:00
|
|
|
break;
|
|
|
|
|
default:
|
2024-10-14 21:42:26 +10:00
|
|
|
litest_abort_msg("%s: invalid touch type %d", __func__, type);
|
2015-05-04 13:51:39 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
touch = libinput_event_get_touch_event(event);
|
|
|
|
|
|
|
|
|
|
return touch;
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-05 15:43:08 +10:00
|
|
|
struct libinput_event_keyboard *
|
|
|
|
|
litest_is_keyboard_event(struct libinput_event *event,
|
|
|
|
|
unsigned int key,
|
|
|
|
|
enum libinput_key_state state)
|
|
|
|
|
{
|
|
|
|
|
struct libinput_event_keyboard *kevent;
|
|
|
|
|
enum libinput_event_type type = LIBINPUT_EVENT_KEYBOARD_KEY;
|
|
|
|
|
|
2019-06-11 08:24:10 +10:00
|
|
|
litest_assert_ptr_notnull(event);
|
2016-08-23 08:11:11 +10:00
|
|
|
litest_assert_event_type(event, type);
|
2015-05-05 15:43:08 +10:00
|
|
|
|
|
|
|
|
kevent = libinput_event_get_keyboard_event(event);
|
2019-06-11 08:24:10 +10:00
|
|
|
litest_assert_ptr_notnull(kevent);
|
2015-05-05 15:43:08 +10:00
|
|
|
|
2015-05-04 09:13:22 +10:00
|
|
|
litest_assert_int_eq(libinput_event_keyboard_get_key(kevent), key);
|
|
|
|
|
litest_assert_int_eq(libinput_event_keyboard_get_key_state(kevent), state);
|
2015-05-05 15:43:08 +10:00
|
|
|
return kevent;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-07 11:52:05 +10:00
|
|
|
struct libinput_event_gesture *
|
|
|
|
|
litest_is_gesture_event(struct libinput_event *event,
|
|
|
|
|
enum libinput_event_type type,
|
|
|
|
|
int nfingers)
|
|
|
|
|
{
|
|
|
|
|
struct libinput_event_gesture *gevent;
|
|
|
|
|
|
2019-06-11 08:24:10 +10:00
|
|
|
litest_assert_ptr_notnull(event);
|
2016-08-23 08:11:11 +10:00
|
|
|
litest_assert_event_type(event, type);
|
2015-07-07 11:52:05 +10:00
|
|
|
|
|
|
|
|
gevent = libinput_event_get_gesture_event(event);
|
2019-06-11 08:24:10 +10:00
|
|
|
litest_assert_ptr_notnull(gevent);
|
2015-07-07 11:52:05 +10:00
|
|
|
|
|
|
|
|
if (nfingers != -1)
|
|
|
|
|
litest_assert_int_eq(libinput_event_gesture_get_finger_count(gevent),
|
|
|
|
|
nfingers);
|
|
|
|
|
return gevent;
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-15 17:48:34 +10:00
|
|
|
void
|
2024-09-12 13:40:44 +10:00
|
|
|
_litest_assert_gesture_event(struct libinput *li,
|
|
|
|
|
enum libinput_event_type type,
|
|
|
|
|
int nfingers,
|
|
|
|
|
const char *func,
|
|
|
|
|
int line)
|
2021-02-15 17:48:34 +10:00
|
|
|
{
|
|
|
|
|
|
2024-09-12 13:40:44 +10:00
|
|
|
_litest_checkpoint(func,
|
|
|
|
|
line,
|
2025-03-12 10:38:12 +10:00
|
|
|
ANSI_CYAN,
|
2024-09-12 13:40:44 +10:00
|
|
|
"asserting gesture event %s %dfg",
|
|
|
|
|
litest_event_type_str(type),
|
|
|
|
|
nfingers);
|
|
|
|
|
|
2021-02-15 17:48:34 +10:00
|
|
|
litest_wait_for_event(li);
|
|
|
|
|
|
2025-04-07 10:53:12 +10:00
|
|
|
_destroy_(libinput_event) *event = libinput_get_event(li);
|
2021-02-15 17:48:34 +10:00
|
|
|
litest_is_gesture_event(event, type, nfingers);
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-10 13:06:08 +10:00
|
|
|
struct libinput_event_tablet_tool *
|
|
|
|
|
litest_is_tablet_event(struct libinput_event *event, enum libinput_event_type type)
|
2015-11-11 14:03:05 +10:00
|
|
|
{
|
2015-11-16 16:28:55 +10:00
|
|
|
struct libinput_event_tablet_tool *tevent;
|
2015-11-11 14:03:05 +10:00
|
|
|
|
2019-06-11 08:24:10 +10:00
|
|
|
litest_assert_ptr_notnull(event);
|
2016-08-23 08:11:11 +10:00
|
|
|
litest_assert_event_type(event, type);
|
2015-11-11 14:03:05 +10:00
|
|
|
|
2015-11-16 16:28:55 +10:00
|
|
|
tevent = libinput_event_get_tablet_tool_event(event);
|
2019-06-11 08:24:10 +10:00
|
|
|
litest_assert_ptr_notnull(tevent);
|
2015-11-11 14:03:05 +10:00
|
|
|
|
|
|
|
|
return tevent;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-19 17:39:11 +10:00
|
|
|
void
|
2025-03-14 10:12:24 +10:00
|
|
|
_litest_assert_tablet_button_event(struct libinput *li,
|
|
|
|
|
unsigned int button,
|
|
|
|
|
enum libinput_button_state state,
|
|
|
|
|
const char *func,
|
|
|
|
|
int lineno)
|
2015-02-19 17:39:11 +10:00
|
|
|
{
|
2015-11-16 16:28:55 +10:00
|
|
|
struct libinput_event_tablet_tool *tev;
|
2015-11-16 16:27:46 +10:00
|
|
|
enum libinput_event_type type = LIBINPUT_EVENT_TABLET_TOOL_BUTTON;
|
2015-02-19 17:39:11 +10:00
|
|
|
|
2025-04-09 18:22:26 +10:00
|
|
|
_litest_checkpoint(func,
|
|
|
|
|
lineno,
|
|
|
|
|
ANSI_CYAN,
|
|
|
|
|
"asserting tablet button event button %d down: %s",
|
|
|
|
|
button,
|
|
|
|
|
yesno(state));
|
|
|
|
|
|
2015-02-19 17:39:11 +10:00
|
|
|
litest_wait_for_event(li);
|
|
|
|
|
|
2025-04-07 10:53:12 +10:00
|
|
|
_destroy_(libinput_event) *event = libinput_get_event(li);
|
2015-06-29 15:09:23 +10:00
|
|
|
litest_assert_notnull(event);
|
2016-08-23 08:11:11 +10:00
|
|
|
litest_assert_event_type(event, type);
|
2015-11-16 16:28:55 +10:00
|
|
|
tev = libinput_event_get_tablet_tool_event(event);
|
|
|
|
|
litest_assert_int_eq(libinput_event_tablet_tool_get_button(tev), button);
|
|
|
|
|
litest_assert_int_eq(libinput_event_tablet_tool_get_button_state(tev), state);
|
2015-02-19 17:39:11 +10:00
|
|
|
}
|
|
|
|
|
|
2020-01-31 12:23:53 +10:00
|
|
|
struct libinput_event_tablet_tool *
|
|
|
|
|
litest_is_proximity_event(struct libinput_event *event,
|
|
|
|
|
enum libinput_tablet_tool_proximity_state state)
|
2015-12-02 17:16:18 +10:00
|
|
|
{
|
|
|
|
|
struct libinput_event_tablet_tool *tev;
|
|
|
|
|
enum libinput_event_type type = LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY;
|
|
|
|
|
|
|
|
|
|
litest_assert_notnull(event);
|
2016-08-23 08:11:11 +10:00
|
|
|
litest_assert_event_type(event, type);
|
2015-12-02 17:16:18 +10:00
|
|
|
tev = libinput_event_get_tablet_tool_event(event);
|
|
|
|
|
litest_assert_int_eq(libinput_event_tablet_tool_get_proximity_state(tev),
|
|
|
|
|
state);
|
2020-01-31 12:23:53 +10:00
|
|
|
return tev;
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-22 10:24:54 +10:00
|
|
|
double
|
|
|
|
|
litest_event_pointer_get_value(struct libinput_event_pointer *ptrev,
|
|
|
|
|
enum libinput_pointer_axis axis)
|
|
|
|
|
{
|
|
|
|
|
struct libinput_event *event;
|
|
|
|
|
enum libinput_event_type type;
|
|
|
|
|
|
|
|
|
|
event = libinput_event_pointer_get_base_event(ptrev);
|
|
|
|
|
type = libinput_event_get_type(event);
|
|
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
|
case LIBINPUT_EVENT_POINTER_AXIS:
|
|
|
|
|
return libinput_event_pointer_get_axis_value(ptrev, axis);
|
|
|
|
|
case LIBINPUT_EVENT_POINTER_SCROLL_WHEEL:
|
|
|
|
|
return libinput_event_pointer_get_scroll_value_v120(ptrev, axis);
|
|
|
|
|
case LIBINPUT_EVENT_POINTER_SCROLL_FINGER:
|
|
|
|
|
case LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS:
|
|
|
|
|
return libinput_event_pointer_get_scroll_value(ptrev, axis);
|
|
|
|
|
default:
|
|
|
|
|
abort();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum libinput_pointer_axis_source
|
|
|
|
|
litest_event_pointer_get_axis_source(struct libinput_event_pointer *ptrev)
|
|
|
|
|
{
|
|
|
|
|
struct libinput_event *event;
|
|
|
|
|
enum libinput_event_type type;
|
|
|
|
|
|
|
|
|
|
event = libinput_event_pointer_get_base_event(ptrev);
|
|
|
|
|
type = libinput_event_get_type(event);
|
|
|
|
|
|
|
|
|
|
if (type == LIBINPUT_EVENT_POINTER_AXIS)
|
|
|
|
|
return libinput_event_pointer_get_axis_source(ptrev);
|
|
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
|
case LIBINPUT_EVENT_POINTER_SCROLL_WHEEL:
|
|
|
|
|
return LIBINPUT_POINTER_AXIS_SOURCE_WHEEL;
|
|
|
|
|
case LIBINPUT_EVENT_POINTER_SCROLL_FINGER:
|
|
|
|
|
return LIBINPUT_POINTER_AXIS_SOURCE_FINGER;
|
|
|
|
|
case LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS:
|
|
|
|
|
return LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS;
|
|
|
|
|
default:
|
|
|
|
|
abort();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-08 15:48:31 +10:00
|
|
|
void
|
|
|
|
|
_litest_assert_tablet_axis_event(struct libinput *li, const char *func, int lineno)
|
|
|
|
|
{
|
|
|
|
|
_litest_checkpoint(func, lineno, ANSI_CYAN, "asserting axis event");
|
|
|
|
|
|
|
|
|
|
litest_wait_for_event(li);
|
|
|
|
|
_destroy_(libinput_event) *event = libinput_get_event(li);
|
|
|
|
|
litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_AXIS);
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-14 10:12:24 +10:00
|
|
|
void
|
|
|
|
|
_litest_assert_tablet_proximity_event(struct libinput *li,
|
|
|
|
|
enum libinput_tablet_tool_proximity_state state,
|
|
|
|
|
const char *func,
|
|
|
|
|
int lineno)
|
2020-01-31 12:23:53 +10:00
|
|
|
{
|
2025-04-08 15:48:31 +10:00
|
|
|
_litest_checkpoint(func,
|
|
|
|
|
lineno,
|
|
|
|
|
ANSI_CYAN,
|
|
|
|
|
"asserting proximity %s event",
|
|
|
|
|
state ? "in" : "out");
|
|
|
|
|
|
2020-01-31 12:23:53 +10:00
|
|
|
litest_wait_for_event(li);
|
2025-04-07 10:53:12 +10:00
|
|
|
_destroy_(libinput_event) *event = libinput_get_event(li);
|
2020-01-31 12:23:53 +10:00
|
|
|
litest_is_proximity_event(event, state);
|
2015-12-02 17:16:18 +10:00
|
|
|
}
|
|
|
|
|
|
2025-03-14 10:12:24 +10:00
|
|
|
void
|
|
|
|
|
_litest_assert_tablet_tip_event(struct libinput *li,
|
|
|
|
|
enum libinput_tablet_tool_tip_state state,
|
|
|
|
|
const char *func,
|
|
|
|
|
int lineno)
|
2018-09-14 14:03:09 +10:00
|
|
|
{
|
|
|
|
|
struct libinput_event_tablet_tool *tev;
|
|
|
|
|
enum libinput_event_type type = LIBINPUT_EVENT_TABLET_TOOL_TIP;
|
|
|
|
|
|
2025-04-09 18:22:26 +10:00
|
|
|
_litest_checkpoint(func,
|
|
|
|
|
lineno,
|
|
|
|
|
ANSI_CYAN,
|
|
|
|
|
"asserting tip %s event",
|
|
|
|
|
state ? "down" : "up");
|
|
|
|
|
|
2018-09-14 14:03:09 +10:00
|
|
|
litest_wait_for_event(li);
|
|
|
|
|
|
2025-04-07 10:53:12 +10:00
|
|
|
_destroy_(libinput_event) *event = libinput_get_event(li);
|
2018-09-14 14:03:09 +10:00
|
|
|
litest_assert_notnull(event);
|
|
|
|
|
litest_assert_event_type(event, type);
|
|
|
|
|
tev = libinput_event_get_tablet_tool_event(event);
|
|
|
|
|
litest_assert_int_eq(libinput_event_tablet_tool_get_tip_state(tev), state);
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-05 10:57:37 +10:00
|
|
|
struct libinput_event_tablet_pad *
|
|
|
|
|
litest_is_pad_button_event(struct libinput_event *event,
|
|
|
|
|
unsigned int button,
|
|
|
|
|
enum libinput_button_state state)
|
|
|
|
|
{
|
|
|
|
|
struct libinput_event_tablet_pad *p;
|
|
|
|
|
enum libinput_event_type type = LIBINPUT_EVENT_TABLET_PAD_BUTTON;
|
|
|
|
|
|
2019-06-11 08:24:10 +10:00
|
|
|
litest_assert_ptr_notnull(event);
|
2016-08-23 08:11:11 +10:00
|
|
|
litest_assert_event_type(event, type);
|
2016-02-05 10:57:37 +10:00
|
|
|
|
|
|
|
|
p = libinput_event_get_tablet_pad_event(event);
|
2019-06-11 08:24:10 +10:00
|
|
|
litest_assert_ptr_notnull(p);
|
2016-02-05 10:57:37 +10:00
|
|
|
|
|
|
|
|
litest_assert_int_eq(libinput_event_tablet_pad_get_button_number(p), button);
|
2017-01-16 14:51:19 +10:00
|
|
|
litest_assert_int_eq(libinput_event_tablet_pad_get_button_state(p), state);
|
2016-02-05 10:57:37 +10:00
|
|
|
|
|
|
|
|
return p;
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-30 14:43:59 +10:00
|
|
|
struct libinput_event_tablet_pad *
|
|
|
|
|
litest_is_pad_dial_event(struct libinput_event *event, unsigned int number)
|
|
|
|
|
{
|
|
|
|
|
struct libinput_event_tablet_pad *p;
|
|
|
|
|
enum libinput_event_type type = LIBINPUT_EVENT_TABLET_PAD_DIAL;
|
|
|
|
|
|
|
|
|
|
litest_assert_ptr_notnull(event);
|
|
|
|
|
litest_assert_event_type(event, type);
|
|
|
|
|
p = libinput_event_get_tablet_pad_event(event);
|
|
|
|
|
|
|
|
|
|
litest_assert_int_eq(libinput_event_tablet_pad_get_dial_number(p), number);
|
|
|
|
|
|
|
|
|
|
return p;
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-05 10:57:37 +10:00
|
|
|
struct libinput_event_tablet_pad *
|
|
|
|
|
litest_is_pad_ring_event(struct libinput_event *event,
|
|
|
|
|
unsigned int number,
|
|
|
|
|
enum libinput_tablet_pad_ring_axis_source source)
|
|
|
|
|
{
|
|
|
|
|
struct libinput_event_tablet_pad *p;
|
|
|
|
|
enum libinput_event_type type = LIBINPUT_EVENT_TABLET_PAD_RING;
|
|
|
|
|
|
2019-06-11 08:24:10 +10:00
|
|
|
litest_assert_ptr_notnull(event);
|
2016-08-23 08:11:11 +10:00
|
|
|
litest_assert_event_type(event, type);
|
2016-02-05 10:57:37 +10:00
|
|
|
p = libinput_event_get_tablet_pad_event(event);
|
|
|
|
|
|
|
|
|
|
litest_assert_int_eq(libinput_event_tablet_pad_get_ring_number(p), number);
|
|
|
|
|
litest_assert_int_eq(libinput_event_tablet_pad_get_ring_source(p), source);
|
|
|
|
|
|
|
|
|
|
return p;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct libinput_event_tablet_pad *
|
|
|
|
|
litest_is_pad_strip_event(struct libinput_event *event,
|
|
|
|
|
unsigned int number,
|
|
|
|
|
enum libinput_tablet_pad_strip_axis_source source)
|
|
|
|
|
{
|
|
|
|
|
struct libinput_event_tablet_pad *p;
|
|
|
|
|
enum libinput_event_type type = LIBINPUT_EVENT_TABLET_PAD_STRIP;
|
|
|
|
|
|
2019-06-11 08:24:10 +10:00
|
|
|
litest_assert_ptr_notnull(event);
|
2016-08-23 08:11:11 +10:00
|
|
|
litest_assert_event_type(event, type);
|
2016-02-05 10:57:37 +10:00
|
|
|
p = libinput_event_get_tablet_pad_event(event);
|
|
|
|
|
|
|
|
|
|
litest_assert_int_eq(libinput_event_tablet_pad_get_strip_number(p), number);
|
|
|
|
|
litest_assert_int_eq(libinput_event_tablet_pad_get_strip_source(p), source);
|
|
|
|
|
|
|
|
|
|
return p;
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-17 11:08:27 +10:00
|
|
|
struct libinput_event_tablet_pad *
|
|
|
|
|
litest_is_pad_key_event(struct libinput_event *event,
|
|
|
|
|
unsigned int key,
|
|
|
|
|
enum libinput_key_state state)
|
|
|
|
|
{
|
|
|
|
|
struct libinput_event_tablet_pad *p;
|
|
|
|
|
enum libinput_event_type type = LIBINPUT_EVENT_TABLET_PAD_KEY;
|
|
|
|
|
|
|
|
|
|
litest_assert(event != NULL);
|
|
|
|
|
litest_assert_event_type(event, type);
|
|
|
|
|
|
|
|
|
|
p = libinput_event_get_tablet_pad_event(event);
|
|
|
|
|
litest_assert(p != NULL);
|
|
|
|
|
|
|
|
|
|
litest_assert_int_eq(libinput_event_tablet_pad_get_key(p), key);
|
|
|
|
|
litest_assert_int_eq(libinput_event_tablet_pad_get_key_state(p), state);
|
|
|
|
|
|
|
|
|
|
return p;
|
|
|
|
|
}
|
|
|
|
|
|
2017-01-20 16:54:16 +11:00
|
|
|
struct libinput_event_switch *
|
|
|
|
|
litest_is_switch_event(struct libinput_event *event,
|
|
|
|
|
enum libinput_switch sw,
|
|
|
|
|
enum libinput_switch_state state)
|
|
|
|
|
{
|
|
|
|
|
struct libinput_event_switch *swev;
|
|
|
|
|
enum libinput_event_type type = LIBINPUT_EVENT_SWITCH_TOGGLE;
|
|
|
|
|
|
|
|
|
|
litest_assert_notnull(event);
|
|
|
|
|
litest_assert_event_type(event, type);
|
|
|
|
|
swev = libinput_event_get_switch_event(event);
|
|
|
|
|
|
|
|
|
|
litest_assert_int_eq(libinput_event_switch_get_switch(swev), sw);
|
|
|
|
|
litest_assert_int_eq(libinput_event_switch_get_switch_state(swev), state);
|
|
|
|
|
|
|
|
|
|
return swev;
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-14 12:57:58 +10:00
|
|
|
void
|
2025-03-14 10:12:24 +10:00
|
|
|
_litest_assert_switch_event(struct libinput *li,
|
|
|
|
|
enum libinput_switch sw,
|
|
|
|
|
enum libinput_switch_state state,
|
|
|
|
|
const char *func,
|
|
|
|
|
int lineno)
|
2023-07-14 12:57:58 +10:00
|
|
|
{
|
|
|
|
|
litest_wait_for_event(li);
|
|
|
|
|
|
2025-04-07 10:53:12 +10:00
|
|
|
_destroy_(libinput_event) *event = libinput_get_event(li);
|
2023-07-14 12:57:58 +10:00
|
|
|
litest_is_switch_event(event, sw, state);
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-05 10:57:37 +10:00
|
|
|
void
|
2025-03-14 10:12:24 +10:00
|
|
|
_litest_assert_pad_button_event(struct libinput *li,
|
|
|
|
|
unsigned int button,
|
|
|
|
|
enum libinput_button_state state,
|
|
|
|
|
const char *func,
|
|
|
|
|
int lineno)
|
2016-02-05 10:57:37 +10:00
|
|
|
{
|
|
|
|
|
litest_wait_for_event(li);
|
|
|
|
|
|
2025-04-07 10:53:12 +10:00
|
|
|
_destroy_(libinput_event) *event = libinput_get_event(li);
|
2021-02-15 18:00:18 +10:00
|
|
|
litest_is_pad_button_event(event, button, state);
|
2016-02-05 10:57:37 +10:00
|
|
|
}
|
|
|
|
|
|
2019-01-17 11:08:27 +10:00
|
|
|
void
|
2025-03-14 10:12:24 +10:00
|
|
|
_litest_assert_pad_key_event(struct libinput *li,
|
|
|
|
|
unsigned int key,
|
|
|
|
|
enum libinput_key_state state,
|
|
|
|
|
const char *func,
|
|
|
|
|
int lineno)
|
2019-01-17 11:08:27 +10:00
|
|
|
{
|
|
|
|
|
litest_wait_for_event(li);
|
|
|
|
|
|
2025-04-07 10:53:12 +10:00
|
|
|
_destroy_(libinput_event) *event = libinput_get_event(li);
|
2021-02-15 18:00:18 +10:00
|
|
|
litest_is_pad_key_event(event, key, state);
|
2019-01-17 11:08:27 +10:00
|
|
|
}
|
|
|
|
|
|
2014-11-10 10:57:27 +10:00
|
|
|
void
|
|
|
|
|
litest_assert_scroll(struct libinput *li,
|
2018-11-22 10:24:54 +10:00
|
|
|
enum libinput_event_type axis_type,
|
2014-11-10 10:57:27 +10:00
|
|
|
enum libinput_pointer_axis axis,
|
2014-11-10 11:03:46 +10:00
|
|
|
int minimum_movement)
|
2014-09-17 15:35:31 +02:00
|
|
|
{
|
2018-11-22 10:24:54 +10:00
|
|
|
struct libinput_event *event;
|
2014-09-17 15:35:31 +02:00
|
|
|
struct libinput_event_pointer *ptrev;
|
2018-11-22 10:24:54 +10:00
|
|
|
bool last_hi_res_event_found, last_low_res_event_found;
|
2015-05-05 11:52:32 +10:00
|
|
|
int value;
|
2016-11-21 14:10:10 +10:00
|
|
|
int nevents = 0;
|
2014-09-17 15:35:31 +02:00
|
|
|
|
2018-11-22 10:24:54 +10:00
|
|
|
litest_assert(axis_type == LIBINPUT_EVENT_POINTER_SCROLL_WHEEL ||
|
|
|
|
|
axis_type == LIBINPUT_EVENT_POINTER_SCROLL_FINGER ||
|
|
|
|
|
axis_type == LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS);
|
|
|
|
|
|
|
|
|
|
last_hi_res_event_found = false;
|
|
|
|
|
last_low_res_event_found = false;
|
2014-09-17 15:35:31 +02:00
|
|
|
event = libinput_get_event(li);
|
2018-11-22 10:24:54 +10:00
|
|
|
litest_assert_ptr_notnull(event);
|
2014-09-17 15:35:31 +02:00
|
|
|
|
|
|
|
|
while (event) {
|
2018-11-22 10:24:54 +10:00
|
|
|
int min = minimum_movement;
|
|
|
|
|
|
|
|
|
|
ptrev = litest_is_axis_event(event, axis_type, axis, 0);
|
2016-11-21 14:10:10 +10:00
|
|
|
nevents++;
|
2014-09-17 15:35:31 +02:00
|
|
|
|
2018-11-22 10:24:54 +10:00
|
|
|
/* Due to how the hysteresis works on touchpad
|
|
|
|
|
* events, the first event is reduced by the
|
|
|
|
|
* hysteresis margin that can cause the first event
|
|
|
|
|
* go under the minimum we expect for all other
|
|
|
|
|
* events */
|
|
|
|
|
if (nevents == 1)
|
|
|
|
|
min = minimum_movement / 2;
|
|
|
|
|
|
|
|
|
|
value = litest_event_pointer_get_value(ptrev, axis);
|
|
|
|
|
if (litest_is_high_res_axis_event(event)) {
|
|
|
|
|
litest_assert(!last_hi_res_event_found);
|
2016-11-21 14:10:10 +10:00
|
|
|
|
2018-11-22 10:24:54 +10:00
|
|
|
if (axis_type == LIBINPUT_EVENT_POINTER_SCROLL_WHEEL)
|
|
|
|
|
min *= 120;
|
2016-11-21 14:10:10 +10:00
|
|
|
|
2018-11-22 10:24:54 +10:00
|
|
|
if (value == 0)
|
|
|
|
|
last_hi_res_event_found = true;
|
|
|
|
|
} else {
|
|
|
|
|
litest_assert(!last_low_res_event_found);
|
|
|
|
|
|
|
|
|
|
if (value == 0)
|
|
|
|
|
last_low_res_event_found = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (value != 0) {
|
2016-11-21 14:10:10 +10:00
|
|
|
if (minimum_movement > 0)
|
|
|
|
|
litest_assert_int_ge(value, min);
|
|
|
|
|
else
|
|
|
|
|
litest_assert_int_le(value, min);
|
2018-11-22 10:24:54 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
libinput_event_destroy(event);
|
|
|
|
|
event = libinput_get_event(li);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
litest_assert(last_low_res_event_found);
|
|
|
|
|
litest_assert(last_hi_res_event_found);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
litest_assert_axis_end_sequence(struct libinput *li,
|
|
|
|
|
enum libinput_event_type axis_type,
|
|
|
|
|
enum libinput_pointer_axis axis,
|
|
|
|
|
enum libinput_pointer_axis_source source)
|
|
|
|
|
{
|
|
|
|
|
struct libinput_event_pointer *ptrev;
|
|
|
|
|
bool last_hi_res_event_found, last_low_res_event_found;
|
|
|
|
|
double val;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
litest_assert(axis_type == LIBINPUT_EVENT_POINTER_SCROLL_WHEEL ||
|
|
|
|
|
axis_type == LIBINPUT_EVENT_POINTER_SCROLL_FINGER ||
|
|
|
|
|
axis_type == LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS);
|
|
|
|
|
|
|
|
|
|
last_hi_res_event_found = false;
|
|
|
|
|
last_low_res_event_found = false;
|
|
|
|
|
|
|
|
|
|
/* both high and low scroll end events must be sent */
|
|
|
|
|
for (i = 0; i < 2; i++) {
|
2025-04-07 10:53:12 +10:00
|
|
|
_destroy_(libinput_event) *event = libinput_get_event(li);
|
2018-11-22 10:24:54 +10:00
|
|
|
ptrev = litest_is_axis_event(event, axis_type, axis, source);
|
|
|
|
|
val = litest_event_pointer_get_value(ptrev, axis);
|
2024-09-16 16:20:26 +10:00
|
|
|
litest_assert(val == 0.0);
|
2018-11-22 10:24:54 +10:00
|
|
|
|
|
|
|
|
if (litest_is_high_res_axis_event(event)) {
|
|
|
|
|
litest_assert(!last_hi_res_event_found);
|
|
|
|
|
last_hi_res_event_found = true;
|
2014-09-17 15:35:31 +02:00
|
|
|
} else {
|
2018-11-22 10:24:54 +10:00
|
|
|
litest_assert(!last_low_res_event_found);
|
|
|
|
|
last_low_res_event_found = true;
|
2014-09-17 15:35:31 +02:00
|
|
|
}
|
|
|
|
|
}
|
2018-11-22 10:24:54 +10:00
|
|
|
|
|
|
|
|
litest_assert(last_low_res_event_found);
|
|
|
|
|
litest_assert(last_hi_res_event_found);
|
2014-09-17 15:35:31 +02:00
|
|
|
}
|
2014-09-16 16:08:29 +10:00
|
|
|
|
2014-12-18 11:29:32 +10:00
|
|
|
void
|
2024-09-12 13:40:44 +10:00
|
|
|
_litest_assert_only_typed_events(struct libinput *li,
|
|
|
|
|
enum libinput_event_type type,
|
|
|
|
|
const char *func,
|
|
|
|
|
int line)
|
2014-12-18 11:29:32 +10:00
|
|
|
{
|
|
|
|
|
struct libinput_event *event;
|
|
|
|
|
|
2016-11-25 14:56:52 +10:00
|
|
|
litest_assert(type != LIBINPUT_EVENT_NONE);
|
2014-12-18 11:29:32 +10:00
|
|
|
|
2024-09-12 13:40:44 +10:00
|
|
|
_litest_checkpoint(func,
|
|
|
|
|
line,
|
2025-03-12 10:38:12 +10:00
|
|
|
ANSI_CYAN,
|
2024-09-12 13:40:44 +10:00
|
|
|
"asserting only typed events %s",
|
|
|
|
|
litest_event_type_str(type));
|
|
|
|
|
|
2014-12-18 11:29:32 +10:00
|
|
|
libinput_dispatch(li);
|
|
|
|
|
event = libinput_get_event(li);
|
2015-05-04 09:13:22 +10:00
|
|
|
litest_assert_notnull(event);
|
2014-12-18 11:29:32 +10:00
|
|
|
|
|
|
|
|
while (event) {
|
2021-02-15 17:34:34 +10:00
|
|
|
litest_assert_event_type(event, type);
|
2014-12-18 11:29:32 +10:00
|
|
|
libinput_event_destroy(event);
|
|
|
|
|
libinput_dispatch(li);
|
|
|
|
|
event = libinput_get_event(li);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-22 10:24:54 +10:00
|
|
|
void
|
|
|
|
|
litest_assert_only_axis_events(struct libinput *li, enum libinput_event_type axis_type)
|
|
|
|
|
{
|
|
|
|
|
struct libinput_event *event;
|
|
|
|
|
|
|
|
|
|
litest_assert(axis_type == LIBINPUT_EVENT_POINTER_SCROLL_WHEEL ||
|
|
|
|
|
axis_type == LIBINPUT_EVENT_POINTER_SCROLL_FINGER ||
|
|
|
|
|
axis_type == LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS);
|
|
|
|
|
|
|
|
|
|
libinput_dispatch(li);
|
|
|
|
|
event = libinput_get_event(li);
|
|
|
|
|
litest_assert_notnull(event);
|
|
|
|
|
|
|
|
|
|
while (event) {
|
|
|
|
|
litest_assert_event_type_is_one_of(event,
|
|
|
|
|
LIBINPUT_EVENT_POINTER_AXIS,
|
|
|
|
|
axis_type);
|
|
|
|
|
libinput_event_destroy(event);
|
|
|
|
|
libinput_dispatch(li);
|
|
|
|
|
event = libinput_get_event(li);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-08 15:16:42 +10:00
|
|
|
void
|
|
|
|
|
litest_assert_no_typed_events(struct libinput *li, enum libinput_event_type type)
|
|
|
|
|
{
|
|
|
|
|
struct libinput_event *event;
|
|
|
|
|
|
|
|
|
|
litest_assert(type != LIBINPUT_EVENT_NONE);
|
|
|
|
|
|
|
|
|
|
libinput_dispatch(li);
|
|
|
|
|
event = libinput_get_event(li);
|
|
|
|
|
|
|
|
|
|
while (event) {
|
|
|
|
|
litest_assert_int_ne(libinput_event_get_type(event), type);
|
|
|
|
|
libinput_event_destroy(event);
|
|
|
|
|
libinput_dispatch(li);
|
|
|
|
|
event = libinput_get_event(li);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-02 14:19:45 +10:00
|
|
|
void
|
|
|
|
|
litest_assert_touch_sequence(struct libinput *li)
|
|
|
|
|
{
|
|
|
|
|
struct libinput_event *event;
|
2017-07-17 14:26:34 +10:00
|
|
|
struct libinput_event_touch *tev;
|
|
|
|
|
int slot;
|
2016-09-02 14:19:45 +10:00
|
|
|
|
|
|
|
|
event = libinput_get_event(li);
|
2017-07-17 14:26:34 +10:00
|
|
|
tev = litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_DOWN);
|
|
|
|
|
slot = libinput_event_touch_get_slot(tev);
|
2016-09-02 14:19:45 +10:00
|
|
|
libinput_event_destroy(event);
|
|
|
|
|
|
|
|
|
|
event = libinput_get_event(li);
|
|
|
|
|
litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_FRAME);
|
|
|
|
|
libinput_event_destroy(event);
|
|
|
|
|
|
|
|
|
|
event = libinput_get_event(li);
|
|
|
|
|
do {
|
2017-07-17 14:26:34 +10:00
|
|
|
tev = litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_MOTION);
|
|
|
|
|
litest_assert_int_eq(slot, libinput_event_touch_get_slot(tev));
|
2016-09-02 14:19:45 +10:00
|
|
|
libinput_event_destroy(event);
|
|
|
|
|
|
|
|
|
|
event = libinput_get_event(li);
|
|
|
|
|
litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_FRAME);
|
|
|
|
|
libinput_event_destroy(event);
|
|
|
|
|
|
|
|
|
|
event = libinput_get_event(li);
|
|
|
|
|
litest_assert_notnull(event);
|
|
|
|
|
} while (libinput_event_get_type(event) != LIBINPUT_EVENT_TOUCH_UP);
|
|
|
|
|
|
2017-07-17 14:26:34 +10:00
|
|
|
tev = litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_UP);
|
|
|
|
|
litest_assert_int_eq(slot, libinput_event_touch_get_slot(tev));
|
2016-09-02 14:19:45 +10:00
|
|
|
libinput_event_destroy(event);
|
|
|
|
|
event = libinput_get_event(li);
|
|
|
|
|
litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_FRAME);
|
|
|
|
|
libinput_event_destroy(event);
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-13 16:04:35 +10:00
|
|
|
void
|
|
|
|
|
litest_assert_touch_motion_frame(struct libinput *li)
|
|
|
|
|
{
|
|
|
|
|
struct libinput_event *event;
|
|
|
|
|
|
|
|
|
|
/* expect at least one, but maybe more */
|
|
|
|
|
event = libinput_get_event(li);
|
|
|
|
|
litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_MOTION);
|
|
|
|
|
libinput_event_destroy(event);
|
|
|
|
|
|
|
|
|
|
event = libinput_get_event(li);
|
|
|
|
|
litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_FRAME);
|
|
|
|
|
libinput_event_destroy(event);
|
|
|
|
|
|
|
|
|
|
event = libinput_get_event(li);
|
|
|
|
|
while (event) {
|
|
|
|
|
litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_MOTION);
|
|
|
|
|
libinput_event_destroy(event);
|
|
|
|
|
|
|
|
|
|
event = libinput_get_event(li);
|
|
|
|
|
litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_FRAME);
|
|
|
|
|
libinput_event_destroy(event);
|
|
|
|
|
|
|
|
|
|
event = libinput_get_event(li);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
litest_assert_touch_down_frame(struct libinput *li)
|
|
|
|
|
{
|
2025-04-07 10:53:12 +10:00
|
|
|
_destroy_(libinput_event) *down = libinput_get_event(li);
|
|
|
|
|
litest_is_touch_event(down, LIBINPUT_EVENT_TOUCH_DOWN);
|
2018-07-13 16:04:35 +10:00
|
|
|
|
2025-04-07 10:53:12 +10:00
|
|
|
_destroy_(libinput_event) *frame = libinput_get_event(li);
|
|
|
|
|
litest_is_touch_event(frame, LIBINPUT_EVENT_TOUCH_FRAME);
|
2018-07-13 16:04:35 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
litest_assert_touch_up_frame(struct libinput *li)
|
|
|
|
|
{
|
2025-04-07 10:53:12 +10:00
|
|
|
_destroy_(libinput_event) *up = libinput_get_event(li);
|
|
|
|
|
litest_is_touch_event(up, LIBINPUT_EVENT_TOUCH_UP);
|
2018-07-13 16:04:35 +10:00
|
|
|
|
2025-04-07 10:53:12 +10:00
|
|
|
_destroy_(libinput_event) *frame = libinput_get_event(li);
|
|
|
|
|
litest_is_touch_event(frame, LIBINPUT_EVENT_TOUCH_FRAME);
|
2018-07-13 16:04:35 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
litest_assert_touch_cancel(struct libinput *li)
|
|
|
|
|
{
|
2025-04-07 10:53:12 +10:00
|
|
|
_destroy_(libinput_event) *cancel = libinput_get_event(li);
|
|
|
|
|
litest_is_touch_event(cancel, LIBINPUT_EVENT_TOUCH_CANCEL);
|
2018-07-13 16:04:35 +10:00
|
|
|
|
2025-04-07 10:53:12 +10:00
|
|
|
_destroy_(libinput_event) *frame = libinput_get_event(li);
|
|
|
|
|
litest_is_touch_event(frame, LIBINPUT_EVENT_TOUCH_FRAME);
|
2018-07-13 16:04:35 +10:00
|
|
|
}
|
|
|
|
|
|
2014-09-16 16:08:29 +10:00
|
|
|
void
|
2025-04-01 09:23:10 +10:00
|
|
|
_litest_timeout(struct libinput *li, const char *func, int lineno, int millis)
|
2014-09-16 16:08:29 +10:00
|
|
|
{
|
2025-04-01 09:23:10 +10:00
|
|
|
if (li)
|
|
|
|
|
_litest_dispatch(li, func, lineno);
|
|
|
|
|
msleep(millis);
|
|
|
|
|
if (li)
|
|
|
|
|
_litest_dispatch(li, func, lineno);
|
2024-09-06 11:38:35 +10:00
|
|
|
}
|
|
|
|
|
|
2025-06-11 09:36:07 +10:00
|
|
|
void
|
|
|
|
|
_litest_assert_logcapture_no_errors(struct litest_logcapture *capture,
|
|
|
|
|
const char *file,
|
|
|
|
|
const char *func,
|
|
|
|
|
int line)
|
|
|
|
|
{
|
|
|
|
|
litest_assert_ptr_notnull(capture);
|
|
|
|
|
|
|
|
|
|
if (capture->errors &&
|
|
|
|
|
strv_for_each((const char **)capture->errors, is_actual_error, NULL)) {
|
|
|
|
|
_autofree_ char *errors = strv_join(capture->errors, "\n");
|
|
|
|
|
_litest_abort_msg(file,
|
|
|
|
|
line,
|
|
|
|
|
func,
|
|
|
|
|
"Unexpected errors in log capture:\n%s\n",
|
|
|
|
|
errors);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
litest_logcapture_destroy(struct litest_logcapture *c)
|
|
|
|
|
{
|
|
|
|
|
strv_free(c->errors);
|
|
|
|
|
strv_free(c->infos);
|
|
|
|
|
strv_free(c->debugs);
|
|
|
|
|
free(c);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LIBINPUT_ATTRIBUTE_PRINTF(3, 0)
|
|
|
|
|
static void
|
|
|
|
|
litest_log_handler_msgcapture(struct libinput *libinput,
|
|
|
|
|
enum libinput_log_priority pri,
|
|
|
|
|
const char *format,
|
|
|
|
|
va_list args)
|
|
|
|
|
{
|
|
|
|
|
struct litest_user_data *user_data = libinput_get_user_data(libinput);
|
|
|
|
|
struct litest_logcapture *capture = user_data->private;
|
|
|
|
|
const char *priority = NULL;
|
|
|
|
|
const char *color =
|
|
|
|
|
use_colors ? ANSI_RGB(255, 255, 70) ANSI_RGB_BG(40, 40, 40) : "";
|
|
|
|
|
|
|
|
|
|
switch (pri) {
|
|
|
|
|
case LIBINPUT_LOG_PRIORITY_ERROR:
|
|
|
|
|
priority = "error ";
|
|
|
|
|
break;
|
|
|
|
|
case LIBINPUT_LOG_PRIORITY_INFO:
|
|
|
|
|
priority = "info ";
|
|
|
|
|
break;
|
|
|
|
|
case LIBINPUT_LOG_PRIORITY_DEBUG:
|
|
|
|
|
priority = "debug ";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_autofree_ char *message = strdup_vprintf(format, args);
|
|
|
|
|
|
|
|
|
|
fprintf(stderr,
|
|
|
|
|
"%slitest captured: %-6s%s %s",
|
|
|
|
|
color,
|
|
|
|
|
priority,
|
|
|
|
|
use_colors ? ANSI_NORMAL : "",
|
|
|
|
|
message);
|
|
|
|
|
|
|
|
|
|
switch (pri) {
|
|
|
|
|
case LIBINPUT_LOG_PRIORITY_ERROR:
|
|
|
|
|
capture->errors = strv_append_take(capture->errors, &message);
|
|
|
|
|
break;
|
|
|
|
|
case LIBINPUT_LOG_PRIORITY_INFO:
|
|
|
|
|
capture->infos = strv_append_take(capture->infos, &message);
|
|
|
|
|
break;
|
|
|
|
|
case LIBINPUT_LOG_PRIORITY_DEBUG:
|
|
|
|
|
capture->debugs = strv_append_take(capture->debugs, &message);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct litest_logcapture *
|
|
|
|
|
litest_logcapture_setup(struct libinput *li)
|
|
|
|
|
{
|
|
|
|
|
struct litest_logcapture *c = zalloc(sizeof(*c));
|
|
|
|
|
litest_context_set_user_data(li, c);
|
|
|
|
|
libinput_log_set_handler(li, litest_log_handler_msgcapture);
|
|
|
|
|
return c;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct litest_logcapture *
|
|
|
|
|
litest_logcapture_remove(struct libinput *li, struct litest_logcapture *capture)
|
|
|
|
|
{
|
|
|
|
|
litest_restore_log_handler(li);
|
|
|
|
|
litest_logcapture_destroy(capture);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-12 12:37:08 +10:00
|
|
|
#define litest_with_logcapture(li_, capture_) \
|
|
|
|
|
for (struct litest_logcapture *capture_ = litest_logcapture_setup(li_); \
|
|
|
|
|
capture_ != NULL; capture_ = litest_logcapture_remove(li_, capture_))
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
_litest_assert_strv_substring(char **strv,
|
|
|
|
|
char *substring,
|
|
|
|
|
const char *file,
|
|
|
|
|
const char *func,
|
|
|
|
|
int line)
|
|
|
|
|
{
|
|
|
|
|
if (!strv) {
|
|
|
|
|
_litest_abort_msg(file,
|
|
|
|
|
line,
|
|
|
|
|
func,
|
|
|
|
|
"Expected substring '%s' but strv is NULL",
|
|
|
|
|
substring);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool found = strv_find_substring(strv, substring, NULL);
|
|
|
|
|
if (!found) {
|
|
|
|
|
_autofree_ char *strv_str = strv_join(strv, "', '");
|
|
|
|
|
_litest_abort_msg(file,
|
|
|
|
|
line,
|
|
|
|
|
func,
|
|
|
|
|
"Expected substring '%s' not found in strv: ['%s']",
|
|
|
|
|
substring,
|
|
|
|
|
strv_str);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-17 10:07:38 +10:00
|
|
|
void
|
|
|
|
|
litest_push_event_frame(struct litest_device *dev)
|
|
|
|
|
{
|
2019-06-11 08:24:10 +10:00
|
|
|
litest_assert_int_ge(dev->skip_ev_syn, 0);
|
2017-01-19 17:20:19 +10:00
|
|
|
dev->skip_ev_syn++;
|
2014-09-17 10:07:38 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
litest_pop_event_frame(struct litest_device *dev)
|
|
|
|
|
{
|
2019-06-11 08:24:10 +10:00
|
|
|
litest_assert_int_gt(dev->skip_ev_syn, 0);
|
2017-01-19 17:20:19 +10:00
|
|
|
dev->skip_ev_syn--;
|
|
|
|
|
if (dev->skip_ev_syn == 0)
|
|
|
|
|
litest_event(dev, EV_SYN, SYN_REPORT, 0);
|
2014-09-17 10:07:38 +10:00
|
|
|
}
|
2014-12-16 11:28:26 +10:00
|
|
|
|
2017-02-09 11:06:01 +10:00
|
|
|
void
|
|
|
|
|
litest_filter_event(struct litest_device *dev, unsigned int type, unsigned int code)
|
|
|
|
|
{
|
|
|
|
|
libevdev_disable_event_code(dev->evdev, type, code);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
litest_unfilter_event(struct litest_device *dev, unsigned int type, unsigned int code)
|
|
|
|
|
{
|
|
|
|
|
/* would need an non-NULL argument for re-enabling, so simply abort
|
|
|
|
|
* until we need to be more sophisticated */
|
2019-06-11 08:24:10 +10:00
|
|
|
litest_assert_int_ne(type, (unsigned int)EV_ABS);
|
2017-02-09 11:06:01 +10:00
|
|
|
|
|
|
|
|
libevdev_enable_event_code(dev->evdev, type, code, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-16 11:28:26 +10:00
|
|
|
static void
|
|
|
|
|
send_abs_xy(struct litest_device *d, double x, double y)
|
|
|
|
|
{
|
|
|
|
|
struct input_event e;
|
|
|
|
|
int val;
|
|
|
|
|
|
|
|
|
|
e.type = EV_ABS;
|
|
|
|
|
e.code = ABS_X;
|
|
|
|
|
e.value = LITEST_AUTO_ASSIGN;
|
2015-06-22 12:48:04 +02:00
|
|
|
val = litest_auto_assign_value(d, &e, 0, x, y, NULL, true);
|
2014-12-16 11:28:26 +10:00
|
|
|
litest_event(d, EV_ABS, ABS_X, val);
|
|
|
|
|
|
|
|
|
|
e.code = ABS_Y;
|
2015-06-22 12:48:04 +02:00
|
|
|
val = litest_auto_assign_value(d, &e, 0, x, y, NULL, true);
|
2014-12-16 11:28:26 +10:00
|
|
|
litest_event(d, EV_ABS, ABS_Y, val);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
send_abs_mt_xy(struct litest_device *d, double x, double y)
|
|
|
|
|
{
|
|
|
|
|
struct input_event e;
|
|
|
|
|
int val;
|
|
|
|
|
|
|
|
|
|
e.type = EV_ABS;
|
|
|
|
|
e.code = ABS_MT_POSITION_X;
|
|
|
|
|
e.value = LITEST_AUTO_ASSIGN;
|
2015-06-22 12:48:04 +02:00
|
|
|
val = litest_auto_assign_value(d, &e, 0, x, y, NULL, true);
|
2014-12-16 11:28:26 +10:00
|
|
|
litest_event(d, EV_ABS, ABS_MT_POSITION_X, val);
|
|
|
|
|
|
|
|
|
|
e.code = ABS_MT_POSITION_Y;
|
|
|
|
|
e.value = LITEST_AUTO_ASSIGN;
|
2015-06-22 12:48:04 +02:00
|
|
|
val = litest_auto_assign_value(d, &e, 0, x, y, NULL, true);
|
2014-12-16 11:28:26 +10:00
|
|
|
litest_event(d, EV_ABS, ABS_MT_POSITION_Y, val);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
litest_semi_mt_touch_down(struct litest_device *d,
|
|
|
|
|
struct litest_semi_mt *semi_mt,
|
|
|
|
|
unsigned int slot,
|
|
|
|
|
double x,
|
|
|
|
|
double y)
|
|
|
|
|
{
|
|
|
|
|
double t, l, r = 0, b = 0; /* top, left, right, bottom */
|
|
|
|
|
|
|
|
|
|
if (d->ntouches_down > 2 || slot > 1)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (d->ntouches_down == 1) {
|
|
|
|
|
l = x;
|
|
|
|
|
t = y;
|
|
|
|
|
} else {
|
|
|
|
|
int other = (slot + 1) % 2;
|
|
|
|
|
l = min(x, semi_mt->touches[other].x);
|
|
|
|
|
t = min(y, semi_mt->touches[other].y);
|
|
|
|
|
r = max(x, semi_mt->touches[other].x);
|
|
|
|
|
b = max(y, semi_mt->touches[other].y);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
send_abs_xy(d, l, t);
|
|
|
|
|
|
|
|
|
|
litest_event(d, EV_ABS, ABS_MT_SLOT, 0);
|
|
|
|
|
|
|
|
|
|
if (d->ntouches_down == 1)
|
|
|
|
|
litest_event(d, EV_ABS, ABS_MT_TRACKING_ID, ++semi_mt->tracking_id);
|
|
|
|
|
|
|
|
|
|
send_abs_mt_xy(d, l, t);
|
|
|
|
|
|
|
|
|
|
if (d->ntouches_down == 2) {
|
|
|
|
|
litest_event(d, EV_ABS, ABS_MT_SLOT, 1);
|
|
|
|
|
litest_event(d, EV_ABS, ABS_MT_TRACKING_ID, ++semi_mt->tracking_id);
|
|
|
|
|
|
|
|
|
|
send_abs_mt_xy(d, r, b);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
litest_event(d, EV_SYN, SYN_REPORT, 0);
|
|
|
|
|
|
|
|
|
|
semi_mt->touches[slot].x = x;
|
|
|
|
|
semi_mt->touches[slot].y = y;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
litest_semi_mt_touch_move(struct litest_device *d,
|
|
|
|
|
struct litest_semi_mt *semi_mt,
|
|
|
|
|
unsigned int slot,
|
|
|
|
|
double x,
|
|
|
|
|
double y)
|
|
|
|
|
{
|
|
|
|
|
double t, l, r = 0, b = 0; /* top, left, right, bottom */
|
|
|
|
|
|
|
|
|
|
if (d->ntouches_down > 2 || slot > 1)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (d->ntouches_down == 1) {
|
|
|
|
|
l = x;
|
|
|
|
|
t = y;
|
|
|
|
|
} else {
|
|
|
|
|
int other = (slot + 1) % 2;
|
|
|
|
|
l = min(x, semi_mt->touches[other].x);
|
|
|
|
|
t = min(y, semi_mt->touches[other].y);
|
|
|
|
|
r = max(x, semi_mt->touches[other].x);
|
|
|
|
|
b = max(y, semi_mt->touches[other].y);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
send_abs_xy(d, l, t);
|
|
|
|
|
|
|
|
|
|
litest_event(d, EV_ABS, ABS_MT_SLOT, 0);
|
|
|
|
|
send_abs_mt_xy(d, l, t);
|
|
|
|
|
|
|
|
|
|
if (d->ntouches_down == 2) {
|
|
|
|
|
litest_event(d, EV_ABS, ABS_MT_SLOT, 1);
|
|
|
|
|
send_abs_mt_xy(d, r, b);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
litest_event(d, EV_SYN, SYN_REPORT, 0);
|
|
|
|
|
|
|
|
|
|
semi_mt->touches[slot].x = x;
|
|
|
|
|
semi_mt->touches[slot].y = y;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
litest_semi_mt_touch_up(struct litest_device *d,
|
|
|
|
|
struct litest_semi_mt *semi_mt,
|
|
|
|
|
unsigned int slot)
|
|
|
|
|
{
|
|
|
|
|
/* note: ntouches_down is decreased before we get here */
|
|
|
|
|
if (d->ntouches_down >= 2 || slot > 1)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
litest_event(d, EV_ABS, ABS_MT_SLOT, d->ntouches_down);
|
|
|
|
|
litest_event(d, EV_ABS, ABS_MT_TRACKING_ID, -1);
|
|
|
|
|
|
|
|
|
|
/* if we have one finger left, send x/y coords for that finger left.
|
|
|
|
|
this is likely to happen with a real touchpad */
|
|
|
|
|
if (d->ntouches_down == 1) {
|
|
|
|
|
int other = (slot + 1) % 2;
|
|
|
|
|
send_abs_xy(d, semi_mt->touches[other].x, semi_mt->touches[other].y);
|
|
|
|
|
litest_event(d, EV_ABS, ABS_MT_SLOT, 0);
|
|
|
|
|
send_abs_mt_xy(d, semi_mt->touches[other].x, semi_mt->touches[other].y);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
litest_event(d, EV_SYN, SYN_REPORT, 0);
|
|
|
|
|
}
|
2015-05-20 09:36:01 +10:00
|
|
|
|
2025-04-03 12:15:43 +10:00
|
|
|
enum litest_mode
|
|
|
|
|
litest_parse_argv(int argc, char **argv, int *njobs_out)
|
2015-05-20 09:46:54 +10:00
|
|
|
{
|
2015-05-20 10:12:39 +10:00
|
|
|
enum {
|
2024-10-15 15:28:56 +10:00
|
|
|
OPT_EXIT_FIRST,
|
2015-05-20 10:12:39 +10:00
|
|
|
OPT_FILTER_TEST,
|
2015-05-20 10:49:13 +10:00
|
|
|
OPT_FILTER_DEVICE,
|
2015-05-20 11:00:37 +10:00
|
|
|
OPT_FILTER_GROUP,
|
2024-10-17 09:04:36 +10:00
|
|
|
OPT_FILTER_RANGEVAL,
|
2018-08-10 11:39:04 +10:00
|
|
|
OPT_FILTER_DEVICELESS,
|
test: implement support for parametrizing tests
litest supports ranged tests but they are not enough, doubly so with
tests where we want to parametrize across multiple options.
This patch adds support for just that, in clunky C style.
The typical invocation for a test is by giving the test parameter
a name, a number of values and then the values themselves:
struct litest_parameters *params = litest_parameters_new("axis", 's', 2, "ABS_X", "ABS_Y",
"enabled", 'b', '2', true, false,
"number", 'u', '2', 10, 11,
NULL);
litest_add_parametrized(sometest, LITEST_ANY, LITEST_ANY, params);
litest_parameters_unref(params);
Currently supported are u (uint32), i (int32), d (double), b (bool),
c (char) and s (string).
In the test itself, the `test_env->params` variable is available and
retrieval of the parameters works like this:
const char *axis;
uint32_t number;
bool enabled;
litest_test_param_fetch(test_env->params,
"axis", &axis,
"enabled", &enabled,
"number", &number,
NULL);
Note that since this is an effectively internal test-suite only
functionality we don't do type-checking here, it's assumed that if you
write the code to pass parameters into a test you remember the type
of said params when you write the test code.
Because we don't have hashmaps or anything useful other than lists the
implementation is a bit clunky: we copy the parameter into the test
during litest_add_*, permutate it for our test list which gives us yet
another linked list C struct, and finally copy the actual value into
the test and test environment as it's executed. Not pretty, but it
works.
A few tests are switched as simple demonstration. The name of the
test has the parameters with their names and values appended now, e.g.:
"pointer:pointer_scroll_wheel_hires_send_only_lores:ms-surface-cover:axis:ABS_X"
"pointer:pointer_motion_relative_min_decel:mouse-roccat:direction:NW"
Filtering by parameters can be done via globs of their string
representation:
libinput-test-suite --filter-params="axis:ABS_*,enabled:true,number:10*"
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1109>
2024-12-22 00:06:19 +10:00
|
|
|
OPT_FILTER_PARAMETER,
|
2024-10-21 12:12:45 +10:00
|
|
|
OPT_OUTPUT_FILE,
|
2016-07-22 15:19:23 +10:00
|
|
|
OPT_JOBS,
|
2015-05-20 10:12:39 +10:00
|
|
|
OPT_LIST,
|
|
|
|
|
OPT_VERBOSE,
|
|
|
|
|
};
|
2015-05-20 09:46:54 +10:00
|
|
|
static const struct option opts[] = {
|
2015-05-20 10:12:39 +10:00
|
|
|
{ "filter-test", 1, 0, OPT_FILTER_TEST },
|
2015-05-20 10:49:13 +10:00
|
|
|
{ "filter-device", 1, 0, OPT_FILTER_DEVICE },
|
2015-05-20 11:00:37 +10:00
|
|
|
{ "filter-group", 1, 0, OPT_FILTER_GROUP },
|
2024-10-17 09:04:36 +10:00
|
|
|
{ "filter-rangeval", 1, 0, OPT_FILTER_RANGEVAL },
|
2018-08-10 11:39:04 +10:00
|
|
|
{ "filter-deviceless", 0, 0, OPT_FILTER_DEVICELESS },
|
test: implement support for parametrizing tests
litest supports ranged tests but they are not enough, doubly so with
tests where we want to parametrize across multiple options.
This patch adds support for just that, in clunky C style.
The typical invocation for a test is by giving the test parameter
a name, a number of values and then the values themselves:
struct litest_parameters *params = litest_parameters_new("axis", 's', 2, "ABS_X", "ABS_Y",
"enabled", 'b', '2', true, false,
"number", 'u', '2', 10, 11,
NULL);
litest_add_parametrized(sometest, LITEST_ANY, LITEST_ANY, params);
litest_parameters_unref(params);
Currently supported are u (uint32), i (int32), d (double), b (bool),
c (char) and s (string).
In the test itself, the `test_env->params` variable is available and
retrieval of the parameters works like this:
const char *axis;
uint32_t number;
bool enabled;
litest_test_param_fetch(test_env->params,
"axis", &axis,
"enabled", &enabled,
"number", &number,
NULL);
Note that since this is an effectively internal test-suite only
functionality we don't do type-checking here, it's assumed that if you
write the code to pass parameters into a test you remember the type
of said params when you write the test code.
Because we don't have hashmaps or anything useful other than lists the
implementation is a bit clunky: we copy the parameter into the test
during litest_add_*, permutate it for our test list which gives us yet
another linked list C struct, and finally copy the actual value into
the test and test environment as it's executed. Not pretty, but it
works.
A few tests are switched as simple demonstration. The name of the
test has the parameters with their names and values appended now, e.g.:
"pointer:pointer_scroll_wheel_hires_send_only_lores:ms-surface-cover:axis:ABS_X"
"pointer:pointer_motion_relative_min_decel:mouse-roccat:direction:NW"
Filtering by parameters can be done via globs of their string
representation:
libinput-test-suite --filter-params="axis:ABS_*,enabled:true,number:10*"
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1109>
2024-12-22 00:06:19 +10:00
|
|
|
{ "filter-parameter", 1, 0, OPT_FILTER_PARAMETER },
|
2024-10-21 12:12:45 +10:00
|
|
|
{ "output-file", 1, 0, OPT_OUTPUT_FILE },
|
2024-10-15 15:28:56 +10:00
|
|
|
{ "exitfirst", 0, 0, OPT_EXIT_FIRST },
|
2016-07-22 15:19:23 +10:00
|
|
|
{ "jobs", 1, 0, OPT_JOBS },
|
2015-05-20 10:12:39 +10:00
|
|
|
{ "list", 0, 0, OPT_LIST },
|
|
|
|
|
{ "verbose", 0, 0, OPT_VERBOSE },
|
2019-03-07 09:16:05 +10:00
|
|
|
{ "help", 0, 0, 'h' },
|
2015-05-20 09:46:54 +10:00
|
|
|
{ 0, 0, 0, 0 }
|
|
|
|
|
};
|
2016-08-01 14:03:33 +10:00
|
|
|
enum {
|
|
|
|
|
JOBS_DEFAULT,
|
2025-06-27 18:41:57 +10:00
|
|
|
JOBS_NONE,
|
2016-08-01 14:03:33 +10:00
|
|
|
JOBS_SINGLE,
|
|
|
|
|
JOBS_CUSTOM
|
|
|
|
|
} want_jobs = JOBS_DEFAULT;
|
2019-05-27 14:28:24 +10:00
|
|
|
char *jobs_env;
|
2025-04-03 12:15:43 +10:00
|
|
|
int jobs = 0;
|
2019-03-05 15:51:06 +10:00
|
|
|
|
|
|
|
|
/* If we are not running from the builddir, we assume we're running
|
|
|
|
|
* against the system as installed */
|
2025-04-03 11:23:34 +10:00
|
|
|
if (!builddir_lookup(NULL))
|
2019-03-22 11:43:13 +10:00
|
|
|
use_system_rules_quirks = true;
|
2016-08-01 14:03:33 +10:00
|
|
|
|
2016-08-01 14:09:02 +10:00
|
|
|
if (in_debugger)
|
2025-06-27 18:41:57 +10:00
|
|
|
want_jobs = JOBS_NONE;
|
2016-08-01 14:09:02 +10:00
|
|
|
|
2019-05-27 14:28:24 +10:00
|
|
|
if ((jobs_env = getenv("LITEST_JOBS"))) {
|
|
|
|
|
if (!safe_atoi(jobs_env, &jobs)) {
|
|
|
|
|
fprintf(stderr,
|
|
|
|
|
"LITEST_JOBS environment variable must be positive integer\n");
|
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-20 09:46:54 +10:00
|
|
|
while (1) {
|
|
|
|
|
int c;
|
|
|
|
|
int option_index = 0;
|
|
|
|
|
|
2024-10-15 15:28:56 +10:00
|
|
|
c = getopt_long(argc, argv, "j:x", opts, &option_index);
|
2015-05-20 09:46:54 +10:00
|
|
|
if (c == -1)
|
|
|
|
|
break;
|
|
|
|
|
switch (c) {
|
2019-03-07 09:16:05 +10:00
|
|
|
default:
|
|
|
|
|
case 'h':
|
|
|
|
|
printf("Usage: %s [--verbose] [--jobs] [--filter-...]\n"
|
|
|
|
|
"\n"
|
|
|
|
|
"Options:\n"
|
2024-10-15 15:28:56 +10:00
|
|
|
" -x | --exitfirst\n"
|
|
|
|
|
" Exit instantly on first failed test\n"
|
2019-03-07 09:16:05 +10:00
|
|
|
" --filter-test=.... \n"
|
|
|
|
|
" Glob to filter on test names\n"
|
|
|
|
|
" --filter-device=.... \n"
|
|
|
|
|
" Glob to filter on device names\n"
|
|
|
|
|
" --filter-group=.... \n"
|
|
|
|
|
" Glob to filter on test groups\n"
|
2024-10-17 09:04:36 +10:00
|
|
|
" --filter-rangeval=N \n"
|
|
|
|
|
" Only run tests with the given range value\n"
|
2019-03-07 09:16:05 +10:00
|
|
|
" --filter-deviceless=.... \n"
|
|
|
|
|
" Glob to filter on tests that do not create test devices\n"
|
test: implement support for parametrizing tests
litest supports ranged tests but they are not enough, doubly so with
tests where we want to parametrize across multiple options.
This patch adds support for just that, in clunky C style.
The typical invocation for a test is by giving the test parameter
a name, a number of values and then the values themselves:
struct litest_parameters *params = litest_parameters_new("axis", 's', 2, "ABS_X", "ABS_Y",
"enabled", 'b', '2', true, false,
"number", 'u', '2', 10, 11,
NULL);
litest_add_parametrized(sometest, LITEST_ANY, LITEST_ANY, params);
litest_parameters_unref(params);
Currently supported are u (uint32), i (int32), d (double), b (bool),
c (char) and s (string).
In the test itself, the `test_env->params` variable is available and
retrieval of the parameters works like this:
const char *axis;
uint32_t number;
bool enabled;
litest_test_param_fetch(test_env->params,
"axis", &axis,
"enabled", &enabled,
"number", &number,
NULL);
Note that since this is an effectively internal test-suite only
functionality we don't do type-checking here, it's assumed that if you
write the code to pass parameters into a test you remember the type
of said params when you write the test code.
Because we don't have hashmaps or anything useful other than lists the
implementation is a bit clunky: we copy the parameter into the test
during litest_add_*, permutate it for our test list which gives us yet
another linked list C struct, and finally copy the actual value into
the test and test environment as it's executed. Not pretty, but it
works.
A few tests are switched as simple demonstration. The name of the
test has the parameters with their names and values appended now, e.g.:
"pointer:pointer_scroll_wheel_hires_send_only_lores:ms-surface-cover:axis:ABS_X"
"pointer:pointer_motion_relative_min_decel:mouse-roccat:direction:NW"
Filtering by parameters can be done via globs of their string
representation:
libinput-test-suite --filter-params="axis:ABS_*,enabled:true,number:10*"
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1109>
2024-12-22 00:06:19 +10:00
|
|
|
" --filter-parameter=param1:glob,param2:glob,... \n"
|
|
|
|
|
" Glob(s) to filter on the given parameters in their string "
|
|
|
|
|
"representation.\n"
|
|
|
|
|
" Boolean parameters are filtered via 'true' and 'false'.\n"
|
2019-03-07 09:16:05 +10:00
|
|
|
" --verbose\n"
|
|
|
|
|
" Enable verbose output\n"
|
|
|
|
|
" --jobs 8\n"
|
2019-05-27 14:28:24 +10:00
|
|
|
" Number of parallel test suites to run (default: 8).\n"
|
|
|
|
|
" This overrides the LITEST_JOBS environment variable.\n"
|
2019-03-07 09:16:05 +10:00
|
|
|
" --list\n"
|
|
|
|
|
" List all tests\n"
|
|
|
|
|
"\n"
|
|
|
|
|
"See the libinput-test-suite(1) man page for details.\n",
|
|
|
|
|
program_invocation_short_name);
|
|
|
|
|
exit(c != 'h');
|
|
|
|
|
break;
|
2015-05-20 10:12:39 +10:00
|
|
|
case OPT_FILTER_TEST:
|
|
|
|
|
filter_test = optarg;
|
2016-08-01 14:03:33 +10:00
|
|
|
if (want_jobs == JOBS_DEFAULT)
|
|
|
|
|
want_jobs = JOBS_SINGLE;
|
2015-05-20 10:12:39 +10:00
|
|
|
break;
|
2015-05-20 10:49:13 +10:00
|
|
|
case OPT_FILTER_DEVICE:
|
|
|
|
|
filter_device = optarg;
|
2016-08-01 14:03:33 +10:00
|
|
|
if (want_jobs == JOBS_DEFAULT)
|
|
|
|
|
want_jobs = JOBS_SINGLE;
|
2015-05-20 10:49:13 +10:00
|
|
|
break;
|
2024-12-23 09:10:12 +10:00
|
|
|
case OPT_FILTER_DEVICELESS:
|
|
|
|
|
run_deviceless = true;
|
|
|
|
|
break;
|
2015-05-20 11:00:37 +10:00
|
|
|
case OPT_FILTER_GROUP:
|
|
|
|
|
filter_group = optarg;
|
|
|
|
|
break;
|
2024-10-17 09:04:36 +10:00
|
|
|
case OPT_FILTER_RANGEVAL:
|
|
|
|
|
filter_rangeval = atoi(optarg);
|
|
|
|
|
break;
|
test: implement support for parametrizing tests
litest supports ranged tests but they are not enough, doubly so with
tests where we want to parametrize across multiple options.
This patch adds support for just that, in clunky C style.
The typical invocation for a test is by giving the test parameter
a name, a number of values and then the values themselves:
struct litest_parameters *params = litest_parameters_new("axis", 's', 2, "ABS_X", "ABS_Y",
"enabled", 'b', '2', true, false,
"number", 'u', '2', 10, 11,
NULL);
litest_add_parametrized(sometest, LITEST_ANY, LITEST_ANY, params);
litest_parameters_unref(params);
Currently supported are u (uint32), i (int32), d (double), b (bool),
c (char) and s (string).
In the test itself, the `test_env->params` variable is available and
retrieval of the parameters works like this:
const char *axis;
uint32_t number;
bool enabled;
litest_test_param_fetch(test_env->params,
"axis", &axis,
"enabled", &enabled,
"number", &number,
NULL);
Note that since this is an effectively internal test-suite only
functionality we don't do type-checking here, it's assumed that if you
write the code to pass parameters into a test you remember the type
of said params when you write the test code.
Because we don't have hashmaps or anything useful other than lists the
implementation is a bit clunky: we copy the parameter into the test
during litest_add_*, permutate it for our test list which gives us yet
another linked list C struct, and finally copy the actual value into
the test and test environment as it's executed. Not pretty, but it
works.
A few tests are switched as simple demonstration. The name of the
test has the parameters with their names and values appended now, e.g.:
"pointer:pointer_scroll_wheel_hires_send_only_lores:ms-surface-cover:axis:ABS_X"
"pointer:pointer_motion_relative_min_decel:mouse-roccat:direction:NW"
Filtering by parameters can be done via globs of their string
representation:
libinput-test-suite --filter-params="axis:ABS_*,enabled:true,number:10*"
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1109>
2024-12-22 00:06:19 +10:00
|
|
|
case OPT_FILTER_PARAMETER: {
|
|
|
|
|
size_t nelems;
|
2025-04-07 10:53:12 +10:00
|
|
|
_autostrvfree_ char **params =
|
|
|
|
|
strv_from_string(optarg, ",", &nelems);
|
test: implement support for parametrizing tests
litest supports ranged tests but they are not enough, doubly so with
tests where we want to parametrize across multiple options.
This patch adds support for just that, in clunky C style.
The typical invocation for a test is by giving the test parameter
a name, a number of values and then the values themselves:
struct litest_parameters *params = litest_parameters_new("axis", 's', 2, "ABS_X", "ABS_Y",
"enabled", 'b', '2', true, false,
"number", 'u', '2', 10, 11,
NULL);
litest_add_parametrized(sometest, LITEST_ANY, LITEST_ANY, params);
litest_parameters_unref(params);
Currently supported are u (uint32), i (int32), d (double), b (bool),
c (char) and s (string).
In the test itself, the `test_env->params` variable is available and
retrieval of the parameters works like this:
const char *axis;
uint32_t number;
bool enabled;
litest_test_param_fetch(test_env->params,
"axis", &axis,
"enabled", &enabled,
"number", &number,
NULL);
Note that since this is an effectively internal test-suite only
functionality we don't do type-checking here, it's assumed that if you
write the code to pass parameters into a test you remember the type
of said params when you write the test code.
Because we don't have hashmaps or anything useful other than lists the
implementation is a bit clunky: we copy the parameter into the test
during litest_add_*, permutate it for our test list which gives us yet
another linked list C struct, and finally copy the actual value into
the test and test environment as it's executed. Not pretty, but it
works.
A few tests are switched as simple demonstration. The name of the
test has the parameters with their names and values appended now, e.g.:
"pointer:pointer_scroll_wheel_hires_send_only_lores:ms-surface-cover:axis:ABS_X"
"pointer:pointer_motion_relative_min_decel:mouse-roccat:direction:NW"
Filtering by parameters can be done via globs of their string
representation:
libinput-test-suite --filter-params="axis:ABS_*,enabled:true,number:10*"
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1109>
2024-12-22 00:06:19 +10:00
|
|
|
const size_t max_filters = ARRAY_LENGTH(filter_params) - 1;
|
|
|
|
|
if (nelems >= max_filters) {
|
|
|
|
|
fprintf(stderr,
|
|
|
|
|
"Only %zd parameter filters are supported\n",
|
|
|
|
|
max_filters);
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
for (size_t i = 0; i < nelems; i++) {
|
|
|
|
|
size_t n;
|
2025-04-07 10:53:12 +10:00
|
|
|
_autostrvfree_ char **strv =
|
|
|
|
|
strv_from_string(params[i], ":", &n);
|
test: implement support for parametrizing tests
litest supports ranged tests but they are not enough, doubly so with
tests where we want to parametrize across multiple options.
This patch adds support for just that, in clunky C style.
The typical invocation for a test is by giving the test parameter
a name, a number of values and then the values themselves:
struct litest_parameters *params = litest_parameters_new("axis", 's', 2, "ABS_X", "ABS_Y",
"enabled", 'b', '2', true, false,
"number", 'u', '2', 10, 11,
NULL);
litest_add_parametrized(sometest, LITEST_ANY, LITEST_ANY, params);
litest_parameters_unref(params);
Currently supported are u (uint32), i (int32), d (double), b (bool),
c (char) and s (string).
In the test itself, the `test_env->params` variable is available and
retrieval of the parameters works like this:
const char *axis;
uint32_t number;
bool enabled;
litest_test_param_fetch(test_env->params,
"axis", &axis,
"enabled", &enabled,
"number", &number,
NULL);
Note that since this is an effectively internal test-suite only
functionality we don't do type-checking here, it's assumed that if you
write the code to pass parameters into a test you remember the type
of said params when you write the test code.
Because we don't have hashmaps or anything useful other than lists the
implementation is a bit clunky: we copy the parameter into the test
during litest_add_*, permutate it for our test list which gives us yet
another linked list C struct, and finally copy the actual value into
the test and test environment as it's executed. Not pretty, but it
works.
A few tests are switched as simple demonstration. The name of the
test has the parameters with their names and values appended now, e.g.:
"pointer:pointer_scroll_wheel_hires_send_only_lores:ms-surface-cover:axis:ABS_X"
"pointer:pointer_motion_relative_min_decel:mouse-roccat:direction:NW"
Filtering by parameters can be done via globs of their string
representation:
libinput-test-suite --filter-params="axis:ABS_*,enabled:true,number:10*"
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1109>
2024-12-22 00:06:19 +10:00
|
|
|
assert(n == 2);
|
|
|
|
|
|
|
|
|
|
const char *name = strv[0];
|
|
|
|
|
const char *glob = strv[1];
|
|
|
|
|
|
|
|
|
|
struct param_filter *f = &filter_params[i];
|
|
|
|
|
snprintf(f->name, sizeof(f->name), "%s", name);
|
|
|
|
|
snprintf(f->glob, sizeof(f->glob), "%s", glob);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
2016-07-22 15:19:23 +10:00
|
|
|
case 'j':
|
|
|
|
|
case OPT_JOBS:
|
|
|
|
|
jobs = atoi(optarg);
|
2016-08-01 14:03:33 +10:00
|
|
|
want_jobs = JOBS_CUSTOM;
|
2016-07-22 15:19:23 +10:00
|
|
|
break;
|
2015-05-20 10:12:39 +10:00
|
|
|
case OPT_LIST:
|
2015-05-25 08:56:53 +10:00
|
|
|
return LITEST_MODE_LIST;
|
2015-05-20 10:12:39 +10:00
|
|
|
case OPT_VERBOSE:
|
2018-08-10 11:32:31 +10:00
|
|
|
verbose = true;
|
2018-08-10 11:39:04 +10:00
|
|
|
break;
|
2024-10-21 12:12:45 +10:00
|
|
|
case OPT_OUTPUT_FILE:
|
|
|
|
|
outfile = fopen(optarg, "w+");
|
|
|
|
|
if (!outfile) {
|
|
|
|
|
fprintf(stderr, "Failed to open %s: %m\n", optarg);
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2024-10-15 15:28:56 +10:00
|
|
|
case 'x':
|
|
|
|
|
case OPT_EXIT_FIRST:
|
|
|
|
|
exit_first = true;
|
|
|
|
|
break;
|
2015-05-20 09:46:54 +10:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-27 18:41:57 +10:00
|
|
|
switch (want_jobs) {
|
|
|
|
|
case JOBS_SINGLE:
|
2016-08-01 14:03:33 +10:00
|
|
|
jobs = 1;
|
2025-06-27 18:41:57 +10:00
|
|
|
break;
|
|
|
|
|
case JOBS_NONE:
|
|
|
|
|
jobs = 0;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
2016-08-01 14:03:33 +10:00
|
|
|
|
2025-04-03 12:15:43 +10:00
|
|
|
*njobs_out = jobs;
|
2018-03-21 12:54:10 +10:00
|
|
|
|
2025-04-03 12:15:43 +10:00
|
|
|
return LITEST_MODE_TEST;
|
2015-05-20 09:36:01 +10:00
|
|
|
}
|