[Pixman] [PATCH] test: Change composite so that it tests randomly generated images

Søren Sandmann sandmann at daimi.au.dk
Sun Mar 7 09:36:29 PST 2010


From: Søren Sandmann Pedersen <ssp at redhat.com>

Previously this test would try to exhaustively test all combinations
of formats and operators, which meant that it would take years to run.

Instead, generate random images and test those. The random seed is
based on time(), so we will get different tests every time it is run.
Whenever the test fails, it will print what the value of lcg_seed was
when the test began.

This patch also adds a table of random seeds that have failed at some
point. These seeds are run first before the random testing begins.
Whenever this tests fails, you are supposed to add the seed that
failed to the table, so that we can track that the bug doesn't get
reintroduced.

Cc: chris at chris-wilson.co.uk
---
 test/Makefile.am |    4 +-
 test/composite.c |  183 ++++++++++++++++++++++++++++--------------------------
 2 files changed, 99 insertions(+), 88 deletions(-)

diff --git a/test/Makefile.am b/test/Makefile.am
index 841ff8d..322f3e3 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -15,7 +15,6 @@ TESTPROGRAMS =			\
 
 a1_trap_test_LDADD = $(TEST_LDADD)
 fetch_test_LDADD = $(TEST_LDADD)
-composite_LDADD = $(TEST_LDADD)
 trap_crasher_LDADD = $(TEST_LDADD)
 oob_test_LDADD = $(TEST_LDADD)
 window_test_LDADD = $(TEST_LDADD)
@@ -32,6 +31,9 @@ scaling_test_SOURCES = scaling-test.c utils.c utils.h
 alphamap_LDADD = $(TEST_LDADD)
 alphamap_SOURCES = alphamap.c utils.c utils.h
 
+composite_LDADD = $(TEST_LDADD)
+composite_SOURCES = composite.c utils.c utils.h
+
 # GTK using test programs
 
 if HAVE_GTK
diff --git a/test/composite.c b/test/composite.c
index 632e14b..0610805 100644
--- a/test/composite.c
+++ b/test/composite.c
@@ -1,6 +1,7 @@
 /*
  * Copyright © 2005 Eric Anholt
  * Copyright © 2009 Chris Wilson
+ * Copyright © 2010 Soeren Sandmann
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
@@ -20,15 +21,14 @@
  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  * PERFORMANCE OF THIS SOFTWARE.
  */
-
+#define PIXMAN_USE_INTERNAL_API
 #include <pixman.h>
 #include <stdio.h>
 #include <stdlib.h> /* abort() */
 #include <math.h>
 #include <config.h>
-
-#define FALSE 0
-#define TRUE !FALSE
+#include <time.h>
+#include "utils.h"
 
 #define ARRAY_LENGTH(A) ((int) (sizeof (A) / sizeof ((A) [0])))
 #define min(a,b) ((a) <= (b) ? (a) : (b))
