summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThibault Saunier <tsaunier@igalia.com>2021-05-24 01:20:47 -0400
committerThibault Saunier <tsaunier@igalia.com>2021-05-27 12:23:05 -0400
commit3883be76e735059f7b35ddf33705f2e62e4f72c9 (patch)
treeb16cb4483c74b5cdf184c277b34b9931213c869a
parent8b8a6c8a18d239a16a7f5cae73001f29587266d1 (diff)
validate:scenario: Allow iterating over arrays in `foreach`
We used to only support ranges, but we want to allow iterating over values in an array too. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-devtools/-/merge_requests/248>
-rw-r--r--validate/gst/validate/gst-validate-scenario.c95
-rw-r--r--validate/tests/launcher_tests/foreach_array.validatetest33
2 files changed, 95 insertions, 33 deletions
diff --git a/validate/gst/validate/gst-validate-scenario.c b/validate/gst/validate/gst-validate-scenario.c
index 86de5a4..c84293e 100644
--- a/validate/gst/validate/gst-validate-scenario.c
+++ b/validate/gst/validate/gst-validate-scenario.c
@@ -436,6 +436,7 @@ _action_copy (GstValidateAction * act)
g_strdup (GST_VALIDATE_ACTION_FILENAME (act));
GST_VALIDATE_ACTION_DEBUG (copy) = g_strdup (GST_VALIDATE_ACTION_DEBUG (act));
GST_VALIDATE_ACTION_N_REPEATS (copy) = GST_VALIDATE_ACTION_N_REPEATS (act);
+ GST_VALIDATE_ACTION_RANGE_NAME (copy) = GST_VALIDATE_ACTION_RANGE_NAME (act);
return copy;
}
@@ -2431,7 +2432,7 @@ _foreach_find_iterator (GQuark field_id, GValue * value,
if (!g_strcmp0 (g_quark_to_string (field_id), "actions"))
return TRUE;
- if (!GST_VALUE_HOLDS_INT_RANGE (value))
+ if (!GST_VALUE_HOLDS_INT_RANGE (value) && !GST_VALUE_HOLDS_ARRAY (value))
return TRUE;
if (GST_VALIDATE_ACTION_RANGE_NAME (action)) {
@@ -3815,11 +3816,41 @@ gst_validate_utils_get_structures (gpointer source,
return res;
}
+static GstValidateAction *
+gst_validate_create_subaction (GstValidateScenario * scenario,
+ GstStructure * lvariables, GstValidateAction * action,
+ GstStructure * nstruct, gint it, gint max)
+{
+ GstValidateAction *subaction;
+
+ subaction = gst_validate_action_new (scenario,
+ _find_action_type (gst_structure_get_name (nstruct)), nstruct, FALSE);
+ GST_VALIDATE_ACTION_RANGE_NAME (subaction) =
+ GST_VALIDATE_ACTION_RANGE_NAME (action);
+ GST_VALIDATE_ACTION_FILENAME (subaction) =
+ g_strdup (GST_VALIDATE_ACTION_FILENAME (action));
+ GST_VALIDATE_ACTION_DEBUG (subaction) =
+ g_strdup (GST_VALIDATE_ACTION_DEBUG (action));
+ GST_VALIDATE_ACTION_LINENO (subaction) = GST_VALIDATE_ACTION_LINENO (action);
+ subaction->repeat = it;
+ subaction->priv->subaction_level = action->priv->subaction_level + 1;
+ GST_VALIDATE_ACTION_N_REPEATS (subaction) = max;
+ gst_validate_structure_resolve_variables (subaction, subaction->structure,
+ lvariables,
+ GST_VALIDATE_STRUCTURE_RESOLVE_VARIABLES_LOCAL_ONLY |
+ GST_VALIDATE_STRUCTURE_RESOLVE_VARIABLES_NO_FAILURE |
+ GST_VALIDATE_STRUCTURE_RESOLVE_VARIABLES_NO_EXPRESSION);
+ gst_structure_free (nstruct);
+
+ return subaction;
+}
+
static GstValidateExecuteActionReturn
gst_validate_foreach_prepare (GstValidateAction * action)
{
gint it, i;
gint min = 0, max = 1, step = 1;
+ const GValue *it_array = NULL;
GstValidateScenario *scenario;
GList *actions, *tmp;
@@ -3838,19 +3869,25 @@ gst_validate_foreach_prepare (GstValidateAction * action)
gst_validate_error_structure (action, "Missing range specifier field.");
if (GST_VALIDATE_ACTION_RANGE_NAME (action)) {
- const GValue *range = gst_structure_get_value (action->structure,
+ const GValue *it_value = gst_structure_get_value (action->structure,
GST_VALIDATE_ACTION_RANGE_NAME (action));
- min = gst_value_get_int_range_min (range);
- max = gst_value_get_int_range_max (range);
- step = gst_value_get_int_range_step (range);
- if (min % step != 0)
- gst_validate_error_structure (action,
- "Range min[%d] must be a multiple of step[%d].", min, step);
+ if (GST_VALUE_HOLDS_INT_RANGE (it_value)) {
+ min = gst_value_get_int_range_min (it_value);
+ max = gst_value_get_int_range_max (it_value);
+ step = gst_value_get_int_range_step (it_value);
+
+ if (min % step != 0)
+ gst_validate_error_structure (action,
+ "Range min[%d] must be a multiple of step[%d].", min, step);
- if (max % step != 0)
- gst_validate_error_structure (action,
- "Range max[%d] must be a multiple of step[%d].", max, step);
+ if (max % step != 0)
+ gst_validate_error_structure (action,
+ "Range max[%d] must be a multiple of step[%d].", max, step);
+ } else {
+ it_array = it_value;
+ max = gst_value_array_get_size (it_array);
+ }
} else {
min = action->repeat;
max = action->repeat + 1;
@@ -3860,27 +3897,17 @@ gst_validate_foreach_prepare (GstValidateAction * action)
"actions");
i = g_list_index (scenario->priv->actions, action);
for (it = min; it < max; it = it + step) {
+ GstStructure *lvariables = gst_structure_new_empty ("vars");
+
+ if (it_array)
+ gst_structure_set_value (lvariables,
+ GST_VALIDATE_ACTION_RANGE_NAME (action),
+ gst_value_array_get_value (it_array, it));
+
for (tmp = actions; tmp; tmp = tmp->next) {
- GstValidateAction *subaction;
- GstStructure *nstruct = gst_structure_copy (tmp->data);
-
- subaction = gst_validate_action_new (scenario,
- _find_action_type (gst_structure_get_name (nstruct)), nstruct, FALSE);
- GST_VALIDATE_ACTION_RANGE_NAME (subaction) =
- GST_VALIDATE_ACTION_RANGE_NAME (action);
- GST_VALIDATE_ACTION_FILENAME (subaction) =
- g_strdup (GST_VALIDATE_ACTION_FILENAME (action));
- GST_VALIDATE_ACTION_DEBUG (subaction) =
- g_strdup (GST_VALIDATE_ACTION_DEBUG (action));
- GST_VALIDATE_ACTION_LINENO (subaction) =
- GST_VALIDATE_ACTION_LINENO (action);
- subaction->repeat = it;
- subaction->priv->subaction_level = action->priv->subaction_level + 1;
- GST_VALIDATE_ACTION_N_REPEATS (subaction) = max;
- scenario->priv->actions =
- g_list_insert (scenario->priv->actions, subaction, i++);
-
- gst_structure_free (nstruct);
+ scenario->priv->actions = g_list_insert (scenario->priv->actions,
+ gst_validate_create_subaction (scenario, lvariables, action,
+ gst_structure_copy (tmp->data), it, max), i++);
}
}
g_list_free_full (actions, (GDestroyNotify) gst_structure_free);
@@ -7246,8 +7273,10 @@ register_action_types (void)
NULL },
{ NULL } }),
"Run actions defined in the `actions` array the number of times specified\n"
- " with a GstIntRange `i=[start, end, step]` parameter passed in, one and only\n"
- " range is required as parameter.",
+ " with an iterator parameter passed in. The iterator can be\n"
+ " a range like :`i=[start, end, step]` or array of values\n"
+ " such as: `values=<value1, value2>`.\n"
+ "One and only iterator field is required as parameter.",
GST_VALIDATE_ACTION_TYPE_NONE);
type->prepare = gst_validate_foreach_prepare;
diff --git a/validate/tests/launcher_tests/foreach_array.validatetest b/validate/tests/launcher_tests/foreach_array.validatetest
new file mode 100644
index 0000000..06780b5
--- /dev/null
+++ b/validate/tests/launcher_tests/foreach_array.validatetest
@@ -0,0 +1,33 @@
+meta,
+ handles-states=true,
+ args = {
+ "videotestsrc pattern=ball name=s ! fakesink",
+ }
+
+foreach, pattern=<green, blue>,
+ actions = {
+ [set-properties, s::pattern="$(pattern)"],
+ }
+
+priv_check-action-type-calls, type=set-properties, n=2
+
+check-properties, s::pattern="Blue"
+
+foreach, pattern=<
+ # We can also pass int values (which works for enums)
+ 1, 3, 5, # green
+ >,
+ actions = {
+ [set-properties, s::pattern="$(pattern)"],
+ }
+
+priv_check-action-type-calls, type=set-properties, n=5
+check-properties, s::pattern="Green"
+
+foreach, pattern=<blue, white, black>,
+ actions = {
+ [set-properties, s::pattern="$(pattern)"],
+ }
+priv_check-action-type-calls, type=set-properties, n=8
+check-properties, s::pattern="100\%\ Black"
+stop