validate: Set 'LOGSDIR' variable in scenarios and config files

Implementing support for variables in config files.
This commit is contained in:
Thibault Saunier 2019-06-23 03:09:58 -04:00
parent b11c5ba185
commit 7d471ee25e
7 changed files with 153 additions and 44 deletions

View file

@ -6,4 +6,39 @@ short-description: GstValidate configuration
# GstValidate Configuration # GstValidate Configuration
GstValidate comes with some possible configuration files GstValidate comes with some possible configuration files
to setup its plugins (and potentially core behaviour). to setup its plugins (and potentially core behaviour),
You can check the [ssim plugin](plugins/ssim.md)
and the [validate flow plugin](plugins/validateflow.md)
for examples.
## Variables
You can use variables in the configs the same way you can
set them in [gst-validate-scenarios](gst-validate-scenarios.md).
Defaults variables are:
- `$(TMPDIR)`: The default temporary directory as returned by
[g_get_tmp_dir()](g_get_tmp_dir).
- `$(CONFIG_PATH)`: The path of the running scenario.
- `$(CONFIG_DIR)`: The directory the running scenario is in.
- `$(LOGSDIR)`: The directory where to place log files. This uses the
`GST_VALIDATE_LOGSDIR` environment variable if avalaible or `$(TMPDIR)`
if the variables hasn't been set. (Note that the
[gst-validate-launcher](gst-validate-launcher.md) set the environment
variables.
You can also set you own variables by using the `set-vars=true` argument:
``` yaml
core, set-vars=true, log-path=$(CONFIG_DIR/../log)
```
It is also possible to set global variables (also usable from [scenarios](gst-validate-scenarios.md))
with
``` yaml
set-globals, TESTSUITE_ROOT_DIR=$(CONFIG_DIR)
```

View file

