diff options
-rw-r--r-- | ChangeLog | 13 | ||||
-rw-r--r-- | test/.cvsignore | 3 | ||||
-rw-r--r-- | test/Makefile.am | 7 | ||||
-rw-r--r-- | test/cairo-test.c | 30 | ||||
-rw-r--r-- | test/cairo-test.h | 48 | ||||
-rw-r--r-- | test/pthread-show-text.c | 110 |
6 files changed, 195 insertions, 16 deletions
@@ -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; +} |