[PATCH:libXt 1/2 v3] Add test framework similar to xserver and use it to test XtAsprintf

Alan Coopersmith alan.coopersmith at oracle.com
Mon Mar 14 19:27:54 PDT 2011


Only two simple test cases to start with:
 - compares the results of snprintf of a short string to a static buffer
	with the new buffer returned by XtAsprintf.
 - compare the results of using XtAsprintf to replicate a portion of a
	very long string with the original string.

Uses malloc debugging flags for various platforms to try to catch errors
with uninitialized memory (such as the recently fixed failure to terminate
the string).

Requires xorg-macros 1.13 for XORG_ENABLE_UNIT_TESTS and XORG_WITH_GLIB.

Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
---

v3: Use test macros from xorg-macros 1.1.3
    Improved GNU libc detection for malloc debug environment variables
    Fix MALLOC_PERTURB_ value to not be 0 or ~0 & comment about why.

 Makefile.am      |    2 +-
 configure.ac     |   27 +++++++++++-
 test/Alloc.c     |  112 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 test/Makefile.am |   12 ++++++
 4 files changed, 149 insertions(+), 4 deletions(-)
 create mode 100644 test/Alloc.c
 create mode 100644 test/Makefile.am

diff --git a/Makefile.am b/Makefile.am
index e9e0316..8ef09ca 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -19,7 +19,7 @@
 #  TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 #  PERFORMANCE OF THIS SOFTWARE.
 
-SUBDIRS = util src include man specs
+SUBDIRS = util src include man specs test
 
 ACLOCAL_AMFLAGS = -I m4
 
diff --git a/configure.ac b/configure.ac
index 96f0ccb..d18b0fe 100644
--- a/configure.ac
+++ b/configure.ac
@@ -35,10 +35,10 @@ AM_MAINTAINER_MODE
 # Initialize libtool
 AC_PROG_LIBTOOL
 
-# Require X.Org macros 1.8 or later for MAN_SUBSTS set by XORG_MANPAGE_SECTIONS
+# Require X.Org macros 1.13 or later for XORG_ENABLE_UNIT_TESTS
 m4_ifndef([XORG_MACROS_VERSION],
-          [m4_fatal([must install xorg-macros 1.8 or later before running autoconf/autogen])])
-XORG_MACROS_VERSION(1.8)
+          [m4_fatal([must install xorg-macros 1.13 or later before running autoconf/autogen])])
+XORG_MACROS_VERSION(1.13)
 XORG_DEFAULT_OPTIONS
 XORG_CHECK_MALLOC_ZERO
 
@@ -95,6 +95,26 @@ if test "x$XKB" = "xyes" ; then
 	AC_DEFINE(XKB, 1, [Define to 1 to use XKB for keysym resolution.])
 fi
 
+# --enable-unit-tests
+XORG_ENABLE_UNIT_TESTS
+XORG_WITH_GLIB([2.16])
+
+# Memory checking support
+case $host_os in
+     solaris*)
+        AC_CHECK_LIB([umem], [umem_alloc],
+            [MALLOC_DEBUG_ENV='LD_PRELOAD=libumem.so UMEM_DEBUG=default'])
+        ;;
+     *-gnu*) # GNU libc - Value is used as a single byte bit pattern,
+        # both directly and inverted, so should not be 0 or 255.
+        MALLOC_DEBUG_ENV='MALLOC_PERTURB_=15'
+        ;;
+     *bsd*|darwin*)
+        MALLOC_DEBUG_ENV='MallocPreScribble=1 MallocScribble=1'
+        ;;
+esac
+AC_SUBST([MALLOC_DEBUG_ENV])
+
 # Replaces XFileSearchPathDefault from Imake configs
 XFILESEARCHPATHDEFAULT='$(sysconfdir)/X11/%L/%T/%N%C%S:$(sysconfdir)/X11/%l/%T/%N%C%S:$(sysconfdir)/X11/%T/%N%C%S:$(sysconfdir)/X11/%L/%T/%N%S:$(sysconfdir)/X11/%l/%T/%N%S:$(sysconfdir)/X11/%T/%N%S:$(datadir)/X11/%L/%T/%N%C%S:$(datadir)/X11/%l/%T/%N%C%S:$(datadir)/X11/%T/%N%C%S:$(datadir)/X11/%L/%T/%N%S:$(datadir)/X11/%l/%T/%N%S:$(datadir)/X11/%T/%N%S:$(libdir)/X11/%L/%T/%N%C%S:$(libdir)/X11/%l/%T/%N%C%S:$(libdir)/X11/%T/%N%C%S:$(libdir)/X11/%L/%T/%N%S:$(libdir)/X11/%l/%T/%N%S:$(libdir)/X11/%T/%N%S'
 
