From 98f942fd72a98923652746df5317a37b3c7e7f36 Mon Sep 17 00:00:00 2001 From: Robert Bragg Date: Mon, 10 Nov 2008 11:48:00 +0000 Subject: [PATCH] * tests/conform/Makefile.am: * tests/conform/wrapper.sh: * tests/conform/test-conform-main.c: * tests/conform/test-timeline.c: Adds Neil's updates to test-timeline.c so it now works with the new unit testing infrastructure. Also some fixes to ensure wrappers get setup correctly for the timeline tests. * tests/interactive/test-main.c: cast the symbol return pointer as (gpointer *) to avoid warning * tests/conform/test-pick.c: g_assert that the test passes, instead of using exit() * test/conform/ADDING_NEW_TESTS: Fixes a silly typo --- ChangeLog | 20 +++ tests/conform/ADDING_NEW_TESTS | 2 +- tests/conform/Makefile.am | 2 +- tests/conform/test-conform-main.c | 1 + tests/conform/test-pick.c | 12 +- tests/conform/test-timeline.c | 289 +++++++++++++++++++++++------- tests/conform/wrapper.sh | 2 +- tests/interactive/test-main.c | 2 +- 8 files changed, 251 insertions(+), 79 deletions(-) diff --git a/ChangeLog b/ChangeLog index deca049bd..6e27e0d4d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2008-11-10 Robert Bragg + * tests/conform/Makefile.am: + * tests/conform/wrapper.sh: + * tests/conform/test-conform-main.c: + * tests/conform/test-timeline.c: + Adds Neil's updates to test-timeline.c so it now works with the new unit + testing infrastructure. + + Also some fixes to ensure wrappers get setup correctly for the timeline + tests. + + * tests/interactive/test-main.c: + cast the symbol return pointer as (gpointer *) to avoid warning + + * tests/conform/test-pick.c: + g_assert that the test passes, instead of using exit() + + * test/conform/ADDING_NEW_TESTS: + Fixes a silly typo + 2008-11-08 Emmanuele Bassi * tests/conform/Makefile.am: diff --git a/tests/conform/ADDING_NEW_TESTS b/tests/conform/ADDING_NEW_TESTS index 8b5dc71f7..738746788 100644 --- a/tests/conform/ADDING_NEW_TESTS +++ b/tests/conform/ADDING_NEW_TESTS @@ -20,7 +20,7 @@ Add a TEST_CONFORM_SIMPLE() entry in test-conform-main.c Notes: ------ -NB: A test fails if it exists. (regardless of the exist status) +NB: A test fails if it exits. (regardless of the exit status) Don't call clutter_init since that is handled in test-conform-common.c diff --git a/tests/conform/Makefile.am b/tests/conform/Makefile.am index bfc4c2cd4..43fe9dfe5 100644 --- a/tests/conform/Makefile.am +++ b/tests/conform/Makefile.am @@ -20,7 +20,7 @@ test_conformance_SOURCES = \ # For convenience, this provides a way to easily run individual unit tests: .PHONY: wrappers wrappers: test-conformance - for i in `./test-conformance -l`; \ + for i in `./test-conformance -l -m thorough`; \ do \ ln -sf $(top_srcdir)/tests/conform/wrapper.sh `basename $$i`; \ done diff --git a/tests/conform/test-conform-main.c b/tests/conform/test-conform-main.c index 3762e41ec..15a5fedc0 100644 --- a/tests/conform/test-conform-main.c +++ b/tests/conform/test-conform-main.c @@ -43,6 +43,7 @@ main (int argc, char **argv) shared_state->argc_addr = &argc; shared_state->argv_addr = &argv; + TEST_CONFORM_SIMPLE ("/timeline", test_timeline); if (g_test_slow ()) { TEST_CONFORM_SIMPLE ("/timeline", test_timeline_dup_frames); diff --git a/tests/conform/test-pick.c b/tests/conform/test-pick.c index 1fdd938fd..c39f32ba1 100644 --- a/tests/conform/test-pick.c +++ b/tests/conform/test-pick.c @@ -15,7 +15,7 @@ struct _State int y, x; guint32 gids[ACTORS_X * ACTORS_Y]; guint actor_width, actor_height; - int ret; + gboolean pass; }; static gboolean @@ -48,7 +48,7 @@ on_timeout (State *state) } if (!pass) - state->ret = 1; + state->pass = FALSE; } clutter_main_quit (); @@ -63,7 +63,7 @@ test_pick (TestConformSimpleFixture *fixture, int y, x; State state; - state.ret = 0; + state.pass = TRUE; state.stage = clutter_stage_new (); @@ -96,10 +96,8 @@ test_pick (TestConformSimpleFixture *fixture, clutter_actor_destroy (state.stage); - printf ("end result: %s\n", state.ret ? "FAIL" : "pass"); - - if (state.ret) - exit (state.ret); + g_print ("end result: %s\n", state.pass ? "pass" : "FAIL"); + g_assert (state.pass); return; } diff --git a/tests/conform/test-timeline.c b/tests/conform/test-timeline.c index 7ea8f2438..e64184dd3 100644 --- a/tests/conform/test-timeline.c +++ b/tests/conform/test-timeline.c @@ -1,89 +1,196 @@ #include #include #include -#include #include -static void -timeline_1_complete (ClutterTimeline *timeline) +#include "test-conform-common.h" + +/* This test runs three timelines at 30 fps with 10 frames. Some of + the timelines have markers. Once the timelines are run it then + checks that all of the frames were hit, all of the markers were hit + and that the completed signal was fired. The timelines are then run + again but this time with a timeout source that introduces a + delay. This should cause some frames to be skipped. The test is run + again but only the markers and the completed signal is checked + for. */ + +#define FRAME_COUNT 10 + +typedef struct _TimelineData TimelineData; + +struct _TimelineData { - g_debug ("1: Completed"); + int timeline_num; + + guint frame_hit_count[FRAME_COUNT + 1]; + GSList *markers_hit; + guint completed_count; +}; + +static void +timeline_data_init (TimelineData *data, int timeline_num) +{ + memset (data, 0, sizeof (TimelineData)); + data->timeline_num = timeline_num; } static void -timeline_2_complete (ClutterTimeline *timeline) +timeline_data_destroy (TimelineData *data) { - g_debug ("2: Completed"); + g_slist_foreach (data->markers_hit, (GFunc) g_free, NULL); + g_slist_free (data->markers_hit); } static void -timeline_3_complete (ClutterTimeline *timeline) +timeline_complete_cb (ClutterTimeline *timeline, + TimelineData *data) { - g_debug ("3: Completed"); + printf ("%i: Completed\n", data->timeline_num); + data->completed_count++; } static void -timeline_1_new_frame_cb (ClutterTimeline *timeline, gint frame_no) +timeline_new_frame_cb (ClutterTimeline *timeline, + gint frame_no, + TimelineData *data) { - g_debug ("1: Doing frame %d.", frame_no); + printf ("%i: Doing frame %d, delta = %i\n", + data->timeline_num, frame_no, + clutter_timeline_get_delta (timeline, NULL)); + data->frame_hit_count[frame_no]++; } static void -timeline_2_new_frame_cb (ClutterTimeline *timeline, gint frame_no) +timeline_marker_reached_cb (ClutterTimeline *timeline, + const gchar *marker_name, + guint frame_num, + TimelineData *data) { - g_debug ("2: Doing frame %d.", frame_no); + printf ("%i: Marker `%s' (%d) reached, delta = %i\n", + data->timeline_num, marker_name, frame_num, + clutter_timeline_get_delta (timeline, NULL)); + data->markers_hit = g_slist_prepend (data->markers_hit, + g_strdup (marker_name)); } -static void -timeline_3_new_frame_cb (ClutterTimeline *timeline, gint frame_no) +static gboolean +check_timeline (ClutterTimeline *timeline, + TimelineData *data, + gboolean check_missed_frames) { - g_debug ("3: Doing frame %d.", frame_no); -} - -static void -timeline_1_marker_reached (ClutterTimeline *timeline, - const gchar *marker_name, - guint frame_num) -{ - g_print ("1: Marker `%s' (%d) reached\n", marker_name, frame_num); -} - -static void -timeline_2_marker_reached (ClutterTimeline *timeline, - const gchar *marker_name, - guint frame_num) -{ - g_print ("2: Marker `%s' (%d) reached\n", marker_name, frame_num); -} - -static void -timeline_3_marker_reached (ClutterTimeline *timeline, - const gchar *marker_name, - guint frame_num) -{ - g_print ("3: Marker `%s' (%d) reached\n", marker_name, frame_num); -} - -G_MODULE_EXPORT int -test_timeline_main (int argc, char **argv) -{ - ClutterTimeline *timeline_1; - ClutterTimeline *timeline_2; - ClutterTimeline *timeline_3; gchar **markers; gsize n_markers; + guint *marker_reached_count; + gboolean succeeded = TRUE; + GSList *node; + int i; + int missed_frame_count = 0; + int frame_offset; - clutter_init (&argc, &argv); + if (clutter_timeline_get_direction (timeline) == CLUTTER_TIMELINE_BACKWARD) + frame_offset = 0; + else + frame_offset = 1; - timeline_1 = clutter_timeline_new (10, 120); + markers = clutter_timeline_list_markers (timeline, -1, &n_markers); + marker_reached_count = g_new0 (guint, n_markers); + + for (node = data->markers_hit; node; node = node->next) + { + for (i = 0; i < n_markers; i++) + if (!strcmp (node->data, markers[i])) + break; + + if (i < n_markers) + marker_reached_count[i]++; + else + { + printf ("FAIL: unknown marker '%s' hit for %i\n", + (char *) node->data, data->timeline_num); + succeeded = FALSE; + } + } + + for (i = 0; i < n_markers; i++) + if (marker_reached_count[i] != 1) + { + printf ("FAIL: marker '%s' hit %i times for %i\n", + markers[i], marker_reached_count[i], data->timeline_num); + succeeded = FALSE; + } + + if (check_missed_frames) + { + for (i = 0; i < FRAME_COUNT; i++) + if (data->frame_hit_count[i + frame_offset] != 1) + missed_frame_count++; + + if (missed_frame_count) + { + printf ("FAIL: missed %i frame%s for %i\n", + missed_frame_count, missed_frame_count == 1 ? "" : "s", + data->timeline_num); + succeeded = FALSE; + } + } + + if (data->completed_count != 1) + { + printf ("FAIL: timeline %i completed %i times\n", + data->timeline_num, data->completed_count); + succeeded = FALSE; + } + + g_strfreev (markers); + g_free (marker_reached_count); + + return succeeded; +} + +static gboolean +timeout_cb (gpointer data) +{ + clutter_main_quit (); + + return FALSE; +} + +static gboolean +delay_cb (gpointer data) +{ + /* Waste a bit of time so that it will skip frames */ + g_usleep (G_USEC_PER_SEC * 66 / 1000); + + return TRUE; +} + +void +test_timeline (TestConformSimpleFixture *fixture, + gconstpointer data) +{ + ClutterTimeline *timeline_1; + TimelineData data_1; + ClutterTimeline *timeline_2; + TimelineData data_2; + ClutterTimeline *timeline_3; + TimelineData data_3; + gchar **markers; + gsize n_markers; + gboolean pass = TRUE; + + timeline_data_init (&data_1, 1); + timeline_1 = clutter_timeline_new (FRAME_COUNT, 30); clutter_timeline_add_marker_at_frame (timeline_1, "foo", 5); clutter_timeline_add_marker_at_frame (timeline_1, "bar", 5); clutter_timeline_add_marker_at_frame (timeline_1, "baz", 5); + clutter_timeline_add_marker_at_frame (timeline_1, "near-end-marker", 9); + clutter_timeline_add_marker_at_frame (timeline_1, "end-marker", 10); markers = clutter_timeline_list_markers (timeline_1, 5, &n_markers); g_assert (markers != NULL); g_assert (n_markers == 3); g_strfreev (markers); + timeline_data_init (&data_2, 2); timeline_2 = clutter_timeline_clone (timeline_1); clutter_timeline_add_marker_at_frame (timeline_2, "bar", 2); markers = clutter_timeline_list_markers (timeline_2, -1, &n_markers); @@ -92,49 +199,95 @@ test_timeline_main (int argc, char **argv) g_assert (strcmp (markers[0], "bar") == 0); g_strfreev (markers); + timeline_data_init (&data_3, 3); timeline_3 = clutter_timeline_clone (timeline_1); clutter_timeline_set_direction (timeline_3, CLUTTER_TIMELINE_BACKWARD); + clutter_timeline_add_marker_at_frame (timeline_3, "foo", 5); clutter_timeline_add_marker_at_frame (timeline_3, "baz", 8); + clutter_timeline_add_marker_at_frame (timeline_3, "near-end-marker", 1); + clutter_timeline_add_marker_at_frame (timeline_3, "end-marker", 0); g_signal_connect (timeline_1, - "marker-reached", G_CALLBACK (timeline_1_marker_reached), - NULL); + "marker-reached", G_CALLBACK (timeline_marker_reached_cb), + &data_1); g_signal_connect (timeline_1, - "new-frame", G_CALLBACK (timeline_1_new_frame_cb), - NULL); + "new-frame", G_CALLBACK (timeline_new_frame_cb), + &data_1); g_signal_connect (timeline_1, - "completed", G_CALLBACK (timeline_1_complete), - NULL); + "completed", G_CALLBACK (timeline_complete_cb), + &data_1); g_signal_connect (timeline_2, - "marker-reached::bar", G_CALLBACK (timeline_2_marker_reached), - NULL); + "marker-reached::bar", + G_CALLBACK (timeline_marker_reached_cb), + &data_2); g_signal_connect (timeline_2, - "new-frame", G_CALLBACK (timeline_2_new_frame_cb), - NULL); + "new-frame", G_CALLBACK (timeline_new_frame_cb), + &data_2); g_signal_connect (timeline_2, - "completed", G_CALLBACK (timeline_2_complete), - NULL); + "completed", G_CALLBACK (timeline_complete_cb), + &data_2); g_signal_connect (timeline_3, - "marker-reached", G_CALLBACK (timeline_3_marker_reached), - NULL); + "marker-reached", G_CALLBACK (timeline_marker_reached_cb), + &data_3); g_signal_connect (timeline_3, - "new-frame", G_CALLBACK (timeline_3_new_frame_cb), - NULL); + "new-frame", G_CALLBACK (timeline_new_frame_cb), + &data_3); g_signal_connect (timeline_3, - "completed", G_CALLBACK (timeline_3_complete), - NULL); + "completed", G_CALLBACK (timeline_complete_cb), + &data_3); + + printf ("Without delay...\n"); clutter_timeline_start (timeline_1); clutter_timeline_start (timeline_2); clutter_timeline_start (timeline_3); + clutter_threads_add_timeout (2000, timeout_cb, NULL); + clutter_main (); + if (!check_timeline (timeline_1, &data_1, TRUE)) + pass = FALSE; + if (!check_timeline (timeline_2, &data_2, TRUE)) + pass = FALSE; + if (!check_timeline (timeline_3, &data_3, TRUE)) + pass = FALSE; + + printf ("With delay...\n"); + + timeline_data_destroy (&data_1); + timeline_data_init (&data_1, 1); + timeline_data_destroy (&data_2); + timeline_data_init (&data_2, 2); + timeline_data_destroy (&data_3); + timeline_data_init (&data_3, 3); + + clutter_timeline_start (timeline_1); + clutter_timeline_start (timeline_2); + clutter_timeline_start (timeline_3); + + clutter_threads_add_timeout (2000, timeout_cb, NULL); + clutter_threads_add_timeout (99, delay_cb, NULL); + + clutter_main (); + + if (!check_timeline (timeline_1, &data_1, FALSE)) + pass = FALSE; + if (!check_timeline (timeline_2, &data_2, FALSE)) + pass = FALSE; + if (!check_timeline (timeline_3, &data_3, FALSE)) + pass = FALSE; + g_object_unref (timeline_1); g_object_unref (timeline_2); g_object_unref (timeline_3); - return EXIT_SUCCESS; + timeline_data_destroy (&data_1); + timeline_data_destroy (&data_2); + timeline_data_destroy (&data_3); + + g_printf ("Overall result: %s\n", pass == TRUE ? "PASS" : "FAIL"); + g_assert (pass == TRUE); } diff --git a/tests/conform/wrapper.sh b/tests/conform/wrapper.sh index 589db08ef..d9a775307 100755 --- a/tests/conform/wrapper.sh +++ b/tests/conform/wrapper.sh @@ -1,7 +1,7 @@ #!/bin/sh UNIT_TEST=`basename $0` -UNIT_TEST_PATH=`./test-conformance -l |grep $UNIT_TEST` +UNIT_TEST_PATH=`./test-conformance -l -m thorough |grep "$UNIT_TEST\$"` echo "Running: gtester -p $UNIT_TEST_PATH ./test-conformance" echo "" diff --git a/tests/interactive/test-main.c b/tests/interactive/test-main.c index f219a2d77..dd00ac46d 100644 --- a/tests/interactive/test-main.c +++ b/tests/interactive/test-main.c @@ -23,7 +23,7 @@ main (int argc, char **argv) main_symbol_name = g_strdup_printf ("%s_main", unit_test); main_symbol_name = g_strdelimit (main_symbol_name, "-", '_'); - if (!g_module_symbol (module, main_symbol_name, &unit_test_main)) + if (!g_module_symbol (module, main_symbol_name, (gpointer *)&unit_test_main)) g_error ("Failed to look up main symbol for the test: %s", unit_test); ret = unit_test_main (argc - 1, argv + 1);