1 ##############################################################################
2 # Copyright (c) 2015 Ericsson AB and others.
4 # All rights reserved. This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 # http://www.apache.org/licenses/LICENSE-2.0
8 ##############################################################################
11 Command-line interface to yardstick
14 from __future__ import absolute_import
19 from pkg_resources import get_distribution
20 from argparse import RawDescriptionHelpFormatter
21 from oslo_config import cfg
23 from yardstick import _init_logging, _LOG_STREAM_HDLR
24 from yardstick.cmd.commands import task
25 from yardstick.cmd.commands import runner
26 from yardstick.cmd.commands import scenario
27 from yardstick.cmd.commands import testcase
28 from yardstick.cmd.commands import plugin
29 from yardstick.cmd.commands import env
30 from yardstick.cmd.commands import report
31 from yardstick.common import import_tools
39 help='increase output verbosity to debug')
41 CONF.register_cli_opts(cli_opts)
43 CONFIG_SEARCH_PATHS = [sys.prefix + "/etc/yardstick",
48 def find_config_files(path_list):
49 for path in path_list:
50 abspath = os.path.abspath(os.path.expanduser(path))
51 confname = abspath + "/yardstick.conf"
52 if os.path.isfile(confname):
58 @import_tools.decorator_banned_modules
59 class YardstickCLI(object): # pragma: no cover
60 """Command-line interface to yardstick"""
64 'task': task.TaskCommands,
65 'runner': runner.RunnerCommands,
66 'scenario': scenario.ScenarioCommands,
67 'testcase': testcase.TestcaseCommands,
68 'plugin': plugin.PluginCommands,
69 'env': env.EnvCommand,
70 'report': report.ReportCommands
75 self._version = 'yardstick version %s ' % \
76 get_distribution('yardstick').version
78 def _find_actions(self, subparsers, actions_module):
79 """find action methods"""
80 # Find action methods inside actions_module and
81 # add them to the command parser.
82 # The 'actions_module' argument may be a class
83 # or module. Action methods start with 'do_'
84 for attr in (a for a in dir(actions_module) if a.startswith('do_')):
85 command = attr[3:].replace('_', '-')
86 callback = getattr(actions_module, attr)
87 desc = callback.__doc__ or ''
88 arguments = getattr(callback, 'arguments', [])
89 subparser = subparsers.add_parser(
93 for (args, kwargs) in arguments:
94 subparser.add_argument(*args, **kwargs)
95 subparser.set_defaults(func=callback)
97 def _add_command_parsers(self, categories, subparsers):
98 """add commands to command-line parser"""
99 for category in categories:
100 command_object = categories[category]()
101 desc = command_object.__doc__ or ''
102 subparser = subparsers.add_parser(
103 category, description=desc,
104 formatter_class=RawDescriptionHelpFormatter
106 subparser.set_defaults(command_object=command_object)
107 cmd_subparsers = subparser.add_subparsers(title='subcommands')
108 self._find_actions(cmd_subparsers, command_object)
110 def _register_cli_opt(self):
112 # register subcommands to parse additional command line arguments
113 def parser(subparsers):
114 self._add_command_parsers(self.categories, subparsers)
116 category_opt = cfg.SubCommandOpt("category",
117 title="Command categories",
118 help="Available categories",
120 self._register_opt(category_opt)
122 def _register_opt(self, opt):
124 CONF.register_cli_opt(opt)
125 self.opts.append(opt)
127 def _load_cli_config(self, argv):
129 # load CLI args and config files
130 CONF(argv, project="yardstick", version=self._version,
131 default_config_files=find_config_files(CONFIG_SEARCH_PATHS))
133 def _handle_global_opts(self):
137 _LOG_STREAM_HDLR.setLevel(logging.DEBUG)
139 def _dispatch_func_notask(self):
141 # dispatch to category parser
142 func = CONF.category.func
145 def _dispatch_func_task(self, task_id):
147 # dispatch to category parser
148 func = CONF.category.func
149 func(CONF.category, task_id=task_id)
151 def _clear_config_opts(self):
154 CONF.unregister_opts(self.opts)
156 def main(self, argv): # pragma: no cover
157 """run the command line interface"""
159 self._register_cli_opt()
161 self._load_cli_config(argv)
163 self._handle_global_opts()
165 self._dispatch_func_notask()
167 self._clear_config_opts()
169 def api(self, argv, task_id): # pragma: no cover
170 """run the api interface"""
172 self._register_cli_opt()
174 self._load_cli_config(argv)
176 self._handle_global_opts()
178 self._dispatch_func_task(task_id)
180 self._clear_config_opts()