kernel/input: add tests
PATCH 1/1 kernel/input: add tests
Add testcases to test the kernel input stack
1) Create a virtual mouse and write in /dev/uinput and check that the data is well received in /dev/input/eventX
2) Create a virtual mouse, write in /dev/uinput, grab the device and check that the data are not received in other proccess.
3) Create a virtual mouse and check that the data are well received in /dev/input/mice
4) Create a virtual mouse and send empty moves: check that nothing is received in /dev/input/mice
5) Create a virtual mouse and send events which cannot be sent and check that they are not received in eventX
--- runtest/input | 5 + testcases/kernel/Makefile | 1 + testcases/kernel/input/.gitignore | 5 + testcases/kernel/input/Makefile | 27 +++++ testcases/kernel/input/input01.c | 201 ++++++++++++++++++++++++++++++++++ testcases/kernel/input/input02.c | 166 ++++++++++++++++++++++++++++ testcases/kernel/input/input03.c | 186 +++++++++++++++++++++++++++++++ testcases/kernel/input/input04.c | 179 ++++++++++++++++++++++++++++++ testcases/kernel/input/input05.c | 174 +++++++++++++++++++++++++++++ testcases/kernel/input/input_helper.c | 91 +++++++++++++++ testcases/kernel/input/input_helper.h | 30 +++++ 11 files changed, 1065 insertions(+) create mode 100644 runtest/input create mode 100644 testcases/kernel/input/.gitignore create mode 100644 testcases/kernel/input/Makefile create mode 100644 testcases/kernel/input/input01.c create mode 100644 testcases/kernel/input/input02.c create mode 100644 testcases/kernel/input/input03.c create mode 100644 testcases/kernel/input/input04.c create mode 100644 testcases/kernel/input/input05.c create mode 100644 testcases/kernel/input/input_helper.c create mode 100644 testcases/kernel/input/input_helper.h
runtest/input new file +5 -0
@@ -0,0 +1,5 @@ +input01 input01 +input02 input02 +input03 input03 +input04 input04 +input05 input05
testcases/kernel/Makefile +1 -0
@@ -42,6 +42,7 @@ SUBDIRS += connectors \ firmware \ fs \ hotplug \ + input \ io \ ipc \ logging \
testcases/kernel/input/.gitignore new file +5 -0
@@ -0,0 +1,5 @@ +/input01 +/input02 +/input03 +/input04 +/input05
testcases/kernel/input/Makefile new file +27 -0
@@ -0,0 +1,27 @@ +# +# Copyright (c) SUSE 2015 +# +# 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 will 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 to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# + +top_srcdir ?= ../../.. + +include $(top_srcdir)/include/mk/testcases.mk + +FILTER_OUT_MAKE_TARGETS := input_helper + +include $(top_srcdir)/include/mk/generic_leaf_target.mk + +$(MAKE_TARGETS): %: %.o input_helper.o
testcases/kernel/input/input01.c new file +201 -0
201 lines not on this page · raw message
testcases/kernel/input/input02.c new file +166 -0
166 lines not on this page · raw message
testcases/kernel/input/input03.c new file +186 -0
186 lines not on this page · raw message
testcases/kernel/input/input04.c new file +179 -0
179 lines not on this page · raw message
testcases/kernel/input/input05.c new file +174 -0
174 lines not on this page · raw message
testcases/kernel/input/input_helper.c new file +91 -0
91 lines not on this page · raw message
testcases/kernel/input/input_helper.h new file +30 -0
@@ -0,0 +1,30 @@ +/* +* Copyright (c) 2015 Cedric Hnyda <[email protected]> +* +* 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 +*/ + +#ifndef INPUT_HELPER_H +#define INPUT_HELPER_H + +#define VIRTUAL_DEVICE "virtual-device-ltp" + +#include <sys/types.h> +#include <dirent.h> + +char *find_event (DIR *d,char *namedir1); +int setup_read (void ); + +#endif /* INPUT_HELPER_H */
Signature · 1 line
2.1.4
PATCH 1/1 kernel/input: add tests
Hi!
runtest/input line 5
Quoted 8 lines
runtest/input new file +5
-0@@ -0,0 +1,5 @@ +input01 input01 +input02 input02 +input03 input03 +input04 input04 +input05 input05
If you create a new runtest file you should also add it to default scenario (scenario_groups/default) so it's actually executed by default.
Quoted 17 lines
testcases/kernel/input/input01.c new file +11
-0@@ -0,0 +1,201 @@ +/* +* Copyright (c) 2015 Cedric Hnyda <[email protected]> +* +* 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
testcases/kernel/input/input01.c line 21
Quoted 10 lines
testcases/kernel/input/input01.c new file +10
-0+* 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 +*/ + +/* +* AUTHOR : Cedric Hnyda +* DATE STARTED : 10/21/2015
Is this really necessary? The Copyright line at the top of the file gives nearly the same information...
Quoted 16 lines
testcases/kernel/input/input01.c new file +16
-0+* Create a virtual device (mouse), send events to /dev/uinput +* and check that the events are well received in /dev/input/eventX +* +*/ + +#include <linux/input.h> +#include <linux/uinput.h> +#include <fnmatch.h> + +#include "input_helper.h" +#include "test.h" +#include "safe_macros.h" +#include "lapi/fcntl.h" + +#define NB_TEST 100 +
testcases/kernel/input/input01.c line 48
Quoted 10 lines
testcases/kernel/input/input01.c new file +10
-0+static void setup (void ); +static void send_information (void ); +static int verify_data (struct input_event iev,int *nb); +static int check_information (void ); +static void cleanup (void ); + +static int fd; +static int fd2; + +char *TCID ="uinput01" ;
^
This should be input01 to match the source file name
Quoted 12 lines
testcases/kernel/input/input01.c new file +12
-0+int main (int ac,char **av) +{ +int lc; +int pid; + +tst_parse_opts (ac, av,NULL ,NULL ); + +for (lc =0 ; lc <TEST_LOOPING (lc); ++lc) { + +setup (); + pid =tst_fork (); +
testcases/kernel/input/input01.c line 71
Quoted 10 lines
testcases/kernel/input/input01.c new file +10
-0+if (!pid) +send_information (); +else { + fd2 =setup_read (); +if (check_information ()) +tst_resm (TFAIL , +"Wrong data received in eventX" ); +else +tst_resm (TPASS ,"Data received in eventX" ); + }
LKML coding style, that is used by LTP prefers curly braces around both code block if they are necessary for one of them. But this is minor.
Quoted 6 lines
testcases/kernel/input/input01.c new file +6
-0+ } +tst_exit (); +} + +static void setup (void ) +{
testcases/kernel/input/input01.c line 87
Quoted 10 lines
testcases/kernel/input/input01.c new file +10
-0+struct uinput_user_dev uidev; + +tst_require_root (); + + fd =open ("/dev/input/uinput" ,O_WRONLY |O_NONBLOCK ); + +if (fd <0 && errno ==ENOENT ) + fd =open ("/dev/uinput" ,O_WRONLY |O_NONBLOCK ); + +if (fd <0 )
^ Eh, did you forget && errno == ENOENT here?
Quoted 5 lines
testcases/kernel/input/input01.c new file +5
-0+tst_brkm (TCONF ,NULL ,"unable to find and open uinput" ); + else if (fd < 0) + tst_brkm(TBROK, NULL, "open failed"); + + if (ioctl(fd, UI_SET_EVBIT, EV_KEY) < 0)
testcases/kernel/input/input01.c line 102
Quoted 10 lines
testcases/kernel/input/input01.c new file +10
-0+tst_brkm (TBROK ,NULL ,"ioctl failed" ); +if (ioctl (fd,UI_SET_KEYBIT ,BTN_LEFT ) <0 ) +tst_brkm (TBROK ,NULL ,"ioctl failed" ); + +if (ioctl (fd,UI_SET_EVBIT ,EV_REL ) <0 ) +tst_brkm (TBROK ,NULL ,"ioctl failed" ); +if (ioctl (fd,UI_SET_RELBIT ,REL_X ) <0 ) +tst_brkm (TBROK ,NULL ,"ioctl failed" ); +if (ioctl (fd,UI_SET_RELBIT ,REL_Y ) <0 ) +tst_brkm (TBROK ,NULL ,"ioctl failed" );
I guess that it's time to add SAFE_IOCTL(). I will add it to LTP tree so that you can use it in the testcases.
testcases/kernel/input/input01.c line 112
Quoted 9 lines
testcases/kernel/input/input01.c new file +9
-0+memset (&uidev,0 ,sizeof (uidev)); +snprintf (uidev.name,UINPUT_MAX_NAME_SIZE ,VIRTUAL_DEVICE ); + uidev.id.bustype =BUS_USB ; + uidev.id.vendor =0x1 ; + uidev.id.product =0x1 ; + uidev.id.version =1 ; + +if (write (fd, &uidev,sizeof (uidev)) <0 ) +tst_brkm (TBROK ,NULL ,"ioctl failed" );
We have SAFE_WRITE() allready. ;)
testcases/kernel/input/input01.c line 116
Quoted 3 lines
testcases/kernel/input/input01.c new file +3
-0+if (ioctl (fd,UI_DEV_CREATE ) <0 ) +tst_brkm (TBROK ,NULL ,"ioctl failed" ); +sleep (1 );
What do we wait here for? Using sleep() in testcases is frowned upon unless there is real need for it. I guess that we wait for the device to appear right? If that is the case we should loop here with a 0.1s sleep and exit the loop once the device was created.
testcases/kernel/input/input01.c line 124
Quoted 8 lines
testcases/kernel/input/input01.c new file +8
-0+} + +static void send_information (void ) +{ +struct input_event ev; +int nb; + +sleep (1 );
Here as well.
testcases/kernel/input/input01.c line 133
Quoted 8 lines
testcases/kernel/input/input01.c new file +8
-0+for (nb =0 ; nb <NB_TEST ; ++nb) { + +memset (&ev,0 ,sizeof (struct input_event )); + ev.type =EV_REL ; + ev.code =REL_X ; + ev.value =10 ; +if (write (fd, &ev,sizeof (struct input_event )) <0 ) +tst_brkm (TBROK , cleanup,"write failed" );
SAFE_WRITE()
testcases/kernel/input/input01.c line 140
Quoted 6 lines
testcases/kernel/input/input01.c new file +6
-0+memset (&ev,0 ,sizeof (struct input_event )); + ev.type =EV_REL ; + ev.code =REL_Y ; + ev.value =1 ; +if (write (fd, &ev,sizeof (struct input_event )) <0 ) +tst_brkm (TBROK , cleanup,"write failed" );
Here as well.
testcases/kernel/input/input01.c line 147
Quoted 6 lines
testcases/kernel/input/input01.c new file +6
-0+memset (&ev,0 ,sizeof (struct input_event )); + ev.type =EV_SYN ; + ev.code =0 ; + ev.value =0 ; +if (write (fd, &ev,sizeof (struct input_event )) <0 ) +tst_brkm (TBROK , cleanup,"write failed" );
And here as well.
testcases/kernel/input/input01.c line 141
Quoted 1 line
testcases/kernel/input/input01.c new file +1
-0+usleep (100 );
We sleep here so that the kernel buffers are not filled up right? What happens when we overfill them? Does the write fail with EAGAIN?
Quoted 11 lines
testcases/kernel/input/input01.c new file +11
-0+ } + +cleanup (); +} + +static int check_information (void ) +{ +int nb; +int fail; +int rd; +uint i;
testcases/kernel/input/input01.c line 170
Quoted 10 lines
testcases/kernel/input/input01.c new file +10
-0+struct input_event iev[64 ]; + + fail =0 ; + nb =0 ; + +while (nb <NB_TEST *3 && !fail) { + rd =read (fd2, iev,sizeof (struct input_event ) *64 ); + +if (rd < (int )sizeof (struct input_event )) + fail =1 ;
What about if (rd < 0) and if (rd % sizeof(struct input_event) == 0), since the read size should be multiple of the input_event structure size.
testcases/kernel/input/input01.c line 180
Quoted 9 lines
testcases/kernel/input/input01.c new file +9
-0+for (i =0 ; i < rd /sizeof (struct input_event ) && !fail; i++) + fail =verify_data (iev[i], &nb); + } + +SAFE_CLOSE (NULL , fd2); +return fail; +} + +static int verify_data (struct input_event iev,int *nb)
^
It's more usuall to pass structure values by pointer in C. Sice if this function couldn't be inlined the whole structure would be compied on stack...
testcases/kernel/input/input01.c line 193
Quoted 13 lines
testcases/kernel/input/input01.c new file +13
-0+{ +if (iev.type ==EV_REL && *nb %3 ==0 + && iev.value ==10 && iev.code ==REL_X ) + (*nb)++; +else if (iev.type ==EV_REL && *nb %3 ==1 + && iev.value ==1 && iev.code ==REL_Y ) + (*nb)++; +else if (iev.type ==EV_SYN && *nb %3 ==2 + && iev.code ==0 ) + (*nb)++; +else +return 1 ; +return 0 ;
Eh, what about adding more returns to make it more readable and also being more verbose about what happened?
if (*nb % 3 == 0) {
if (iev->type != EV_REL) {
tst_resm(TINFO, "%i: Unexpected event type %i expected %i",
*nb, ev->type, EV_REL);
return 1;
}
if (iev->code != REL_X) {
...
}
if (iev->value != 10) {
...
}
return 0;
}
if (*nb % 3 == 1) {
if ( ...
....
}
...Quoted 93 lines
testcases/kernel/input/input01.c new file +8
-0+} + +static void cleanup (void ) +{ +if (ioctl (fd,UI_DEV_DESTROY ) <0 ) +tst_brkm (TBROK ,NULL ,"ioctl failed" ); +SAFE_CLOSE (NULL , fd); +}testcases/kernel/input/input02.c new file +79
-0@@ -0,0 +1,166 @@ +/* +* Copyright (c) 2015 Cedric Hnyda <[email protected]> +* +* 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 +*/ + +/* +* AUTHOR : Cedric Hnyda +* DATE STARTED : 10/21/2015 +* +* Create a virtual device (mouse), send events to /dev/uinput +* and check that the events are not received in /dev/input/eventX +* because the device is grabbed by another process +* +*/ + +#include <linux/input.h> +#include <linux/uinput.h> +#include <fnmatch.h> + +#include "test.h" +#include "safe_macros.h" +#include "lapi/fcntl.h" +#include "input_helper.h" + +#define NB_TEST 100 + +static void setup (void ); +static void send_information (void ); +static int check_information (void ); +static void cleanup (void ); + +static int fd; +static int fd2; + +char *TCID ="uinput02" ; + +int main (int ac,char **av) +{ +int lc; +int pid; + +tst_parse_opts (ac, av,NULL ,NULL ); + +for (lc =0 ; lc <TEST_LOOPING (lc); ++lc) { + +setup (); + pid =tst_fork (); + fd2 =setup_read (); + +if (!pid) +send_information (); +else { +if (check_information ()) +tst_resm (TFAIL ,"Data received in eventX" ); +else +tst_resm (TPASS ,"No data received in eventX" ); + } + } +tst_exit (); +} + +static void setup (void ) +{ +struct uinput_user_dev uidev; + +tst_require_root ();
testcases/kernel/input/input02.c line 89
Quoted 10 lines
testcases/kernel/input/input02.c new file +10
-0+ + fd =open ("/dev/input/uinput" ,O_WRONLY |O_NONBLOCK ); + +if (fd <0 && errno ==ENOENT ) + fd =open ("/dev/uinput" ,O_WRONLY |O_NONBLOCK ); + +if (fd <0 ) +tst_brkm (TCONF ,NULL ,"unable to find and open uinput" ); +else if (fd <0 ) +tst_brkm (TBROK ,NULL ,"open failed" );
This exact code fragment is part of the input01.c setup. Can you please create open_uinput() function in the library instead of copy&pasting code?
Quoted 15 lines
testcases/kernel/input/input02.c new file +15
-0+if (ioctl (fd,UI_SET_EVBIT ,EV_KEY ) <0 ) +tst_brkm (TBROK ,NULL ,"ioctl failed" ); +if (ioctl (fd,UI_SET_KEYBIT ,BTN_LEFT ) <0 ) +tst_brkm (TBROK ,NULL ,"ioctl failed" ); + +if (ioctl (fd,UI_SET_EVBIT ,EV_REL ) <0 ) +tst_brkm (TBROK ,NULL ,"ioctl failed" ); +if (ioctl (fd,UI_SET_RELBIT ,REL_X ) <0 ) +tst_brkm (TBROK ,NULL ,"ioctl failed" ); +if (ioctl (fd,UI_SET_RELBIT ,REL_Y ) <0 ) +tst_brkm (TBROK ,NULL ,"ioctl failed" ); + +memset (&uidev,0 ,sizeof (uidev)); +snprintf (uidev.name,UINPUT_MAX_NAME_SIZE ,VIRTUAL_DEVICE ); + uidev.id.bustype =BUS_USB ;
testcases/kernel/input/input02.c line 114
Quoted 10 lines
testcases/kernel/input/input02.c new file +10
-0+ uidev.id.vendor =0x1 ; + uidev.id.product =0x1 ; + uidev.id.version =1 ; + +if (write (fd, &uidev,sizeof (uidev)) <0 ) +tst_brkm (TBROK ,NULL ,"ioctl failed" ); + +if (ioctl (fd,UI_DEV_CREATE ) <0 ) +tst_brkm (TBROK ,NULL ,"ioctl failed" ); +sleep (1 );
The same comments apply here as well.
Quoted 11 lines
testcases/kernel/input/input02.c new file +11
-0+} + +static void send_information (void ) +{ +int nb; +struct input_event ev; + +if (ioctl (fd2,EVIOCGRAB ,1 )) +tst_brkm (TBROK , cleanup,"ioctl failed" ); +tst_resm (TINFO ,"The virtual device was grabbed" ); +
testcases/kernel/input/input02.c line 136
Quoted 10 lines
testcases/kernel/input/input02.c new file +10
-0+sleep (1 ); + +for (nb =0 ; nb <NB_TEST ; ++nb) { +memset (&ev,0 ,sizeof (struct input_event )); + ev.type =EV_SYN ; + ev.code =0 ; + ev.value =0 ; +if (write (fd, &ev,sizeof (struct input_event )) <0 ) +tst_brkm (TBROK , cleanup,"write failed" ); +usleep (100 );
Hmm, are you sure that EV_SYN actually appear on the other end of the input stac even when no changes were done?
Quoted 116 lines
testcases/kernel/input/input02.c new file +30
-0+ } + +cleanup (); +} + +static int check_information (void ) +{ +int nb; +int rd; +struct input_event iev[64 ]; + + nb =0 ; + +while (nb ==0 ) { + rd =read (fd2, iev,sizeof (struct input_event ) *64 ); +if (rd ==0 ) +break ; + nb++; + } + +SAFE_CLOSE (NULL , fd2); +return nb ==0 ; +} + +static void cleanup (void ) +{ +if (ioctl (fd,UI_DEV_DESTROY ) <0 ) +tst_brkm (TBROK ,NULL ,"ioctl failed" ); +SAFE_CLOSE (NULL , fd); +}testcases/kernel/input/input03.c new file +80
-0@@ -0,0 +1,186 @@ +/* +* Copyright (c) 2015 Cedric Hnyda <[email protected]> +* +* 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 +*/ + +/* +* AUTHOR : Cedric Hnyda +* DATE STARTED : 10/21/2015 +* +* Create a virtual device (mouse), send events to /dev/uinput +* and check that the events are well received in /dev/input/mice +* +*/ + +#include <linux/input.h> +#include <linux/uinput.h> +#include <fnmatch.h> + +#include "test.h" +#include "safe_macros.h" +#include "lapi/fcntl.h" +#include "input_helper.h" + +#define NB_TEST 100 +#define X_VALUE 10 +#define Y_VALUE 10 + +static void setup (void ); +static void send_information (void ); +static int check_information (void ); +static void cleanup (void ); + +static int fd; +static int fd2; + +char *TCID ="uinput03" ; + +int main (int ac,char **av) +{ +int lc; +int pid; + +tst_parse_opts (ac, av,NULL ,NULL ); + +for (lc =0 ; lc <TEST_LOOPING (lc); ++lc) { + +setup (); + pid =tst_fork (); + +if (!pid) +send_information (); +else { +if (check_information ()) +tst_resm (TFAIL ,"Wrong data received" ); +else +tst_resm (TPASS , +"Data received in /dev/input/mice" ); + } + } +tst_exit (); +} + +static void setup (void ) +{ +struct uinput_user_dev uidev; + +tst_require_root ();
testcases/kernel/input/input03.c line 90
Quoted 10 lines
testcases/kernel/input/input03.c new file +10
-0+ + fd =open ("/dev/input/uinput" ,O_WRONLY |O_NONBLOCK ); + +if (fd <0 && errno ==ENOENT ) + fd =open ("/dev/uinput" ,O_WRONLY |O_NONBLOCK ); + +if (fd <0 ) +tst_brkm (TCONF ,NULL ,"unable to find and open uinput" ); +else if (fd <0 ) +tst_brkm (TBROK ,NULL ,"open failed" );
Here as well, fix the code and move it to the library.
Quoted 15 lines
testcases/kernel/input/input03.c new file +15
-0+if (ioctl (fd,UI_SET_EVBIT ,EV_KEY ) <0 ) +tst_brkm (TBROK ,NULL ,"ioctl failed" ); +if (ioctl (fd,UI_SET_KEYBIT ,BTN_LEFT ) <0 ) +tst_brkm (TBROK ,NULL ,"ioctl failed" ); + +if (ioctl (fd,UI_SET_EVBIT ,EV_REL ) <0 ) +tst_brkm (TBROK ,NULL ,"ioctl failed" ); +if (ioctl (fd,UI_SET_RELBIT ,REL_X ) <0 ) +tst_brkm (TBROK ,NULL ,"ioctl failed" ); +if (ioctl (fd,UI_SET_RELBIT ,REL_Y ) <0 ) +tst_brkm (TBROK ,NULL ,"ioctl failed" ); + +memset (&uidev,0 ,sizeof (uidev)); +snprintf (uidev.name,UINPUT_MAX_NAME_SIZE ,VIRTUAL_DEVICE ); + uidev.id.bustype =BUS_USB ;
testcases/kernel/input/input03.c line 115
Quoted 10 lines
testcases/kernel/input/input03.c new file +10
-0+ uidev.id.vendor =0x1 ; + uidev.id.product =0x1 ; + uidev.id.version =1 ; + +if (write (fd, &uidev,sizeof (uidev)) <0 ) +tst_brkm (TBROK ,NULL ,"ioctl failed" ); + +if (ioctl (fd,UI_DEV_CREATE ) <0 ) +tst_brkm (TBROK ,NULL ,"ioctl failed" ); +sleep (1 );
And here as well.
Quoted 26 lines
testcases/kernel/input/input03.c new file +26
-0+} + +static void send_information (void ) +{ +int nb; +struct input_event ev; + +sleep (1 ); + +for (nb =0 ; nb <NB_TEST ; ++nb) { + +memset (&ev,0 ,sizeof (struct input_event )); + ev.type =EV_REL ; + ev.code =REL_X ; + ev.value =X_VALUE ; +if (write (fd, &ev,sizeof (struct input_event )) <0 ) +tst_brkm (TBROK , cleanup,"write failed" ); + +memset (&ev,0 ,sizeof (struct input_event )); + ev.type =EV_REL ; + ev.code =REL_Y ; + ev.value =Y_VALUE ; +if (write (fd, &ev,sizeof (struct input_event )) <0 ) +tst_brkm (TBROK , cleanup,"write failed" ); + +memset (&ev,0 ,sizeof (struct input_event ));
testcases/kernel/input/input03.c line 152
Quoted 10 lines
testcases/kernel/input/input03.c new file +10
-0+ ev.type =EV_SYN ; + ev.code =0 ; + ev.value =0 ; +if (write (fd, &ev,sizeof (struct input_event )) <0 ) +tst_brkm (TBROK , cleanup,"write failed" ); +usleep (100 ); + + } + +cleanup ();
Eh, why do you call cleanup() here?
Also this function si nearly identical to the one in input01.c. What about adding send_rel_move(int fd, int x, int y) to the library that would actually write the events and calling it from the testcases?
Quoted 13 lines
testcases/kernel/input/input03.c new file +13
-0+} + +static int check_information (void ) +{ +int nb; +int fail; +int rd; +char buf[3 ]; + + fd2 =SAFE_OPEN (NULL ,"/dev/input/mice" ,O_RDONLY ); + fail =0 ; + nb =0 ; +
testcases/kernel/input/input03.c line 175
Quoted 10 lines
testcases/kernel/input/input03.c new file +10
-0+while (nb <NB_TEST && !fail) { +memset (buf,0 ,sizeof (char ) *3 ); + rd =read (fd2, buf,sizeof (char ) *3 ); + +if (rd < (int )sizeof (char ) *3 ) + fail =1 ; +if (buf[1 ] !=X_VALUE || buf[2 ] != -Y_VALUE || buf[0 ] !=40 ) + fail =1 ; + nb++; + }
The sizeof(char) == 1 by definition, remove it from the code.
Quoted 97 lines
testcases/kernel/input/input03.c new file +10
-0+SAFE_CLOSE (NULL , fd2); +return fail; +} + +static void cleanup (void ) +{ +if (ioctl (fd,UI_DEV_DESTROY ) <0 ) +tst_brkm (TBROK ,NULL ,"ioctl failed" ); +SAFE_CLOSE (NULL , fd); +}testcases/kernel/input/input04.c new file +81
-0@@ -0,0 +1,179 @@ +/* +* Copyright (c) 2015 Cedric Hnyda <[email protected]> +* +* 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 +*/ + +/* +* AUTHOR : Cedric Hnyda +* DATE STARTED : 11/13/2015 +* +* Create a virtual device (mouse), send empty events to /dev/uinput +* and check that the events are not received in /dev/input/mice +* +*/ + +#include <linux/input.h> +#include <linux/uinput.h> +#include <fnmatch.h> + +#include "test.h" +#include "safe_macros.h" +#include "lapi/fcntl.h" +#include "input_helper.h" + +#define NB_TEST 100 +#define X_VALUE 0 +#define Y_VALUE 0 + +static void setup (void ); +static void send_information (void ); +static int check_information (void ); +static void cleanup (void ); + +static int fd; +static int fd2; + +char *TCID ="uinput04" ; + +int main (int ac,char **av) +{ +int lc; +int pid; + +tst_parse_opts (ac, av,NULL ,NULL ); + +for (lc =0 ; lc <TEST_LOOPING (lc); ++lc) { + +setup (); + pid =tst_fork (); + +if (!pid) +send_information (); +else { +if (check_information ()) +tst_resm (TPASS , +"No data received in /dev/input/mice" ); +else +tst_resm (TFAIL , +"Data received /dev/input/mice" ); + } + } +tst_exit (); +} + +static void setup (void ) +{ +struct uinput_user_dev uidev; + +tst_require_root ();
testcases/kernel/input/input04.c line 91
Quoted 10 lines
testcases/kernel/input/input04.c new file +10
-0+ + fd =open ("/dev/input/uinput" ,O_WRONLY |O_NONBLOCK ); + +if (fd <0 && errno ==ENOENT ) + fd =open ("/dev/uinput" ,O_WRONLY |O_NONBLOCK ); + +if (fd <0 ) +tst_brkm (TCONF ,NULL ,"unable to find and open uinput" ); +else if (fd <0 ) +tst_brkm (TBROK ,NULL ,"open failed" );
Here as well. Move it to the library.
Quoted 15 lines
testcases/kernel/input/input04.c new file +15
-0+if (ioctl (fd,UI_SET_EVBIT ,EV_KEY ) <0 ) +tst_brkm (TBROK ,NULL ,"ioctl failed" ); +if (ioctl (fd,UI_SET_KEYBIT ,BTN_LEFT ) <0 ) +tst_brkm (TBROK ,NULL ,"ioctl failed" ); + +if (ioctl (fd,UI_SET_EVBIT ,EV_REL ) <0 ) +tst_brkm (TBROK ,NULL ,"ioctl failed" ); +if (ioctl (fd,UI_SET_RELBIT ,REL_X ) <0 ) +tst_brkm (TBROK ,NULL ,"ioctl failed" ); +if (ioctl (fd,UI_SET_RELBIT ,REL_Y ) <0 ) +tst_brkm (TBROK ,NULL ,"ioctl failed" ); + +memset (&uidev,0 ,sizeof (uidev)); +snprintf (uidev.name,UINPUT_MAX_NAME_SIZE ,VIRTUAL_DEVICE ); + uidev.id.bustype =BUS_USB ;
testcases/kernel/input/input04.c line 116
Quoted 10 lines
testcases/kernel/input/input04.c new file +10
-0+ uidev.id.vendor =0x1 ; + uidev.id.product =0x1 ; + uidev.id.version =1 ; + +if (write (fd, &uidev,sizeof (uidev)) <0 ) +tst_brkm (TBROK ,NULL ,"ioctl failed" ); + +if (ioctl (fd,UI_DEV_CREATE ) <0 ) +tst_brkm (TBROK ,NULL ,"ioctl failed" ); +sleep (1 );
Here as well.
Quoted 23 lines
testcases/kernel/input/input04.c new file +23
-0+} + +static void send_information (void ) +{ +struct input_event ev; +int nb; + +sleep (1 ); + +for (nb =0 ; nb <NB_TEST ; ++nb) { + +memset (&ev,0 ,sizeof (struct input_event )); + ev.type =EV_REL ; + ev.code =REL_X ; + ev.value =X_VALUE ; +if (write (fd, &ev,sizeof (struct input_event )) <0 ) +tst_brkm (TBROK , cleanup,"write failed" ); + +memset (&ev,0 ,sizeof (struct input_event )); + ev.type =EV_REL ; + ev.code =REL_Y ; + ev.value =Y_VALUE ; +if (write (fd, &ev,sizeof (struct input_event )) <0 )
testcases/kernel/input/input04.c line 151
Quoted 10 lines
testcases/kernel/input/input04.c new file +10
-0+tst_brkm (TBROK , cleanup,"write failed" ); + +memset (&ev,0 ,sizeof (struct input_event )); + ev.type =EV_SYN ; + ev.code =0 ; + ev.value =0 ; +if (write (fd, &ev,sizeof (struct input_event )) <0 ) +tst_brkm (TBROK , cleanup,"write failed" ); +usleep (100 ); + }
Here as well, you could just called send_rel_move(fd, 0, 0);
Quoted 197 lines
testcases/kernel/input/input04.c new file +27
-0+cleanup (); +} + +static int check_information (void ) +{ +int rv; +struct timeval timeout; +fd_set set; + + fd2 =SAFE_OPEN (NULL ,"/dev/input/mice" ,O_RDWR ); +FD_ZERO (&set); +FD_SET (fd2, &set); + timeout.tv_sec =0 ; + timeout.tv_usec =10000 ; + rv =select (fd2 +1 , &set,NULL ,NULL , &timeout); +if (rv <0 ) +tst_brkm (TBROK ,NULL ,"select failed" ); +SAFE_CLOSE (NULL , fd2); +return rv ==0 ; +} + +static void cleanup (void ) +{ +if (ioctl (fd,UI_DEV_DESTROY ) <0 ) +tst_brkm (TBROK ,NULL ,"ioctl failed" ); +SAFE_CLOSE (NULL , fd); +}testcases/kernel/input/input05.c new file +164
-0@@ -0,0 +1,174 @@ +/* +* Copyright (c) 2015 Cedric Hnyda <[email protected]> +* +* 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 +*/ + +/* +* AUTHOR : Cedric Hnyda +* DATE STARTED : 11/16/2015 +* +* Create a virtual device (mouse), send events to /dev/uinput +* and check that the events are not received in /dev/input/eventX +* because it is not possible to sent such events +* +*/ + +#include <linux/input.h> +#include <linux/uinput.h> +#include <fnmatch.h> + +#include "test.h" +#include "safe_macros.h" +#include "lapi/fcntl.h" +#include "input_helper.h" + +#define X_VALUE 10 +#define Y_VALUE 10 + +#define NB_TEST 100 + +static void setup (void ); +static void send_information (void ); +static int check_information (void ); +static void cleanup (void ); + +static int fd; +static int fd2; + +char *TCID ="uinput05" ; + +int main (int ac,char **av) +{ +int lc; +int pid; + +tst_parse_opts (ac, av,NULL ,NULL ); + +for (lc =0 ; lc <TEST_LOOPING (lc); ++lc) { + +setup (); + pid =tst_fork (); + fd2 =setup_read (); + +if (!pid) +send_information (); +else { +if (check_information ()) +tst_resm (TFAIL ,"Data received in eventX" ); +else +tst_resm (TPASS ,"No data received in eventX" ); + } + } +tst_exit (); +} + +static void setup (void ) +{ +struct uinput_user_dev uidev; + +tst_require_root (); + + fd =open ("/dev/input/uinput" ,O_WRONLY |O_NONBLOCK ); + +if (fd <0 && errno ==ENOENT ) + fd =open ("/dev/uinput" ,O_WRONLY |O_NONBLOCK ); + +if (fd <0 ) +tst_brkm (TCONF ,NULL ,"unable to find and open uinput" ); +else if (fd <0 ) +tst_brkm (TBROK ,NULL ,"open failed" ); + +if (ioctl (fd,UI_SET_EVBIT ,EV_KEY ) <0 ) +tst_brkm (TBROK ,NULL ,"ioctl failed" ); +if (ioctl (fd,UI_SET_KEYBIT ,BTN_LEFT ) <0 ) +tst_brkm (TBROK ,NULL ,"ioctl failed" ); + +memset (&uidev,0 ,sizeof (uidev)); +snprintf (uidev.name,UINPUT_MAX_NAME_SIZE ,VIRTUAL_DEVICE ); + uidev.id.bustype =BUS_USB ; + uidev.id.vendor =0x1 ; + uidev.id.product =0x1 ; + uidev.id.version =1 ; + +if (write (fd, &uidev,sizeof (uidev)) <0 ) +tst_brkm (TBROK ,NULL ,"ioctl failed" ); + +if (ioctl (fd,UI_DEV_CREATE ) <0 ) +tst_brkm (TBROK ,NULL ,"ioctl failed" ); +sleep (1 ); +} + +static void send_information (void ) +{ +int nb; +struct input_event ev; + +sleep (1 ); + +for (nb =0 ; nb <NB_TEST ; ++nb) { + +memset (&ev,0 ,sizeof (struct input_event )); + ev.type =EV_REL ; + ev.code =REL_X ; + ev.value =X_VALUE ; +if (write (fd, &ev,sizeof (struct input_event )) <0 ) +tst_brkm (TBROK , cleanup,"write failed" ); + +memset (&ev,0 ,sizeof (struct input_event )); + ev.type =EV_REL ; + ev.code =REL_Y ; + ev.value =Y_VALUE ; +if (write (fd, &ev,sizeof (struct input_event )) <0 ) +tst_brkm (TBROK , cleanup,"write failed" ); + +memset (&ev,0 ,sizeof (struct input_event )); + ev.type =EV_SYN ; + ev.code =0 ; + ev.value =0 ; +if (write (fd, &ev,sizeof (struct input_event )) <0 ) +tst_brkm (TBROK , cleanup,"write failed" ); +usleep (100 ); + + } + +cleanup (); +} + +static int check_information (void ) +{ +int nb; +int rd; +struct input_event iev[64 ]; + + nb =0 ; + +while (nb ==0 ) { + rd =read (fd2, iev,sizeof (struct input_event ) *64 ); +if (rd ==0 ) +break ; + nb++; + } +
testcases/kernel/input/input05.c line 174
Quoted 10 lines
testcases/kernel/input/input05.c new file +10
-0+SAFE_CLOSE (NULL , fd2); +return nb ==0 ; +} + +static void cleanup (void ) +{ +if (ioctl (fd,UI_DEV_DESTROY ) <0 ) +tst_brkm (TBROK ,NULL ,"ioctl failed" ); +SAFE_CLOSE (NULL , fd); +}
This is nearly identical to the prevoius one. Most of the code should be in the library.
Quoted 51 lines
testcases/kernel/input/input_helper.c new file +45
-0@@ -0,0 +1,91 @@ +/* +* Copyright (c) 2015 Cedric Hnyda <[email protected]> +* +* 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 +*/ + +#include <linux/input.h> +#include <linux/uinput.h> +#include <fnmatch.h> +#include "test.h" +#include "safe_macros.h" +#include "input_helper.h" + +int setup_read (void ) +{ +DIR *d; +char namedir1[1024 ]; +char *event; +struct dirent *dp; +int fd2; + + event =NULL ; + + d =opendir ("/sys/devices/virtual/input/" ); +while ((dp =readdir (d))) { +if (!fnmatch ("input[0-9]*" , dp->d_name,0 )) { +memset (namedir1,0 ,sizeof (namedir1)); +strcat (namedir1,"/sys/devices/virtual/input/" ); +strcat (namedir1, dp->d_name); +if (closedir (d) <0 ) +tst_brkm (TBROK ,NULL ,"closedir failed" ); + d =opendir (namedir1); + event =find_event (d, namedir1);
testcases/kernel/input/input_helper.c line 55
Quoted 10 lines
testcases/kernel/input/input_helper.c new file +10
-0+if (event) +break ; + } + } + +closedir (d); + fd2 =SAFE_OPEN (NULL , event,O_RDONLY ); +free (event); +return fd2; +}
So these two functions looks for input device with VIRTUAL_DEVICE in name, right?
Why don't we simply try to open all input devices in /dev/input/ one by one do the EVIOCGNAME ioctl() and do strcmp() on it?
testcases/kernel/input/input_helper.c line 66
Quoted 10 lines
testcases/kernel/input/input_helper.c new file +10
-0+char *find_event (DIR *d,char *namedir1) +{ +char namedir2[1024 ]; +char buf[256 ]; +char *event; +struct dirent *dp; +int fd3; +int nb; + + event =malloc (sizeof (char ) *256 );
Again sizeof(char) == 1
Quoted 66 lines
testcases/kernel/input/input_helper.c new file +24
-0+while ((dp =readdir (d))) { +if (!fnmatch ("event*" , dp->d_name,0 )) { +memset (namedir2,0 ,sizeof (namedir2)); +strcpy (namedir2, namedir1); +strcat (namedir2,"/name" ); + fd3 =open (namedir2,O_RDONLY ); +if (fd3 >0 ) { + nb =read (fd3, &buf,sizeof (VIRTUAL_DEVICE )); +if (nb <0 ) +tst_brkm (TBROK ,NULL ,"read failed" ); +close (fd3); +if (!strncmp (buf,VIRTUAL_DEVICE , +strlen (VIRTUAL_DEVICE ))) { +memset (event,0 ,256 ); +strcat (event,"/dev/input/" ); +strcat (event, dp->d_name); +return event; + } + } + } + } +free (event); +return NULL ; +}testcases/kernel/input/input_helper.h new file +30
-0@@ -0,0 +1,30 @@ +/* +* Copyright (c) 2015 Cedric Hnyda <[email protected]> +* +* 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 +*/ + +#ifndef INPUT_HELPER_H +#define INPUT_HELPER_H + +#define VIRTUAL_DEVICE "virtual-device-ltp" + +#include <sys/types.h> +#include <dirent.h> + +char *find_event (DIR *d,char *namedir1); +int setup_read (void ); + +#endif /* INPUT_HELPER_H */ Signature · 5 lines
2.1.4 -- Mailing list info: http://lists.linux.it/listinfo/ltp
Signature · 2 lines
Cyril Hrubis [email protected]