diff --git a/validate/tools/launcher/apps/ges-launch.py b/validate/tools/launcher/apps/ges-launch.py index d3070e3f1d..10976c03fb 100644 --- a/validate/tools/launcher/apps/ges-launch.py +++ b/validate/tools/launcher/apps/ges-launch.py @@ -23,7 +23,7 @@ import subprocess import utils from urllib import unquote import xml.etree.ElementTree as ET -from baseclasses import GstValidateTest, TestsManager, Scenario +from baseclasses import GstValidateTest, TestsManager, ScenarioManager GES_DURATION_TOLERANCE = utils.GST_SECOND / 2 GES_LAUNCH_COMMAND = "ges-launch-1.0" @@ -156,6 +156,8 @@ class GESRenderTest(GESTest): class GESTestsManager(TestsManager): name = "ges" + _scenarios = ScenarioManager() + def __init__(self): super(GESTestsManager, self).__init__() @@ -206,13 +208,14 @@ class GESTestsManager(TestsManager): else: projects.append(utils.path2url(proj)) - SCENARIOS = [Scenario.get_scenario("play_15s"), - Scenario.get_scenario("seek_forward"), - Scenario.get_scenario("seek_backward"), - Scenario.get_scenario("scrub_forward_seeking")] + SCENARIOS = ["play_15s", + "seek_forward", + "seek_backward", + "scrub_forward_seeking"] for proj in projects: # First playback casses - for scenario in SCENARIOS: + for scenario_name in SCENARIOS: + scenario = self._scenarios.get_scenario(scenario_name) classname = "ges.playback.%s.%s" % (scenario.name, os.path.basename(proj).replace(".xges", "")) self.add_test(GESPlaybackTest(classname, diff --git a/validate/tools/launcher/apps/gst-validate.py b/validate/tools/launcher/apps/gst-validate.py index 10c1fcf99d..f71201a172 100644 --- a/validate/tools/launcher/apps/gst-validate.py +++ b/validate/tools/launcher/apps/gst-validate.py @@ -22,7 +22,7 @@ import subprocess import ConfigParser from loggable import Loggable -from baseclasses import GstValidateTest, TestsManager, Test, Scenario, NamedDic +from baseclasses import GstValidateTest, TestsManager, Test, ScenarioManager, NamedDic from utils import MediaFormatCombination, get_profile,\ path2url, DEFAULT_TIMEOUT, which, GST_SECOND, Result, \ compare_rendered_with_original, Protocols @@ -51,13 +51,16 @@ class PlaybinDescriptor(PipelineDescriptor): pipe = self._pipeline if options.mute: fakesink = "fakesink" - if scenario and scenario.seeks: - fakesink = "'" + fakesink + " sync=true'" + try: + if scenario and bool(scenario.seek) == True: + fakesink = "'" + fakesink + " sync=true'" + except AttributeError: + pass pipe += " audio-sink=%s video-sink=%s" %(fakesink, fakesink) pipe += " uri=%s" % uri - if scenario.reverse and protocol == Protocols.HTTP: + if hasattr(scenario, "reverse-playback") and protocol == Protocols.HTTP: # 10MB so we can reverse playbacl pipe += " ring-buffer-max-size=10240" @@ -89,24 +92,24 @@ G_V_ENCODING_TARGET_COMBINATIONS = [ # List of scenarios to run depending on the protocol in use -G_V_SCENARIOS = {Protocols.FILE: [Scenario.get_scenario("play_15s"), - Scenario.get_scenario("reverse_playback"), - Scenario.get_scenario("fast_forward"), - Scenario.get_scenario("seek_forward"), - Scenario.get_scenario("seek_backward"), - Scenario.get_scenario("seek_with_stop"), - Scenario.get_scenario("scrub_forward_seeking")], - Protocols.HTTP: [Scenario.get_scenario("play_15s"), - Scenario.get_scenario("fast_forward"), - Scenario.get_scenario("seek_forward"), - Scenario.get_scenario("seek_backward"), - Scenario.get_scenario("seek_with_stop"), - Scenario.get_scenario("reverse_playback")], - Protocols.HLS: [Scenario.get_scenario("play_15s"), - Scenario.get_scenario("fast_forward"), - Scenario.get_scenario("seek_forward"), - Scenario.get_scenario("seek_with_stop"), - Scenario.get_scenario("seek_backward")], +G_V_SCENARIOS = {Protocols.FILE: ["play_15s", + "reverse_playback", + "fast_forward", + "seek_forward", + "seek_backward", + "seek_with_stop", + "scrub_forward_seeking"], + Protocols.HTTP: ["play_15s", + "fast_forward", + "seek_forward", + "seek_backward", + "seek_with_stop", + "reverse_playback"], + Protocols.HLS: ["play_15s", + "fast_forward", + "seek_forward", + "seek_with_stop", + "seek_backward"], } G_V_BLACKLISTED_TESTS = \ @@ -160,18 +163,20 @@ class GstValidateMediaCheckTest(Test): class GstValidateTranscodingTest(GstValidateTest): + _scenarios = ScenarioManager() def __init__(self, classname, options, reporter, combination, uri, file_infos, timeout=DEFAULT_TIMEOUT, - scenario=Scenario.get_scenario("play_15s")): + scenario_name="play_15s"): + scenario = self._scenarios.get_scenario(scenario_name) try: timeout = G_V_PROTOCOL_TIMEOUTS[file_infos.get("file-info", "protocol")] except KeyError: pass - if scenario.max_duration is not None: - hard_timeout = 4 * scenario.max_duration + timeout - else: + try: + hard_timeout = 4 * int(scenario.duration) + timeout + except AttributeError: hard_timeout = None super(GstValidateTranscodingTest, self).__init__( @@ -215,6 +220,8 @@ class GstValidateTranscodingTest(GstValidateTest): class GstValidateManager(TestsManager, Loggable): name = "validate" + _scenarios = ScenarioManager() + def __init__(self): TestsManager.__init__(self) @@ -338,10 +345,12 @@ class GstValidateManager(TestsManager, Loggable): if pipe_descriptor.needs_uri(): for uri, minfo in self._list_uris(): protocol = minfo.config.get("file-info", "protocol") - for scenario in G_V_SCENARIOS[protocol]: + for scenario_name in G_V_SCENARIOS[protocol]: + scenario = self._scenarios.get_scenario(scenario_name) npipe = pipe_descriptor.get_pipeline(self.options, protocol, - scenario, uri) + scenario, + uri) if minfo.config.getboolean("media-info", "seekable") is False: self.debug("Do not run %s as %s does not support seeking", scenario, uri) diff --git a/validate/tools/launcher/baseclasses.py b/validate/tools/launcher/baseclasses.py index ba9c39245c..5c24c73520 100644 --- a/validate/tools/launcher/baseclasses.py +++ b/validate/tools/launcher/baseclasses.py @@ -26,6 +26,7 @@ import utils import urlparse import subprocess import reporters +import ConfigParser from loggable import Loggable from optparse import OptionGroup @@ -568,25 +569,42 @@ class NamedDic(object): for name, value in props.iteritems(): setattr(self, name, value) - class Scenario(object): - - def __init__(self, name, max_duration=None, seeks=True, reverse=False): + def __init__(self, name, props): self.name = name - self.max_duration = max_duration - self.seeks = seeks - self.reverse = reverse - @classmethod - def get_scenario(cls, name): - return [scenario for scenario in ALL_SCENARIOS if scenario.name == name][0] + for prop, value in props: + setattr(self, prop, value) + +class ScenarioManager(object): + _instance = None + all_scenarios = [] + GST_VALIDATE_COMMAND = "gst-validate-1.0" + + def __new__(cls, *args, **kwargs): + if not cls._instance: + cls._instance = super(ScenarioManager, cls).__new__( + cls, *args, **kwargs) + cls._instance.config = None + return cls._instance + + def get_scenario(self, name): + if self.all_scenarios: + return [scenario for scenario in self.all_scenarios if scenario.name == name][0] + + scenario_defs = os.path.join(self.config.main_dir, "scenarios.def") + try: + subprocess.check_output([self.GST_VALIDATE_COMMAND, + "--scenarios-defs-output-file", + scenario_defs]) + except subprocess.CalledProcessError: + pass + + config = ConfigParser.ConfigParser() + f = open(scenario_defs) + config.readfp(f) + + for section in config.sections(): + self.all_scenarios.append(Scenario(section, + config.items(section))) -ALL_SCENARIOS = [ - Scenario("play_15s", seeks=False, max_duration=15), - Scenario("reverse_playback", reverse=True), - Scenario("fast_forward", seeks=True), - Scenario("seek_forward", seeks=True), - Scenario("seek_backward", seeks=True), - Scenario("scrub_forward_seeking", seeks=True), - Scenario("seek_with_stop", seeks=True), -] diff --git a/validate/tools/launcher/main.py b/validate/tools/launcher/main.py index bfceb33296..ee8d1fc8b0 100644 --- a/validate/tools/launcher/main.py +++ b/validate/tools/launcher/main.py @@ -24,7 +24,7 @@ import loggable from optparse import OptionParser, OptionGroup from httpserver import HTTPServer -from baseclasses import _TestsLauncher +from baseclasses import _TestsLauncher, ScenarioManager from utils import printc, path2url, DEFAULT_MAIN_DIR, launch_command, Colors @@ -169,6 +169,8 @@ def main(): options.remote_assets_url, options.clone_dir)) + # Ensure that the scenario manager singleton is ready to be used + ScenarioManager().config = options tests_launcher.list_tests() httpsrv = HTTPServer(options) diff --git a/validate/tools/launcher/utils.py b/validate/tools/launcher/utils.py index f7d2d74a32..e43cf29cb0 100644 --- a/validate/tools/launcher/utils.py +++ b/validate/tools/launcher/utils.py @@ -238,3 +238,9 @@ def compare_rendered_with_original(orig_duration, dest_file, tolerance=DURATION_ "wrong-duration") else: return (Result.PASSED, "") + + +def get_scenarios(): + GST_VALIDATE_COMMAND = "gst-validate-1.0" + os.system("%s --scenarios-defs-output-file %s" % (GST_VALIDATE_COMMAND, + ))