summaryrefslogtreecommitdiffstats
path: root/python/mozperftest/mozperftest/layers.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/mozperftest/mozperftest/layers.py')
-rw-r--r--python/mozperftest/mozperftest/layers.py177
1 files changed, 177 insertions, 0 deletions
diff --git a/python/mozperftest/mozperftest/layers.py b/python/mozperftest/mozperftest/layers.py
new file mode 100644
index 0000000000..8cec547bf5
--- /dev/null
+++ b/python/mozperftest/mozperftest/layers.py
@@ -0,0 +1,177 @@
+# 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/.
+import traceback
+
+from mozperftest.utils import MachLogger
+
+
+class StopRunError(Exception):
+ pass
+
+
+class Layer(MachLogger):
+ # layer name
+ name = "unset"
+
+ # activated by default ?
+ activated = False
+
+ # list of arguments grabbed by PerftestArgumentParser
+ arguments = {}
+
+ # If true, calls on_exception() on errors
+ user_exception = False
+
+ def __init__(self, env, mach_command):
+ MachLogger.__init__(self, mach_command)
+ self.return_code = 0
+ self.mach_cmd = mach_command
+ self.run_process = mach_command.run_process
+ self.env = env
+
+ def _normalize_arg(self, name):
+ if name.startswith("--"):
+ name = name[2:]
+ if not name.startswith(self.name):
+ name = "%s-%s" % (self.name, name)
+ return name.replace("-", "_")
+
+ def get_arg_names(self):
+ return [self._normalize_arg(arg) for arg in self.arguments]
+
+ def set_arg(self, name, value):
+ """Sets the argument"""
+ name = self._normalize_arg(name)
+ if name not in self.get_arg_names():
+ raise KeyError(
+ "%r tried to set %r, but does not own it" % (self.name, name)
+ )
+ return self.env.set_arg(name, value)
+
+ def get_arg(self, name, default=None):
+ return self.env.get_arg(name, default, self)
+
+ def __enter__(self):
+ self.debug("Running %s:setup" % self.name)
+ self.setup()
+ return self
+
+ def __exit__(self, type, value, traceback):
+ # XXX deal with errors here
+ self.debug("Running %s:teardown" % self.name)
+ self.teardown()
+
+ def __call__(self, metadata):
+ has_exc_handler = self.env.hooks.exists("on_exception")
+ self.debug("Running %s:run" % self.name)
+ try:
+ metadata = self.run(metadata)
+ except Exception as e:
+ if self.user_exception and has_exc_handler:
+ self.error("User handled error")
+ for line in traceback.format_exc().splitlines():
+ self.error(line)
+ resume_run = self.env.hooks.run("on_exception", self.env, self, e)
+ if resume_run:
+ return metadata
+ raise StopRunError()
+ else:
+ raise
+ return metadata
+
+ def setup(self):
+ pass
+
+ def teardown(self):
+ pass
+
+ def run(self, metadata):
+ return metadata
+
+
+class Layers(Layer):
+ def __init__(self, env, mach_command, factories):
+ super(Layers, self).__init__(env, mach_command)
+
+ def _active(layer):
+ # if it's activated by default, see if we need to deactivate
+ # it by looking for the --no-layername option
+ if layer.activated:
+ return not env.get_arg("no-" + layer.name, False)
+ # if it's deactivated by default, we look for --layername
+ return env.get_arg(layer.name, False)
+
+ self.layers = [
+ factory(env, mach_command) for factory in factories if _active(factory)
+ ]
+ self.env = env
+ self._counter = -1
+
+ def _normalize_arg(self, name):
+ if name.startswith("--"):
+ name = name[2:]
+ return name.replace("-", "_")
+
+ def get_layer(self, name):
+ for layer in self.layers:
+ if layer.name == name:
+ return layer
+ return None
+
+ @property
+ def name(self):
+ return " + ".join([l.name for l in self.layers])
+
+ def __iter__(self):
+ self._counter = -1
+ return self
+
+ def __next__(self):
+ self._counter += 1
+ try:
+ return self.layers[self._counter]
+ except IndexError:
+ raise StopIteration
+
+ def __enter__(self):
+ self.setup()
+ return self
+
+ def __exit__(self, type, value, traceback):
+ # XXX deal with errors here
+ self.teardown()
+
+ def setup(self):
+ for layer in self.layers:
+ self.debug("Running %s:setup" % layer.name)
+ layer.setup()
+
+ def teardown(self):
+ for layer in self.layers:
+ self.debug("Running %s:teardown" % layer.name)
+ layer.teardown()
+
+ def __call__(self, metadata):
+ for layer in self.layers:
+ metadata = layer(metadata)
+ return metadata
+
+ def set_arg(self, name, value):
+ """Sets the argument"""
+ name = self._normalize_arg(name)
+ found = False
+ for layer in self.layers:
+ if name in layer.get_arg_names():
+ found = True
+ break
+
+ if not found:
+ raise KeyError(
+ "%r tried to set %r, but does not own it" % (self.name, name)
+ )
+
+ return self.env.set_arg(name, value)
+
+ def get_arg(self, name, default=None):
+ return self.env.get_arg(name, default)