Make run-benchmark script supports 'config' key in test plan.
[WebKit-https.git] / Tools / Scripts / webkitpy / benchmark_runner / utils.py
1 #!/usr/bin/env python
2
3 import imp
4 import inspect
5 import logging
6 import os
7 import signal
8 import shutil
9 import sys
10
11
12 _log = logging.getLogger(__name__)
13
14
15 # Borrow following code from stackoverflow
16 # Link: http://stackoverflow.com/questions/11461356/issubclass-returns-flase-on-the-same-class-imported-from-different-paths
17 def is_subclass(child, parent_name):
18     return inspect.isclass(child) and parent_name in [cls.__name__ for cls in inspect.getmro(child)]
19
20
21 def load_subclasses(dirname, base_class_name, base_class_file, loader):
22     filelist = [base_class_file] + [f for f in os.listdir(dirname) if f.endswith('_' + base_class_file)]
23     filelist += [f for f in os.listdir(dirname) if f.endswith('.py') and f not in ['__init__.py'] + filelist]
24     for filename in filelist:
25         module_name = os.path.splitext(filename)[0]
26         module = imp.load_source(module_name, os.path.join(dirname, filename))
27         for item_name in dir(module):
28             item = getattr(module, item_name)
29             if is_subclass(item, base_class_name):
30                 loader(item)
31
32
33 def get_path_from_project_root(relative_path_to_project_root):
34     # Choose the directory containing current file as start point,
35     # compute relative path base on the parameter,
36     # and return an absolute path
37     return os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), relative_path_to_project_root))
38
39
40 def force_remove(path):
41     try:
42         shutil.rmtree(path)
43     except Exception as error:
44         # Directory/file does not exist or privilege issue, just ignore it
45         _log.info("Error removing %s: %s" % (path, error))
46         pass
47
48
49 def write_defaults(domain, key, value):
50     # Returns whether the key in the domain is updated
51     from Foundation import NSUserDefaults
52     defaults = NSUserDefaults.standardUserDefaults()
53     defaults_for_domain = defaults.persistentDomainForName_(domain)
54     if not defaults_for_domain:
55         return False
56     old_value = defaults_for_domain.get(key)
57     if old_value == value:
58         return False
59     mutable_defaults_for_domain = defaults_for_domain.mutableCopy()
60     mutable_defaults_for_domain[key] = value
61     defaults.setPersistentDomain_forName_(mutable_defaults_for_domain, domain)
62     defaults.synchronize()
63     return True
64
65
66 # Borrow this code from
67 # 'http://stackoverflow.com/questions/2281850/timeout-function-if-it-takes-too-long-to-finish'
68 class TimeoutError(Exception):
69     pass
70
71
72 class timeout:
73
74     def __init__(self, seconds=1, error_message='Timeout'):
75         self.seconds = seconds
76         self.error_message = error_message
77
78     def handle_timeout(self, signum, frame):
79         raise TimeoutError(self.error_message)
80
81     def __enter__(self):
82         signal.signal(signal.SIGALRM, self.handle_timeout)
83         signal.alarm(self.seconds)
84
85     def __exit__(self, type, value, traceback):
86         signal.alarm(0)