summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog13
-rw-r--r--test/.cvsignore3
-rw-r--r--test/Makefile.am7
-rw-r--r--test/cairo-test.c30
-rw-r--r--test/cairo-test.h48
-rw-r--r--test/pthread-show-text.c110
6 files changed, 195 insertions, 16 deletions
diff --git a/ChangeLog b/ChangeLog
index 5e569562..1bd6a49d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2005-09-13 Carl Worth <cworth@cworth.org>
+
+ * test/cairo-test.h: Add documentation for cairo_test functions.
+
+ * test/cairo-test.c: (cairo_test_init), (cairo_test_expecting):
+ Abstract log fie creation into cairo_test_init for use by tests
+ that don't use cairo_test().
+
+ * test/.cvsignore:
+ * test/Makefile.am:
+ * test/pthread-show-text.c: (start), (main): Add new test for bug
+ #4299 as reported by Alexey Shabalin.
+
2005-09-12 Carl Worth <cworth@cworth.org>
Originally 2005-09-06 Carl Worth <cworth@cworth.org>:
diff --git a/test/.cvsignore b/test/.cvsignore
index bfda73e6..1b33925b 100644
--- a/test/.cvsignore
+++ b/test/.cvsignore
@@ -39,9 +39,10 @@ pdf-clip
pdf-clip.pdf
pdf-surface
pdf-surface.pdf
+pixman-rotate
ps-surface
ps-surface.ps
-pixman-rotate
+pthread-show-text
rectangle-rounding-error
rel-path
scale-source-surface-paint
diff --git a/test/Makefile.am b/test/Makefile.am
index c056a8d9..a92f1374 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -56,6 +56,10 @@ unbounded-operator \
user-data \
rel-path
+if HAVE_PTHREAD
+TESTS += pthread-show-text
+endif
+
if CAIRO_HAS_FT_FONT
TESTS += ft-font-create-for-ft-face
endif
@@ -218,8 +222,9 @@ paint_with_alpha_LDADD = $(LDADDS)
path_data_LDADD = $(LDADDS)
pdf_surface_LDADD = $(LDADDS)
pdf_clip_LDADD = $(LDADDS)
-ps_surface_LDADD = $(LDADDS)
pixman_rotate_LDADD = $(LDADDS)
+ps_surface_LDADD = $(LDADDS)
+pthread_show_text_LDADD = $(LDADDS)
rectangle_rounding_error_LDADD = $(LDADDS)
scale_source_surface_paint_LDADD = $(LDADDS)
select_font_no_show_text_LDADD = $(LDADDS)
diff --git a/test/cairo-test.c b/test/cairo-test.c
index 824ee687..029002bc 100644
--- a/test/cairo-test.c
+++ b/test/cairo-test.c
@@ -50,6 +50,9 @@
#define vsnprintf _vsnprintf
#endif
+static void
+xunlink (const char *pathname);
+
#define CAIRO_TEST_LOG_SUFFIX ".log"
#define CAIRO_TEST_PNG_SUFFIX "-out.png"
#define CAIRO_TEST_REF_SUFFIX "-ref.png"
@@ -61,6 +64,22 @@
FILE *cairo_test_log_file;
void
+cairo_test_init (const char *test_name)
+{
+ char *log_name;
+
+ xasprintf (&log_name, "%s%s", test_name, CAIRO_TEST_LOG_SUFFIX);
+ xunlink (log_name);
+
+ cairo_test_log_file = fopen (log_name, "a");
+ if (cairo_test_log_file == NULL) {
+ fprintf (stderr, "Error opening log file: %s\n", log_name);
+ cairo_test_log_file = stderr;
+ }
+ free (log_name);
+}
+
+void
cairo_test_log (const char *fmt, ...)
{
va_list va;
@@ -534,17 +553,8 @@ cairo_test_expecting (cairo_test_t *test, cairo_test_draw_function_t draw,
{ "xlib", create_xlib_surface, cleanup_xlib},
#endif
};
- char *log_name;
-
- xasprintf (&log_name, "%s%s", test->name, CAIRO_TEST_LOG_SUFFIX);
- xunlink (log_name);
- cairo_test_log_file = fopen (log_name, "a");
- if (cairo_test_log_file == NULL) {
- fprintf (stderr, "Error opening log file: %s\n", log_name);
- cairo_test_log_file = stderr;
- }
- free (log_name);
+ cairo_test_init (test->name);
/* The intended logic here is that we return overall SUCCESS
* iff. there is at least one tested backend and that all tested
diff --git a/test/cairo-test.h b/test/cairo-test.h
index a047fbca..147e5c7e 100644
--- a/test/cairo-test.h
+++ b/test/cairo-test.h
@@ -71,15 +71,58 @@ typedef struct cairo_test {
typedef cairo_test_status_t (*cairo_test_draw_function_t) (cairo_t *cr, int width, int height);
-/* cairo_test.c */
+/* The standard test interface which works by examining result image.
+ *
+ * cairo_test() accepts a draw function which will be called once for
+ * each testable backend. The following checks will be performed for
+ * each backend:
+ *
+ * 1) If draw() does not return CAIRO_TEST_SUCCESS then this backend
+ * fails.
+ *
+ * 2) Otherwise, if cairo_status(cr) indicates an error then this
+ * backend fails.
+ *
+ * 3) Otherwise, if the image size is 0, then this backend passes.
+ *
+ * 4) Otherwise, if every channel of every pixel exactly matches the
+ * reference image then this backend passes. If not, this backend
+ * fails.
+ *
+ * The overall test result is PASS if and only if there is at least
+ * one backend that is tested and if all tested backend pass according
+ * to the four criteria above.
+ */
cairo_test_status_t
cairo_test (cairo_test_t *test, cairo_test_draw_function_t draw);
+/* Like cairo_test, but the text is expected to fail for the stated
+ * reason. Any test calling this variant should be listed in the
+ * XFAIL_TESTS list in Makefile.am. */
cairo_test_status_t
cairo_test_expect_failure (cairo_test_t *test,
cairo_test_draw_function_t draw,
const char *reason);
+/* cairo_test_init() and cairo_test_log() exist to help in writing
+ * tests for which cairo_test() is not appropriate for one reason or
+ * another. For example, some tests might not be doing any drawing at
+ * all, or may need to create their own cairo_t rather than be handed
+ * one by cairo_test.
+ */
+
+/* Initialize test-specific resources, (log files, etc.) */
+void
+cairo_test_init (const char *test_name);
+
+/* Print a message to the log file, ala printf. */
+void
+cairo_test_log (const char *fmt, ...);
+
+/* Helper functions that take care of finding source images even when
+ * building in a non-srcdir manner, (ie. the tests will be run in a
+ * directory that is different from the one where the source image
+ * exists). */
cairo_surface_t *
cairo_test_create_surface_from_png (const char *filename);
@@ -87,9 +130,6 @@ cairo_pattern_t *
cairo_test_create_pattern_from_png (const char *filename);
void
-cairo_test_log (const char *fmt, ...);
-
-void
xasprintf (char **strp, const char *fmt, ...);
#endif
diff --git a/test/pthread-show-text.c b/test/pthread-show-text.c
new file mode 100644
index 00000000..b0e37ff7
--- /dev/null
+++ b/test/pthread-show-text.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth@cworth.org>
+ */
+
+/* Test case for bug #4299:
+
+ Assertion fails in "cairo-font.c" when using multithreads
+ https://bugs.freedesktop.org/show_bug.cgi?id=4299
+*/
+
+#include "cairo-test.h"
+#include "xmalloc.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <pthread.h>
+#if HAVE_FCFINI
+#include <fontconfig/fontconfig.h>
+#endif
+
+static void *
+start (void *closure)
+{
+ cairo_surface_t *surface;
+ cairo_t *cr;
+ int i;
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 100, 100);
+ cr = cairo_create (surface);
+
+ cairo_save (cr);
+ {
+ cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
+ cairo_paint (cr);
+ }
+ cairo_restore (cr);
+
+ cairo_move_to (cr, 10, 10);
+
+ for (i=0; i < 3; i++) {
+ cairo_set_font_size (cr, 8 + i % 3);
+ cairo_show_text (cr, "Hello world.\n");
+ }
+
+ cairo_destroy (cr);
+ cairo_surface_destroy (surface);
+
+ return NULL;
+}
+
+int
+main (int argc, char *argv[0])
+{
+ int err;
+ int i, num_threads;
+ pthread_t *pthread;
+
+ if (argc > 1) {
+ num_threads = atoi (argv[1]);
+ } else {
+ num_threads = 10;
+ }
+
+ cairo_test_init ("pthread-show-text");
+
+ cairo_test_log ("Running with %d threads.\n", num_threads);
+
+ pthread = xmalloc (num_threads * sizeof (pthread_t));
+
+ for (i = 0; i < num_threads; i++) {
+ err = pthread_create (&pthread[i], NULL, start, NULL);
+ if (err) {
+ cairo_test_log ("pthread_create failed: %s\n", strerror(err));
+ return CAIRO_TEST_FAILURE;
+ }
+ }
+
+ for (i = 0; i < num_threads; i++)
+ pthread_join (pthread[i], NULL);
+
+ free (pthread);
+
+ cairo_debug_reset_static_data ();
+#if HAVE_FCFINI
+ FcFini ();
+#endif
+
+ return CAIRO_TEST_SUCCESS;
+}