Files
impala/tests/util/plugin_runner.py
Alex Leblang a0ad16af41 Testing framework changes for VTune plugin
This patch contains changes to the general test and plugin framework that were needed to make the VTune plugin run. These changes create a conext dictionary that is passed to the plugin.

Change-Id: I12ee2076fb0d777813c56bbb338e6d20426afaff
Reviewed-on: http://gerrit.ent.cloudera.com:8080/111
Reviewed-by: Alex Leblang <alex.leblang@cloudera.com>
Tested-by: Alex Leblang <alex.leblang@cloudera.com>
2014-01-08 10:52:12 -08:00

96 lines
3.8 KiB
Python

#!/usr/bin/env python
# Copyright (c) 2012 Cloudera, Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import imp
import logging
import os
import pkgutil
import sys
PLUGIN_DIR = os.path.join(os.environ['IMPALA_HOME'], 'tests', 'benchmark', 'plugins')
# Setup logging for this module.
logging.basicConfig(level=logging.INFO, format='%(filename)s: %(message)s')
LOG = logging.getLogger('plugin_runner')
LOG.setLevel(level=logging.DEBUG)
class PluginRunner(object):
''' Loads user specified plugins, if found, and initializes them.
Looks in /tests/plugins and searches each module for plugin_name. plugin_name
is the name of the class that the user has used to implement a plugin. If the class
is found, it is initialized and added to self.__plugins. If it's not found, an error
message is logged and the plugin in not loaded.
'''
def __init__(self, plugin_infos):
self.__available_modules = self.__get_plugin_modules()
self.__get_plugins_from_modules(plugin_infos)
self.plugins = self.__plugins
def __get_plugin_modules(self):
''' Gets all the modules in the directory and imports them'''
modules = pkgutil.iter_modules(path=[PLUGIN_DIR])
for loader, mod_name, ispkg in modules:
yield __import__("tests.benchmark.plugins.%s" % mod_name, fromlist=[mod_name])
def __get_plugins_from_modules(self, plugin_infos):
'''Look for user speicifed plugins in the availabe modules.'''
self.__plugins = []
plugin_names = []
for module in self.__available_modules:
for plugin_info in plugin_infos:
plugin_name, scope = self.__get_plugin_info(plugin_info)
plugin_names.append(plugin_name)
if hasattr(module, plugin_name):
self.__plugins.append(getattr(module, plugin_name)(scope=scope.lower()))
# The plugin(s) that could not be loaded are captured in the set difference
# between plugin_names and self.__plugins
plugins_found = [p.__name__ for p in self.__plugins]
LOG.debug("Plugins found: %s" % ', '.join(plugins_found))
plugins_not_found = set(plugin_names).difference(plugins_found)
# If the user's entered a plugin that does not exist, raise an error.
if len(plugins_not_found):
msg = "Plugin(s) not found: %s" % (','.join(list(plugins_not_found)))
raise RuntimeError, msg
def __get_plugin_info(self, plugin_info):
info = plugin_info.split(':')
if len(info) == 1:
return info[0], 'query'
elif len(info) == 2:
return info[0], info[1]
else:
raise ValueError("Plugin names specified in the form <plugin_name>[:<scope>]")
def print_plugin_names(self):
for p in self.__plugins:
LOG.info("Plugin: %s, Scope: %s" % (p.__name__, p.scope))
def run_plugins_pre(self, context=None, scope=None):
if len(self.__plugins) == 0: return
if context: context['scope'] = scope
for p in self.__plugins:
if not scope or p.scope == scope.lower():
LOG.info('Running pre-hook for %s at scope %s' % (p.__name__, scope))
p.run_pre_hook(context=context)
def run_plugins_post(self, context=None, scope=None):
if len(self.__plugins) == 0: return
for p in self.__plugins:
if not scope or p.scope == scope.lower():
LOG.info('Running post-hook for %s at scope %s' % (p.__name__, scope))
p.run_post_hook(context=context)