From 2cd77406e1bff9919762969704a561690de91e1a Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Sun, 23 Sep 2012 02:13:38 +0200 Subject: [PATCH] tests: Add GESProject tests --- tests/check/Makefile.am | 8 +- tests/check/ges/project.c | 437 ++++++++++++++++++++++++++++++++++++++ tests/check/ges/test-project.xges | 28 +++ tests/check/ges/test.xptv | 50 ----- 4 files changed, 471 insertions(+), 52 deletions(-) create mode 100644 tests/check/ges/project.c create mode 100644 tests/check/ges/test-project.xges delete mode 100644 tests/check/ges/test.xptv diff --git a/tests/check/Makefile.am b/tests/check/Makefile.am index d737150..0ecf7e0 100644 --- a/tests/check/Makefile.am +++ b/tests/check/Makefile.am @@ -39,7 +39,8 @@ check_PROGRAMS = \ ges/titles\ ges/transition \ ges/overlays\ - ges/text_properties + ges/text_properties\ + ges/project noinst_LTLIBRARIES=$(testutils_noisnt_libraries) noinst_HEADERS=$(testutils_noinst_headers) @@ -49,4 +50,7 @@ TESTS = $(check_PROGRAMS) AM_CFLAGS = $(common_cflags) -UG_DISABLE_ASSERT -UG_DISABLE_CAST_CHECKS LDADD = $(common_ldadd) libtestutils.la -EXTRA_DIST = #gst-plugins-bad.supp +EXTRA_DIST = \ + ges/test-project.xges \ + ges/audio_only.ogg \ + ges/audio_video.ogg diff --git a/tests/check/ges/project.c b/tests/check/ges/project.c new file mode 100644 index 0000000..55a5c04 --- /dev/null +++ b/tests/check/ges/project.c @@ -0,0 +1,437 @@ +/* GStreamer Editing Services + * + * Copyright (C) <2012> Thibault Saunier + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "test-utils.h" +#include +#include + +GST_START_TEST (test_project_simple) +{ + gchar *id; + GESProject *project; + GESTimeline *timeline; + + ges_init (); + + project = GES_PROJECT (ges_asset_request (GES_TYPE_TIMELINE, NULL, NULL)); + fail_unless (GES_IS_PROJECT (project)); + assert_equals_string (ges_asset_get_id (GES_ASSET (project)), "project-0"); + + timeline = GES_TIMELINE (ges_asset_extract (GES_ASSET (project), NULL)); + fail_unless (GES_IS_TIMELINE (timeline)); + id = ges_extractable_get_id (GES_EXTRACTABLE (timeline)); + assert_equals_string (id, "project-0"); + + g_free (id); +} + +GST_END_TEST; + +static void +asset_removed_add_cb (GESProject * project, GESAsset * asset, gboolean * called) +{ + *called = TRUE; +} + +GST_START_TEST (test_project_add_assets) +{ + GESProject *project; + GESAsset *asset; + gboolean added_cb_called = FALSE; + gboolean removed_cb_called = FALSE; + + ges_init (); + + project = GES_PROJECT (ges_asset_request (GES_TYPE_TIMELINE, NULL, NULL)); + fail_unless (GES_IS_PROJECT (project)); + fail_unless (GES_IS_PROJECT (project)); + + g_signal_connect (project, "asset-added", + (GCallback) asset_removed_add_cb, &added_cb_called); + g_signal_connect (project, "asset-removed", + (GCallback) asset_removed_add_cb, &removed_cb_called); + + asset = ges_asset_request (GES_TYPE_TIMELINE_TEST_SOURCE, NULL, NULL); + fail_unless (GES_IS_ASSET (asset)); + + fail_unless (ges_project_add_asset (project, asset)); + fail_unless (added_cb_called); + ASSERT_OBJECT_REFCOUNT (project, "The project", 2); + ASSERT_OBJECT_REFCOUNT (asset, "The asset (1 for project and one for " + "us + 1 cache)", 3); + + fail_unless (ges_project_remove_asset (project, asset)); + fail_unless (removed_cb_called); + gst_object_unref (asset); + gst_object_unref (project); + + ASSERT_OBJECT_REFCOUNT (asset, "The asset (1 ref in cache)", 1); + ASSERT_OBJECT_REFCOUNT (project, "The project (1 ref in cache)", 1); + +} + +GST_END_TEST; + +static void +error_loading_asset_cb (GESProject * project, GError * error, gchar * id, + GType extractable_type, GMainLoop * mainloop) +{ + fail_unless (g_error_matches (error, GST_PARSE_ERROR, + GST_PARSE_ERROR_NO_SUCH_ELEMENT)); + g_main_loop_quit (mainloop); +} + +GST_START_TEST (test_project_unexistant_effect) +{ + GESProject *project; + GMainLoop *mainloop; + gboolean added_cb_called = FALSE; + gboolean removed_cb_called = FALSE; + + ges_init (); + + project = GES_PROJECT (ges_asset_request (GES_TYPE_TIMELINE, NULL, NULL)); + fail_unless (GES_IS_PROJECT (project)); + fail_unless (GES_IS_PROJECT (project)); + + mainloop = g_main_loop_new (NULL, FALSE); + g_signal_connect (project, "asset-added", + (GCallback) asset_removed_add_cb, &added_cb_called); + g_signal_connect (project, "asset-removed", + (GCallback) asset_removed_add_cb, &removed_cb_called); + g_signal_connect (project, "error-loading-asset", + (GCallback) error_loading_asset_cb, mainloop); + + fail_unless (ges_project_create_asset (project, "nowaythiselementexists", + GES_TYPE_TRACK_PARSE_LAUNCH_EFFECT)); + g_main_loop_run (mainloop); + + /* And.... try again! */ + fail_unless (ges_project_create_asset (project, "nowaythiselementexists", + GES_TYPE_TRACK_PARSE_LAUNCH_EFFECT)); + g_main_loop_run (mainloop); + + fail_if (added_cb_called); + fail_if (removed_cb_called); + + ASSERT_OBJECT_REFCOUNT (project, "The project", 2); + gst_object_unref (project); + g_main_loop_unref (mainloop); + + ASSERT_OBJECT_REFCOUNT (project, "The project (1 ref in cache)", 1); + +} + +GST_END_TEST; + +static GMainLoop *mainloop; + +static void +asset_added_cb (GESProject * project, GESAsset * asset) +{ + gchar *uri = ges_test_file_uri ("audio_video.ogg"); + GstDiscovererInfo *info; + + if (ges_asset_get_extractable_type (asset) == + GES_TYPE_TRACK_PARSE_LAUNCH_EFFECT) { + assert_equals_string (ges_asset_get_id (asset), "agingtv"); + } else { + info = ges_asset_filesource_get_info (GES_ASSET_FILESOURCE (asset)); + fail_unless (GST_IS_DISCOVERER_INFO (info)); + assert_equals_string (ges_asset_get_id (asset), uri); + } + + g_free (uri); +} + +static void +project_loaded_cb (GESProject * project, GESTimeline * timeline) +{ + g_main_loop_quit (mainloop); +} + +static gchar * +_set_new_uri (GESProject * project, GError * error, GESAsset * wrong_asset) +{ + fail_unless (!g_strcmp0 (ges_asset_get_id (wrong_asset), + "file:///test/not/exisiting")); + + return ges_test_file_uri ("audio_video.ogg"); +} + +static void +_test_project (GESProject * project, GESTimeline * timeline) +{ + guint a_meta; + gchar *media_uri; + GESTrack *track; + const GList *profiles; + GstEncodingContainerProfile *profile; + GList *tracks, *tmp, *tmptckobj, *tlobjs; + + fail_unless (GES_IS_TIMELINE (timeline)); + assert_equals_int (g_list_length (timeline->layers), 2); + + assert_equals_string (ges_meta_container_get_string (GES_META_CONTAINER + (project), "name"), "Example project"); + tlobjs = + ges_timeline_layer_get_objects (GES_TIMELINE_LAYER (timeline->layers-> + data)); + fail_unless (ges_meta_container_get_uint (GES_META_CONTAINER (timeline-> + layers->data), "a", &a_meta)); + assert_equals_int (a_meta, 3); + assert_equals_int (g_list_length (tlobjs), 1); + media_uri = ges_test_file_uri ("audio_video.ogg"); + assert_equals_string (ges_asset_get_id (ges_extractable_get_asset + (GES_EXTRACTABLE (tlobjs->data))), media_uri); + g_free (media_uri); + + /* Check tracks and the objects they contain */ + tracks = ges_timeline_get_tracks (timeline); + assert_equals_int (g_list_length (tracks), 2); + for (tmp = tracks; tmp; tmp = tmp->next) { + GList *trackobjs; + track = GES_TRACK (tmp->data); + + trackobjs = ges_track_get_objects (track); + switch (track->type) { + case GES_TRACK_TYPE_VIDEO: + GST_DEBUG_OBJECT (track, "Testing track"); + assert_equals_int (g_list_length (trackobjs), 2); + for (tmptckobj = trackobjs; tmptckobj; tmptckobj = tmptckobj->next) { + GESTrackObject *tckobj = GES_TRACK_OBJECT (tmptckobj->data); + + if (GES_IS_TRACK_EFFECT (tckobj)) { + guint nb_scratch_lines; + + ges_track_object_get_child_properties (tckobj, "scratch-lines", + &nb_scratch_lines, NULL); + assert_equals_int (nb_scratch_lines, 12); + + gnl_object_check (ges_track_object_get_gnlobject (tckobj), + 0, 1000000000, 0, 1000000000, 0, TRUE); + } else { + gnl_object_check (ges_track_object_get_gnlobject (tckobj), + 0, 1000000000, 0, 1000000000, 1, TRUE); + } + } + break; + case GES_TRACK_TYPE_AUDIO: + assert_equals_int (g_list_length (trackobjs), 2); + break; + default: + g_assert (1); + } + + g_list_free_full (trackobjs, gst_object_unref); + + } + g_list_free_full (tracks, gst_object_unref); + + /* Now test the encoding profile */ + profiles = ges_project_list_encoding_profiles (project); + assert_equals_int (g_list_length ((GList *) profiles), 1); + profile = profiles->data; + fail_unless (GST_IS_ENCODING_CONTAINER_PROFILE (profile)); + profiles = gst_encoding_container_profile_get_profiles (profile); + assert_equals_int (g_list_length ((GList *) profiles), 2); +} + +GST_START_TEST (test_project_load_xges) +{ + gboolean saved; + GESProject *project; + GESTimeline *timeline; + GESAsset *formatter_asset; + gchar *tmpuri, *uri = ges_test_file_uri ("test-project.xges"); + + project = ges_project_new (uri); + fail_unless (GES_IS_PROJECT (project)); + + /* Connect the signals */ + g_signal_connect (project, "asset-added", (GCallback) asset_added_cb, NULL); + g_signal_connect (project, "loaded", (GCallback) project_loaded_cb, NULL); + + /* Make sure we update the project's dummy URL to some actual URL */ + g_signal_connect (project, "missing-uri", (GCallback) _set_new_uri, NULL); + + /* Now extract a timeline from it */ + GST_LOG ("Loading project"); + timeline = GES_TIMELINE (ges_asset_extract (GES_ASSET (project), NULL)); + fail_unless (GES_IS_TIMELINE (timeline)); + + mainloop = g_main_loop_new (NULL, FALSE); + g_main_loop_run (mainloop); + GST_LOG ("Test first loading"); + _test_project (project, timeline); + g_free (uri); + + tmpuri = g_build_filename (g_get_tmp_dir (), "test-project_TMP.xges", NULL); + uri = gst_filename_to_uri (tmpuri, NULL); + g_free (tmpuri); + + formatter_asset = ges_asset_request (GES_TYPE_FORMATTER, "ges", NULL); + saved = + ges_project_save (project, timeline, uri, formatter_asset, TRUE, NULL); + fail_unless (saved); + gst_object_unref (timeline); + gst_object_unref (project); + + project = ges_project_new (uri); + ASSERT_OBJECT_REFCOUNT (project, "Our + cache", 2); + g_signal_connect (project, "asset-added", (GCallback) asset_added_cb, NULL); + g_signal_connect (project, "loaded", (GCallback) project_loaded_cb, NULL); + + GST_LOG ("Loading saved project"); + timeline = GES_TIMELINE (ges_asset_extract (GES_ASSET (project), NULL)); + fail_unless (GES_IS_TIMELINE (timeline)); + g_main_loop_run (mainloop); + _test_project (project, timeline); + gst_object_unref (timeline); + gst_object_unref (project); + g_free (uri); + + ASSERT_OBJECT_REFCOUNT (project, "Still 1 ref for asset cache", 1); + + g_main_loop_unref (mainloop); +} + +GST_END_TEST; + +/* FIXME This test does not pass for some bad reason */ +#if 0 +static void +project_loaded_now_play_cb (GESProject * project, GESTimeline * timeline) +{ + GstBus *bus; + GstMessage *message; + gboolean carry_on = TRUE; + + GESTimelinePipeline *pipeline = ges_timeline_pipeline_new (); + + fail_unless (ges_timeline_pipeline_add_timeline (pipeline, timeline)); + + bus = gst_element_get_bus (GST_ELEMENT (pipeline)); + fail_if (gst_element_set_state (GST_ELEMENT (pipeline), + GST_STATE_PAUSED) == GST_STATE_CHANGE_FAILURE); + + GST_DEBUG ("Let's poll the bus"); + + while (carry_on) { + message = gst_bus_poll (bus, GST_MESSAGE_ANY, GST_SECOND / 10); + if (message) { + GST_ERROR ("GOT MESSAGE: %" GST_PTR_FORMAT, message); + switch (GST_MESSAGE_TYPE (message)) { + case GST_MESSAGE_EOS: + /* we should check if we really finished here */ + GST_WARNING ("Got an EOS, we did not even start!"); + carry_on = FALSE; + fail_if (TRUE); + break; + case GST_MESSAGE_SEGMENT_START: + case GST_MESSAGE_SEGMENT_DONE: + /* We shouldn't see any segement messages, since we didn't do a segment seek */ + GST_WARNING ("Saw a Segment start/stop"); + fail_if (TRUE); + break; + case GST_MESSAGE_ERROR: + fail_error_message (message); + break; + case GST_MESSAGE_ASYNC_DONE: + GST_DEBUG ("prerolling done"); + carry_on = FALSE; + break; + default: + break; + } + gst_mini_object_unref (GST_MINI_OBJECT (message)); + } + } + + fail_if (gst_element_set_state (GST_ELEMENT (pipeline), + GST_STATE_READY) == GST_STATE_CHANGE_FAILURE); + gst_object_unref (pipeline); + g_main_loop_quit (mainloop); +} + + +GST_START_TEST (test_load_xges_and_play) +{ + GESProject *project; + GESTimeline *timeline; + gchar *uri = ges_test_file_uri ("test-project_TMP.xges"); + + project = ges_project_new (uri); + fail_unless (GES_IS_PROJECT (project)); + + mainloop = g_main_loop_new (NULL, FALSE); + /* Connect the signals */ + g_signal_connect (project, "loaded", (GCallback) project_loaded_now_play_cb, + NULL); + + /* Now extract a timeline from it */ + timeline = GES_TIMELINE (ges_asset_extract (GES_ASSET (project), NULL)); + fail_unless (GES_IS_TIMELINE (timeline)); + + g_main_loop_run (mainloop); + + g_free (uri); + gst_object_unref (project); + gst_object_unref (timeline); + g_main_loop_unref (mainloop); +} + +GST_END_TEST; +#endif + +static Suite * +ges_suite (void) +{ + Suite *s = suite_create ("ges-project"); + TCase *tc_chain = tcase_create ("project"); + + suite_add_tcase (s, tc_chain); + + tcase_add_test (tc_chain, test_project_simple); + tcase_add_test (tc_chain, test_project_add_assets); + tcase_add_test (tc_chain, test_project_load_xges); + /*tcase_add_test (tc_chain, test_load_xges_and_play); */ + tcase_add_test (tc_chain, test_project_unexistant_effect); + + return s; +} + +int +main (int argc, char **argv) +{ + int nf; + + Suite *s = ges_suite (); + SRunner *sr = srunner_create (s); + + gst_check_init (&argc, &argv); + ges_init (); + + srunner_run_all (sr, CK_NORMAL); + nf = srunner_ntests_failed (sr); + srunner_free (sr); + + return nf; +} diff --git a/tests/check/ges/test-project.xges b/tests/check/ges/test-project.xges new file mode 100644 index 0000000..c613e87 --- /dev/null +++ b/tests/check/ges/test-project.xges @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/check/ges/test.xptv b/tests/check/ges/test.xptv deleted file mode 100644 index 0dc3f54..0000000 --- a/tests/check/ges/test.xptv +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- 2.7.4