tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

layers.py (5064B)


      1 # This Source Code Form is subject to the terms of the Mozilla Public
      2 # License, v. 2.0. If a copy of the MPL was not distributed with this
      3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
      4 import traceback
      5 
      6 from mozperftest.utils import MachLogger
      7 
      8 
      9 class StopRunError(Exception):
     10    pass
     11 
     12 
     13 class Layer(MachLogger):
     14    # layer name
     15    name = "unset"
     16 
     17    # activated by default ?
     18    activated = False
     19 
     20    # list of arguments grabbed by PerftestArgumentParser
     21    arguments = {}
     22 
     23    # If true, calls on_exception() on errors
     24    user_exception = False
     25 
     26    def __init__(self, env, mach_command):
     27        MachLogger.__init__(self, mach_command)
     28        self.return_code = 0
     29        self.mach_cmd = mach_command
     30        self.run_process = mach_command.run_process
     31        self.env = env
     32 
     33    def _normalize_arg(self, name):
     34        if name.startswith("--"):
     35            name = name[2:]
     36        if not name.startswith(self.name):
     37            name = "%s-%s" % (self.name, name)
     38        return name.replace("-", "_")
     39 
     40    def get_arg_names(self):
     41        return [self._normalize_arg(arg) for arg in self.arguments]
     42 
     43    def set_arg(self, name, value):
     44        """Sets the argument"""
     45        name = self._normalize_arg(name)
     46        if name not in self.get_arg_names():
     47            raise KeyError(
     48                "%r tried to set %r, but does not own it" % (self.name, name)
     49            )
     50        return self.env.set_arg(name, value)
     51 
     52    def get_arg(self, name, default=None):
     53        return self.env.get_arg(name, default, self)
     54 
     55    def __enter__(self):
     56        self.info("Running %s:setup" % self.name)
     57        self.setup()
     58        return self
     59 
     60    def __exit__(self, type, value, traceback):
     61        # XXX deal with errors here
     62        self.info("Running %s:teardown" % self.name)
     63        self.teardown()
     64 
     65    def __call__(self, metadata):
     66        has_exc_handler = self.env.hooks.exists("on_exception")
     67        self.info("Running %s:run" % self.name)
     68        try:
     69            metadata = self.run(metadata)
     70        except Exception as e:
     71            if self.user_exception and has_exc_handler:
     72                self.error("User handled error")
     73                for line in traceback.format_exc().splitlines():
     74                    self.error(line)
     75                resume_run = self.env.hooks.run("on_exception", self.env, self, e)
     76                if resume_run:
     77                    return metadata
     78                raise StopRunError()
     79            else:
     80                raise
     81        return metadata
     82 
     83    def setup(self):
     84        pass
     85 
     86    def teardown(self):
     87        pass
     88 
     89    def run(self, metadata):
     90        return metadata
     91 
     92 
     93 class Layers(Layer):
     94    def __init__(self, env, mach_command, factories):
     95        super().__init__(env, mach_command)
     96 
     97        def _active(layer):
     98            # if it's activated by default, see if we need to deactivate
     99            # it by looking for the --no-layername option
    100            if layer.activated:
    101                return not env.get_arg("no-" + layer.name, False)
    102            # if it's deactivated by default, we look for --layername
    103            return env.get_arg(layer.name, False)
    104 
    105        self.layers = [
    106            factory(env, mach_command) for factory in factories if _active(factory)
    107        ]
    108        self.env = env
    109        self._counter = -1
    110 
    111    def _normalize_arg(self, name):
    112        if name.startswith("--"):
    113            name = name[2:]
    114        return name.replace("-", "_")
    115 
    116    def get_layer(self, name):
    117        for layer in self.layers:
    118            if layer.name == name:
    119                return layer
    120        return None
    121 
    122    @property
    123    def name(self):
    124        return " + ".join([l.name for l in self.layers])
    125 
    126    def __iter__(self):
    127        self._counter = -1
    128        return self
    129 
    130    def __next__(self):
    131        self._counter += 1
    132        try:
    133            return self.layers[self._counter]
    134        except IndexError:
    135            raise StopIteration
    136 
    137    def __enter__(self):
    138        self.setup()
    139        return self
    140 
    141    def __exit__(self, type, value, traceback):
    142        # XXX deal with errors here
    143        self.teardown()
    144 
    145    def setup(self):
    146        for layer in self.layers:
    147            self.debug("Running %s:setup" % layer.name)
    148            layer.setup()
    149 
    150    def teardown(self):
    151        for layer in self.layers:
    152            self.debug("Running %s:teardown" % layer.name)
    153            layer.teardown()
    154 
    155    def __call__(self, metadata):
    156        for layer in self.layers:
    157            metadata = layer(metadata)
    158        return metadata
    159 
    160    def set_arg(self, name, value):
    161        """Sets the argument"""
    162        name = self._normalize_arg(name)
    163        found = False
    164        for layer in self.layers:
    165            if name in layer.get_arg_names():
    166                found = True
    167                break
    168 
    169        if not found:
    170            raise KeyError(
    171                "%r tried to set %r, but does not own it" % (self.name, name)
    172            )
    173 
    174        return self.env.set_arg(name, value)
    175 
    176    def get_arg(self, name, default=None):
    177        return self.env.get_arg(name, default)