validate: Pass information about GstValidate execution over a socket
authorThibault Saunier <thibault.saunier@osg.samsung.com>
Thu, 1 Sep 2016 20:39:38 +0000 (17:39 -0300)
committerThibault Saunier <thibault.saunier@osg.samsung.com>
Thu, 8 Sep 2016 16:10:29 +0000 (13:10 -0300)
Instead of trying to parsing stdout, generate json messages and
send them over a socket so that gst-validate-launcher can properly
have informations about gst-validate subprocess execution.

validate/configure.ac
validate/gst/validate/Makefile.am
validate/gst/validate/gst-validate-internal.h
validate/gst/validate/gst-validate-pipeline-monitor.c
validate/gst/validate/gst-validate-report.c
validate/gst/validate/gst-validate-runner.c
validate/gst/validate/gst-validate-scenario.c
validate/gst/validate/meson.build
validate/gst/validate/validate.c
validate/launcher/baseclasses.py
validate/meson.build

index e8a1ad3..aa9ea27 100644 (file)
@@ -201,6 +201,10 @@ if test "x$HAVE_CAIRO" != "xyes"; then
   AC_MSG_NOTICE([Cairo is needed for the gst-validate-images-tool])
 fi
 
+PKG_CHECK_MODULES(JSON_GLIB, json-glib-1.0)
+AC_SUBST(JSON_GLIB_LIBS)
+AC_SUBST(JSON_GLIB_CFLAGS)
+
 dnl checks for gstreamer
 
 AG_GST_CHECK_GST_CHECK($GST_API_VERSION, [$GST_REQ], no)
index 79419a6..389d532 100644 (file)
@@ -50,14 +50,14 @@ lib_LTLIBRARIES = libgstvalidate-@GST_API_VERSION@.la
 libgstvalidate_@GST_API_VERSION@_la_SOURCES = $(source_c)
 libgstvalidate_@GST_API_VERSION@include_HEADERS = $(source_h)
 libgstvalidate_@GST_API_VERSION@_la_CFLAGS = $(GST_ALL_CFLAGS)\
-       $(GIO_CFLAGS) $(GST_PBUTILS_CFLAGS) \
+       $(JSON_GLIB_CFLAGS) $(GIO_CFLAGS) $(GST_PBUTILS_CFLAGS) \
        -DGST_USE_UNSTABLE_API
 libgstvalidate_@GST_API_VERSION@_la_LDFLAGS = $(GST_LIB_LDFLAGS) $(GST_ALL_LDFLAGS) \
        $(GST_LT_LDFLAGS) $(GIO_LDFLAGS) $(GST_PBUTILS_LDFAGS)
 libgstvalidate_@GST_API_VERSION@_la_LIBADD = \
        $(GST_PLUGINS_BASE_LIBS) $(GST_BASE_LIBS) \
        $(GST_ALL_LIBS) $(GIO_LIBS) $(GST_PBUTILS_LIBS) \
-       $(GLIB_LIBS) $(LIBM)
+       $(JSON_GLIB_LIBS) $(GLIB_LIBS) $(LIBM)
 
 libgstvalidate_@GST_API_VERSION@includedir = $(includedir)/gstreamer-@GST_API_VERSION@/gst/validate
 
@@ -71,9 +71,9 @@ libgstvalidateplugin_@GST_API_VERSION@_la_CFLAGS = $(GST_ALL_CFLAGS)\
 libgstvalidateplugin_@GST_API_VERSION@_la_LDFLAGS = $(GST_LIB_LDFLAGS) $(GST_ALL_LDFLAGS) \
        $(GST_LT_LDFLAGS) $(GIO_LDFLAGS) $(GST_PBUTILS_LDFAGS)
 libgstvalidateplugin_@GST_API_VERSION@_la_LIBADD = \
-       $(GST_PLUGINS_BASE_LIBS) $(GST_BASE_LIBS) \
+       $(JSON_GLIB_CFLAGS) $(GST_PLUGINS_BASE_LIBS) $(GST_BASE_LIBS) \
        $(GST_ALL_LIBS) $(GIO_LIBS) $(GST_PBUTILS_LIBS) \
-       $(GLIB_LIBS) $(LIBM)
+       $(JSON_GLIB_LIBS) $(GLIB_LIBS) $(LIBM)
 
 CLEANFILES =
 
