Path: blob/master/AndroidRunner/PluginHandler.py
629 views
import logging1import os2from shutil import copyfile34from pluginbase import PluginBase56import paths7from .Python3 import Python38from .util import makedirs91011class PluginHandler(object):12def __init__(self, name, params):13self.logger = logging.getLogger(self.__class__.__name__)14self.pluginParams = params15self.name = name16self.name_lower = name.lower()17self.moduleName = self.name_lower.capitalize()18self.subject_aggregated = False19self.subject_aggregated_default = False20self.paths = paths.paths_dict()2122self.plugin_base = PluginBase(package='AndroidRunner.plugins')2324# Check lower-cased plugin directory's sub-directories for the the requested plugin name25runner_plugin_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'Plugins')26if self.name_lower in self.list_subdir(runner_plugin_path):27self.plugin_source = self.plugin_base.make_plugin_source(searchpath=[os.path.join(runner_plugin_path, self.name_lower)])28self.pluginModule = self.plugin_source.load_plugin(self.moduleName)29self.currentProfiler = getattr(self.pluginModule, self.moduleName)(params, self.paths)30self.name = self.name_lower31else:32config_plugin_path = os.path.join(paths.CONFIG_DIR, 'Plugins')33if os.path.isdir(config_plugin_path):34copyfile(os.path.join(paths.ROOT_DIR, 'AndroidRunner', 'Plugins', 'Profiler.py'), os.path.join(35config_plugin_path, 'Profiler.py'))36self.plugin_source = self.plugin_base.make_plugin_source(searchpath=[config_plugin_path])37self.pluginModule = self.plugin_source.load_plugin(self.name)38self.currentProfiler = getattr(self.pluginModule, self.name)(params, self.paths)39else:40raise ImportError41self.logger.debug('%s: Initialized' % self.name)4243def dependencies(self):44return self.currentProfiler.dependencies()4546def load(self, device):47"""Load (and start) the profiler process on the device"""48self.logger.debug('%s: %s: Loading configuration' % (self.moduleName, device))49self.currentProfiler.load(device)5051def start_profiling(self, device, **kwargs):52"""Start the profiling process"""53self.logger.debug('%s: %s: Start profiling' % (self.moduleName, device))54self.currentProfiler.start_profiling(device, **kwargs)5556def stop_profiling(self, device, **kwargs):57"""Stop the profiling process"""58self.logger.debug('%s: %s: Stop profiling' % (self.moduleName, device))59self.currentProfiler.stop_profiling(device, **kwargs)6061def collect_results(self, device):62"""Collect the data and clean up extra files on the device"""63self.logger.debug('%s: %s: Collecting data' % (self.moduleName, device))64self.currentProfiler.collect_results(device)6566def unload(self, device):67"""Stop the profiler, removing configuration files on device"""68self.logger.debug('%s: %s: Cleanup' % (self.moduleName, device))69self.currentProfiler.unload(device)7071def set_output(self):72# TODO clean up!73self.paths['OUTPUT_DIR'] = os.path.join(paths.OUTPUT_DIR, self.name)74makedirs(self.paths['OUTPUT_DIR'])75self.logger.debug('%s: Setting output: %s' % (self.moduleName, self.paths['OUTPUT_DIR']))76self.currentProfiler.set_output(self.paths['OUTPUT_DIR'])7778def aggregate_subject(self):79aggregate_subject_function = self.pluginParams.get('subject_aggregation', 'default')80aggregate_subject_function_lower = aggregate_subject_function.lower()8182if aggregate_subject_function_lower == 'none':83return84elif aggregate_subject_function_lower == 'default':85self.logger.debug('%s: aggregating subject results')86self.currentProfiler.aggregate_subject()87self.subject_aggregated = True88self.subject_aggregated_default = True89else:90aggregate_subject_script = Python3(os.path.join(paths.CONFIG_DIR, aggregate_subject_function))91self.logger.debug('%s: aggregating subject results')92self.subject_aggregated = True93self.subject_aggregated_default = False94aggregate_subject_script.run(None, self.paths['OUTPUT_DIR'])9596def aggregate_data_end(self, output_dir):97aggregate_function = self.pluginParams.get('experiment_aggregation', 'default')98aggregate_function_lower = aggregate_function.lower()99100data_dir = os.path.join(output_dir, 'data')101result_file = os.path.join(output_dir, 'Aggregated_Results_{}.csv'.format(self.moduleName))102103if aggregate_function_lower == 'none':104return105elif aggregate_function_lower == 'default':106if self.subject_aggregated_default:107self.logger.debug('%s: aggregating results')108self.currentProfiler.aggregate_end(data_dir, result_file)109elif not self.subject_aggregated:110self.logger.debug('%s: aggregating results')111self.aggregate_subjects_default(data_dir)112self.currentProfiler.aggregate_end(data_dir, result_file)113else:114self.logger.info("{} profiler: User defined subject aggregation used,"115" default experiment aggregation not possible.".format(self.moduleName))116return117else:118aggregate_script = Python3(os.path.join(paths.CONFIG_DIR, aggregate_function))119self.logger.debug('%s: aggregating results')120aggregate_script.run(None, data_dir, result_file)121122def aggregate_subjects_default(self, data_dir):123for device in self.list_subdir(data_dir):124device_dir = os.path.join(data_dir, device)125for subject in self.list_subdir(device_dir):126subject_dir = os.path.join(device_dir, subject)127if os.path.isdir(os.path.join(subject_dir, self.name)):128self.currentProfiler.set_output(os.path.join(subject_dir, self.name))129self.currentProfiler.aggregate_subject()130else:131for browser in self.list_subdir(subject_dir):132browser_dir = os.path.join(subject_dir, browser)133if os.path.isdir(os.path.join(browser_dir, self.name)):134self.currentProfiler.set_output(os.path.join(browser_dir, self.name))135self.currentProfiler.aggregate_subject()136137@staticmethod138def list_subdir(a_dir):139"""List immediate subdirectories of a_dir"""140# https://stackoverflow.com/a/800201141return [name for name in os.listdir(a_dir)142if os.path.isdir(os.path.join(a_dir, name))]143144145