@@ -144,5 +164,6 @@ AC_CONFIG_FILES([Makefile
 		include/Makefile
 		man/Makefile
 		specs/Makefile
+		test/Makefile
 		xt.pc])
 AC_OUTPUT
diff --git a/test/Alloc.c b/test/Alloc.c
new file mode 100644
index 0000000..7f02e19
--- /dev/null
+++ b/test/Alloc.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ *
+ * 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:
+ *
+ * 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.
+ */
+
+#include <X11/Intrinsic.h>
+#include <glib.h>
+#include <stdio.h>
+#include <string.h>
+
+static const char *program_name;
+
+/* Just a long string of characters to pull from */
+const char test_chars[] =
+    "|000 nul|001 soh|002 stx|003 etx|004 eot|005 enq|006 ack|007 bel|"
+    "|010 bs |011 ht |012 nl |013 vt |014 np |015 cr |016 so |017 si |"
+    "|020 dle|021 dc1|022 dc2|023 dc3|024 dc4|025 nak|026 syn|027 etb|"
+    "|030 can|031 em |032 sub|033 esc|034 fs |035 gs |036 rs |037 us |"
+    "|040 sp |041  ! |042  \" |043  # |044  $ |045  % |046  & |047  ' |"
+    "|050  ( |051  ) |052  * |053  + |054  , |055  - |056  . |057  / |"
+    "|060  0 |061  1 |062  2 |063  3 |064  4 |065  5 |066  6 |067  7 |"
+    "|070  8 |071  9 |072  : |073  ; |074  < |075  = |076  > |077  ? |"
+    "|100  @ |101  A |102  B |103  C |104  D |105  E |106  F |107  G |"
+    "|110  H |111  I |112  J |113  K |114  L |115  M |116  N |117  O |"
+    "|120  P |121  Q |122  R |123  S |124  T |125  U |126  V |127  W |"
+    "|130  X |131  Y |132  Z |133  [ |134  \\ |135  ] |136  ^ |137  _ |"
+    "|140  ` |141  a |142  b |143  c |144  d |145  e |146  f |147  g |"
+    "|150  h |151  i |152  j |153  k |154  l |155  m |156  n |157  o |"
+    "|160  p |161  q |162  r |163  s |164  t |165  u |166  v |167  w |"
+    "|170  x |171  y |172  z |173  { |174  | |175  } |176  ~ |177 del|"
+    "| 00 nul| 01 soh| 02 stx| 03 etx| 04 eot| 05 enq| 06 ack| 07 bel|"
+    "| 08 bs | 09 ht | 0a nl | 0b vt | 0c np | 0d cr | 0e so | 0f si |"
+    "| 10 dle| 11 dc1| 12 dc2| 13 dc3| 14 dc4| 15 nak| 16 syn| 17 etb|"
+    "| 18 can| 19 em | 1a sub| 1b esc| 1c fs | 1d gs | 1e rs | 1f us |"
+    "| 20 sp | 21  ! | 22  \" | 23  # | 24  $ | 25  % | 26  & | 27  ' |"
+    "| 28  ( | 29  ) | 2a  * | 2b  + | 2c  , | 2d  - | 2e  . | 2f  / |"
+    "| 30  0 | 31  1 | 32  2 | 33  3 | 34  4 | 35  5 | 36  6 | 37  7 |"
+    "| 38  8 | 39  9 | 3a  : | 3b  ; | 3c  < | 3d  = | 3e  > | 3f  ? |"
+    "| 40  @ | 41  A | 42  B | 43  C | 44  D | 45  E | 46  F | 47  G |"
+    "| 48  H | 49  I | 4a  J | 4b  K | 4c  L | 4d  M | 4e  N | 4f  O |"
+    "| 50  P | 51  Q | 52  R | 53  S | 54  T | 55  U | 56  V | 57  W |"
+    "| 58  X | 59  Y | 5a  Z | 5b  [ | 5c  \\ | 5d  ] | 5e  ^ | 5f  _ |"
+    "| 60  ` | 61  a | 62  b | 63  c | 64  d | 65  e | 66  f | 67  g |"
+    "| 68  h | 69  i | 6a  j | 6b  k | 6c  l | 6d  m | 6e  n | 6f  o |"
+    "| 70  p | 71  q | 72  r | 73  s | 74  t | 75  u | 76  v | 77  w |"
+    "| 78  x | 79  y | 7a  z | 7b  { | 7c  | | 7d  } | 7e  ~ | 7f del|";
+
+
+/* Test a simple short string & int */
+static void test_XtAsprintf_short(void)
+{
+    char snbuf[1024];
+    char *asbuf;
+    gint32 r = g_test_rand_int();
+    int snlen, aslen;
+
+    snlen = snprintf(snbuf, sizeof(snbuf), "%s: %d\n", program_name, r);
+    aslen = XtAsprintf(&asbuf, "%s: %d\n", program_name, r);
+
+    g_assert(asbuf != NULL);
+    g_assert(snlen == aslen);
+    g_assert(strcmp(snbuf, asbuf) == 0);
+    g_assert(asbuf[aslen] == '\0');
+}
+
+/* Test a string long enough to be past the 256 character limit that
+   makes XtAsprintf re-run snprintf after allocating memory */
+static void test_XtAsprintf_long(void)
+{
+    char *asbuf;
+    int aslen;
+    gint r1 = g_test_rand_int_range(0, 256);
+    gint r2 = g_test_rand_int_range(1024, sizeof(test_chars) - r1);
+
+    aslen = XtAsprintf(&asbuf, "%.*s", r2, test_chars + r1);
+
+    g_assert(asbuf != NULL);
+    g_assert(aslen == r2);
+    g_assert(strncmp(asbuf, test_chars + r1, r2) == 0);
+    g_assert(asbuf[aslen] == '\0');
+}
+
+int main(int argc, char** argv)
+{
+    program_name = argv[0];
+
+    g_test_init(&argc, &argv, NULL);
+    g_test_bug_base("https://bugzilla.freedesktop.org/show_bug.cgi?id=");
+
+    g_test_add_func("/Alloc/XtAsprintf/short", test_XtAsprintf_short);
+    g_test_add_func("/Alloc/XtAsprintf/long", test_XtAsprintf_long);
+
+    return g_test_run();
+}
diff --git a/test/Makefile.am b/test/Makefile.am
new file mode 100644
index 0000000..3e067da
--- /dev/null
+++ b/test/Makefile.am
@@ -0,0 +1,12 @@
+if ENABLE_UNIT_TESTS
+check_PROGRAMS = Alloc
+
+TESTS=$(check_PROGRAMS)
+
+AM_CFLAGS = $(CWARNFLAGS) $(XT_CFLAGS) $(GLIB_CFLAGS)
+INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include
+LDADD= $(top_builddir)/src/libXt.la $(GLIB_LIBS)
+
+TESTS_ENVIRONMENT = $(MALLOC_DEBUG_ENV)
+
+endif ENABLE_UNIT_TESTS
-- 
1.7.3.2



More information about the xorg-devel mailing list