mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-19 00:01:23 +00:00
validate: Pass information about GstValidate execution over a socket
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.
This commit is contained in:
parent
29e5ac1362
commit
2fff14e469
11 changed files with 333 additions and 117 deletions
|
@ -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)
|
||||
|
|
|
@ -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 =
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -19,9 +19,12 @@
|
|||
|
||||
""" 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)
|
||||
ret = []
|
||||
for report in self.reports:
|
||||
if report['level'] == 'critical':
|
||||
ret.append(report['summary'])
|
||||
|
||||
if ret == "[":
|
||||
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:
|
||||
|
|
|
@ -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')))
|
||||
|
|
Loading…
Reference in a new issue