3 # Copyright (c) 2013,Thibault Saunier <thibault.saunier@collabora.com>
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU Lesser General Public
7 # License as published by the Free Software Foundation; either
8 # version 2.1 of the License, or (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 # Lesser General Public License for more details.
15 # You should have received a copy of the GNU Lesser General Public
16 # License along with this program; if not, write to the
17 # Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18 # Boston, MA 02110-1301, USA.
29 from operator import itemgetter
32 GST_SECOND = long(1000000000)
34 DEFAULT_MAIN_DIR = os.path.join(os.path.expanduser("~"), "gst-validate")
35 DEFAULT_GST_QA_ASSETS = os.path.join(DEFAULT_MAIN_DIR, "gst-integration-testsuites")
36 DISCOVERER_COMMAND = "gst-discoverer-1.0"
37 # Use to set the duration from which a test is concidered as being 'long'
46 KNOWN_ERROR = "Known error"
49 class Protocols(object):
56 def needs_clock_sync(protocol):
57 if protocol == Protocols.HLS:
72 def desactivate_colors():
83 os.makedirs(directory)
90 exts = filter(None, os.environ.get('PATHEXT', '').split(os.pathsep))
91 path = os.environ.get('PATH', None)
94 for p in os.environ.get('PATH', '').split(os.pathsep):
95 p = os.path.join(p, name)
96 if os.access(p, os.X_OK):
100 if os.access(pext, os.X_OK):
105 def get_color_for_result(result):
106 if result is Result.FAILED:
108 elif result is Result.TIMEOUT:
109 color = Colors.WARNING
110 elif result is Result.PASSED:
111 color = Colors.OKGREEN
113 color = Colors.OKBLUE
118 def printc(message, color="", title=False):
121 for l in message.split("\n"):
125 length = len(message)
126 message = length * '=' + "\n" + str(message) + "\n" + length * '='
128 if hasattr(message, "result") and color == '':
129 color = get_color_for_result(message.result)
131 sys.stdout.write(color + str(message) + Colors.ENDC + "\n")
135 def launch_command(command, color=None, fails=False):
136 printc(command, Colors.OKGREEN, True)
137 res = os.system(command)
138 if res != 0 and fails is True:
139 raise subprocess.CalledProcessError(res, "%s failed" % command)
143 return urlparse.urljoin('file:', urllib.pathname2url(path))
147 path = urlparse.urlparse(url).path
148 if "win32" in sys.platform:
150 return path[1:] # We need to remove the first '/' on windows
155 url = urlparse.urlparse(string)
156 if url.scheme != "" and url.scheme != "":
162 def touch(fname, times=None):
163 with open(fname, 'a'):
164 os.utime(fname, times)
167 def get_subclasses(klass, env):
169 for symb in env.iteritems():
171 if issubclass(symb[1], klass) and not symb[1] is klass:
172 subclasses.append(symb[1])
180 return "%u:%02u:%02u.%09u" % (time / (GST_SECOND * 60 * 60),
181 (time / (GST_SECOND * 60)) % 60,
182 (time / GST_SECOND) % 60,
186 def look_for_file_in_source_dir(subdir, name):
187 root_dir = os.path.abspath(os.path.dirname(os.path.join(os.path.dirname(os.path.abspath(__file__)))))
188 p = os.path.join(root_dir, subdir, name)
189 if os.path.exists(p):
195 # Returns the path $top_src_dir/@subdir/@name if running from source, or
196 # $DATADIR/gstreamer-1.0/validate/@name if not
197 def get_data_file(subdir, name):
198 # Are we running from sources?
199 p = look_for_file_in_source_dir(subdir, name)
203 # Look in system data dirs
204 p = os.path.join(config.DATADIR, 'gstreamer-1.0', 'validate', name)
205 if os.path.exists(p):
211 # Some utilities to parse gst-validate output #
215 def gsttime_from_tuple(stime):
216 return long((int(stime[0]) * 3600 + int(stime[1]) * 60 + int(stime[2])) * GST_SECOND + int(stime[3]))
218 timeregex = re.compile(r'(?P<_0>.+):(?P<_1>.+):(?P<_2>.+)\.(?P<_3>.+)')
221 def parse_gsttimeargs(time):
222 stime = map(itemgetter(1), sorted(
223 timeregex.match(time).groupdict().items()))
224 return long((int(stime[0]) * 3600 + int(stime[1]) * 60 + int(stime[2])) * GST_SECOND + int(stime[3]))
227 def get_duration(media_file):
232 res = subprocess.check_output([DISCOVERER_COMMAND, media_file])
233 except subprocess.CalledProcessError:
234 # gst-media-check returns !0 if seeking is not possible, we do not care
238 for l in res.split('\n'):
239 if "Duration: " in l:
240 duration = parse_gsttimeargs(l.replace("Duration: ", ""))
247 GST_VALIDATE_COMMAND = "gst-validate-1.0"
248 os.system("%s --scenarios-defs-output-file %s" % (GST_VALIDATE_COMMAND,