aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Sommerseth <davids@redhat.com>2012-12-18 22:27:51 +0100
committerDavid Sommerseth <davids@redhat.com>2012-12-18 22:27:51 +0100
commitfa6ff23d9c10e8f94b0d9ed85f4723f4646d0ad3 (patch)
treee9d158718812fa322932c5500bea14a77314955e
parentd3976bd04b251dfdb6a2823326acbdfbfa57c1e6 (diff)
downloadrteval-fa6ff23d9c10e8f94b0d9ed85f4723f4646d0ad3.tar.gz
Added infrastructure to add command line arguments from modules
All rteval modules must now provide a ModuleParameters() function which returns a dictionary containing the option setup it expects. Each module will get a separate option group, and all its options will be prefixed with the module name. These option variables will be stored as well, prefixed with the module name. So if the a module 'dummy' configures an option 'value1', it will be stored as 'dummy_value1' in the option container. To set this option, you will need to use --dummy-value1 from the command line. Signed-off-by: David Sommerseth <davids@redhat.com>
-rwxr-xr-xrteval-cmd9
-rw-r--r--rteval/modules/__init__.py40
-rw-r--r--rteval/modules/loads/__init__.py11
-rw-r--r--rteval/modules/measurement/__init__.py29
4 files changed, 76 insertions, 13 deletions
diff --git a/rteval-cmd b/rteval-cmd
index 8d1e30d..b886781 100755
--- a/rteval-cmd
+++ b/rteval-cmd
@@ -95,11 +95,10 @@ def summarize(repfile, xslt):
-def parse_options(cfg, cmdargs):
+def parse_options(cfg, parser, cmdargs):
'''parse the command line arguments'''
rtevcfg = cfg.GetSection('rteval')
- parser = optparse.OptionParser()
parser.add_option("-d", "--duration", dest="duration",
type="string", default=rtevcfg.duration,
help="specify length of test run (default: %default)")
@@ -162,6 +161,7 @@ def parse_options(cfg, cmdargs):
v = v[:-1]
mult = 3600.0 * 24.0
cmd_opts.duration = float(v) * mult
+
return (cmd_opts, cmd_args)
@@ -235,7 +235,10 @@ if __name__ == '__main__':
measuremods = MeasurementModules(config, logger=logger)
# parse command line options
- (cmd_opts, cmd_args) = parse_options(config, sys.argv[1:])
+ parser = optparse.OptionParser()
+ loadmods.SetupModuleOptions(parser)
+ measuremods.SetupModuleOptions(parser)
+ (cmd_opts, cmd_args) = parse_options(config, parser, sys.argv[1:])
# copy the command line options into the rteval config section
# (cmd line overrides config file values)
diff --git a/rteval/modules/__init__.py b/rteval/modules/__init__.py
index 153d854..ea5a0a2 100644
--- a/rteval/modules/__init__.py
+++ b/rteval/modules/__init__.py
@@ -24,7 +24,7 @@
from rteval.Log import Log
from rteval.rtevalConfig import rtevalCfgSection
-import time, libxml2, threading
+import time, libxml2, threading, optparse
__all__ = ["rtevalModulePrototype", "ModuleContainer", "RtEvalModules"]
@@ -187,7 +187,7 @@ objects during module import."""
self.__iter_list = None
- def __importmod(self, modname, modroot=None):
+ def LoadModule(self, modname, modroot=None):
"""Imports a module and saves references to the imported module.
If the same module is tried imported more times, it will return the module
reference from the first import"""
@@ -212,10 +212,34 @@ reference from the first import"""
"""Imports a module and calls the modules' ModuleInfo() function and returns
the information provided by the module"""
- mod = self.__importmod(modname, modroot)
+ mod = self.LoadModule(modname, modroot)
return mod.ModuleInfo()
+ def SetupModuleOptions(self, parser):
+ """Sets up a separate optptarse OptionGroup per module with its supported parameters"""
+
+ for (modname, mod) in self.__modsloaded.items():
+ opts = mod.ModuleParameters()
+ if len(opts) == 0:
+ continue
+
+ shortmod = modname.split('.')[-1]
+ grparser = optparse.OptionGroup(parser, "Options for the %s module" % shortmod)
+ for (o, s) in opts.items():
+ descr = s.has_key('descr') and s['descr'] or ""
+ default = s.has_key('default') and s['default'] or None
+ metavar = s.has_key('metavar') and s['metavar'] or None
+ grparser.add_option('--%s-%s' % (shortmod, o),
+ dest="%s_%s" % (shortmod, o),
+ action='store',
+ help='%s%s' % (descr,
+ default and '(default: %s)' % default or ''),
+ default=default,
+ metavar=metavar)
+ parser.add_option_group(grparser)
+
+
def InstantiateModule(self, modname, modcfg, modroot = None):
"""Imports a module and instantiates an object from the modules create() function.
The instantiated object is returned in this call"""
@@ -223,7 +247,7 @@ The instantiated object is returned in this call"""
if modcfg and not isinstance(modcfg, rtevalCfgSection):
raise TypeError("modcfg attribute is not a rtevalCfgSection() object")
- mod = self.__importmod(modname, modroot)
+ mod = self.LoadModule(modname, modroot)
return mod.create(modcfg, self.__logger)
@@ -313,6 +337,10 @@ and will also be given to the instantiated objects during module import."""
"Registers an instantiated module object which RtEvalModules will control"
return self.__modules.RegisterModuleObject(modname, modobj)
+ def _LoadModule(self, modname, modroot=None):
+ "Loads and imports a module"
+ return self.__modules.LoadModule(modname, modroot)
+
def ModulesLoaded(self):
"Returns number of imported modules"
return self.__modules.ModulesLoaded()
@@ -321,6 +349,10 @@ and will also be given to the instantiated objects during module import."""
"Returns a list of module names"
return self.__modules.GetModulesList()
+ def SetupModuleOptions(self, parser):
+ "Sets up optparse based option groups for the loaded modules"
+ return self.__modules.SetupModuleOptions(parser)
+
def GetNamedModuleObject(self, modname):
"Returns a list of module names"
return self.__modules.GetNamedModuleObject(modname)
diff --git a/rteval/modules/loads/__init__.py b/rteval/modules/loads/__init__.py
index f4d4de4..3c897b8 100644
--- a/rteval/modules/loads/__init__.py
+++ b/rteval/modules/loads/__init__.py
@@ -95,6 +95,17 @@ class LoadModules(RtEvalModules):
self.__loadavg_samples = 0
self.__cfg = config
RtEvalModules.__init__(self, "modules.loads", logger)
+ self.__LoadModules(self.__cfg.GetSection(self._module_config))
+
+
+ def __LoadModules(self, modcfg):
+ "Loads and imports all the configured modules"
+
+ for m in modcfg:
+ # hope to eventually have different kinds but module is only on
+ # for now (jcw)
+ if m[1].lower() == 'module':
+ self._LoadModule(m[0])
def Setup(self, modparams):
diff --git a/rteval/modules/measurement/__init__.py b/rteval/modules/measurement/__init__.py
index a12eba2..1298932 100644
--- a/rteval/modules/measurement/__init__.py
+++ b/rteval/modules/measurement/__init__.py
@@ -118,6 +118,21 @@ measurement profiles, based on their characteristics"""
self.__modules_root = "modules.measurement"
self.__iter_item = None
+ # Temporary module container, which is used to evalute measurement modules.
+ # This will container will be destroyed after Setup() has been called
+ self.__container = ModuleContainer(self.__modules_root, self.__logger)
+ self.__LoadModules(self.__cfg.GetSection("measurement"))
+
+
+ def __LoadModules(self, modcfg):
+ "Loads and imports all the configured modules"
+
+ for m in modcfg:
+ # hope to eventually have different kinds but module is only on
+ # for now (jcw)
+ if m[1].lower() == 'module':
+ self.__container.LoadModule(m[0])
+
def GetProfile(self, with_load, run_parallel):
"Returns the appropriate MeasurementProfile object, based on the profile type"
@@ -129,20 +144,22 @@ measurement profiles, based on their characteristics"""
return None
+ def SetupModuleOptions(self, parser):
+ "Sets up all the measurement modules' parameters for the option parser"
+ self.__container.SetupModuleOptions(parser)
+
+
def Setup(self, modparams):
"Loads all measurement modules and group them into different measurement profiles"
if not isinstance(modparams, dict):
raise TypeError("modparams attribute is not of a dictionary type")
- # Temporary module container, which is used to evalute measurement modules
- container = ModuleContainer(self.__modules_root, self.__logger)
-
modcfg = self.__cfg.GetSection("measurement")
for (modname, modtype) in modcfg:
if modtype.lower() == 'module': # Only 'module' will be supported (ds)
# Extract the measurement modules info
- modinfo = container.ModuleInfo(modname)
+ modinfo = self.__container.ModuleInfo(modname)
# Get the correct measurement profile container for this module
mp = self.GetProfile(modinfo["loads"], modinfo["parallel"])
@@ -154,13 +171,13 @@ measurement profiles, based on their characteristics"""
# Export the module imported here and transfer it to the
# measurement profile
- mp.ImportModule(container.ExportModule(modname))
+ mp.ImportModule(self.__container.ExportModule(modname))
# Setup this imported module inside the appropriate measurement profile
self.__cfg.AppendConfig(modname, modparams)
mp.Setup(modname, self.__cfg.GetSection(modname))
- del container
+ del self.__container
def MakeReport(self):