# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
"""Utility functions for Talos"""
import os
import platform
import re
import string
import time
import urllib.parse
from sys
import stdout
try:
from mozlog
import get_proxy_logger
LOG = get_proxy_logger()
except ModuleNotFoundError:
LOG = stdout
# directory of this file for use with interpolatePath()
here = os.path.dirname(os.path.realpath(__file__))
class Timer(object):
def __init__(self):
self._start_time = 0
self.start()
def start(self):
self._start_time = time.time()
def elapsed(self):
seconds = time.time() - self._start_time
return time.strftime(
"%H:%M:%S", time.gmtime(seconds))
class TalosError(Exception):
"Errors found while running the talos harness."
class TalosRegression(Exception):
"""When a regression is detected at runtime, report it properly
Currently this
is a simple definition so we can detect the
class type
"""
class TalosCrash(Exception):
"""Exception type where we want to report a crash and stay
compatible
with tbpl
while allowing us to
continue on.
https://bugzilla.mozilla.org/show_bug.cgi?id=829734
"""
def interpolate(template, **kwargs):
"""
Use string.Template to substitute variables
in a string.
The placeholder ${talos}
is always defined
and will be replaced by the
folder containing this file (
global variable
'here').
You can add placeholders using kwargs.
"""
kwargs.setdefault(
"talos", here)
return string.Template(template).safe_substitute(**kwargs)
def findall(string, token):
"""find all occurences in a string"""
return [m.start()
for m
in re.finditer(re.escape(token), string)]
def tokenize(string, start, end):
"""
tokenize a string by start + end tokens,
returns parts
and position of last token
"""
assert end
not in start,
"End token '%s' is contained in start token '%s'" % (
end,
start,
)
assert start
not in end,
"Start token '%s' is contained in end token '%s'" % (
start,
end,
)
_start = findall(string, start)
_end = findall(string, end)
if not _start
and not _end:
return [], -1
assert len(_start),
"Could not find start token: '%s'" % start
assert len(_end),
"Could not find end token: '%s'" % end
assert len(_start) == len(
_end
),
"Unmatched number of tokens found: '%s' (%d) vs '%s' (%d)" % (
start,
len(_start),
end,
len(_end),
)
for i
in range(len(_start)):
assert _end[i] > _start[i],
"End token '%s' occurs before start token '%s'" % (
end,
start,
)
parts = []
for i
in range(len(_start)):
parts.append(string[_start[i] + len(start) : _end[i]])
return parts, _end[-1]
def urlsplit(url, default_scheme=
"file"):
"""front-end to urlparse.urlsplit"""
if "://" not in url:
url =
"%s://%s" % (default_scheme, url)
if url.startswith(
"file://"):
# file:// URLs do not play nice with windows
# https://bugzilla.mozilla.org/show_bug.cgi?id=793875
return [
"file",
"", url[len(
"file://") :],
"",
""]
# split the URL and return a list
return [i
for i
in urllib.parse.urlsplit(url)]
def parse_pref(value):
"""parse a preference value from a string"""
from mozprofile.prefs
import Preferences
return Preferences.cast(value)
def GenerateBrowserCommandLine(
browser_path, extra_args, profile_dir, url, profiling_info=
None
):
# TODO: allow for spaces in file names on Windows
command_args = [browser_path.strip()]
if platform.system() ==
"Darwin":
command_args.extend([
"-foreground"])
if isinstance(extra_args, list):
command_args.extend(extra_args)
elif extra_args.strip():
command_args.extend([extra_args])
command_args.extend([
"-profile", profile_dir])
if profiling_info:
# pageloader tests use a tpmanifest browser pref instead of passing in a manifest url
# profiling info is handled differently for pageloader vs non-pageloader (startup) tests
# for pageloader the profiling info was mirrored already in an env var; so here just
# need to setup profiling info for startup / non-pageloader tests
if url
is not None:
# for non-pageloader/non-manifest tests the profiling info is added to the test url
if url.find(
"?") != -1:
url +=
"&" + urllib.parse.urlencode(profiling_info)
else:
url +=
"?" + urllib.parse.urlencode(profiling_info)
# if there's a url i.e. startup test / non-manifest test, add it to the cmd line args
if url
is not None:
command_args.extend(url.split(
" "))
return command_args
def run_in_debug_mode(browser_config):
if (
browser_config.get(
"debug")
or browser_config.get(
"debugger")
or browser_config.get(
"debugg_args")
):
return True
return False