Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
S2-group
GitHub Repository: S2-group/android-runner
Path: blob/master/AndroidRunner/PluginHandler.py
629 views
1
import logging
2
import os
3
from shutil import copyfile
4
5
from pluginbase import PluginBase
6
7
import paths
8
from .Python3 import Python3
9
from .util import makedirs
10
11
12
class PluginHandler(object):
13
def __init__(self, name, params):
14
self.logger = logging.getLogger(self.__class__.__name__)
15
self.pluginParams = params
16
self.name = name
17
self.name_lower = name.lower()
18
self.moduleName = self.name_lower.capitalize()
19
self.subject_aggregated = False
20
self.subject_aggregated_default = False
21
self.paths = paths.paths_dict()
22
23
self.plugin_base = PluginBase(package='AndroidRunner.plugins')
24
25
# Check lower-cased plugin directory's sub-directories for the the requested plugin name
26
runner_plugin_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'Plugins')
27
if self.name_lower in self.list_subdir(runner_plugin_path):
28
self.plugin_source = self.plugin_base.make_plugin_source(searchpath=[os.path.join(runner_plugin_path, self.name_lower)])
29
self.pluginModule = self.plugin_source.load_plugin(self.moduleName)
30
self.currentProfiler = getattr(self.pluginModule, self.moduleName)(params, self.paths)
31
self.name = self.name_lower
32
else:
33
config_plugin_path = os.path.join(paths.CONFIG_DIR, 'Plugins')
34
if os.path.isdir(config_plugin_path):
35
copyfile(os.path.join(paths.ROOT_DIR, 'AndroidRunner', 'Plugins', 'Profiler.py'), os.path.join(
36
config_plugin_path, 'Profiler.py'))
37
self.plugin_source = self.plugin_base.make_plugin_source(searchpath=[config_plugin_path])
38
self.pluginModule = self.plugin_source.load_plugin(self.name)
39
self.currentProfiler = getattr(self.pluginModule, self.name)(params, self.paths)
40
else:
41
raise ImportError
42
self.logger.debug('%s: Initialized' % self.name)
43
44
def dependencies(self):
45
return self.currentProfiler.dependencies()
46
47
def load(self, device):
48
"""Load (and start) the profiler process on the device"""
49
self.logger.debug('%s: %s: Loading configuration' % (self.moduleName, device))
50
self.currentProfiler.load(device)
51
52
def start_profiling(self, device, **kwargs):
53
"""Start the profiling process"""
54
self.logger.debug('%s: %s: Start profiling' % (self.moduleName, device))
55
self.currentProfiler.start_profiling(device, **kwargs)
56
57
def stop_profiling(self, device, **kwargs):
58
"""Stop the profiling process"""
59
self.logger.debug('%s: %s: Stop profiling' % (self.moduleName, device))
60
self.currentProfiler.stop_profiling(device, **kwargs)
61
62
def collect_results(self, device):
63
"""Collect the data and clean up extra files on the device"""
64
self.logger.debug('%s: %s: Collecting data' % (self.moduleName, device))
65
self.currentProfiler.collect_results(device)
66
67
def unload(self, device):
68
"""Stop the profiler, removing configuration files on device"""
69
self.logger.debug('%s: %s: Cleanup' % (self.moduleName, device))
70
self.currentProfiler.unload(device)
71
72
def set_output(self):
73
# TODO clean up!
74
self.paths['OUTPUT_DIR'] = os.path.join(paths.OUTPUT_DIR, self.name)
75
makedirs(self.paths['OUTPUT_DIR'])
76
self.logger.debug('%s: Setting output: %s' % (self.moduleName, self.paths['OUTPUT_DIR']))
77
self.currentProfiler.set_output(self.paths['OUTPUT_DIR'])
78
79
def aggregate_subject(self):
80
aggregate_subject_function = self.pluginParams.get('subject_aggregation', 'default')
81
aggregate_subject_function_lower = aggregate_subject_function.lower()
82
83
if aggregate_subject_function_lower == 'none':
84
return
85
elif aggregate_subject_function_lower == 'default':
86
self.logger.debug('%s: aggregating subject results')
87
self.currentProfiler.aggregate_subject()
88
self.subject_aggregated = True
89
self.subject_aggregated_default = True
90
else:
91
aggregate_subject_script = Python3(os.path.join(paths.CONFIG_DIR, aggregate_subject_function))
92
self.logger.debug('%s: aggregating subject results')
93
self.subject_aggregated = True
94
self.subject_aggregated_default = False
95
aggregate_subject_script.run(None, self.paths['OUTPUT_DIR'])
96
97
def aggregate_data_end(self, output_dir):
98
aggregate_function = self.pluginParams.get('experiment_aggregation', 'default')
99
aggregate_function_lower = aggregate_function.lower()
100
101
data_dir = os.path.join(output_dir, 'data')
102
result_file = os.path.join(output_dir, 'Aggregated_Results_{}.csv'.format(self.moduleName))
103
104
if aggregate_function_lower == 'none':
105
return
106
elif aggregate_function_lower == 'default':
107
if self.subject_aggregated_default:
108
self.logger.debug('%s: aggregating results')
109
self.currentProfiler.aggregate_end(data_dir, result_file)
110
elif not self.subject_aggregated:
111
self.logger.debug('%s: aggregating results')
112
self.aggregate_subjects_default(data_dir)
113
self.currentProfiler.aggregate_end(data_dir, result_file)
114
else:
115
self.logger.info("{} profiler: User defined subject aggregation used,"
116
" default experiment aggregation not possible.".format(self.moduleName))
117
return
118
else:
119
aggregate_script = Python3(os.path.join(paths.CONFIG_DIR, aggregate_function))
120
self.logger.debug('%s: aggregating results')
121
aggregate_script.run(None, data_dir, result_file)
122
123
def aggregate_subjects_default(self, data_dir):
124
for device in self.list_subdir(data_dir):
125
device_dir = os.path.join(data_dir, device)
126
for subject in self.list_subdir(device_dir):
127
subject_dir = os.path.join(device_dir, subject)
128
if os.path.isdir(os.path.join(subject_dir, self.name)):
129
self.currentProfiler.set_output(os.path.join(subject_dir, self.name))
130
self.currentProfiler.aggregate_subject()
131
else:
132
for browser in self.list_subdir(subject_dir):
133
browser_dir = os.path.join(subject_dir, browser)
134
if os.path.isdir(os.path.join(browser_dir, self.name)):
135
self.currentProfiler.set_output(os.path.join(browser_dir, self.name))
136
self.currentProfiler.aggregate_subject()
137
138
@staticmethod
139
def list_subdir(a_dir):
140
"""List immediate subdirectories of a_dir"""
141
# https://stackoverflow.com/a/800201
142
return [name for name in os.listdir(a_dir)
143
if os.path.isdir(os.path.join(a_dir, name))]
144
145