validate:flow: Add a way to set the types of events to log/ignore

Added two properties to the plugin:
     * ignored-event-types: A list of event types to be ignored when logging events
     * logged-event-types: A list of event types to be logged when logging events

This commits also moves the "ignored-event-fields" property to using a proper
GstValueList for the list of event fields to be taken into account, instead
of the home grown separated by comas list of string, making the API more
uniform.

This also adds a simple helper method: `gst_validate_utils_get_strv`
This commit is contained in:
Thibault Saunier 2020-01-15 21:15:30 -03:00
parent a2e926ff0a
commit 5b82274f17
7 changed files with 80 additions and 47 deletions

View file

@ -85,7 +85,9 @@ In order to use the plugin a validate configuration file must be provided, conta
* `pad`: Required. Name of the pad that will be monitored.
* `record-buffers`: Default: false. Whether buffers will be logged. By default only events are logged.
* `buffers-checksum`: Default: false. Whether a checkum of the buffer data is logged. Implies `record-buffers`.
* `ignored-event-fields`: Default: `stream-start=stream-id` (as they are often non reproducible). Key with a list of coma (`,`) separated list of fields to not record.
* `ignored-event-fields`: Default: `"stream-start={ stream-id }"` (as they are often non reproducible). Key with a serialized GstValueList(str) of fields to not record.
* `ignored-event-types`: Default: `{ }`. List of event type names to not record
* `logged-event-types`: Default: `NULL`. List of event type names to not record, if noone provided, all events are logged, except the ones defined in the `ignored-event-types`.
* `expectations-dir`: Path to the directory where the expectations will be written if they don't exist, relative to the current working directory. By default the current working directory is used, but this setting is usually set automatically as part of the `%(validateflow)s` expansion to a correct path like `~/gst-validate/gst-integration-testsuites/flow-expectations/<test name>`.
* `actual-results-dir`: Path to the directory where the events will be recorded. The expectation file will be compared to this. By default the current working directory is used, but this setting is usually set automatically as part of the `%(validateflow)s` expansion to the test log directory, i.e. `~/gst-validate/logs/validate/launch_pipeline/<test name>`.

View file

@ -1064,3 +1064,37 @@ gst_validate_set_globals (GstStructure * structure)
gst_structure_foreach (structure,
(GstStructureForeachFunc) _set_vars_func, global_vars);
}
/**
* gst_validate_utils_get_strv:
* @str: A GstStructure
* @fieldname: A fieldname containing a GstValueList or is not defined
*
* Returns: An array of strings from the GstValueList defined in @fieldname
*/
gchar **
gst_validate_utils_get_strv (GstStructure * str, const gchar * fieldname)
{
const GValue *list;
gchar **parsed_list;
guint i, size;
list = gst_structure_get_value (str, fieldname);
if (!list)
return NULL;
if (!GST_VALUE_HOLDS_LIST (list)) {
g_error
("%s must have type list of string, e.g. %s={ val1, val2 }, got: \"%s\"",
fieldname, fieldname, gst_value_serialize (list));
return NULL;
}
size = gst_value_list_get_size (list);
parsed_list = g_malloc_n (size + 1, sizeof (gchar *));
for (i = 0; i < size; i++)
parsed_list[i] = g_value_dup_string (gst_value_list_get_value (list, i));
parsed_list[i] = NULL;
return parsed_list;
}

View file

