This uses glib's testing framework provided glib-devel was available at
configure time (same as the X server's testing framework).

How this works:
The wacom driver is recompiled for the testing framework and linked into the
wacom-tests binary (there's a warning about that but ignore that). Since the
.so uses a number of symbols from the Xorg binary, these are provided as
stubs in fake-symbols.c. Additional binaries can be added through the
check_PROGRAMS automake variable.

The driver will be rebuild without static symbols for the test, allowing
each function call to be tested.

To run the tests, run 'make check'.

Signed-off-by: Peter Hutterer <[email protected]>
---
 Makefile.am         |    2 +-
 configure.ac        |   54 +++++++
 test/Makefile.am    |   18 +++
 test/fake-symbols.c |  385 +++++++++++++++++++++++++++++++++++++++++++++++++++
 test/fake-symbols.h |  140 +++++++++++++++++++
 test/wacom-tests.c  |   13 ++
 6 files changed, 611 insertions(+), 1 deletions(-)
 create mode 100644 test/Makefile.am
 create mode 100644 test/fake-symbols.c
 create mode 100644 test/fake-symbols.h
 create mode 100644 test/wacom-tests.c

diff --git a/Makefile.am b/Makefile.am
index 1e936d9..bf24997 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -22,7 +22,7 @@
 DISTCHECK_CONFIGURE_FLAGS = --with-sdkdir='$${includedir}/xorg' \
                            --with-xorg-conf-dir='$${datadir}/X11/xorg.conf.d'
 
-SUBDIRS = conf src man include tools
+SUBDIRS = conf src man include tools test
 MAINTAINERCLEANFILES = ChangeLog INSTALL
 
 pkgconfigdir = $(libdir)/pkgconfig
diff --git a/configure.ac b/configure.ac
index c8296aa..45d1d89 100644
--- a/configure.ac
+++ b/configure.ac
@@ -98,6 +98,59 @@ AC_ARG_WITH([xorg-conf-dir],
             [configdir="$sysconfigdir"])
 AC_SUBST(configdir)
 AM_CONDITIONAL(HAS_XORG_CONF_DIR, [test "x$sysconfigdir" != "x"])
+
+# enalbe unit-tests if glib-devel is available
+AC_ARG_ENABLE(unit-tests, AS_HELP_STRING([--enable-unit-tests],
+                          [Enable unit-tests (default: auto)]),
+                          [UNITTESTS=$enableval],
+                          [UNITTESTS=auto])
+
+# If unittests aren't explicitly disabled, check for required support
+if test "x$UNITTESTS" != xno ; then
+       PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.16],
+                         [HAVE_GLIB=yes], [HAVE_GLIB=no])
+
+       # Check if linker supports -wrap, passed via compiler flags
+       # When cross-compiling, reports no, since unit tests run from
+       # "make check", so would be running on build machine,  not target
+       AC_MSG_CHECKING([whether the linker supports -wrap])
+       save_LDFLAGS="$LDFLAGS"
+       LDFLAGS="$LDFLAGS -Wl,-wrap,exit"
+       AC_RUN_IFELSE([AC_LANG_PROGRAM([[
+        void __wrap_exit (int s)
+        {
+            __real_exit (0);
+        }]],
+        [[exit (1);]])],
+                     [linker_can_wrap="yes"],
+                     [linker_can_wrap="no"],
+                     [linker_can_wrap="no"])
+       AC_MSG_RESULT([$linker_can_wrap])
+       LDFLAGS="$save_LDFLAGS"
+fi
+
+if test "x$UNITTESTS" = xauto; then
+       if test "x$HAVE_GLIB" = xyes && test "x$linker_can_wrap" = xyes; then
+           UNITTESTS=yes
+       else
+           UNITTESTS=no
+       fi
+fi
+if test "x$UNITTESTS" = xyes; then
+       if test "x$HAVE_GLIB" = xno; then
+           AC_MSG_ERROR([glib required to build unit tests])
+       fi
+       if test "x$linker_can_wrap" = xno; then
+           AC_MSG_ERROR([ld -wrap support required to build unit tests])
+       fi
+       AC_DEFINE(UNITTESTS, 1, [Enable unit tests])
+       AC_SUBST([GLIB_LIBS])
+       AC_SUBST([GLIB_CFLAGS])
+fi
+AM_CONDITIONAL(UNITTESTS, [test "x$UNITTESTS" = xyes])
+
+
+
 # -----------------------------------------------------------------------------
 
 AC_CONFIG_FILES([Makefile
@@ -106,5 +159,6 @@ AC_CONFIG_FILES([Makefile
                  man/Makefile
                  include/Makefile
                  tools/Makefile
+                 test/Makefile
                  xorg-wacom.pc])
 AC_OUTPUT
diff --git a/test/Makefile.am b/test/Makefile.am
new file mode 100644
index 0000000..01151de
--- /dev/null
+++ b/test/Makefile.am
@@ -0,0 +1,18 @@
+if UNITTESTS
+include ../src/Makefile.am
+
+check_PROGRAMS = wacom-tests
+check_LTLIBRARRIES = @DRIVER_NAME@_drv.la
+@DRIVER_NAME@_drv_la_CFLAGS = -DNO_STATIC -I$(top_srcdir)/src $(XORG_CFLAGS) 
$(CWARNFLAGS) -fvisibility=default
+
+TESTS=$(check_PROGRAMS)
+
+INCLUDES = -I$(top_srcdir)/src
+AM_CFLAGS += $(GLIB_CFLAGS)
+TEST_LDADD=$(GLIB_LIBS) @DRIVER_NAME@_drv.la
+COMMON_SOURCES=fake-symbols.c fake-symbols.h
+
+wacom_tests_LDADD=$(TEST_LDADD)
+wacom_tests_SOURCES=wacom-tests.c $(COMMON_SOURCES)
+
+endif
diff --git a/test/fake-symbols.c b/test/fake-symbols.c
new file mode 100644
index 0000000..8bd88b9
--- /dev/null
+++ b/test/fake-symbols.c
@@ -0,0 +1,385 @@
+#include "fake-symbols.h"
+
+_X_EXPORT
+int xf86ReadSerial (int fd, void *buf, int count)
+{
+    return 0;
+}
+
+
+_X_EXPORT int
+xf86WriteSerial (int fd, const void *buf, int count)
+{
+    return 0;
+}
+
+_X_EXPORT int
+xf86CloseSerial (int fd)
+{
+    return 0;
+}
+
+_X_EXPORT int
+xf86WaitForInput (int fd, int timeout)
+{
+    return 0;
+}
+
+_X_EXPORT int
+xf86OpenSerial (pointer options)
+{
+    return 0;
+}
+
+_X_EXPORT int
+xf86SetSerialSpeed (int fd, int speed)
+{
+    return 0;
+}
+
+_X_EXPORT pointer
+xf86ReplaceIntOption(pointer optlist, const char *name, const int val)
+{
+    return NULL;
+}
+
+_X_EXPORT char *
+xf86SetStrOption(pointer optlist, const char *name, char *deflt)
+{
+    return NULL;
+}
+
+_X_EXPORT int
+xf86SetBoolOption(pointer optlist, const char *name, int deflt)
+{
+    return 0;
+}
+
+_X_EXPORT pointer
+xf86AddNewOption(pointer head, const char *name, const char *val)
+{
+    return NULL;
+}
+_X_EXPORT char *
+xf86FindOptionValue(pointer options, const char *name)
+{
+    return NULL;
+}
+
+_X_EXPORT char *
+xf86OptionName(pointer opt)
+{
+    return NULL;
+}
+
+_X_EXPORT char *
+xf86OptionValue(pointer opt)
+{
+    return NULL;
+}
+
+_X_EXPORT int
+xf86NameCmp(const char *s1, const char *s2)
+{
+    return 0;
+}
+
+_X_EXPORT char *
+xf86CheckStrOption(pointer optlist, const char *name, char *deflt)
+{
+    return NULL;
+}
+
+_X_EXPORT void
+xf86AddEnabledDevice(InputInfoPtr pInfo)
+{
+    return;
+}
+
+_X_EXPORT void
+xf86RemoveEnabledDevice(InputInfoPtr pInfo)
+{
+    return;
+}
+
+_X_EXPORT Atom
+XIGetKnownProperty(char *name)
+{
+    return None;
+}
+
+_X_EXPORT void
+xf86AddInputDriver(InputDriverPtr driver, pointer module, int flags)
+{
+    return;
+}
+
+_X_EXPORT int
+xf86ScaleAxis(int      Cx,
+              int      to_max,
+              int      to_min,
+              int      from_max,
+              int      from_min )
+{
+    return 0;
+}
+
+
+_X_EXPORT void
+DeleteInputDeviceRequest(DeviceIntPtr pDev)
+{
+    return;
+}
+
+
+_X_EXPORT void
+FreeInputAttributes(InputAttributes *attrs)
+{
+    return;
+}
+
+
+_X_EXPORT void
+xf86PostButtonEvent(DeviceIntPtr       device,
+                    int                        is_absolute,
+                    int                        button,
+                    int                        is_down,
+                    int                        first_valuator,
+                    int                        num_valuators,
+                    ...)
+{
+    return;
+}
+
+_X_EXPORT int
+Xasprintf(char ** ret, const char * _X_RESTRICT_KYWD format, ...)
+{
+    return 0;
+}
+
+
+_X_EXPORT int
+XISetDevicePropertyDeletable(DeviceIntPtr dev, Atom property, Bool deletable)
+{
+    return 0;
+}
+
+
+_X_EXPORT InputInfoPtr
+xf86FirstLocalDevice(void)
+{
+    return NULL;
+}
+
+
+_X_EXPORT void
+xf86DeleteInput(InputInfoPtr pInp, int flags)
+{
+    return;
+}
+
+_X_EXPORT pointer
+xf86OptionListDuplicate(pointer options)
+{
+    return NULL;
+}
+
+_X_EXPORT Bool
+InitButtonClassDeviceStruct(DeviceIntPtr dev, int numButtons, Atom* labels,
+                            CARD8 *map)
+{
+    return FALSE;
+}
+
+_X_EXPORT void
+InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval, 
int maxval,
+                      int resolution, int min_res, int max_res, int mode)
+{
+    return;
+}
+
+_X_EXPORT void
+xf86PostKeyboardEvent(DeviceIntPtr      device,
+                      unsigned int      key_code,
+                      int               is_down)
+{
+    return;
+}
+
+_X_EXPORT int
+xf86SetIntOption(pointer optlist, const char *name, int deflt)
+{
+    return 0;
+}
+
+_X_EXPORT void
+xf86PostButtonEventP(DeviceIntPtr      device,
+                     int               is_absolute,
+                     int               button,
+                     int               is_down,
+                     int               first_valuator,
+                     int               num_valuators,
+                     const int         *valuators)
+{
+    return;
+}
+
+_X_EXPORT Bool
+InitPtrFeedbackClassDeviceStruct(DeviceIntPtr dev, PtrCtrlProcPtr controlProc)
+{
+    return FALSE;
+}
+
+_X_EXPORT int
+XIChangeDeviceProperty (DeviceIntPtr dev, Atom property, Atom type,
+                        int format, int mode, unsigned long len,
+                        pointer value, Bool sendevent)
+{
+    return 0;
+}
+
+_X_EXPORT CARD32
+GetTimeInMillis (void)
+{
+    return 0;
+}
+
+
+_X_EXPORT int
+NewInputDeviceRequest (InputOption *options, InputAttributes *attrs,
+                       DeviceIntPtr *pdev)
+{
+    return 0;
+}
+
+
+_X_EXPORT Bool
+InitLedFeedbackClassDeviceStruct (DeviceIntPtr dev, LedCtrlProcPtr controlProc)
+{
+    return FALSE;
+}
+
+
+_X_EXPORT ScreenPtr
+miPointerGetScreen(DeviceIntPtr pDev)
+{
+    return NULL;
+}
+
+_X_EXPORT InputAttributes*
+DuplicateInputAttributes(InputAttributes *attrs)
+{
+    return NULL;
+}
+
+_X_EXPORT int
+ValidAtom(Atom atom)
+{
+    return None;
+}
+
+_X_EXPORT Bool
+InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet *rmlvo,
+                         BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
+{
+    return FALSE;
+}
+
+_X_EXPORT long
+XIRegisterPropertyHandler(DeviceIntPtr         dev,
+                          int (*SetProperty) (DeviceIntPtr dev,
+                                              Atom property,
+                                              XIPropertyValuePtr prop,
+                                              BOOL checkonly),
+                          int (*GetProperty) (DeviceIntPtr dev,
+                                              Atom property),
+                          int (*DeleteProperty) (DeviceIntPtr dev,
+                                                 Atom property))
+{
+    return 0;
+}
+
+_X_EXPORT int
+InitProximityClassDeviceStruct(DeviceIntPtr dev)
+{
+    return 0;
+}
+
+
+_X_EXPORT void
+xf86Msg(MessageType type, const char *format, ...)
+{
+    return;
+}
+
+
+_X_EXPORT void
+xf86PostMotionEventP(DeviceIntPtr      device,
+                    int                        is_absolute,
+                    int                        first_valuator,
+                    int                        num_valuators,
+                    const int          *valuators)
+{
+    return;
+}
+
+
+_X_EXPORT Bool
+InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes, Atom *labels,
+                              int numMotionEvents, int mode)
+{
+    return FALSE;
+}
+
+
+_X_EXPORT pointer
+xf86ReplaceStrOption(pointer optlist, const char *name, const char* val)
+{
+    return NULL;
+}
+
+
+_X_EXPORT pointer
+xf86NextOption(pointer list)
+{
+    return NULL;
+}
+
+
+_X_EXPORT int
+XIGetDeviceProperty (DeviceIntPtr dev, Atom property, XIPropertyValuePtr 
*value)
+{
+    return 0;
+}
+
+
+_X_EXPORT Atom
+MakeAtom(const char *string, unsigned len, Bool makeit)
+{
+    return None;
+}
+
+
+_X_EXPORT int
+GetMotionHistorySize(void)
+{
+    return 0;
+}
+
+
+_X_EXPORT void
+xf86PostProximityEventP(DeviceIntPtr   device,
+                        int            is_in,
+                        int            first_valuator,
+                        int            num_valuators,
+                        const int      *valuators)
+{
+    return;
+}
+
+
+_X_EXPORT Bool
+InitFocusClassDeviceStruct(DeviceIntPtr dev)
+{
+    return FALSE;
+}
diff --git a/test/fake-symbols.h b/test/fake-symbols.h
new file mode 100644
index 0000000..7f449c6
--- /dev/null
+++ b/test/fake-symbols.h
@@ -0,0 +1,140 @@
+#include <xorg-server.h>
+#include <xf86Xinput.h>
+
+extern int xf86ReadSerial (int fd, void *buf, int count);
+extern int xf86WriteSerial (int fd, const void *buf, int count);
+extern int xf86CloseSerial (int fd);
+extern int xf86WaitForInput (int fd, int timeout);
+extern int xf86OpenSerial (pointer options);
+extern int xf86SetSerialSpeed (int fd, int speed);
+
+extern pointer xf86ReplaceIntOption(pointer optlist, const char *name, const 
int val);
+extern pointer xf86AddNewOption(pointer head, const char *name, const char 
*val);
+extern char* xf86OptionName(pointer opt);
+extern char* xf86FindOptionValue(pointer options, const char *name);
+extern int xf86NameCmp(const char *s1, const char *s2);
+extern char* xf86CheckStrOption(pointer optlist, const char *name, char 
*deflt);
+
+
+extern char * xf86SetStrOption(pointer optlist, const char *name, char *deflt);
+extern int xf86SetBoolOption(pointer optlist, const char *name, int deflt);
+extern pointer xf86AddNewOption(pointer head, const char *name, const char 
*val);
+extern char* xf86FindOptionValue(pointer options, const char *name);
+extern char* xf86OptionName(pointer opt);
+extern char *xf86OptionValue(pointer opt);
+extern int xf86NameCmp(const char *s1, const char *s2);
+extern char * xf86CheckStrOption(pointer optlist, const char *name, char 
*deflt);
+extern void xf86AddEnabledDevice(InputInfoPtr pInfo);
+extern void xf86RemoveEnabledDevice(InputInfoPtr pInfo);
+extern Atom XIGetKnownProperty(char *name);
+extern void xf86AddInputDriver(InputDriverPtr driver, pointer module, int 
flags);
+extern int
+xf86ScaleAxis(int      Cx,
+              int      to_max,
+              int      to_min,
+              int      from_max,
+              int      from_min );
+
+extern void DeleteInputDeviceRequest(DeviceIntPtr pDev);
+extern void FreeInputAttributes(InputAttributes *attrs);
+extern void
+xf86PostButtonEvent(DeviceIntPtr       device,
+                    int                        is_absolute,
+                    int                        button,
+                    int                        is_down,
+                    int                        first_valuator,
+                    int                        num_valuators,
+                    ...);
+extern int Xasprintf(char ** ret, const char * _X_RESTRICT_KYWD format, ...);
+extern int
+XISetDevicePropertyDeletable(DeviceIntPtr dev, Atom property, Bool deletable);
+
+extern InputInfoPtr xf86FirstLocalDevice(void);
+extern void xf86DeleteInput(InputInfoPtr pInp, int flags);
+extern pointer xf86OptionListDuplicate(pointer options);
+extern Bool
+InitButtonClassDeviceStruct(DeviceIntPtr dev, int numButtons, Atom* labels,
+                            CARD8 *map);
+extern void
+InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval, 
int maxval,
+                      int resolution, int min_res, int max_res, int mode);
+extern void
+xf86PostKeyboardEvent(DeviceIntPtr      device,
+                      unsigned int      key_code,
+                      int               is_down);
+extern int
+xf86SetIntOption(pointer optlist, const char *name, int deflt);
+extern void
+xf86PostButtonEventP(DeviceIntPtr      device,
+                     int               is_absolute,
+                     int               button,
+                     int               is_down,
+                     int               first_valuator,
+                     int               num_valuators,
+                     const int         *valuators);
+extern Bool
+InitPtrFeedbackClassDeviceStruct(DeviceIntPtr dev, PtrCtrlProcPtr controlProc);
+
+extern int
+XIChangeDeviceProperty (DeviceIntPtr dev, Atom property, Atom type,
+                        int format, int mode, unsigned long len,
+                        pointer value, Bool sendevent);
+extern CARD32 GetTimeInMillis (void);
+
+extern int
+NewInputDeviceRequest (InputOption *options, InputAttributes *attrs,
+                       DeviceIntPtr *pdev);
+
+extern Bool
+InitLedFeedbackClassDeviceStruct (DeviceIntPtr dev, LedCtrlProcPtr 
controlProc);
+
+extern ScreenPtr miPointerGetScreen(DeviceIntPtr pDev);
+extern InputAttributes* DuplicateInputAttributes(InputAttributes *attrs);
+extern int ValidAtom(Atom atom);
+extern Bool
+InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet *rmlvo,
+                         BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func);
+extern long
+XIRegisterPropertyHandler(DeviceIntPtr         dev,
+                          int (*SetProperty) (DeviceIntPtr dev,
+                                              Atom property,
+                                              XIPropertyValuePtr prop,
+                                              BOOL checkonly),
+                          int (*GetProperty) (DeviceIntPtr dev,
+                                              Atom property),
+                          int (*DeleteProperty) (DeviceIntPtr dev,
+                                                 Atom property));
+extern int InitProximityClassDeviceStruct(DeviceIntPtr dev);
+extern void xf86Msg(MessageType type, const char *format, ...);
+
+extern void
+xf86PostMotionEventP(DeviceIntPtr      device,
+                    int                        is_absolute,
+                    int                        first_valuator,
+                    int                        num_valuators,
+                    const int          *valuators);
+
+extern Bool
+InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes, Atom *labels,
+                              int numMotionEvents, int mode);
+
+extern pointer
+xf86ReplaceStrOption(pointer optlist, const char *name, const char* val);
+
+extern pointer xf86NextOption(pointer list);
+
+extern int
+XIGetDeviceProperty (DeviceIntPtr dev, Atom property, XIPropertyValuePtr 
*value);
+
+extern Atom MakeAtom(const char *string, unsigned len, Bool makeit);
+
+extern int GetMotionHistorySize(void);
+
+extern void
+xf86PostProximityEventP(DeviceIntPtr   device,
+                        int            is_in,
+                        int            first_valuator,
+                        int            num_valuators,
+                        const int      *valuators);
+
+extern Bool InitFocusClassDeviceStruct(DeviceIntPtr dev);
diff --git a/test/wacom-tests.c b/test/wacom-tests.c
new file mode 100644
index 0000000..8209397
--- /dev/null
+++ b/test/wacom-tests.c
@@ -0,0 +1,13 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include "fake-symbols.h"
+
+
+int main(int argc, char** argv)
+{
+    g_test_init(&argc, &argv, NULL);
+    return g_test_run();
+}
-- 
1.7.3.4


------------------------------------------------------------------------------
Special Offer-- Download ArcSight Logger for FREE (a $49 USD value)!
Finally, a world-class log management solution at an even better price-free!
Download using promo code Free_Logger_4_Dev2Dev. Offer expires 
February 28th, so secure your free ArcSight Logger TODAY! 
http://p.sf.net/sfu/arcsight-sfd2d
_______________________________________________
Linuxwacom-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel

Reply via email to