index 13a61c9..b846d50 100644 (file)
@@ -25,6 +25,7 @@
 #include <gst/gst.h>
 #include "gst-validate-scenario.h"
 #include "gst-validate-monitor.h"
+#include <json-glib/json-glib.h>
 
 GST_DEBUG_CATEGORY_EXTERN (gstvalidate_debug);
 #define GST_CAT_DEFAULT gstvalidate_debug
@@ -49,5 +50,6 @@ G_GNUC_INTERNAL void _priv_validate_override_registry_deinit (void);
 G_GNUC_INTERNAL GstValidateMonitor * gst_validate_get_monitor (GObject *object);
 G_GNUC_INTERNAL void gst_validate_init_runner (void);
 G_GNUC_INTERNAL void gst_validate_deinit_runner (void);
-
+G_GNUC_INTERNAL void gst_validate_report_deinit (void);
+gboolean gst_validate_send (JsonNode * root);
 #endif
index 443ee66..0c23810 100644 (file)
@@ -90,6 +90,7 @@ print_position (GstValidateMonitor * monitor)
 {
   GstQuery *query;
   gint64 position, duration;
+  JsonBuilder *jbuilder;
   GstElement *pipeline =
       GST_ELEMENT (GST_VALIDATE_MONITOR_GET_OBJECT (monitor));
 
@@ -114,6 +115,21 @@ print_position (GstValidateMonitor * monitor)
     gst_query_parse_segment (query, &rate, NULL, NULL, NULL);
   gst_query_unref (query);
 
+  jbuilder = json_builder_new ();
+  json_builder_begin_object (jbuilder);
+  json_builder_set_member_name (jbuilder, "type");
+  json_builder_add_string_value (jbuilder, "position");
+  json_builder_set_member_name (jbuilder, "position");
+  json_builder_add_int_value (jbuilder, position);
+  json_builder_set_member_name (jbuilder, "duration");
+  json_builder_add_int_value (jbuilder, duration);
+  json_builder_set_member_name (jbuilder, "speed");
+  json_builder_add_double_value (jbuilder, rate);
+  json_builder_end_object (jbuilder);
+
+  gst_validate_send (json_builder_get_root (jbuilder));
+  g_object_unref (jbuilder);
+
   gst_validate_printf (NULL,
       "<position: %" GST_TIME_FORMAT " duration: %" GST_TIME_FORMAT
       " speed: %f />\r", GST_TIME_ARGS (position), GST_TIME_ARGS (duration),
@@ -423,15 +439,21 @@ _bus_handler (GstBus * bus, GstMessage * message,
     }
     case GST_MESSAGE_BUFFERING:
     {
+      JsonBuilder *jbuilder = json_builder_new ();
       GstBufferingMode mode;
       gint percent;
 
       gst_message_parse_buffering (message, &percent);
       gst_message_parse_buffering_stats (message, &mode, NULL, NULL, NULL);
 
+      json_builder_begin_object (jbuilder);
+      json_builder_set_member_name (jbuilder, "type");
+      json_builder_add_string_value (jbuilder, "buffering");
+      json_builder_set_member_name (jbuilder, "state");
       if (percent == 100) {
         /* a 100% message means buffering is done */
         gst_validate_printf (NULL, "\nDone buffering\n");
+        json_builder_add_string_value (jbuilder, "done");
         if (monitor->buffering) {
           monitor->print_pos_srcid =
               g_timeout_add (PRINT_POSITION_TIMEOUT,
@@ -443,13 +465,22 @@ _bus_handler (GstBus * bus, GstMessage * message,
         if (!monitor->buffering) {
           monitor->buffering = TRUE;
           gst_validate_printf (NULL, "\nStart buffering\n");
+          json_builder_add_string_value (jbuilder, "started");
           if (monitor->print_pos_srcid
               && g_source_remove (monitor->print_pos_srcid)) {
             monitor->print_pos_srcid = 0;
           }
+        } else {
+          json_builder_add_string_value (jbuilder, "progress");
         }
         gst_validate_printf (NULL, "%s %d%%  \r", "Buffering...", percent);
       }
+      json_builder_set_member_name (jbuilder, "position");
+      json_builder_add_int_value (jbuilder, percent);
+      json_builder_end_object (jbuilder);
+
+      gst_validate_send (json_builder_get_root (jbuilder));
+      g_object_unref (jbuilder);
       break;
     }
     case GST_MESSAGE_STREAM_COLLECTION:
index cf831dd..47545b4 100644 (file)
@@ -43,8 +43,48 @@ static GstValidateDebugFlags _gst_validate_flags = 0;
 static GHashTable *_gst_validate_issues = NULL;
 static FILE **log_files = NULL;
 
-GType _gst_validate_report_type;
-GST_DEFINE_MINI_OBJECT_TYPE (GstValidateReport, gst_validate_report);
+/* Tcp server for communications with gst-validate-launcher */
+GSocketClient *socket_client = NULL;
+GSocketConnection *server_connection = NULL;
+GOutputStream *server_ostream = NULL;
+
+GType _gst_validate_report_type = 0;
+
+static JsonNode *
+gst_validate_report_serialize (GstValidateReport * report)
+{
+  JsonNode *node = json_node_alloc ();
+  JsonObject *jreport = json_object_new ();
+
+  json_object_set_string_member (jreport, "type", "report");
+  json_object_set_string_member (jreport, "summary", report->issue->summary);
+  json_object_set_string_member (jreport, "level",
+      gst_validate_report_level_get_name (report->level));
+  json_object_set_string_member (jreport, "detected-on", report->reporter_name);
+  json_object_set_string_member (jreport, "details", report->message);
+
+  node = json_node_init_object (node, jreport);
+
+  return node;
+}
+
+GType
+gst_validate_report_get_type (void)
+{
+  if (_gst_validate_report_type == 0) {
+    _gst_validate_report_type =
+        g_boxed_type_register_static (g_intern_static_string
+        ("GstValidateReport"), (GBoxedCopyFunc) gst_mini_object_ref,
+        (GBoxedFreeFunc) gst_mini_object_unref);
+
+    json_boxed_register_serialize_func (_gst_validate_report_type,
+        JSON_NODE_OBJECT,
+        (JsonBoxedSerializeFunc) gst_validate_report_serialize);
+  }
+
+  return _gst_validate_report_type;
+}
+
 
 GRegex *newline_regex = NULL;
 
@@ -319,8 +359,7 @@ gst_validate_report_load_issues (void)
       _("a gstreamer plugin is missing and prevented Validate from running"),
       NULL);
   REGISTER_VALIDATE_ISSUE (CRITICAL, NOT_NEGOTIATED,
-      _("a NOT NEGOTIATED message has been emitted on the bus."),
-      NULL);
+      _("a NOT NEGOTIATED message has been posted on the bus."), NULL);
   REGISTER_VALIDATE_ISSUE (WARNING, WARNING_ON_BUS,
       _("We got a WARNING message on the bus"), NULL);
   REGISTER_VALIDATE_ISSUE (CRITICAL, ERROR_ON_BUS,
@@ -348,10 +387,58 @@ gst_validate_report_load_issues (void)
   REGISTER_VALIDATE_ISSUE (ISSUE, G_LOG_ISSUE, _("We got a g_log issue"), NULL);
 }
 
+gboolean
+gst_validate_send (JsonNode * root)
+{
+  gboolean res = FALSE;
+  JsonGenerator *jgen;
+  gsize message_length;
+  gchar *object, *message;
+  GError *error = NULL;
+
+  if (!server_ostream)
+    goto done;
+
+  jgen = json_generator_new ();
+  json_generator_set_root (jgen, root);
+
+  object = json_generator_to_data (jgen, &message_length);
+  message = g_malloc0 (message_length + 5);
+  GST_WRITE_UINT32_BE (message, message_length);
+  strcpy (&message[4], object);
+  g_free (object);
+
+  res = g_output_stream_write_all (server_ostream, message, message_length + 4,
+      NULL, NULL, &error);
+
+  if (!res) {
+    if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_PENDING)) {
+      GST_ERROR ("Stream was busy, trying again later.");
+
+      g_free (message);
+      g_object_unref (jgen);
+      g_idle_add ((GSourceFunc) gst_validate_send, root);
+      return G_SOURCE_REMOVE;
+    }
+
+    GST_ERROR ("ERROR: Can't write to remote: %s", error->message);
+  } else if (!g_output_stream_flush (server_ostream, NULL, &error)) {
+    GST_ERROR ("ERROR: Can't flush stream: %s", error->message);
+  }
+
+  g_free (message);
+  g_object_unref (jgen);
+
+done:
+  json_node_free (root);
+
+  return G_SOURCE_REMOVE;
+}
+
 void
 gst_validate_report_init (void)
 {
-  const gchar *var, *file_env;
+  const gchar *var, *file_env, *server_env;
   const GDebugKey keys[] = {
     {"fatal_criticals", GST_VALIDATE_FATAL_CRITICALS},
     {"fatal_warnings", GST_VALIDATE_FATAL_WARNINGS},
@@ -379,6 +466,42 @@ gst_validate_report_init (void)
     gst_validate_report_load_issues ();
   }
 
+  server_env = g_getenv ("GST_VALIDATE_SERVER");
+  if (server_env) {
+    GstUri *server_uri = gst_uri_from_string (server_env);
+
+    if (server_uri && !g_strcmp0 (gst_uri_get_scheme (server_uri), "tcp")) {
+      JsonBuilder *jbuilder;
+      GError *err = NULL;
+      socket_client = g_socket_client_new ();
+
+      server_connection = g_socket_client_connect_to_host (socket_client,
+          gst_uri_get_host (server_uri), gst_uri_get_port (server_uri),
+          NULL, &err);
+
+      if (!server_connection) {
+        g_clear_error (&err);
+        g_clear_object (&socket_client);
+
+      } else {
+        server_ostream =
+            g_io_stream_get_output_stream (G_IO_STREAM (server_connection));
+        jbuilder = json_builder_new ();
+        json_builder_begin_object (jbuilder);
+        json_builder_set_member_name (jbuilder, "started");
+        json_builder_add_boolean_value (jbuilder, TRUE);
+        json_builder_end_object (jbuilder);
+
+        gst_validate_send (json_builder_get_root (jbuilder));
+        g_object_unref (jbuilder);
+      }
+
+      gst_uri_unref (server_uri);
+    } else {
+      GST_ERROR ("Server URI not valid: %s", server_env);
+    }
+  }
+
   file_env = g_getenv ("GST_VALIDATE_FILE");
   if (file_env != NULL && *file_env != '\0') {
     gint i;
@@ -391,12 +514,11 @@ gst_validate_report_init (void)
         g_malloc0 (sizeof (FILE *) * (g_strv_length (wanted_files) + 1));
     for (i = 0; i < g_strv_length (wanted_files); i++) {
       FILE *log_file;
-
       if (g_strcmp0 (wanted_files[i], "stderr") == 0) {
         log_file = stderr;
-      } else if (g_strcmp0 (wanted_files[i], "stdout") == 0)
+      } else if (g_strcmp0 (wanted_files[i], "stdout") == 0) {
         log_file = stdout;
-      else {
+      else {
         log_file = g_fopen (wanted_files[i], "w");
       }
 
@@ -422,6 +544,16 @@ gst_validate_report_init (void)
 #endif
 }
 
+void
+gst_validate_report_deinit (void)
+{
+  if (server_ostream)
+    g_output_stream_close (server_ostream, NULL, NULL);
+  g_clear_object (&socket_client);
+  g_clear_object (&server_connection);
+  g_clear_object (&server_ostream);
+}
+
 GstValidateIssue *
 gst_validate_issue_from_id (GstValidateIssueId issue_id)
 {
index 87298e8..06d63c1 100644 (file)
@@ -538,6 +538,8 @@ gst_validate_runner_add_report (GstValidateRunner * runner,
   GstValidateReportingDetails reporter_level =
       gst_validate_reporter_get_reporting_level (report->reporter);
 
+  gst_validate_send (json_boxed_serialize (GST_MINI_OBJECT_TYPE (report),
+          report));
   /* Let's use our own reporting strategy */
   if (reporter_level == GST_VALIDATE_SHOW_UNKNOWN) {
     gst_validate_report_set_reporting_level (report,
@@ -633,18 +635,23 @@ _do_report_synthesis (GstValidateRunner * runner)
       continue;
 
     report = (GstValidateReport *) (reports->data);
+
     gst_validate_report_print_level (report);
     gst_validate_report_print_detected_on (report);
 
-    if (report->level == GST_VALIDATE_REPORT_LEVEL_CRITICAL)
+    if (report->level == GST_VALIDATE_REPORT_LEVEL_CRITICAL) {
       criticals = g_list_append (criticals, report);
+      gst_validate_report_print_details (report);
+    }
 
     for (tmp = g_list_next (reports); tmp; tmp = tmp->next) {
       report = (GstValidateReport *) (tmp->data);
       gst_validate_report_print_detected_on (report);
 
-      if (report->level == GST_VALIDATE_REPORT_LEVEL_CRITICAL)
+      if (report->level == GST_VALIDATE_REPORT_LEVEL_CRITICAL) {
         criticals = g_list_append (criticals, report);
+        gst_validate_report_print_details (report);
+      }
     }
     report = (GstValidateReport *) (reports->data);
     gst_validate_report_print_description (report);
index ff969ff..4a04db9 100644 (file)
@@ -188,7 +188,7 @@ G_DEFINE_TYPE_WITH_CODE (GstValidateScenario, gst_validate_scenario,
         _reporter_iface_init));
 
 /* GstValidateAction implementation */
-GType _gst_validate_action_type;
+GType _gst_validate_action_type = 0;
 
 struct _GstValidateActionPrivate
 {
@@ -204,7 +204,42 @@ struct _GstValidateActionPrivate
   GWeakRef scenario;
 };
 
-GST_DEFINE_MINI_OBJECT_TYPE (GstValidateAction, gst_validate_action);
+static JsonNode *
+gst_validate_action_serialize (GstValidateAction * action)
+{
+  JsonNode *node = json_node_alloc ();
+  JsonObject *jreport = json_object_new ();
+  gchar *action_args = gst_structure_to_string (action->structure);
+
+  json_object_set_string_member (jreport, "type", "action");
+  json_object_set_string_member (jreport, "action-type", action->type);
+  json_object_set_int_member (jreport, "playback-time",
+      (gint64) action->playback_time);
+  json_object_set_string_member (jreport, "args", action_args);
+  g_free (action_args);
+
+  node = json_node_init_object (node, jreport);
+
+  return node;
+}
+
+GType
+gst_validate_action_get_type (void)
+{
+  if (_gst_validate_action_type == 0) {
+    _gst_validate_action_type =
+        g_boxed_type_register_static (g_intern_static_string
+        ("GstValidateAction"), (GBoxedCopyFunc) gst_mini_object_ref,
+        (GBoxedFreeFunc) gst_mini_object_unref);
+
+    json_boxed_register_serialize_func (_gst_validate_action_type,
+        JSON_NODE_OBJECT,
+        (JsonBoxedSerializeFunc) gst_validate_action_serialize);
+  }
+
+  return _gst_validate_action_type;
+}
+
 static GstValidateAction *gst_validate_action_new (GstValidateScenario *
     scenario, GstValidateActionType * type);
 static gboolean execute_next_action (GstValidateScenario * scenario);
@@ -294,6 +329,9 @@ gboolean
 _action_check_and_set_printed (GstValidateAction * action)
 {
   if (action->priv->printed == FALSE) {
+    gst_validate_send (json_boxed_serialize (GST_MINI_OBJECT_TYPE
+            (action), action));
+
     action->priv->printed = TRUE;
 
     return FALSE;
index c617d25..9d74883 100644 (file)
@@ -46,7 +46,7 @@ gstvalidate = shared_library('gstvalidate',
     install: true,
     c_args : [gst_c_args],
     dependencies : [gst_dep, glib_dep, gio_dep, gmodule_dep,
-                    gst_pbutils_dep, mathlib])
+                    gst_pbutils_dep, mathlib, json_dep])
 
 validate_gen_sources = []
 if build_gir
index a7bf251..99bc502 100644 (file)
@@ -276,6 +276,7 @@ gst_validate_deinit (void)
   _priv_validate_override_registry_deinit ();
   core_config = NULL;
   validate_initialized = FALSE;
+  gst_validate_report_deinit ();
 
   g_mutex_unlock (&_gst_validate_registry_mutex);
   g_mutex_clear (&_gst_validate_registry_mutex);
index 852f737..ebdb6ea 100644 (file)
 
 """ Class representing tests and test managers. """
 
+import json
 import os
 import sys
 import re
+import SocketServer
+import struct
 import time
 import utils
 import signal
@@ -441,6 +444,33 @@ class Test(Loggable):
         return self.result
 
 
+class GstValidateListener(SocketServer.BaseRequestHandler):
+    def handle(self):
+        """Implements BaseRequestHandler handle method"""
+        while True:
+            raw_len = self.request.recv(4)
+            if raw_len == '':
+                return
+            msglen = struct.unpack('>I', raw_len)[0]
+            msg = self.request.recv(msglen)
+            if msg == '':
+                return
+
+            obj = json.loads(msg)
+            test = getattr(self.server, "test")
+
+            obj_type = obj.get("type", '')
+            if obj_type == 'position':
+                test.set_position(obj['position'], obj['duration'],
+                                obj['speed'])
+            elif obj_type == 'buffering':
+                test.set_position(obj['position'], 100)
+            elif obj_type == 'action':
+                test.add_action_execution(obj)
+            elif obj_type == 'report':
+                test.add_report(obj)
+
+
 class GstValidateTest(Test):
 
     """ A class representing a particular test. """
@@ -474,6 +504,11 @@ class GstValidateTest(Test):
         if p:
             application_name = p
 
+        self.reports = []
+        self.position = -1
+        self.duration = -1
+        self.speed = 1.0
+        self.actions_infos = []
         self.media_descriptor = media_descriptor
 
         override_path = self.get_override_file(media_descriptor)
@@ -500,6 +535,57 @@ class GstValidateTest(Test):
             self.scenario = None
         else:
             self.scenario = scenario
+        self.server = None
+
+    def stop_server(self):
+        if self.server:
+            self.server.server_close()
+            self.server.shutdown()
+            self.server_thread.join()
+            self.server = None
+
+    def kill_subprocess(self):
+        Test.kill_subprocess(self)
+        self.stop_server()
+
+    def add_report(self, report):
+        self.reports.append(report)
+
+    def set_position(self, position, duration, speed=None):
+        self.position = position
+        self.duration = duration
+        if speed:
+            self.speed = speed
+
+    def add_action_execution(self, action_infos):
+        if action_infos['action-type'] == 'eos':
+            self._sent_eos_pos = time.time()
+        self.actions_infos.append(action_infos)
+
+    def server_wrapper(self, ready):
+        self.server = SocketServer.TCPServer(('localhost', 0), GstValidateListener)
+        self.server.socket.settimeout(0.0)
+        self.server.test = self
+        self.serverport = self.server.socket.getsockname()[1]
+        self.info("%s server port: %s" % (self, self.serverport))
+        ready.set()
+
+        # Activate the server; this will keep running until you
+        # interrupt the program with Ctrl-C
+        self.server.serve_forever()
+
+    def test_start(self, queue):
+        ready = threading.Event()
+        self.server_thread = threading.Thread(target=self.server_wrapper,
+                                              kwargs={'ready': ready})
+        self.server_thread.start()
+        ready.wait()
+
+        Test.test_start(self, queue)
+
+    def test_end(self):
+        Test.test_end(self)
+        self.stop_server()
 
     def get_override_file(self, media_descriptor):
         if media_descriptor:
@@ -510,10 +596,12 @@ class GstValidateTest(Test):
 
         return None
 
+    def get_current_position(self):
+        return self.position
+
     def get_current_value(self):
         if self.scenario:
-            sent_eos = self.sent_eos_position()
-            if sent_eos is not None:
+            if self._sent_eos_pos is not None:
                 t = time.time()
                 if ((t - sent_eos)) > 30:
                     if self.media_descriptor.get_protocol() == Protocols.HLS:
@@ -528,7 +616,7 @@ class GstValidateTest(Test):
 
                     return Result.FAILED
 
-        return self.get_current_position()
+        return self.position
 
     def get_subproc_env(self):
         self.validatelogs = self.logfile + '.validate.logs'
@@ -541,6 +629,7 @@ class GstValidateTest(Test):
 
         utils.touch(self.validatelogs)
         subproc_env["GST_VALIDATE_FILE"] = logfiles
+        subproc_env["GST_VALIDATE_SERVER"] = "tcp://localhost:%s" % self.serverport
         self.extra_logfiles.append(self.validatelogs)
 
         if 'GST_DEBUG' in os.environ and not self.options.redirect_logs:
@@ -598,21 +687,15 @@ class GstValidateTest(Test):
         return value
 
     def get_validate_criticals_errors(self):
-        ret = "["
-        errors = []
-        for l in open(self.validatelogs, 'r').readlines():
-            if "critical : " in l:
-                error = l.split("critical : ")[1].replace("\n", '')
-                if error not in errors:
-                    if ret != "[":
-                        ret += ", "
-                    ret += error
-                    errors.append(error)
-
-        if ret == "[":
+        ret = []
+        for report in self.reports:
+            if report['level'] == 'critical':
+                ret.append(report['summary'])
+
+        if not ret:
             return None
-        else:
-            return ret + "]"
+
+        return str(ret)
 
     def check_results(self):
         if self.result is Result.FAILED or self.result is Result.PASSED or self.result is Result.TIMEOUT:
@@ -638,89 +721,6 @@ class GstValidateTest(Test):
         else:
             self.set_result(Result.PASSED)
 
-    def _parse_position(self, p):
-        self.log("Parsing %s" % p)
-        times = self.findpos_regex.findall(p)
-
-        if len(times) != 1:
-            self.warning("Got a unparsable value: %s" % p)
-            return 0, 0
-
-        return (utils.gsttime_from_tuple(times[0][:4]),
-                utils.gsttime_from_tuple(times[0][4:]))
-
-    def _parse_buffering(self, b):
-        return b.lower().split("buffering... ")[1].split("%")[0], 100
-
-    def _get_position(self):
-        position = duration = -1
-
-        self.debug("Getting position")
-        m = None
-        for l in reversed(open(self.validatelogs, 'r').readlines()):
-            l = l.lower()
-            if "<position:" in l or "buffering" in l:
-                m = l
-                break
-
-        if m is None:
-            self.debug("Could not fine any positionning info")
-            return position, duration
-
-        for j in m.split("\r"):
-            j = j.lstrip().rstrip()
-            if j.startswith("<position:") and j.endswith("/>"):
-                position, duration = self._parse_position(j)
-            elif j.startswith("buffering") and j.endswith("%"):
-                position, duration = self._parse_buffering(j)
-            else:
-                self.log("No info in %s" % j)
-
-        return position, duration
-
-    def _get_last_seek_values(self):
-        m = None
-        rate = start = stop = None
-
-        for l in reversed(open(self.validatelogs, 'r').readlines()):
-            l = l.lower()
-            if "seeking to: " in l:
-                m = l
-                break
-
-        if m is None:
-            self.debug("Could not fine any seeking info")
-            return start, stop, rate
-
-        values = self.findlastseek_regex.findall(m)
-        if len(values) != 1:
-            self.warning("Got an unparsable seek value %s", m)
-            return start, stop, rate
-
-        v = values[0]
-        return (utils.gsttime_from_tuple(v[:4]),
-                utils.gsttime_from_tuple(v[4:8]),
-                float(str(v[8]) + "." + str(v[9])))
-
-    def sent_eos_position(self):
-        if self._sent_eos_pos is not None:
-            return self._sent_eos_pos
-
-        for l in reversed(open(self.validatelogs, 'r').readlines()):
-            l = l.lower()
-            if "sending eos" in l:
-                self._sent_eos_pos = time.time()
-                return self._sent_eos_pos
-
-        return None
-
-    def get_current_position(self):
-        position, duration = self._get_position()
-        if position == -1:
-            return position
-
-        return position
-
     def get_valgrind_suppression_file(self, subdir, name):
         p = get_data_file(subdir, name)
         if p:
index 08b7fdd..d370e06 100644 (file)
@@ -1,5 +1,6 @@
 inc_dirs = include_directories('.')
 
+json_dep = dependency('json-glib-1.0')
 cdata = configuration_data()
 cdata.set('GST_API_VERSION', '"@0@"'.format(apiversion))
 cdata.set('VALIDATEPLUGINDIR', '"@0@/@1@/gstreamer-1.0/validate"'.format(get_option('prefix'),get_option('libdir')))