validate: Add support for text based override files

Allowing user to easily determine the severity of issue
types in a config file

https://bugzilla.gnome.org/show_bug.cgi?id=737852
This commit is contained in:
Thibault Saunier 2014-10-03 18:51:17 +02:00 committed by Mathieu Duponchelle
parent b0d39c1c45
commit 34a9c36edc
5 changed files with 276 additions and 6 deletions

View file

@ -29,6 +29,7 @@
#include <gmodule.h>
#include "gst-validate-utils.h"
#include "gst-validate-internal.h"
#include "gst-validate-override-registry.h"
@ -134,7 +135,7 @@ static void
name = gst_validate_monitor_get_element_name (monitor);
for (iter = registry->name_overrides.head; iter; iter = g_list_next (iter)) {
entry = iter->data;
if (strcmp (name, entry->name) == 0) {
if (g_strcmp0 (name, entry->name) == 0) {
gst_validate_monitor_attach_override (monitor, entry->override);
}
}
@ -152,7 +153,7 @@ static void
if (!element)
return;
for (iter = registry->name_overrides.head; iter; iter = g_list_next (iter)) {
for (iter = registry->gtype_overrides.head; iter; iter = g_list_next (iter)) {
entry = iter->data;
if (G_TYPE_CHECK_INSTANCE_TYPE (element, entry->gtype)) {
gst_validate_monitor_attach_override (monitor, entry->override);
@ -201,6 +202,129 @@ gst_validate_override_registry_attach_overrides (GstValidateMonitor * monitor)
GST_VALIDATE_OVERRIDE_REGISTRY_UNLOCK (reg);
}
enum
{
WRONG_FILE,
WRONG_OVERRIDES,
OK
};
static gboolean
_add_override_from_struct (GstStructure * soverride)
{
GQuark issue_id;
GstValidateReportLevel level;
GstValidateOverride *override;
const gchar *str_issue_id, *str_new_severity,
*factory_name = NULL, *name = NULL, *klass = NULL;
gboolean registered = FALSE;
if (!gst_structure_has_name (soverride, "change-severity")) {
GST_ERROR ("Currently only 'change-severity' overrides are supported");
return FALSE;
}
str_issue_id = gst_structure_get_string (soverride, "issue-id");
if (!str_issue_id) {
GST_ERROR ("No issue id provided in override: %" GST_PTR_FORMAT, soverride);
return FALSE;
}
issue_id = g_quark_from_string (str_issue_id);
if (gst_validate_issue_from_id (issue_id) == NULL) {
GST_ERROR ("No GstValidateIssue registered for %s", str_issue_id);
return FALSE;
}
str_new_severity = gst_structure_get_string (soverride, "new-severity");
if (str_new_severity == NULL) {
GST_ERROR ("No 'new-severity' field found in %" GST_PTR_FORMAT, soverride);
return FALSE;
}
level = gst_validate_report_level_from_name (str_new_severity);
if (level == GST_VALIDATE_REPORT_LEVEL_UNKNOWN) {
GST_ERROR ("Unknown level name %s", str_new_severity);
return FALSE;
}
override = gst_validate_override_new ();
gst_validate_override_change_severity (override, issue_id, level);
name = gst_structure_get_string (soverride, "element-name");
klass = gst_structure_get_string (soverride, "element-classification");
factory_name = gst_structure_get_string (soverride, "element-factory-name");
if (factory_name) {
GType type;
GstElement *element = gst_element_factory_make (factory_name, NULL);
if (element == NULL) {
GST_ERROR ("Unknown element factory name: %s (gst is %sinitialized)",
factory_name, gst_is_initialized ()? "" : "NOT ");
if (!name && !klass)
return FALSE;
} else {
type = G_OBJECT_TYPE (element);
gst_validate_override_register_by_type (type, override);
}
registered = TRUE;
}
if (name) {
gst_validate_override_register_by_name (name, override);
registered = TRUE;
}
if (klass) {
gst_validate_override_register_by_klass (klass, override);
registered = TRUE;
}
if (!registered) {
GstValidateIssue *issue = gst_validate_issue_from_id (issue_id);
if (!issue) {
return FALSE;
}
gst_validate_issue_set_default_level (issue, level);
}
return TRUE;
}
static gboolean
_load_text_override_file (const gchar * filename)
{
gint ret = OK;
GList *structs = structs_parse_from_filename (filename);
if (structs) {
GList *tmp;
for (tmp = structs; tmp; tmp = tmp->next) {
if (!_add_override_from_struct (tmp->data)) {
GST_ERROR ("Wrong overrides %" GST_PTR_FORMAT, tmp->data);
ret = WRONG_OVERRIDES;
}
}
return ret;
}
return WRONG_FILE;
}
int
gst_validate_override_registry_preload (void)
{
@ -221,9 +345,13 @@ gst_validate_override_registry_preload (void)
GST_INFO ("Loading overrides from %s", *modname);
module = g_module_open (*modname, G_MODULE_BIND_LAZY);
if (module == NULL) {
loaderr = g_module_error ();
GST_ERROR ("Failed to load %s %s", *modname,
loaderr ? loaderr : "no idea why");
if (_load_text_override_file (*modname) == WRONG_FILE) {
loaderr = g_module_error ();
GST_ERROR ("Failed to load %s %s", *modname,
loaderr ? loaderr : "no idea why");
}
continue;
}
if (g_module_symbol (module, GST_VALIDATE_OVERRIDE_INIT_SYMBOL,

View file

@ -90,6 +90,17 @@ gst_validate_issue_new (GstValidateIssueId issue_id, const gchar * summary,
return issue;
}
void
gst_validate_issue_set_default_level (GstValidateIssue * issue,
GstValidateReportLevel default_level)
{
GST_INFO ("Setting issue %s::%s default level to %s",
issue->area, issue->name,
gst_validate_report_level_get_name (default_level));
issue->default_level = default_level;
}
static void
gst_validate_issue_free (GstValidateIssue * issue)
{
@ -353,6 +364,24 @@ gst_validate_report_level_get_name (GstValidateReportLevel level)
}
}
GstValidateReportLevel
gst_validate_report_level_from_name (const gchar * issue_name)
{
if (g_strcmp0 (issue_name, "critical") == 0)
return GST_VALIDATE_REPORT_LEVEL_CRITICAL;
else if (g_strcmp0 (issue_name, "warning") == 0)
return GST_VALIDATE_REPORT_LEVEL_WARNING;
else if (g_strcmp0 (issue_name, "issue") == 0)
return GST_VALIDATE_REPORT_LEVEL_ISSUE;
else if (g_strcmp0 (issue_name, "ignore") == 0)
return GST_VALIDATE_REPORT_LEVEL_IGNORE;
return GST_VALIDATE_REPORT_LEVEL_UNKNOWN;
}
gboolean
gst_validate_report_should_print (GstValidateReport * report)
{

View file

@ -50,6 +50,7 @@ typedef enum {
GST_VALIDATE_REPORT_LEVEL_WARNING,
GST_VALIDATE_REPORT_LEVEL_ISSUE,
GST_VALIDATE_REPORT_LEVEL_IGNORE,
GST_VALIDATE_REPORT_LEVEL_UNKNOWN,
GST_VALIDATE_REPORT_LEVEL_NUM_ENTRIES,
} GstValidateReportLevel;
@ -183,6 +184,8 @@ void gst_validate_issue_register (GstValidateIssue * issue);
GstValidateIssue *gst_validate_issue_new (GstValidateIssueId issue_id, const gchar * summary,
const gchar * description,
GstValidateReportLevel default_level);
void gst_validate_issue_set_default_level (GstValidateIssue *issue,
GstValidateReportLevel default_level);
GstValidateReport *gst_validate_report_new (GstValidateIssue * issue,
GstValidateReporter * reporter,
@ -211,6 +214,7 @@ gboolean gst_validate_report_should_print (GstValidateReport * report);
gboolean gst_validate_report_set_master_report(GstValidateReport *report, GstValidateReport *master_report);
void gst_validate_report_set_reporting_level (GstValidateReport *report, GstValidateReportingLevel level);
void gst_validate_report_add_repeated_report (GstValidateReport *report, GstValidateReport *repeated_report);
GstValidateReportLevel gst_validate_report_level_from_name (const gchar *issue_name);
G_END_DECLS

View file

@ -29,7 +29,8 @@ clean-local: clean-local-check
check_PROGRAMS = \
validate/padmonitor \
validate/monitoring \
validate/reporting
validate/reporting \
validate/overrides
noinst_LTLIBRARIES=$(testutils_noisnt_libraries)
noinst_HEADERS=$(testutils_noinst_headers)

View file

@ -0,0 +1,108 @@
/* GstValidate
* Copyright (C) 2014 Thibault Saunier <thibault.saunier@collabora.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., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <gst/check/gstcheck.h>
#include <glib/gstdio.h>
#include <gst/validate/validate.h>
#include <gst/validate/gst-validate-override-registry.h>
static const gchar *some_overrides =
"change-severity, issue-id=buffer::not-expected-one, new-severity=critical\n"
"change-severity, issue-id=buffer::not-expected-one, new-severity=warning, element-factory-name=queue";
static void
_check_message_level (const gchar * factoryname, GstValidateReportLevel level,
const gchar * message_id)
{
GList *reports;
GstElement *element;
GstValidateRunner *runner;
GstValidateMonitor *monitor;
element = gst_element_factory_make (factoryname, NULL);
fail_unless (g_setenv ("GST_VALIDATE_REPORT_LEVEL", "all", TRUE));
runner = gst_validate_runner_new ();
monitor =
gst_validate_monitor_factory_create (GST_OBJECT (element), runner, NULL);
GST_VALIDATE_REPORT (monitor, g_quark_from_string (message_id),
"Just some fakery");
reports = gst_validate_runner_get_reports (runner);
fail_unless_equals_int (g_list_length (reports), 1);
fail_unless_equals_int (((GstValidateReport *) reports->data)->level, level);
g_list_free_full (reports, (GDestroyNotify) gst_validate_report_unref);
gst_object_unref (element);
gst_object_unref (monitor);
}
GST_START_TEST (check_text_overrides)
{
GstValidateIssue *issue;
gchar *override_filename =
g_strdup_printf ("%s%c%s", g_get_tmp_dir (), G_DIR_SEPARATOR,
"some_overrides");
fail_unless (g_file_set_contents (override_filename,
some_overrides, -1, NULL));
issue =
gst_validate_issue_from_id (g_quark_from_string
("buffer::not-expected-one"));
fail_unless (issue != NULL);
assert_equals_int (issue->default_level, GST_VALIDATE_REPORT_LEVEL_WARNING);
g_setenv ("GST_VALIDATE_OVERRIDE", override_filename, TRUE);
gst_validate_override_registry_preload ();
assert_equals_int (issue->default_level, GST_VALIDATE_REPORT_LEVEL_CRITICAL);
/* Check that with a queue, the level of a
* buffer::not-expected-one is WARNING */
_check_message_level ("queue", GST_VALIDATE_REPORT_LEVEL_WARNING,
"buffer::not-expected-one");
/* Check that with an identity, the level of a
* buffer::not-expected-one is CRITICAL */
_check_message_level ("identity", GST_VALIDATE_REPORT_LEVEL_CRITICAL,
"buffer::not-expected-one");
g_remove (override_filename);
g_free (override_filename);
}
GST_END_TEST;
static Suite *
gst_validate_suite (void)
{
Suite *s = suite_create ("registry");
TCase *tc_chain = tcase_create ("registry");
suite_add_tcase (s, tc_chain);
gst_validate_init ();
tcase_add_test (tc_chain, check_text_overrides);
return s;
}
GST_CHECK_MAIN (gst_validate);