@ -45,6 +45,8 @@ GST_VALIDATE_API
gboolean gst_validate_utils_enum_from_str (GType type,
const gchar * str_enum,
guint * enum_value);
GST_VALIDATE_API
gchar ** gst_validate_utils_get_strv (GstStructure *str, const gchar *fieldname);
GST_VALIDATE_API
GList * gst_validate_utils_structs_parse_from_filename (const gchar * scenario_file,

View file

@ -33,6 +33,8 @@
#include <string.h>
#include <stdio.h>
#include "../../gst/validate/gst-validate-utils.h"
typedef void (*Uint64Formatter) (gchar * dest, guint64 time);
void
@ -255,15 +257,23 @@ validate_flow_format_buffer (GstBuffer * buffer, gboolean add_checksum)
gchar *
validate_flow_format_event (GstEvent * event,
const gchar * const *caps_properties, GstStructure * ignored_event_fields)
const gchar * const *caps_properties, GstStructure * ignored_event_fields,
const gchar * const *ignored_event_types,
const gchar * const *logged_event_types)
{
const gchar *event_type;
gchar *structure_string;
gchar *event_string;
const gchar *ignored_fields;
gchar **ignored_fields;
event_type = gst_event_type_get_name (GST_EVENT_TYPE (event));
if (logged_event_types && !g_strv_contains (logged_event_types, event_type))
return NULL;
if (ignored_event_types && g_strv_contains (ignored_event_types, event_type))
return NULL;
if (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT) {
const GstSegment *segment;
gst_event_parse_segment (event, &segment);
@ -279,14 +289,14 @@ validate_flow_format_event (GstEvent * event,
gst_structure_copy (gst_event_get_structure (event));
ignored_fields =
gst_structure_get_string (ignored_event_fields, event_type);
gst_validate_utils_get_strv (ignored_event_fields, event_type);
if (ignored_fields) {
gint i = 0;
gchar *field, **fields = g_strsplit (ignored_fields, ",", -1);
gchar *field;
for (field = fields[i]; field; field = fields[++i])
for (field = ignored_fields[i]; field; field = ignored_fields[++i])
gst_structure_remove_field (printable, field);
g_strfreev (fields);
g_strfreev (ignored_fields);
}
structure_string = gst_structure_to_string (printable);

View file

@ -33,6 +33,6 @@ gchar* validate_flow_format_caps (const GstCaps* caps, const gchar * const *keys
gchar* validate_flow_format_buffer (GstBuffer *buffer, gboolean add_checksum);
gchar* validate_flow_format_event (GstEvent *event, const gchar * const *caps_properties, GstStructure *ignored_event_fields);
gchar* validate_flow_format_event(GstEvent* event, const gchar* const* caps_properties, GstStructure* ignored_event_fields, const gchar* const* ignored_event_types, const gchar* const* logged_event_types);
#endif // __GST_VALIDATE_FLOW_FORMATTING_H__

View file

@ -61,6 +61,9 @@ struct _ValidateFlowOverride
gchar **caps_properties;
GstStructure *ignored_event_fields;
gchar **logged_event_types;
gchar **ignored_event_types;
gchar *expectations_file_path;
gchar *actual_results_file_path;
ValidateFlowMode mode;
@ -160,9 +163,14 @@ validate_flow_override_event_handler (GstValidateOverride * override,
event_string = validate_flow_format_event (event,
(const gchar * const *) flow->caps_properties,
flow->ignored_event_fields);
validate_flow_override_printf (flow, "event %s\n", event_string);
g_free (event_string);
flow->ignored_event_fields,
(const gchar * const *) flow->ignored_event_types,
(const gchar * const *) flow->logged_event_types);
if (event_string) {
validate_flow_override_printf (flow, "event %s\n", event_string);
g_free (event_string);
}
}
static void
@ -180,32 +188,6 @@ validate_flow_override_buffer_handler (GstValidateOverride * override,
g_free (buffer_str);
}
static gchar **
parse_caps_properties_setting (const ValidateFlowOverride * flow,
GstStructure * config)
{
const GValue *list;
gchar **parsed_list;
guint i, size;
list = gst_structure_get_value (config, "caps-properties");
if (!list)
return NULL;
if (!GST_VALUE_HOLDS_LIST (list)) {
GST_ERROR_OBJECT (flow,
"caps-properties must have type list of string, e.g. caps-properties={ width, height };");
return NULL;
}
size = gst_value_list_get_size (list);
parsed_list = g_malloc_n (size + 1, sizeof (gchar *));
for (i = 0; i < size; i++)
parsed_list[i] = g_value_dup_string (gst_value_list_get_value (list, i));
parsed_list[i] = NULL;
return parsed_list;
}
static gchar *
make_safe_file_name (const gchar * name)
{
@ -260,7 +242,13 @@ validate_flow_override_new (GstStructure * config)
/* caps-properties: Caps events can include many dfferent properties, but
* many of these may be irrelevant for some tests. If this option is set,
* only the listed properties will be written to the expectation log. */
flow->caps_properties = parse_caps_properties_setting (flow, config);
flow->caps_properties =
gst_validate_utils_get_strv (config, "caps-properties");
flow->logged_event_types =
gst_validate_utils_get_strv (config, "logged-event-types");
flow->ignored_event_types =
gst_validate_utils_get_strv (config, "ignored-event-types");
ignored_event_fields =
(gchar *) gst_structure_get_string (config, "ignored-event-fields");
@ -274,12 +262,12 @@ validate_flow_override_new (GstStructure * config)
g_free (ignored_event_fields);
} else {
flow->ignored_event_fields =
gst_structure_new_from_string ("ignored,stream-start=stream-id");
gst_structure_new_from_string ("ignored,stream-start={stream-id}");
}
if (!gst_structure_has_field (flow->ignored_event_fields, "stream-start"))
gst_structure_set (flow->ignored_event_fields, "stream-start",
G_TYPE_STRING, "stream-id", NULL);
G_TYPE_STRING, "{stream-id}", NULL);
@ -501,13 +489,9 @@ validate_flow_override_finalize (GObject * object)
g_free (flow->output_file_path);
if (flow->output_file)
fclose (flow->output_file);
if (flow->caps_properties) {
gchar **str_pointer;
for (str_pointer = flow->caps_properties; *str_pointer != NULL;
str_pointer++)
g_free (*str_pointer);
g_free (flow->caps_properties);
}
g_strfreev (flow->caps_properties);
g_strfreev (flow->logged_event_types);
g_strfreev (flow->ignored_event_types);
if (flow->ignored_event_fields)
gst_structure_free (flow->ignored_event_fields);

View file

@ -169,6 +169,7 @@ EXPORTS
gst_validate_utils_enum_from_str
gst_validate_utils_flags_from_str
gst_validate_utils_get_clocktime
gst_validate_utils_get_strv
gst_validate_utils_parse_expression
gst_validate_utils_structs_parse_from_filename
gst_validate_verbosity_flags_get_type