@@ -692,6 +692,11 @@ composite_test (image_t *dst,
     color_correct (dst->format->format, &expected);
 
     diff = eval_diff (&expected, &result, dst->format->format);
+
+    /* FIXME: We should find out what deviation is acceptable. 3.0
+     * is clearly absurd for 2 bit formats for example. On the other
+     * hand currently 1.0 does not work.
+     */
     if (diff > 3.0)
     {
 	char buf[40];
@@ -709,7 +714,7 @@ composite_test (image_t *dst,
 		result.r, result.g, result.b, result.a,
 		*(unsigned long *) pixman_image_get_data (dst->image),
 		expected.r, expected.g, expected.b, expected.a);
-	
+
 	if (mask != NULL)
 	{
 	    printf ("src color: %.2f %.2f %.2f %.2f\n"
@@ -792,102 +797,106 @@ image_fini (image_t *info)
     pixman_image_unref (info->image);
 }
 
-int
-main (void)
+static int
+random_color (void)
+{
+    return lcg_rand_n (ARRAY_LENGTH (colors));
+}
+
+static int
+random_format (void)
+{
+    return lcg_rand_n (ARRAY_LENGTH (formats));
+}
+
+static pixman_bool_t
+run_test (void)
 {
-    pixman_bool_t ok, group_ok = TRUE, ca;
-    int i, d, m, s;
-    int tests_passed = 0, tests_total = 0;
+    uint32_t seed = lcg_seed;
+    image_t src, mask, dst;
     int sizes[] = { 1, 1 | REPEAT, 10 };
-    int num_tests;
+    int n_sizes = ARRAY_LENGTH (sizes);
+    const operator_t *op;
+    int ca;
+    int ok;
+
+    image_init (&dst, random_color(), random_format(), 1);
+    image_init (&src, random_color(), random_format(), lcg_rand_n (n_sizes));
+    image_init (&mask, random_color(), random_format(), lcg_rand_n (n_sizes));
 
-    for (i = 0; i < ARRAY_LENGTH (colors); i++)
+    op = &(operators [lcg_rand_n (ARRAY_LENGTH (operators))]);
+
+    ca = lcg_rand_n (3);
+
+    switch (ca)
     {
-	colors[i].r *= colors[i].a;
-	colors[i].g *= colors[i].a;
-	colors[i].b *= colors[i].a;
+    case 0:
+	ok = composite_test (&dst, op, &src, NULL, FALSE);
+	break;
+    case 1:
+	ok = composite_test (&dst, op, &src, &mask, FALSE);
+	break;
+    case 2:
+	ok = composite_test (&dst, op, &src, &mask,
+			     mask.size? TRUE : FALSE);
+	break;
+    default:
+	ok = FALSE;
+	break;
     }
 
-    num_tests = ARRAY_LENGTH (colors) * ARRAY_LENGTH (formats);
+    image_fini (&src);
+    image_fini (&mask);
+    image_fini (&dst);
 
-    for (d = 0; d < num_tests; d++)
+    if (!ok)
     {
-	image_t dst;
+	printf ("Error detected. Please add this value to the 'seeds' "
+		"table in %s: 0x%8x\n", __FILE__, seed);
+    }
+    return ok;
+}
 
-	image_init (
-	    &dst, d / ARRAY_LENGTH (formats), d % ARRAY_LENGTH (formats), 1);
+/* This is a table of seeds that have failed at some point previously.
+ *
+ * Whenever this test fails for you, please add the seed to this table
+ * before fixing the bug. That way we can track that the bug doesn't
+ * get reintroduced.
+ */
+static const uint32_t seeds[] =
+{
+    0x6aeece7d,
+    0x8dd8204a,
+};
 
+int
+main (void)
+{
+#define N_TESTS (4 * 1024 * 1024)
 
-	for (s = -ARRAY_LENGTH (colors);
-	     s < ARRAY_LENGTH (sizes) * num_tests;
-	     s++)
-	{
-	    image_t src;
+    pixman_bool_t ok = TRUE;
+    int i;
 
-	    if (s < 0)
-	    {
-		image_init (&src, -s - 1, 0, 0);
-	    }
-	    else
-	    {
-		image_init (&src,
-			    s / ARRAY_LENGTH (sizes) / ARRAY_LENGTH (formats),
-			    s / ARRAY_LENGTH (sizes) % ARRAY_LENGTH (formats),
-			    sizes[s % ARRAY_LENGTH (sizes)]);
-	    }
+    /* Regression tests */
+    for (i = 0; i < ARRAY_LENGTH (seeds); ++i)
+    {
+	lcg_srand (seeds[i]);
 
-	    for (m = -ARRAY_LENGTH (colors);
-		 m < ARRAY_LENGTH (sizes) * num_tests;
-		 m++)
-	    {
-		image_t mask;
-
-		if (m < 0)
-		{
-		    image_init (&mask, -m - 1, 0, 0);
-		}
-		else
-		{
-		    image_init (
-			&mask,
-			m / ARRAY_LENGTH (sizes) / ARRAY_LENGTH (formats),
-			m / ARRAY_LENGTH (sizes) % ARRAY_LENGTH (formats),
-			sizes[m % ARRAY_LENGTH (sizes)]);
-		}
-
-		for (ca = -1; ca <= 1; ca++)
-		{
-		    for (i = 0; i < ARRAY_LENGTH (operators); i++)
-		    {
-			const operator_t *op = &operators[i];
-
-			switch (ca)
-			{
-			case -1:
-			    ok = composite_test (&dst, op, &src, NULL, FALSE);
-			    break;
-			case 0:
-			    ok = composite_test (&dst, op, &src, &mask, FALSE);
-			    break;
-			case 1:
-			    ok = composite_test (&dst, op, &src, &mask,
-						 mask.size? TRUE : FALSE);
-			    break;
-                        default:
-                            break;
-			}
-			group_ok = group_ok && ok;
-			tests_passed += ok;
-			tests_total++;
-		    }
-		}
-
-		image_fini (&mask);
-	    }
-	    image_fini (&src);
+	if (!run_test())
+	{
+	    printf ("Error in regression test %d\n", i);
+	    return -1;
 	}
-	image_fini (&dst);
     }
 
-    return group_ok == FALSE;
+    /* Test random combinations */
+    lcg_srand (time(NULL));
+
+    for (i = 0; i < N_TESTS; ++i)
+    {
+	if (!run_test ())
+	    return -1;
+    }
+
+    return !ok;
 }
-- 
1.6.0.6



More information about the Pixman mailing list