harness: add _set_forwarding function

To be able to disable the slightly "magic" forwarding of the
necessary events between the harnesses.

Also introduce a new test-suite for GstHarness, that documents the
feature, and should hopefully expand into documenting most of the
features the harness possesses.

https://bugzilla.gnome.org/show_bug.cgi?id=752746
This commit is contained in:
Havard Graff 2015-07-24 00:41:57 +02:00 committed by Tim-Philipp Müller
parent ffa90b2e72
commit 28100e0b6a
6 changed files with 148 additions and 3 deletions

View file

@ -1232,6 +1232,7 @@ gst_harness_crank_multiple_clock_waits
gst_harness_play gst_harness_play
gst_harness_set_blocking_push_mode gst_harness_set_blocking_push_mode
gst_harness_set_forwarding
gst_harness_create_buffer gst_harness_create_buffer
gst_harness_push gst_harness_push

View file

@ -139,6 +139,7 @@ LIBGSTCHECK_EXPORTED_FUNCS = \
gst_harness_set_caps_str \ gst_harness_set_caps_str \
gst_harness_set_drop_buffers \ gst_harness_set_drop_buffers \
gst_harness_set_blocking_push_mode \ gst_harness_set_blocking_push_mode \
gst_harness_set_forwarding \
gst_harness_set_propose_allocator \ gst_harness_set_propose_allocator \
gst_harness_set_sink_caps \ gst_harness_set_sink_caps \
gst_harness_set_src_caps \ gst_harness_set_src_caps \

View file