@ -353,7 +353,8 @@ static gboolean
_load_text_override_file (const gchar * filename) _load_text_override_file (const gchar * filename)
{ {
gint ret = OK; gint ret = OK;
GList *structs = gst_validate_utils_structs_parse_from_filename (filename); GList *structs =
gst_validate_utils_structs_parse_from_filename (filename, NULL);
if (structs) { if (structs) {
GList *tmp; GList *tmp;

View file

@ -2908,31 +2908,6 @@ gst_validate_scenario_update_segment_from_seek (GstValidateScenario * scenario,
} }
} }
static gboolean
_structure_set_variables (GQuark field_id, GValue * value,
GstValidateAction * action)
{
gchar *str;
GstValidateScenario *scenario;
if (!G_VALUE_HOLDS_STRING (value))
return TRUE;
scenario = gst_validate_action_get_scenario (action);
if (!scenario)
return TRUE;
str = gst_validate_replace_variables_in_string (scenario->priv->vars,
g_value_get_string (value));
if (str) {
g_value_set_string (value, str);
g_free (str);
}
gst_object_unref (scenario);
return TRUE;
}
static gboolean static gboolean
gst_validate_action_default_prepare_func (GstValidateAction * action) gst_validate_action_default_prepare_func (GstValidateAction * action)
{ {
@ -2943,9 +2918,8 @@ gst_validate_action_default_prepare_func (GstValidateAction * action)
GstValidateActionType *type = gst_validate_get_action_type (action->type); GstValidateActionType *type = gst_validate_get_action_type (action->type);
GstValidateScenario *scenario = gst_validate_action_get_scenario (action); GstValidateScenario *scenario = gst_validate_action_get_scenario (action);
gst_structure_filter_and_map_in_place (action->structure, gst_validate_structure_resolve_variables (action->structure,
(GstStructureFilterMapFunc) _structure_set_variables, action); scenario->priv->vars);
for (i = 0; type->parameters[i].name; i++) { for (i = 0; type->parameters[i].name; i++) {
if (g_str_has_suffix (type->parameters[i].types, "(GstClockTime)")) if (g_str_has_suffix (type->parameters[i].types, "(GstClockTime)"))
gst_validate_action_get_clocktime (scenario, action, gst_validate_action_get_clocktime (scenario, action,
@ -3370,7 +3344,8 @@ _load_scenario_file (GstValidateScenario * scenario,
*is_config = FALSE; *is_config = FALSE;
structures = gst_validate_utils_structs_parse_from_filename (scenario_file); structures =
gst_validate_utils_structs_parse_from_filename (scenario_file, NULL);
if (structures == NULL) if (structures == NULL)
goto failed; goto failed;

View file

@ -578,7 +578,7 @@ _file_get_lines (GFile * file)
} }
static gchar ** static gchar **
_get_lines (const gchar * scenario_file) _get_lines (const gchar * scenario_file, gchar ** file_path)
{ {
GFile *file = NULL; GFile *file = NULL;
gchar **lines = NULL; gchar **lines = NULL;
@ -589,6 +589,9 @@ _get_lines (const gchar * scenario_file)
return NULL; return NULL;
} }
if (file_path)
*file_path = g_file_get_path (file);
lines = _file_get_lines (file); lines = _file_get_lines (file);
g_object_unref (file); g_object_unref (file);
@ -638,11 +641,12 @@ failed:
* gst_validate_utils_structs_parse_from_filename: (skip): * gst_validate_utils_structs_parse_from_filename: (skip):
*/ */
GList * GList *
gst_validate_utils_structs_parse_from_filename (const gchar * scenario_file) gst_validate_utils_structs_parse_from_filename (const gchar * scenario_file,
gchar ** file_path)
{ {
gchar **lines; gchar **lines;
lines = _get_lines (scenario_file); lines = _get_lines (scenario_file, file_path);
if (lines == NULL) { if (lines == NULL) {
GST_DEBUG ("Got no line for file: %s", scenario_file); GST_DEBUG ("Got no line for file: %s", scenario_file);
@ -954,11 +958,7 @@ gst_validate_replace_variables_in_string (GstStructure * local_vars,
if (!_variables_regex) if (!_variables_regex)
_variables_regex = g_regex_new ("\\$\\((\\w+)\\)", 0, 0, NULL); _variables_regex = g_regex_new ("\\$\\((\\w+)\\)", 0, 0, NULL);
if (!global_vars) { gst_validate_set_globals (NULL);
global_vars =
gst_structure_new ("vars", "TMPDIR", G_TYPE_STRING, g_get_tmp_dir (),
NULL);
}
g_regex_match (_variables_regex, string, 0, &match_info); g_regex_match (_variables_regex, string, 0, &match_info);
while (g_match_info_matches (match_info)) { while (g_match_info_matches (match_info)) {
@ -1008,3 +1008,59 @@ gst_validate_replace_variables_in_string (GstStructure * local_vars,
return string; return string;
} }
static gboolean
_structure_set_variables (GQuark field_id, GValue * value,
GstStructure * local_variables)
{
gchar *str;
if (!G_VALUE_HOLDS_STRING (value))
return TRUE;
str = gst_validate_replace_variables_in_string (local_variables,
g_value_get_string (value));
if (str) {
g_value_set_string (value, str);
g_free (str);
}
return TRUE;
}
void
gst_validate_structure_resolve_variables (GstStructure * structure,
GstStructure * local_variables)
{
gst_structure_filter_and_map_in_place (structure,
(GstStructureFilterMapFunc) _structure_set_variables, local_variables);
}
static gboolean
_set_vars_func (GQuark field_id, const GValue * value, GstStructure * vars)
{
gst_structure_id_set_value (vars, field_id, value);
return TRUE;
}
void
gst_validate_set_globals (GstStructure * structure)
{
if (!global_vars) {
const gchar *logsdir = g_getenv ("GST_VALIDATE_LOGSDIR");
if (!logsdir)
logsdir = g_get_tmp_dir ();
global_vars =
gst_structure_new ("vars", "TMPDIR", G_TYPE_STRING, g_get_tmp_dir (),
"LOGSDIR", G_TYPE_STRING, logsdir, NULL);
}
if (!structure)
return;
gst_structure_foreach (structure,
(GstStructureForeachFunc) _set_vars_func, global_vars);
}

View file

@ -47,7 +47,8 @@ gboolean gst_validate_utils_enum_from_str (GType type,
guint * enum_value); guint * enum_value);
GST_VALIDATE_API GST_VALIDATE_API
GList * gst_validate_utils_structs_parse_from_filename (const gchar * scenario_file); GList * gst_validate_utils_structs_parse_from_filename (const gchar * scenario_file,
gchar **file_path);
GST_VALIDATE_API GST_VALIDATE_API
GList * gst_validate_structs_parse_from_gfile (GFile * scenario_file); GList * gst_validate_structs_parse_from_gfile (GFile * scenario_file);
@ -70,5 +71,7 @@ void gst_validate_spin_on_fault_signals (void);
GST_VALIDATE_API GST_VALIDATE_API
gboolean gst_validate_element_matches_target (GstElement * element, GstStructure * s); gboolean gst_validate_element_matches_target (GstElement * element, GstStructure * s);
gchar * gst_validate_replace_variables_in_string (GstStructure * local_vars, const gchar * in_string); gchar * gst_validate_replace_variables_in_string (GstStructure * local_vars, const gchar * in_string);
void gst_validate_structure_resolve_variables (GstStructure *structure, GstStructure *local_variables);
void gst_validate_set_globals (GstStructure *structure);
#endif #endif

View file

@ -55,6 +55,7 @@ static GstRegistry *_gst_validate_registry_default = NULL;
static GList *core_config = NULL; static GList *core_config = NULL;
static gboolean validate_initialized = FALSE; static gboolean validate_initialized = FALSE;
static gboolean loaded_globals = FALSE;
GstClockTime _priv_start_time; GstClockTime _priv_start_time;
GQuark _Q_VALIDATE_MONITOR; GQuark _Q_VALIDATE_MONITOR;
@ -125,17 +126,28 @@ gst_structure_validate_name (const gchar * name)
return TRUE; return TRUE;
} }
static gboolean
_set_vars_func (GQuark field_id, const GValue * value, GstStructure * vars)
{
gst_structure_id_set_value (vars, field_id, value);
return TRUE;
}
static GList * static GList *
create_config (const gchar * config, const gchar * suffix) create_config (const gchar * config, const gchar * suffix)
{ {
GstStructure *local_vars = gst_structure_new_empty ("vars");
GList *structures = NULL, *tmp, *result = NULL; GList *structures = NULL, *tmp, *result = NULL;
gchar *config_file = NULL;
if (!suffix) { if (!suffix) {
GST_WARNING ("suffix is NULL"); GST_WARNING ("suffix is NULL");
return NULL; return NULL;
} }
structures = gst_validate_utils_structs_parse_from_filename (config); structures =
gst_validate_utils_structs_parse_from_filename (config, &config_file);
if (!structures) { if (!structures) {
GstCaps *confs = NULL; GstCaps *confs = NULL;
@ -157,16 +169,42 @@ create_config (const gchar * config, const gchar * suffix)
} }
} }
if (config_file) {
gchar *config_dir = g_path_get_dirname (config_file);
gst_structure_set (local_vars,
"CONFIG_DIR", G_TYPE_STRING, config_dir,
"CONFIG_PATH", G_TYPE_STRING, config_file, NULL);
g_free (config_dir);
}
g_free (config_file);
for (tmp = structures; tmp; tmp = tmp->next) { for (tmp = structures; tmp; tmp = tmp->next) {
GstStructure *structure = tmp->data; GstStructure *structure = tmp->data;
if (gst_structure_has_name (structure, suffix)) if (gst_structure_has_name (structure, suffix)) {
result = g_list_append (result, structure); if (gst_structure_has_field (structure, "set-vars")) {
else gst_structure_remove_field (structure, "set-vars");
gst_structure_foreach (structure,
(GstStructureForeachFunc) _set_vars_func, local_vars);
} else {
gst_validate_structure_resolve_variables (structure, local_vars);
result = g_list_append (result, structure);
}
} else {
if (!loaded_globals && gst_structure_has_name (structure, "set-globals")) {
gst_validate_structure_resolve_variables (structure, local_vars);
gst_validate_set_globals (structure);
}
gst_structure_free (structure); gst_structure_free (structure);
}
} }
loaded_globals = TRUE;
g_list_free (structures); g_list_free (structures);
gst_structure_free (local_vars);
return result; return result;
} }

View file

@ -867,6 +867,7 @@ class GstValidateTest(Test):
subproc_env = os.environ.copy() subproc_env = os.environ.copy()
subproc_env["GST_VALIDATE_UUID"] = self.get_uuid() subproc_env["GST_VALIDATE_UUID"] = self.get_uuid()
subproc_env["GST_VALIDATE_LOGSDIR"] = self.options.logsdir
if 'GST_DEBUG' in os.environ and not self.options.redirect_logs: if 'GST_DEBUG' in os.environ and not self.options.redirect_logs:
gstlogsfile = os.path.splitext(self.logfile)[0] + '.gstdebug' gstlogsfile = os.path.splitext(self.logfile)[0] + '.gstdebug'