From 18682cacc1429263465b0777be82ba0aa7ee16dc Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Thu, 29 Sep 2005 18:37:48 +0000 Subject: [PATCH] check/: fix tests for the new warning Original commit message from CVS: * check/gst/gstbin.c: * check/states/sinks.c: fix tests for the new warning * check/gst/gstpipeline.c: add a test for pipeline and bus interaction * gst/gstelement.c: elements should be NULL if they get disposed; add a warning if not --- ChangeLog | 10 ++++ check/gst/gstbin.c | 4 ++ check/gst/gstpipeline.c | 104 +++++++++++++++++++++++++++++++++++++++++- check/states/sinks.c | 3 ++ gst/gstelement.c | 5 +- tests/check/generic/sinks.c | 3 ++ tests/check/gst/gstbin.c | 4 ++ tests/check/gst/gstpipeline.c | 104 +++++++++++++++++++++++++++++++++++++++++- 8 files changed, 234 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4222476..41e3999 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,15 @@ 2005-09-29 Thomas Vander Stichele + * check/gst/gstbin.c: + * check/states/sinks.c: + fix tests for the new warning + * check/gst/gstpipeline.c: + add a test for pipeline and bus interaction + * gst/gstelement.c: + elements should be NULL if they get disposed; add a warning if not + +2005-09-29 Thomas Vander Stichele + * gst/gstobject.c: for 2.6 refcounting, make debug log more correct by printing the actual refcounts at the time of swap (Wim) diff --git a/check/gst/gstbin.c b/check/gst/gstbin.c index c7bedcd..4d6c7f8 100644 --- a/check/gst/gstbin.c +++ b/check/gst/gstbin.c @@ -133,6 +133,8 @@ GST_START_TEST (test_message_state_changed) ASSERT_OBJECT_REFCOUNT (bin, "bin", 1); /* clean up */ + gst_element_set_state (GST_ELEMENT (bin), GST_STATE_NULL); + gst_object_unref (bus); gst_object_unref (bin); } @@ -192,6 +194,8 @@ GST_START_TEST (test_message_state_changed_child) ASSERT_OBJECT_REFCOUNT (bin, "bin", 1); /* clean up */ + fail_unless (gst_element_set_state (GST_ELEMENT (bin), GST_STATE_NULL) + == GST_STATE_CHANGE_SUCCESS); gst_object_unref (bus); gst_object_unref (bin); } diff --git a/check/gst/gstpipeline.c b/check/gst/gstpipeline.c index d876645..422c245 100644 --- a/check/gst/gstpipeline.c +++ b/check/gst/gstpipeline.c @@ -108,7 +108,7 @@ GST_START_TEST (test_async_state_change_fake) GST_END_TEST; -GST_START_TEST (test_bus) +GST_START_TEST (test_get_bus) { GstPipeline *pipeline; GstBus *bus; @@ -129,6 +129,107 @@ GST_START_TEST (test_bus) GST_END_TEST; +GMainLoop *loop = NULL; + +gboolean +message_received (GstBus * bus, GstMessage * message, gpointer data) +{ + GstElement *pipeline = GST_ELEMENT (data); + GstMessageType type = message->type; + + GST_DEBUG ("message received"); + switch (type) { + case GST_MESSAGE_STATE_CHANGED: + { + GstState old, new; + + GST_DEBUG ("state change message received"); + gst_message_parse_state_changed (message, &old, &new); + GST_DEBUG ("new state %d", new); + if (message->src == GST_OBJECT (pipeline) && new == GST_STATE_PLAYING) { + GST_DEBUG ("quitting main loop"); + g_main_loop_quit (loop); + } + } + break; + case GST_MESSAGE_ERROR: + { + g_print ("error\n"); + } + break; + default: + break; + } + + return TRUE; +} + +GST_START_TEST (test_bus) +{ + GstElement *pipeline; + GstElement *src, *sink; + GstBus *bus; + guint id; + GstState current; + + pipeline = gst_pipeline_new (NULL); + fail_unless (pipeline != NULL, "Could not create pipeline"); + ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1); + g_object_set (pipeline, "play-timeout", 0LL, NULL); + + src = gst_element_factory_make ("fakesrc", NULL); + fail_unless (src != NULL); + sink = gst_element_factory_make ("fakesink", NULL); + fail_unless (sink != NULL); + + gst_bin_add_many (GST_BIN (pipeline), src, sink, NULL); + fail_unless (gst_element_link (src, sink)); + + bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); + ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline after get_bus", 1); + ASSERT_OBJECT_REFCOUNT (bus, "bus", 2); + + id = gst_bus_add_watch (bus, message_received, pipeline); + ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline after add_watch", 1); + ASSERT_OBJECT_REFCOUNT (bus, "bus after add_watch", 3); + + gst_element_set_state_async (pipeline, GST_STATE_PLAYING); + loop = g_main_loop_new (NULL, FALSE); + GST_DEBUG ("going into main loop"); + g_main_loop_run (loop); + GST_DEBUG ("left main loop"); + + /* PLAYING now */ + + ASSERT_OBJECT_REFCOUNT_BETWEEN (pipeline, "pipeline after gone to playing", 1, + 3); + + /* cleanup */ + GST_DEBUG ("cleanup"); + + /* current semantics require us to go step by step; this will change */ + gst_element_set_state (pipeline, GST_STATE_PAUSED); + gst_element_set_state (pipeline, GST_STATE_READY); + gst_element_set_state (pipeline, GST_STATE_NULL); + fail_unless (gst_element_get_state (pipeline, ¤t, NULL, NULL) == + GST_STATE_CHANGE_SUCCESS); + fail_unless (current == GST_STATE_NULL, "state is not NULL but %d", current); + ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline at start of cleanup", 1); + ASSERT_OBJECT_REFCOUNT (bus, "bus at start of cleanup", 3); + + fail_unless (g_source_remove (id)); + ASSERT_OBJECT_REFCOUNT (bus, "bus after removing source", 2); + + GST_DEBUG ("unreffing pipeline"); + gst_object_unref (pipeline); + + + ASSERT_OBJECT_REFCOUNT (bus, "bus after unref pipeline", 1); + gst_object_unref (bus); +} + +GST_END_TEST; + Suite * gst_pipeline_suite (void) { @@ -139,6 +240,7 @@ gst_pipeline_suite (void) tcase_add_test (tc_chain, test_async_state_change_empty); tcase_add_test (tc_chain, test_async_state_change_fake_ready); tcase_add_test (tc_chain, test_async_state_change_fake); + tcase_add_test (tc_chain, test_get_bus); tcase_add_test (tc_chain, test_bus); return s; diff --git a/check/states/sinks.c b/check/states/sinks.c index 92d2eda..c9ccd49 100644 --- a/check/states/sinks.c +++ b/check/states/sinks.c @@ -51,6 +51,9 @@ GST_START_TEST (test_sink) ret = gst_element_set_state (sink, GST_STATE_READY); fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "failed to go to ready"); + ret = gst_element_set_state (sink, GST_STATE_NULL); + fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "failed to go to null"); + gst_object_unref (sink); } diff --git a/gst/gstelement.c b/gst/gstelement.c index 3e9963f..6a368dd 100644 --- a/gst/gstelement.c +++ b/gst/gstelement.c @@ -2121,6 +2121,9 @@ gst_element_dispose (GObject * object) GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "dispose"); + g_return_if_fail (GST_STATE (element) == GST_STATE_NULL); + g_return_if_fail (GST_STATE_PENDING (element) == GST_STATE_VOID_PENDING); + /* first we break all our links with the outside */ while (element->pads) { gst_element_remove_pad (element, GST_PAD_CAST (element->pads->data)); @@ -2135,7 +2138,7 @@ gst_element_dispose (GObject * object) gst_object_replace ((GstObject **) & element->bus, NULL); GST_UNLOCK (element); - GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "dispose parent"); + GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "parent class dispose"); G_OBJECT_CLASS (parent_class)->dispose (object); } diff --git a/tests/check/generic/sinks.c b/tests/check/generic/sinks.c index 92d2eda..c9ccd49 100644 --- a/tests/check/generic/sinks.c +++ b/tests/check/generic/sinks.c @@ -51,6 +51,9 @@ GST_START_TEST (test_sink) ret = gst_element_set_state (sink, GST_STATE_READY); fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "failed to go to ready"); + ret = gst_element_set_state (sink, GST_STATE_NULL); + fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "failed to go to null"); + gst_object_unref (sink); } diff --git a/tests/check/gst/gstbin.c b/tests/check/gst/gstbin.c index c7bedcd..4d6c7f8 100644 --- a/tests/check/gst/gstbin.c +++ b/tests/check/gst/gstbin.c @@ -133,6 +133,8 @@ GST_START_TEST (test_message_state_changed) ASSERT_OBJECT_REFCOUNT (bin, "bin", 1); /* clean up */ + gst_element_set_state (GST_ELEMENT (bin), GST_STATE_NULL); + gst_object_unref (bus); gst_object_unref (bin); } @@ -192,6 +194,8 @@ GST_START_TEST (test_message_state_changed_child) ASSERT_OBJECT_REFCOUNT (bin, "bin", 1); /* clean up */ + fail_unless (gst_element_set_state (GST_ELEMENT (bin), GST_STATE_NULL) + == GST_STATE_CHANGE_SUCCESS); gst_object_unref (bus); gst_object_unref (bin); } diff --git a/tests/check/gst/gstpipeline.c b/tests/check/gst/gstpipeline.c index d876645..422c245 100644 --- a/tests/check/gst/gstpipeline.c +++ b/tests/check/gst/gstpipeline.c @@ -108,7 +108,7 @@ GST_START_TEST (test_async_state_change_fake) GST_END_TEST; -GST_START_TEST (test_bus) +GST_START_TEST (test_get_bus) { GstPipeline *pipeline; GstBus *bus; @@ -129,6 +129,107 @@ GST_START_TEST (test_bus) GST_END_TEST; +GMainLoop *loop = NULL; + +gboolean +message_received (GstBus * bus, GstMessage * message, gpointer data) +{ + GstElement *pipeline = GST_ELEMENT (data); + GstMessageType type = message->type; + + GST_DEBUG ("message received"); + switch (type) { + case GST_MESSAGE_STATE_CHANGED: + { + GstState old, new; + + GST_DEBUG ("state change message received"); + gst_message_parse_state_changed (message, &old, &new); + GST_DEBUG ("new state %d", new); + if (message->src == GST_OBJECT (pipeline) && new == GST_STATE_PLAYING) { + GST_DEBUG ("quitting main loop"); + g_main_loop_quit (loop); + } + } + break; + case GST_MESSAGE_ERROR: + { + g_print ("error\n"); + } + break; + default: + break; + } + + return TRUE; +} + +GST_START_TEST (test_bus) +{ + GstElement *pipeline; + GstElement *src, *sink; + GstBus *bus; + guint id; + GstState current; + + pipeline = gst_pipeline_new (NULL); + fail_unless (pipeline != NULL, "Could not create pipeline"); + ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1); + g_object_set (pipeline, "play-timeout", 0LL, NULL); + + src = gst_element_factory_make ("fakesrc", NULL); + fail_unless (src != NULL); + sink = gst_element_factory_make ("fakesink", NULL); + fail_unless (sink != NULL); + + gst_bin_add_many (GST_BIN (pipeline), src, sink, NULL); + fail_unless (gst_element_link (src, sink)); + + bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); + ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline after get_bus", 1); + ASSERT_OBJECT_REFCOUNT (bus, "bus", 2); + + id = gst_bus_add_watch (bus, message_received, pipeline); + ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline after add_watch", 1); + ASSERT_OBJECT_REFCOUNT (bus, "bus after add_watch", 3); + + gst_element_set_state_async (pipeline, GST_STATE_PLAYING); + loop = g_main_loop_new (NULL, FALSE); + GST_DEBUG ("going into main loop"); + g_main_loop_run (loop); + GST_DEBUG ("left main loop"); + + /* PLAYING now */ + + ASSERT_OBJECT_REFCOUNT_BETWEEN (pipeline, "pipeline after gone to playing", 1, + 3); + + /* cleanup */ + GST_DEBUG ("cleanup"); + + /* current semantics require us to go step by step; this will change */ + gst_element_set_state (pipeline, GST_STATE_PAUSED); + gst_element_set_state (pipeline, GST_STATE_READY); + gst_element_set_state (pipeline, GST_STATE_NULL); + fail_unless (gst_element_get_state (pipeline, ¤t, NULL, NULL) == + GST_STATE_CHANGE_SUCCESS); + fail_unless (current == GST_STATE_NULL, "state is not NULL but %d", current); + ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline at start of cleanup", 1); + ASSERT_OBJECT_REFCOUNT (bus, "bus at start of cleanup", 3); + + fail_unless (g_source_remove (id)); + ASSERT_OBJECT_REFCOUNT (bus, "bus after removing source", 2); + + GST_DEBUG ("unreffing pipeline"); + gst_object_unref (pipeline); + + + ASSERT_OBJECT_REFCOUNT (bus, "bus after unref pipeline", 1); + gst_object_unref (bus); +} + +GST_END_TEST; + Suite * gst_pipeline_suite (void) { @@ -139,6 +240,7 @@ gst_pipeline_suite (void) tcase_add_test (tc_chain, test_async_state_change_empty); tcase_add_test (tc_chain, test_async_state_change_fake_ready); tcase_add_test (tc_chain, test_async_state_change_fake); + tcase_add_test (tc_chain, test_get_bus); tcase_add_test (tc_chain, test_bus); return s; -- 2.7.4