@ -156,6 +156,8 @@ struct _GstHarnessPrivate
GstCaps *src_caps; GstCaps *src_caps;
GstCaps *sink_caps; GstCaps *sink_caps;
gboolean forwarding;
GstPad *sink_forward_pad; GstPad *sink_forward_pad;
volatile gint recv_buffers; volatile gint recv_buffers;
@ -242,7 +244,7 @@ gst_harness_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
break; break;
} }
if (forward && priv->sink_forward_pad) { if (priv->forwarding && forward && priv->sink_forward_pad) {
gst_pad_push_event (priv->sink_forward_pad, event); gst_pad_push_event (priv->sink_forward_pad, event);
} else { } else {
g_async_queue_push (priv->sink_event_queue, event); g_async_queue_push (priv->sink_event_queue, event);
@ -358,7 +360,7 @@ gst_harness_sink_query (GstPad * pad, GstObject * parent, GstQuery * query)
break; break;
case GST_QUERY_ALLOCATION: case GST_QUERY_ALLOCATION:
{ {
if (priv->sink_forward_pad != NULL) { if (priv->forwarding && priv->sink_forward_pad != NULL) {
GstPad *peer = gst_pad_get_peer (priv->sink_forward_pad); GstPad *peer = gst_pad_get_peer (priv->sink_forward_pad);
g_assert (peer != NULL); g_assert (peer != NULL);
res = gst_pad_query (peer, query); res = gst_pad_query (peer, query);
@ -676,6 +678,9 @@ gst_harness_new_full (GstElement * element,
priv->stress = g_ptr_array_new_with_free_func ( priv->stress = g_ptr_array_new_with_free_func (
(GDestroyNotify) gst_harness_stress_free); (GDestroyNotify) gst_harness_stress_free);
/* we have forwarding on as a default */
gst_harness_set_forwarding (h, TRUE);
return h; return h;
} }
@ -1400,6 +1405,40 @@ gst_harness_set_blocking_push_mode (GstHarness * h)
priv->blocking_push_mode = TRUE; priv->blocking_push_mode = TRUE;
} }
/**
* gst_harness_set_forwarding:
* @h: a #GstHarness
* @forwarding: a #gboolean to enable/disable forwarding
*
* As a convenience, a src-harness will forward %GST_EVENT_STREAM_START,
* %GST_EVENT_CAPS and %GST_EVENT_SEGMENT to the main-harness if forwarding
* is enabled, and forward any sticky-events from the main-harness to
* the sink-harness. It will also forward the %GST_QUERY_ALLOCATION.
*
* If forwarding is disabled, the user will have to either manually push
* these events from the src-harness using gst_harness_src_push_event, or
* create and push them manually. While this will allow full control and
* inspection of these events, for the most cases having forwarding enabled
* will be sufficient when writing a test where the src-harness' main function
* is providing data for the main-harness.
*
* Forwarding is enabled by default.
*
* MT safe.
*
* Since: 1.6
*/
void
gst_harness_set_forwarding (GstHarness * h, gboolean forwarding)
{
GstHarnessPrivate *priv = h->priv;
priv->forwarding = forwarding;
if (h->src_harness)
gst_harness_set_forwarding (h->src_harness, forwarding);
if (h->sink_harness)
gst_harness_set_forwarding (h->sink_harness, forwarding);
}
/** /**
* gst_harness_create_buffer: * gst_harness_create_buffer:
* @h: a #GstHarness * @h: a #GstHarness
@ -1995,6 +2034,7 @@ gst_harness_add_src_harness (GstHarness * h,
h->src_harness->priv->sink_forward_pad = gst_object_ref (h->srcpad); h->src_harness->priv->sink_forward_pad = gst_object_ref (h->srcpad);
gst_harness_use_testclock (h->src_harness); gst_harness_use_testclock (h->src_harness);
h->src_harness->priv->has_clock_wait = has_clock_wait; h->src_harness->priv->has_clock_wait = has_clock_wait;
gst_harness_set_forwarding (h->src_harness, h->priv->forwarding);
} }
/** /**
@ -2186,7 +2226,9 @@ gst_harness_add_sink_harness (GstHarness * h, GstHarness * sink_harness)
h->sink_harness = sink_harness; h->sink_harness = sink_harness;
priv->sink_forward_pad = gst_object_ref (h->sink_harness->srcpad); priv->sink_forward_pad = gst_object_ref (h->sink_harness->srcpad);
gst_harness_use_testclock (h->sink_harness); gst_harness_use_testclock (h->sink_harness);
if (priv->forwarding)
gst_pad_sticky_events_foreach (h->sinkpad, forward_sticky_events, h); gst_pad_sticky_events_foreach (h->sinkpad, forward_sticky_events, h);
gst_harness_set_forwarding (h->sink_harness, priv->forwarding);
} }
/** /**

View file

@ -126,10 +126,13 @@ gboolean gst_harness_crank_single_clock_wait (GstHarness * h);
gboolean gst_harness_crank_multiple_clock_waits (GstHarness * h, gboolean gst_harness_crank_multiple_clock_waits (GstHarness * h,
guint waits); guint waits);
/* misc */
void gst_harness_play (GstHarness * h); void gst_harness_play (GstHarness * h);
void gst_harness_set_blocking_push_mode (GstHarness * h); void gst_harness_set_blocking_push_mode (GstHarness * h);
void gst_harness_set_forwarding (GstHarness * h, gboolean forwarding);
/* buffers */ /* buffers */
GstBuffer * gst_harness_create_buffer (GstHarness * h, gsize size); GstBuffer * gst_harness_create_buffer (GstHarness * h, gsize size);

View file

@ -158,6 +158,7 @@ check_PROGRAMS = \
libs/flowcombiner \ libs/flowcombiner \
libs/sparsefile \ libs/sparsefile \
libs/collectpads \ libs/collectpads \
libs/gstharness \
libs/gstnetclientclock \ libs/gstnetclientclock \
libs/gstnettimeprovider \ libs/gstnettimeprovider \
libs/gsttestclock \ libs/gsttestclock \

View file

@ -0,0 +1,97 @@
/*
* Tests and examples of GstHarness
*
* Copyright (C) 2015 Havard Graff <havard@pexip.com>
*
* 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 <gst/check/gstcheck.h>
#include <gst/check/gstharness.h>
GST_START_TEST(test_src_harness)
{
GstHarness * h = gst_harness_new ("identity");
/* add a fakesrc that syncs to the clock and a
capsfilter that adds some caps to it */
gst_harness_add_src_parse (h,
"fakesrc sync=1 ! capsfilter caps=\"mycaps\"", TRUE);
/* this cranks the clock and transfers the resulting buffer
from the src-harness into the identity element */
gst_harness_push_from_src (h);
/* verify that identity outputs a buffer by pulling and unreffing */
gst_buffer_unref (gst_harness_pull (h));
gst_harness_teardown (h);
}
GST_END_TEST;
GST_START_TEST(test_src_harness_no_forwarding)
{
GstHarness * h = gst_harness_new ("identity");
/* turn of forwarding of necessary events */
gst_harness_set_forwarding (h, FALSE);
/* add a fakesrc that syncs to the clock and a
capsfilter that adds some caps to it */
gst_harness_add_src_parse (h,
"fakesrc sync=1 ! capsfilter caps=\"mycaps\"", TRUE);
/* start the fakesrc to produce the first events */
gst_harness_play (h->src_harness);
/* transfer STREAM_START event */
gst_harness_src_push_event (h);
/* crank the clock to produce the CAPS and SEGMENT events */
gst_harness_crank_single_clock_wait (h->src_harness);
/* transfer CAPS event */
gst_harness_src_push_event (h);
/* transfer SEGMENT event */
gst_harness_src_push_event (h);
/* now transfer the buffer produced by exploiting
the ability to say 0 cranks but 1 push */
gst_harness_src_crank_and_push_many (h, 0, 1);
/* and verify that the identity element outputs it */
gst_buffer_unref (gst_harness_pull (h));
gst_harness_teardown (h);
}
GST_END_TEST;
static Suite *
gst_harness_suite (void)
{
Suite *s = suite_create ("GstHarness");
TCase *tc_chain = tcase_create ("harness");
suite_add_tcase (s, tc_chain);
tcase_add_test (tc_chain, test_src_harness);
tcase_add_test (tc_chain, test_src_harness_no_forwarding);
return s;
}
GST_CHECK_MAIN (gst_harness);