Message ID | 20241125-input_refactoring-v1-3-b622b3aa698d@suse.com |
---|---|
State | Superseded |
Headers | show |
Series | Rewrite input testing suite | expand |
On Mon, Nov 25, 2024 at 8:19 PM Andrea Cervesato <andrea.cervesato@suse.de> wrote: > From: Andrea Cervesato <andrea.cervesato@suse.com> > > Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com> > --- > testcases/kernel/input/Makefile | 4 +- > testcases/kernel/input/input03.c | 174 > +++++++++++++++------------------------ > 2 files changed, 70 insertions(+), 108 deletions(-) > > diff --git a/testcases/kernel/input/Makefile > b/testcases/kernel/input/Makefile > index > 5bc729802d1e302d7d52d71be0b6b22a20efb852..8c302dbc8c75cf4fd42bc162b4bb8a9882237164 > 100644 > --- a/testcases/kernel/input/Makefile > +++ b/testcases/kernel/input/Makefile > @@ -8,8 +8,8 @@ LTPLIBS = uinput > include $(top_srcdir)/include/mk/testcases.mk > > FILTER_OUT_MAKE_TARGETS := input_helper > -input01 input02: LDLIBS += -lltpuinput > +input01 input02 input03: LDLIBS += -lltpuinput > > include $(top_srcdir)/include/mk/generic_leaf_target.mk > > -input03 input04 input05 input06: %: input_helper.o > +input04 input05 input06: %: input_helper.o > diff --git a/testcases/kernel/input/input03.c > b/testcases/kernel/input/input03.c > index > 6cd753d0b1bf98ce671dfa739cde817b4c52c547..f66a5b1e504ca63a032ec9b49b5ab1e69a4bc2ce > 100644 > --- a/testcases/kernel/input/input03.c > +++ b/testcases/kernel/input/input03.c > @@ -1,145 +1,107 @@ > +// SPDX-License-Identifier: GPL-2.0-or-later > /* > * Copyright (c) 2015 Cedric Hnyda <chnyda@suse.com> > - * > - * This program is free software; you can redistribute it and/or > - * modify it under the terms of the GNU General Public License as > - * published by the Free Software Foundation; either version 2 of > - * the License, or (at your option) any later version. > - * > - * This program is distributed in the hope that it would be useful, > - * but WITHOUT ANY WARRANTY; without even the implied warranty of > - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > - * GNU General Public License for more details. > - * > - * You should have received a copy of the GNU General Public License > - * along with this program; if not, write the Free Software Foundation, > - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA > + * Copyright (C) 2024 SUSE LLC Andrea Cervesato < > andrea.cervesato@suse.com> > */ > > - /* > - * Create a virtual device (mouse), send events to /dev/uinput > - * and check that the events are well received in /dev/input/mice > - */ > +/*\ > + * [Description] > + * > + * Verify that /dev/input/mice receive events sent from a virtual device, > + * that in our case is a mouse. The events are a sequence of mouse right > click. > + */ > > -#include <linux/input.h> > #include <linux/uinput.h> > > -#include "test.h" > -#include "safe_macros.h" > -#include "lapi/fcntl.h" > -#include "input_helper.h" > +#include "input_common.h" > > -#define NB_TEST 10 > +#define NUM_EVENTS 10 > #define PS2_RIGHT_BTN 0x02 > +#define MOUSE_DEV "/dev/input/mice" > > -static void setup(void); > -static void send_events(void); > -static int check_events(void); > -static void cleanup(void); > +static int fd_send = -1; > +static int fd_recv = -1; > > -static int fd, fd2; > - > -char *TCID = "input03"; > - > -int main(int ac, char **av) > +static void recv_data(void) > { > - int lc; > - int pid; > - > - tst_parse_opts(ac, av, NULL, NULL); > - > - setup(); > - > - for (lc = 0; TEST_LOOPING(lc); ++lc) { > - pid = tst_fork(); > - > - switch (pid) { > - case 0: > - send_events(); > - exit(0); > - case -1: > - tst_brkm(TBROK | TERRNO, cleanup, "fork() failed"); > - default: > - if (check_events()) > - tst_resm(TFAIL, "Wrong data received"); > - else > - tst_resm(TPASS, > - "Data received in > /dev/input/mice"); > - break; > - } > - > - SAFE_WAITPID(NULL, pid, NULL, 0); > - } > + tst_res(TINFO, "Reading events back"); > > - cleanup(); > - tst_exit(); > -} > + char buf[30]; > + int events = 0; > + int pressed = 0; > + int num_bytes = 0; > > -static void setup(void) > -{ > - tst_require_root(); > + while (events < NUM_EVENTS) { > + memset(buf, 0, sizeof(buf)); > > - fd = open_uinput(); > + num_bytes = SAFE_READ(0, fd_recv, buf, sizeof(buf)); > > - setup_mouse_events(fd); > - SAFE_IOCTL(NULL, fd, UI_SET_EVBIT, EV_KEY); > - SAFE_IOCTL(NULL, fd, UI_SET_KEYBIT, BTN_RIGHT); > + for (int i = 0; i < num_bytes / 3; i++) { > + if (buf[3*i] & PS2_RIGHT_BTN) > + pressed = 1; > > - create_device(fd); > + if (pressed == 1 && !(buf[3*i] & PS2_RIGHT_BTN)) { > + pressed = 0; > + events++; > + } > + } > + } > > - fd2 = SAFE_OPEN(NULL, "/dev/input/mice", O_RDONLY); > + TST_EXP_EQ_LI(events, NUM_EVENTS); > } > > -static void send_events(void) > +static void send_mouse_events(void) > { > - int nb; > + tst_res(TINFO, "Sending right click"); > > - for (nb = 0; nb < NB_TEST; ++nb) { > - send_event(fd, EV_KEY, BTN_RIGHT, 1); > - send_event(fd, EV_SYN, 0, 0); > + for (int i = 0; i < NUM_EVENTS; i++) { > + send_event(fd_send, EV_KEY, BTN_RIGHT, 1); > + send_event(fd_send, EV_SYN, 0, 0); > usleep(1000); > - send_event(fd, EV_KEY, BTN_RIGHT, 0); > - send_event(fd, EV_SYN, 0, 0); > + > + send_event(fd_send, EV_KEY, BTN_RIGHT, 0); > + send_event(fd_send, EV_SYN, 0, 0); > usleep(1000); > } > } > > -static int check_events(void) > +static void run(void) > { > - int nb, rd, i, pressed = 0; > - char buf[30]; > + if (!SAFE_FORK()) { > + send_mouse_events(); > + exit(0); > + } > > - nb = 0; > + recv_data(); > We have to make sure recv_data() is performed first then sending mouse events, Otherwise, it will be more easily stuck here forever. --- a/testcases/kernel/input/input03.c +++ b/testcases/kernel/input/input03.c @@ -31,6 +31,8 @@ static void recv_data(void) int pressed = 0; int num_bytes = 0; + TST_CHECKPOINT_WAKE(0); + while (events < NUM_EVENTS) { memset(buf, 0, sizeof(buf)); @@ -54,6 +56,8 @@ static void send_mouse_events(void) { tst_res(TINFO, "Sending right click"); + TST_CHECKPOINT_WAIT(0); + for (int i = 0; i < NUM_EVENTS; i++) { send_event(fd_send, EV_KEY, BTN_RIGHT, 1); send_event(fd_send, EV_SYN, 0, 0); @@ -103,5 +107,6 @@ static struct tst_test test = { .cleanup = cleanup, .forks_child = 1, .needs_root = 1, + .needs_checkpoints = 1, }; The reset looks good. Reviewed-by: Li Wang <liwang@redhat.com>
diff --git a/testcases/kernel/input/Makefile b/testcases/kernel/input/Makefile index 5bc729802d1e302d7d52d71be0b6b22a20efb852..8c302dbc8c75cf4fd42bc162b4bb8a9882237164 100644 --- a/testcases/kernel/input/Makefile +++ b/testcases/kernel/input/Makefile @@ -8,8 +8,8 @@ LTPLIBS = uinput include $(top_srcdir)/include/mk/testcases.mk FILTER_OUT_MAKE_TARGETS := input_helper -input01 input02: LDLIBS += -lltpuinput +input01 input02 input03: LDLIBS += -lltpuinput include $(top_srcdir)/include/mk/generic_leaf_target.mk -input03 input04 input05 input06: %: input_helper.o +input04 input05 input06: %: input_helper.o diff --git a/testcases/kernel/input/input03.c b/testcases/kernel/input/input03.c index 6cd753d0b1bf98ce671dfa739cde817b4c52c547..f66a5b1e504ca63a032ec9b49b5ab1e69a4bc2ce 100644 --- a/testcases/kernel/input/input03.c +++ b/testcases/kernel/input/input03.c @@ -1,145 +1,107 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (c) 2015 Cedric Hnyda <chnyda@suse.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Copyright (C) 2024 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com> */ - /* - * Create a virtual device (mouse), send events to /dev/uinput - * and check that the events are well received in /dev/input/mice - */ +/*\ + * [Description] + * + * Verify that /dev/input/mice receive events sent from a virtual device, + * that in our case is a mouse. The events are a sequence of mouse right click. + */ -#include <linux/input.h> #include <linux/uinput.h> -#include "test.h" -#include "safe_macros.h" -#include "lapi/fcntl.h" -#include "input_helper.h" +#include "input_common.h" -#define NB_TEST 10 +#define NUM_EVENTS 10 #define PS2_RIGHT_BTN 0x02 +#define MOUSE_DEV "/dev/input/mice" -static void setup(void); -static void send_events(void); -static int check_events(void); -static void cleanup(void); +static int fd_send = -1; +static int fd_recv = -1; -static int fd, fd2; - -char *TCID = "input03"; - -int main(int ac, char **av) +static void recv_data(void) { - int lc; - int pid; - - tst_parse_opts(ac, av, NULL, NULL); - - setup(); - - for (lc = 0; TEST_LOOPING(lc); ++lc) { - pid = tst_fork(); - - switch (pid) { - case 0: - send_events(); - exit(0); - case -1: - tst_brkm(TBROK | TERRNO, cleanup, "fork() failed"); - default: - if (check_events()) - tst_resm(TFAIL, "Wrong data received"); - else - tst_resm(TPASS, - "Data received in /dev/input/mice"); - break; - } - - SAFE_WAITPID(NULL, pid, NULL, 0); - } + tst_res(TINFO, "Reading events back"); - cleanup(); - tst_exit(); -} + char buf[30]; + int events = 0; + int pressed = 0; + int num_bytes = 0; -static void setup(void) -{ - tst_require_root(); + while (events < NUM_EVENTS) { + memset(buf, 0, sizeof(buf)); - fd = open_uinput(); + num_bytes = SAFE_READ(0, fd_recv, buf, sizeof(buf)); - setup_mouse_events(fd); - SAFE_IOCTL(NULL, fd, UI_SET_EVBIT, EV_KEY); - SAFE_IOCTL(NULL, fd, UI_SET_KEYBIT, BTN_RIGHT); + for (int i = 0; i < num_bytes / 3; i++) { + if (buf[3*i] & PS2_RIGHT_BTN) + pressed = 1; - create_device(fd); + if (pressed == 1 && !(buf[3*i] & PS2_RIGHT_BTN)) { + pressed = 0; + events++; + } + } + } - fd2 = SAFE_OPEN(NULL, "/dev/input/mice", O_RDONLY); + TST_EXP_EQ_LI(events, NUM_EVENTS); } -static void send_events(void) +static void send_mouse_events(void) { - int nb; + tst_res(TINFO, "Sending right click"); - for (nb = 0; nb < NB_TEST; ++nb) { - send_event(fd, EV_KEY, BTN_RIGHT, 1); - send_event(fd, EV_SYN, 0, 0); + for (int i = 0; i < NUM_EVENTS; i++) { + send_event(fd_send, EV_KEY, BTN_RIGHT, 1); + send_event(fd_send, EV_SYN, 0, 0); usleep(1000); - send_event(fd, EV_KEY, BTN_RIGHT, 0); - send_event(fd, EV_SYN, 0, 0); + + send_event(fd_send, EV_KEY, BTN_RIGHT, 0); + send_event(fd_send, EV_SYN, 0, 0); usleep(1000); } } -static int check_events(void) +static void run(void) { - int nb, rd, i, pressed = 0; - char buf[30]; + if (!SAFE_FORK()) { + send_mouse_events(); + exit(0); + } - nb = 0; + recv_data(); +} - while (nb < NB_TEST) { - rd = read(fd2, buf, sizeof(buf)); +static void setup(void) +{ + fd_send = open_uinput(); - if (rd < 0) - tst_brkm(TBROK | TERRNO, NULL, "read() failed"); + setup_mouse_events(fd_send); + SAFE_IOCTL(fd_send, UI_SET_EVBIT, EV_KEY); + SAFE_IOCTL(fd_send, UI_SET_KEYBIT, BTN_RIGHT); - if (rd % 3) { - tst_resm(TINFO, "read() returned %i", rd); - return 1; - } + create_input_device(fd_send); - for (i = 0; i < rd / 3; i++) { - if (buf[3*i] & PS2_RIGHT_BTN) - pressed = 1; - - if (pressed == 1 && !(buf[3*i] & PS2_RIGHT_BTN)) { - pressed = 0; - nb++; - } - } - } - - return nb != NB_TEST; + fd_recv = SAFE_OPEN(MOUSE_DEV, O_RDONLY); } static void cleanup(void) { - if (fd2 > 0 && close(fd2)) - tst_resm(TWARN, "close(fd2) failed"); + if (fd_send != -1) + destroy_input_device(fd_send); - destroy_device(fd); + if (fd_recv != -1) + SAFE_CLOSE(fd_recv); } + +static struct tst_test test = { + .test_all = run, + .setup = setup, + .cleanup = cleanup, + .forks_child = 1, + .needs_root = 1, +}; +