Merge "Further improvements in rally info"
This commit is contained in:
commit
80e20252f3
@ -176,8 +176,11 @@ class Scenario(object):
|
|||||||
:param method_name: method name
|
:param method_name: method name
|
||||||
:returns: True if the method is a benchmark scenario, False otherwise
|
:returns: True if the method is a benchmark scenario, False otherwise
|
||||||
"""
|
"""
|
||||||
return (hasattr(cls, method_name) and
|
try:
|
||||||
Scenario.meta(cls, "is_scenario", method_name, default=False))
|
getattr(cls, method_name)
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
return Scenario.meta(cls, "is_scenario", method_name, default=False)
|
||||||
|
|
||||||
def context(self):
|
def context(self):
|
||||||
"""Returns the context of the current benchmark scenario."""
|
"""Returns the context of the current benchmark scenario."""
|
||||||
|
@ -84,15 +84,15 @@ class SLA(object):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_by_name(name):
|
def get_by_name(name):
|
||||||
"""Returns SLA by name."""
|
"""Returns SLA by name or config option name."""
|
||||||
for sla in utils.itersubclasses(SLA):
|
for sla in utils.itersubclasses(SLA):
|
||||||
if name == sla.__name__:
|
if name == sla.__name__ or name == sla.OPTION_NAME:
|
||||||
return sla
|
return sla
|
||||||
raise exceptions.NoSuchSLA(name=name)
|
raise exceptions.NoSuchSLA(name=name)
|
||||||
|
|
||||||
|
|
||||||
class FailureRateDeprecated(SLA):
|
class FailureRateDeprecated(SLA):
|
||||||
"""Failure rate in percents."""
|
"""[Deprecated] Failure rate in percents."""
|
||||||
OPTION_NAME = "max_failure_percent"
|
OPTION_NAME = "max_failure_percent"
|
||||||
CONFIG_SCHEMA = {"type": "number", "minimum": 0.0, "maximum": 100.0}
|
CONFIG_SCHEMA = {"type": "number", "minimum": 0.0, "maximum": 100.0}
|
||||||
|
|
||||||
|
@ -296,7 +296,7 @@ def run(argv, categories):
|
|||||||
validate_deprecated_args(argv, fn)
|
validate_deprecated_args(argv, fn)
|
||||||
ret = fn(*fn_args, **fn_kwargs)
|
ret = fn(*fn_args, **fn_kwargs)
|
||||||
return(ret)
|
return(ret)
|
||||||
except IOError as e:
|
except (IOError, TypeError) as e:
|
||||||
if CONF.debug:
|
if CONF.debug:
|
||||||
raise
|
raise
|
||||||
print(e)
|
print(e)
|
||||||
|
@ -67,10 +67,11 @@ class InfoCommands(object):
|
|||||||
Usage:
|
Usage:
|
||||||
$ rally info find <query>
|
$ rally info find <query>
|
||||||
|
|
||||||
To see lists of entities you can query docs for, type one of the following:
|
To get information about main concepts of Rally as well as to list entities
|
||||||
|
you can query docs for, type one of the following:
|
||||||
$ rally info BenchmarkScenarios
|
$ rally info BenchmarkScenarios
|
||||||
$ rally info SLA
|
$ rally info SLA
|
||||||
$ rally info DeployEngines
|
$ rally info DeploymentEngines
|
||||||
$ rally info ServerProviders
|
$ rally info ServerProviders
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -103,43 +104,154 @@ class InfoCommands(object):
|
|||||||
"""
|
"""
|
||||||
self.BenchmarkScenarios()
|
self.BenchmarkScenarios()
|
||||||
self.SLA()
|
self.SLA()
|
||||||
self.DeployEngines()
|
self.DeploymentEngines()
|
||||||
self.ServerProviders()
|
self.ServerProviders()
|
||||||
|
|
||||||
def BenchmarkScenarios(self):
|
def BenchmarkScenarios(self):
|
||||||
"""List benchmark scenarios available in Rally."""
|
"""Get information about benchmark scenarios available in Rally."""
|
||||||
scenarios = self._get_descriptions(scenario_base.Scenario)
|
def scenarios_filter(scenario_cls):
|
||||||
info = self._compose_table("Benchmark scenario groups", scenarios)
|
return any(scenario_base.Scenario.is_scenario(scenario_cls, m)
|
||||||
info += (" To get information about benchmark scenarios inside "
|
for m in dir(scenario_cls))
|
||||||
"each scenario group, run:\n"
|
scenarios = self._get_descriptions(scenario_base.Scenario,
|
||||||
" $ rally info find <ScenarioGroupName>\n\n")
|
scenarios_filter)
|
||||||
|
info = (self._make_header("Rally - Benchmark scenarios") +
|
||||||
|
"\n\n"
|
||||||
|
"Benchmark scenarios are what Rally actually uses to test "
|
||||||
|
"the performance of an OpenStack deployment.\nEach Benchmark "
|
||||||
|
"scenario implements a sequence of atomic operations "
|
||||||
|
"(server calls) to simulate\ninteresing user/operator/"
|
||||||
|
"client activity in some typical use case, usually that of "
|
||||||
|
"a specific OpenStack\nproject. Iterative execution of this "
|
||||||
|
"sequence produces some kind of load on the target cloud.\n"
|
||||||
|
"Benchmark scenarios play the role of building blocks in "
|
||||||
|
"benchmark task configuration files."
|
||||||
|
"\n\n"
|
||||||
|
"Scenarios in Rally are put together in groups. Each "
|
||||||
|
"scenario group is concentrated on some specific \nOpenStack "
|
||||||
|
'functionality. For example, the "NovaServers" scenario '
|
||||||
|
"group contains scenarios that employ\nseveral basic "
|
||||||
|
"operations available in Nova."
|
||||||
|
"\n\n" +
|
||||||
|
self._compose_table("List of Benchmark scenario groups",
|
||||||
|
scenarios) +
|
||||||
|
"To get information about benchmark scenarios inside "
|
||||||
|
"each scenario group, run:\n"
|
||||||
|
" $ rally info find <ScenarioGroupName>\n\n")
|
||||||
print(info)
|
print(info)
|
||||||
|
|
||||||
def SLA(self):
|
def SLA(self):
|
||||||
"""List server providers available in Rally."""
|
"""Get information about SLA available in Rally."""
|
||||||
sla = self._get_descriptions(sla_base.SLA)
|
sla = self._get_descriptions(sla_base.SLA)
|
||||||
info = self._compose_table("SLA", sla)
|
# NOTE(msdubov): Add config option names to the "Name" column
|
||||||
|
for i in range(len(sla)):
|
||||||
|
description = sla[i]
|
||||||
|
sla_cls = sla_base.SLA.get_by_name(description[0])
|
||||||
|
sla[i] = (sla_cls.OPTION_NAME, description[1])
|
||||||
|
info = (self._make_header("Rally - SLA checks "
|
||||||
|
"(Service-Level Agreements)") +
|
||||||
|
"\n\n"
|
||||||
|
"SLA in Rally enable quick and easy checks of "
|
||||||
|
"whether the results of a particular\nbenchmark task have "
|
||||||
|
"passed certain success criteria."
|
||||||
|
"\n\n"
|
||||||
|
"SLA checks can be configured in the 'sla' section of "
|
||||||
|
"benchmark task configuration\nfiles, used to launch new "
|
||||||
|
"tasks by the 'rally task start <config_file>' command.\n"
|
||||||
|
"For each SLA check you would like to use, you should put "
|
||||||
|
"its name as a key and the\ntarget check parameter as an "
|
||||||
|
"assosiated value, e.g.:\n\n"
|
||||||
|
" sla:\n"
|
||||||
|
" max_seconds_per_iteration: 4\n"
|
||||||
|
" max_failure_percent: 1"
|
||||||
|
"\n\n" +
|
||||||
|
self._compose_table("List of SLA checks", sla) +
|
||||||
|
"To get information about specific SLA checks, run:\n"
|
||||||
|
" $ rally info find <sla_check_name>\n")
|
||||||
|
print(info)
|
||||||
|
|
||||||
|
def DeploymentEngines(self):
|
||||||
|
"""Get information about deploy engines available in Rally."""
|
||||||
|
engines = self._get_descriptions(deploy.EngineFactory)
|
||||||
|
info = (self._make_header("Rally - Deployment engines") +
|
||||||
|
"\n\n"
|
||||||
|
"Rally is an OpenStack benchmarking system. Before starting "
|
||||||
|
"benchmarking with Rally,\nyou obviously have either to "
|
||||||
|
"deploy a new OpenStack cloud or to register an existing\n"
|
||||||
|
"one in Rally. Deployment engines in Rally are essentially "
|
||||||
|
"plugins that control the\nprocess of deploying some "
|
||||||
|
"OpenStack distribution, say, with DevStack or FUEL, and\n"
|
||||||
|
"register these deployments in Rally before any benchmarking "
|
||||||
|
"procedures against them\ncan take place."
|
||||||
|
"\n\n"
|
||||||
|
"A typical use case in Rally would be when you first "
|
||||||
|
"register a deployment using the\n'rally deployment create' "
|
||||||
|
"command and then reference this deployment by uuid "
|
||||||
|
"when\nstarting a benchmark task with 'rally task start'. "
|
||||||
|
"The 'rally deployment create'\ncommand awaits a deployment "
|
||||||
|
"configuration file as its parameter. This file may look "
|
||||||
|
"like:\n"
|
||||||
|
"{\n"
|
||||||
|
' "type": "ExistingCloud",\n'
|
||||||
|
' "auth_url": "http://example.net:5000/v2.0/",\n'
|
||||||
|
' "admin": { <credentials> },\n'
|
||||||
|
" ...\n"
|
||||||
|
"}"
|
||||||
|
"\n\n" +
|
||||||
|
self._compose_table("List of Deployment engines", engines) +
|
||||||
|
"To get information about specific Deployment engines, run:\n"
|
||||||
|
" $ rally info find <DeploymentEngineName>\n")
|
||||||
print(info)
|
print(info)
|
||||||
|
|
||||||
def DeployEngines(self):
|
def DeployEngines(self):
|
||||||
"""List deploy engines available in Rally."""
|
"""Get information about deploy engines available in Rally."""
|
||||||
engines = self._get_descriptions(deploy.EngineFactory)
|
# NOTE(msdubov): This alias should be removed as soon as we rename
|
||||||
info = self._compose_table("Deploy engines", engines)
|
# DeployEngines to DeploymentEngines (which is more
|
||||||
print(info)
|
# grammatically correct).
|
||||||
|
self.DeploymentEngines()
|
||||||
|
|
||||||
def ServerProviders(self):
|
def ServerProviders(self):
|
||||||
"""List server providers available in Rally."""
|
"""Get information about server providers available in Rally."""
|
||||||
providers = self._get_descriptions(serverprovider.ProviderFactory)
|
providers = self._get_descriptions(serverprovider.ProviderFactory)
|
||||||
info = self._compose_table("Server providers", providers)
|
info = (self._make_header("Rally - Server providers") +
|
||||||
|
"\n\n"
|
||||||
|
"Rally is an OpenStack benchmarking system. Before starting "
|
||||||
|
"benchmarking with Rally,\nyou obviously have either to "
|
||||||
|
"deploy a new OpenStack cloud or to register an existing\n"
|
||||||
|
"one in Rally with one of the Deployment engines. These "
|
||||||
|
"deployment engines, in turn,\nmay need Server "
|
||||||
|
"providers to manage virtual machines used for "
|
||||||
|
"OpenStack deployment\nand its following benchmarking. The "
|
||||||
|
"key feature of server providers is that they\nprovide a "
|
||||||
|
"unified interface for interacting with different "
|
||||||
|
"virtualization\ntechnologies (LXS, Virsh etc.)."
|
||||||
|
"\n\n"
|
||||||
|
"Server providers are usually referenced in deployment "
|
||||||
|
"configuration files\npassed to the 'rally deployment create'"
|
||||||
|
" command, e.g.:\n"
|
||||||
|
"{\n"
|
||||||
|
' "type": "DevstackEngine",\n'
|
||||||
|
' "provider": {\n'
|
||||||
|
' "type": "ExistingServers",\n'
|
||||||
|
' "credentials": [{"user": "root", "host": "10.2.0.8"}]\n'
|
||||||
|
" }\n"
|
||||||
|
"}"
|
||||||
|
"\n\n" +
|
||||||
|
self._compose_table("List of Server providers", providers) +
|
||||||
|
"To get information about specific Server providers, run:\n"
|
||||||
|
" $ rally info find <ServerProviderName>\n")
|
||||||
print(info)
|
print(info)
|
||||||
|
|
||||||
def _get_descriptions(self, base_cls):
|
def _get_descriptions(self, base_cls, subclass_filter=None):
|
||||||
descriptions = []
|
descriptions = []
|
||||||
for entity in utils.itersubclasses(base_cls):
|
subclasses = utils.itersubclasses(base_cls)
|
||||||
|
if subclass_filter:
|
||||||
|
subclasses = filter(subclass_filter, subclasses)
|
||||||
|
for entity in subclasses:
|
||||||
name = entity.__name__
|
name = entity.__name__
|
||||||
doc = utils.parse_docstring(entity.__doc__)
|
doc = utils.parse_docstring(entity.__doc__)
|
||||||
description = doc["short_description"] or ""
|
description = doc["short_description"] or ""
|
||||||
descriptions.append((name, description))
|
descriptions.append((name, description))
|
||||||
|
descriptions.sort(key=lambda d: d[0])
|
||||||
return descriptions
|
return descriptions
|
||||||
|
|
||||||
def _find_info(self, query):
|
def _find_info(self, query):
|
||||||
@ -171,30 +283,23 @@ class InfoCommands(object):
|
|||||||
def _get_scenario_group_info(self, query):
|
def _get_scenario_group_info(self, query):
|
||||||
try:
|
try:
|
||||||
scenario_group = scenario_base.Scenario.get_by_name(query)
|
scenario_group = scenario_base.Scenario.get_by_name(query)
|
||||||
info = ("%s (benchmark scenario group).\n\n" %
|
if not any(scenario_base.Scenario.is_scenario(scenario_group, m)
|
||||||
scenario_group.__name__)
|
for m in dir(scenario_group)):
|
||||||
|
return None
|
||||||
|
info = self._make_header("%s (benchmark scenario group)" %
|
||||||
|
scenario_group.__name__)
|
||||||
|
info += "\n\n"
|
||||||
info += utils.format_docstring(scenario_group.__doc__)
|
info += utils.format_docstring(scenario_group.__doc__)
|
||||||
info += "\nBenchmark scenarios:\n"
|
|
||||||
scenarios = scenario_group.list_benchmark_scenarios()
|
scenarios = scenario_group.list_benchmark_scenarios()
|
||||||
first_column_len = max(map(len, scenarios)) + cliutils.MARGIN
|
descriptions = []
|
||||||
second_column_len = len("Description") + cliutils.MARGIN
|
|
||||||
table = ""
|
|
||||||
for scenario_name in scenarios:
|
for scenario_name in scenarios:
|
||||||
cls, method_name = scenario_name.split(".")
|
cls, method_name = scenario_name.split(".")
|
||||||
if hasattr(scenario_group, method_name):
|
if hasattr(scenario_group, method_name):
|
||||||
scenario = getattr(scenario_group, method_name)
|
scenario = getattr(scenario_group, method_name)
|
||||||
doc = utils.parse_docstring(scenario.__doc__)
|
doc = utils.parse_docstring(scenario.__doc__)
|
||||||
descr = doc["short_description"] or ""
|
descr = doc["short_description"] or ""
|
||||||
second_column_len = max(second_column_len,
|
descriptions.append((scenario_name, descr))
|
||||||
len(descr) + cliutils.MARGIN)
|
info += self._compose_table("Benchmark scenarios", descriptions)
|
||||||
table += " " + scenario_name
|
|
||||||
table += " " * (first_column_len - len(scenario_name))
|
|
||||||
table += descr + "\n"
|
|
||||||
info += "-" * (first_column_len + second_column_len + 1) + "\n"
|
|
||||||
info += (" Name" + " " * (first_column_len - len("Name")) +
|
|
||||||
"Description\n")
|
|
||||||
info += "-" * (first_column_len + second_column_len + 1) + "\n"
|
|
||||||
info += table
|
|
||||||
return info
|
return info
|
||||||
except exceptions.NoSuchScenario:
|
except exceptions.NoSuchScenario:
|
||||||
return None
|
return None
|
||||||
@ -203,10 +308,12 @@ class InfoCommands(object):
|
|||||||
try:
|
try:
|
||||||
scenario = scenario_base.Scenario.get_scenario_by_name(query)
|
scenario = scenario_base.Scenario.get_scenario_by_name(query)
|
||||||
scenario_group_name = utils.get_method_class(scenario).__name__
|
scenario_group_name = utils.get_method_class(scenario).__name__
|
||||||
info = ("%(scenario_group)s.%(scenario_name)s "
|
header = ("%(scenario_group)s.%(scenario_name)s "
|
||||||
"(benchmark scenario).\n\n" %
|
"(benchmark scenario)" %
|
||||||
{"scenario_group": scenario_group_name,
|
{"scenario_group": scenario_group_name,
|
||||||
"scenario_name": scenario.__name__})
|
"scenario_name": scenario.__name__})
|
||||||
|
info = self._make_header(header)
|
||||||
|
info += "\n\n"
|
||||||
doc = utils.parse_docstring(scenario.__doc__)
|
doc = utils.parse_docstring(scenario.__doc__)
|
||||||
if not doc["short_description"]:
|
if not doc["short_description"]:
|
||||||
return None
|
return None
|
||||||
@ -226,8 +333,10 @@ class InfoCommands(object):
|
|||||||
def _get_sla_info(self, query):
|
def _get_sla_info(self, query):
|
||||||
try:
|
try:
|
||||||
sla = sla_base.SLA.get_by_name(query)
|
sla = sla_base.SLA.get_by_name(query)
|
||||||
info = "%s (SLA).\n\n" % sla.__name__
|
header = "%s (SLA)" % sla.OPTION_NAME
|
||||||
info += utils.format_docstring(sla.__doc__)
|
info = self._make_header(header)
|
||||||
|
info += "\n\n"
|
||||||
|
info += utils.format_docstring(sla.__doc__) + "\n"
|
||||||
return info
|
return info
|
||||||
except exceptions.NoSuchSLA:
|
except exceptions.NoSuchSLA:
|
||||||
return None
|
return None
|
||||||
@ -235,7 +344,9 @@ class InfoCommands(object):
|
|||||||
def _get_deploy_engine_info(self, query):
|
def _get_deploy_engine_info(self, query):
|
||||||
try:
|
try:
|
||||||
deploy_engine = deploy.EngineFactory.get_by_name(query)
|
deploy_engine = deploy.EngineFactory.get_by_name(query)
|
||||||
info = "%s (deploy engine).\n\n" % deploy_engine.__name__
|
header = "%s (deploy engine)" % deploy_engine.__name__
|
||||||
|
info = self._make_header(header)
|
||||||
|
info += "\n\n"
|
||||||
info += utils.format_docstring(deploy_engine.__doc__)
|
info += utils.format_docstring(deploy_engine.__doc__)
|
||||||
return info
|
return info
|
||||||
except exceptions.NoSuchEngine:
|
except exceptions.NoSuchEngine:
|
||||||
@ -244,14 +355,22 @@ class InfoCommands(object):
|
|||||||
def _get_server_provider_info(self, query):
|
def _get_server_provider_info(self, query):
|
||||||
try:
|
try:
|
||||||
server_provider = serverprovider.ProviderFactory.get_by_name(query)
|
server_provider = serverprovider.ProviderFactory.get_by_name(query)
|
||||||
info = "%s (server provider).\n\n" % server_provider.__name__
|
header = "%s (server provider)" % server_provider.__name__
|
||||||
|
info = self._make_header(header)
|
||||||
|
info += "\n\n"
|
||||||
info += utils.format_docstring(server_provider.__doc__)
|
info += utils.format_docstring(server_provider.__doc__)
|
||||||
return info
|
return info
|
||||||
except exceptions.NoSuchVMProvider:
|
except exceptions.NoSuchVMProvider:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def _make_header(self, string):
|
||||||
|
header = "-" * (len(string) + 2) + "\n"
|
||||||
|
header += " " + string + " \n"
|
||||||
|
header += "-" * (len(string) + 2)
|
||||||
|
return header
|
||||||
|
|
||||||
def _compose_table(self, title, descriptions):
|
def _compose_table(self, title, descriptions):
|
||||||
table = title + ":\n"
|
table = " " + title + ":\n"
|
||||||
len0 = lambda x: len(x[0])
|
len0 = lambda x: len(x[0])
|
||||||
len1 = lambda x: len(x[1])
|
len1 = lambda x: len(x[1])
|
||||||
first_column_len = max(map(len0, descriptions)) + cliutils.MARGIN
|
first_column_len = max(map(len0, descriptions)) + cliutils.MARGIN
|
||||||
@ -264,5 +383,6 @@ class InfoCommands(object):
|
|||||||
table += " " + name
|
table += " " + name
|
||||||
table += " " * (first_column_len - len(name))
|
table += " " * (first_column_len - len(name))
|
||||||
table += descr + "\n"
|
table += descr + "\n"
|
||||||
|
table += "-" * (first_column_len + second_column_len + 1) + "\n"
|
||||||
table += "\n"
|
table += "\n"
|
||||||
return table
|
return table
|
||||||
|
@ -258,30 +258,41 @@ def parse_docstring(docstring):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
if docstring:
|
if docstring:
|
||||||
docstring_lines = docstrings.prepare_docstring(docstring)
|
lines = docstrings.prepare_docstring(docstring)
|
||||||
docstring_lines = filter(lambda line: line != "", docstring_lines)
|
lines = filter(lambda line: line != "", lines)
|
||||||
else:
|
else:
|
||||||
docstring_lines = []
|
lines = []
|
||||||
|
|
||||||
if docstring_lines:
|
if lines:
|
||||||
|
short_description = lines[0]
|
||||||
|
|
||||||
short_description = docstring_lines[0]
|
param_start = first_index(lines, lambda l: l.startswith(":param"))
|
||||||
|
returns_start = first_index(lines, lambda l: l.startswith(":returns"))
|
||||||
param_lines_start = first_index(docstring_lines,
|
if param_start or returns_start:
|
||||||
lambda line: line.startswith(":param")
|
description_end = param_start or returns_start
|
||||||
or line.startswith(":returns"))
|
long_description = "\n".join(lines[1:description_end])
|
||||||
if param_lines_start:
|
|
||||||
long_description = "\n".join(docstring_lines[1:param_lines_start])
|
|
||||||
else:
|
else:
|
||||||
long_description = "\n".join(docstring_lines[1:])
|
long_description = "\n".join(lines[1:])
|
||||||
|
|
||||||
if not long_description:
|
if not long_description:
|
||||||
long_description = None
|
long_description = None
|
||||||
|
|
||||||
|
param_lines = []
|
||||||
|
if param_start:
|
||||||
|
current_line = lines[param_start]
|
||||||
|
current_line_index = param_start + 1
|
||||||
|
while current_line_index < (returns_start or len(lines)):
|
||||||
|
if lines[current_line_index].startswith(":param"):
|
||||||
|
param_lines.append(current_line)
|
||||||
|
current_line = lines[current_line_index]
|
||||||
|
else:
|
||||||
|
continuation_line = lines[current_line_index].strip()
|
||||||
|
current_line += " " + continuation_line
|
||||||
|
current_line_index += 1
|
||||||
|
param_lines.append(current_line)
|
||||||
params = []
|
params = []
|
||||||
param_regex = re.compile("^:param (?P<name>\w+): (?P<doc>.*)$")
|
param_regex = re.compile("^:param (?P<name>\w+): (?P<doc>.*)$")
|
||||||
for param_line in filter(lambda line: line.startswith(":param"),
|
for param_line in param_lines:
|
||||||
docstring_lines):
|
|
||||||
match = param_regex.match(param_line)
|
match = param_regex.match(param_line)
|
||||||
if match:
|
if match:
|
||||||
params.append({
|
params.append({
|
||||||
@ -290,11 +301,10 @@ def parse_docstring(docstring):
|
|||||||
})
|
})
|
||||||
|
|
||||||
returns = None
|
returns = None
|
||||||
returns_line = filter(lambda line: line.startswith(":returns"),
|
if returns_start:
|
||||||
docstring_lines)
|
returns_line = " ".join([l.strip() for l in lines[returns_start:]])
|
||||||
if returns_line:
|
|
||||||
returns_regex = re.compile("^:returns: (?P<doc>.*)$")
|
returns_regex = re.compile("^:returns: (?P<doc>.*)$")
|
||||||
match = returns_regex.match(returns_line[0])
|
match = returns_regex.match(returns_line)
|
||||||
if match:
|
if match:
|
||||||
returns = match.group("doc")
|
returns = match.group("doc")
|
||||||
|
|
||||||
|
@ -32,21 +32,28 @@ class InfoTestCase(unittest.TestCase):
|
|||||||
self.assertIn("Dummy.dummy_random_fail_in_atomic", output)
|
self.assertIn("Dummy.dummy_random_fail_in_atomic", output)
|
||||||
|
|
||||||
def test_find_scenario_group_base_class(self):
|
def test_find_scenario_group_base_class(self):
|
||||||
output = self.rally("info find CeilometerScenario")
|
# NOTE(msdubov): We shouldn't display info about base scenario classes
|
||||||
self.assertIn("(benchmark scenario group)", output)
|
# containing no end-user scenarios
|
||||||
|
self.assertRaises(utils.RallyCmdError, self.rally,
|
||||||
|
("info find CeilometerScenario"))
|
||||||
|
|
||||||
def test_find_scenario(self):
|
def test_find_scenario(self):
|
||||||
self.assertIn("(benchmark scenario)", self.rally("info find dummy"))
|
self.assertIn("(benchmark scenario)", self.rally("info find dummy"))
|
||||||
|
|
||||||
def test_find_sla(self):
|
def test_find_sla(self):
|
||||||
self.assertIn("(SLA)", self.rally("info find FailureRate"))
|
expected = "failure_rate (SLA)"
|
||||||
|
self.assertIn(expected, self.rally("info find failure_rate"))
|
||||||
|
|
||||||
|
def test_find_sla_by_class_name(self):
|
||||||
|
expected = "failure_rate (SLA)"
|
||||||
|
self.assertIn(expected, self.rally("info find FailureRate"))
|
||||||
|
|
||||||
def test_find_deployment_engine(self):
|
def test_find_deployment_engine(self):
|
||||||
marker_string = "ExistingCloud (deploy engine)."
|
marker_string = "ExistingCloud (deploy engine)"
|
||||||
self.assertIn(marker_string, self.rally("info find ExistingCloud"))
|
self.assertIn(marker_string, self.rally("info find ExistingCloud"))
|
||||||
|
|
||||||
def test_find_server_provider(self):
|
def test_find_server_provider(self):
|
||||||
marker_string = "ExistingServers (server provider)."
|
marker_string = "ExistingServers (server provider)"
|
||||||
self.assertIn(marker_string, self.rally("info find ExistingServers"))
|
self.assertIn(marker_string, self.rally("info find ExistingServers"))
|
||||||
|
|
||||||
def test_find_fails(self):
|
def test_find_fails(self):
|
||||||
@ -54,21 +61,29 @@ class InfoTestCase(unittest.TestCase):
|
|||||||
("info find NonExistingStuff"))
|
("info find NonExistingStuff"))
|
||||||
|
|
||||||
def test_find_misspelling_typos(self):
|
def test_find_misspelling_typos(self):
|
||||||
marker_string = "ExistingServers (server provider)."
|
marker_string = "ExistingServers (server provider)"
|
||||||
self.assertIn(marker_string, self.rally("info find ExistinfServert"))
|
self.assertIn(marker_string, self.rally("info find ExistinfServert"))
|
||||||
|
|
||||||
def test_find_misspelling_truncated(self):
|
def test_find_misspelling_truncated(self):
|
||||||
marker_string = ("NovaServers.boot_and_delete_server "
|
marker_string = ("NovaServers.boot_and_delete_server "
|
||||||
"(benchmark scenario).")
|
"(benchmark scenario)")
|
||||||
self.assertIn(marker_string, self.rally("info find boot_and_delete"))
|
self.assertIn(marker_string, self.rally("info find boot_and_delete"))
|
||||||
|
|
||||||
|
def test_find_misspelling_truncated_many_substitutions(self):
|
||||||
|
try:
|
||||||
|
self.rally("info find Nova")
|
||||||
|
except utils.RallyCmdError as e:
|
||||||
|
self.assertIn("NovaServers", e.output)
|
||||||
|
self.assertIn("NovaServers.boot_and_delete_server", e.output)
|
||||||
|
self.assertIn("NovaServers.snapshot_server", e.output)
|
||||||
|
|
||||||
def test_list(self):
|
def test_list(self):
|
||||||
output = self.rally("info list")
|
output = self.rally("info list")
|
||||||
self.assertIn("Benchmark scenario groups:", output)
|
self.assertIn("Benchmark scenario groups:", output)
|
||||||
self.assertIn("NovaServers", output)
|
self.assertIn("NovaServers", output)
|
||||||
self.assertIn("SLA:", output)
|
self.assertIn("SLA checks:", output)
|
||||||
self.assertIn("FailureRate", output)
|
self.assertIn("failure_rate", output)
|
||||||
self.assertIn("Deploy engines:", output)
|
self.assertIn("Deployment engines:", output)
|
||||||
self.assertIn("ExistingCloud", output)
|
self.assertIn("ExistingCloud", output)
|
||||||
self.assertIn("Server providers:", output)
|
self.assertIn("Server providers:", output)
|
||||||
self.assertIn("ExistingServers", output)
|
self.assertIn("ExistingServers", output)
|
||||||
@ -77,15 +92,16 @@ class InfoTestCase(unittest.TestCase):
|
|||||||
output = self.rally("info BenchmarkScenarios")
|
output = self.rally("info BenchmarkScenarios")
|
||||||
self.assertIn("Benchmark scenario groups:", output)
|
self.assertIn("Benchmark scenario groups:", output)
|
||||||
self.assertIn("NovaServers", output)
|
self.assertIn("NovaServers", output)
|
||||||
|
self.assertNotIn("NovaScenario", output)
|
||||||
|
|
||||||
def test_SLA(self):
|
def test_SLA(self):
|
||||||
output = self.rally("info SLA")
|
output = self.rally("info SLA")
|
||||||
self.assertIn("SLA:", output)
|
self.assertIn("SLA checks:", output)
|
||||||
self.assertIn("FailureRate", output)
|
self.assertIn("failure_rate", output)
|
||||||
|
|
||||||
def test_DeployEngines(self):
|
def test_DeploymentEngines(self):
|
||||||
output = self.rally("info DeployEngines")
|
output = self.rally("info DeploymentEngines")
|
||||||
self.assertIn("Deploy engines:", output)
|
self.assertIn("Deployment engines:", output)
|
||||||
self.assertIn("ExistingCloud", output)
|
self.assertIn("ExistingCloud", output)
|
||||||
|
|
||||||
def test_ServerProviders(self):
|
def test_ServerProviders(self):
|
||||||
|
@ -32,6 +32,13 @@ class TestCriterion(base.SLA):
|
|||||||
|
|
||||||
class BaseSLATestCase(test.TestCase):
|
class BaseSLATestCase(test.TestCase):
|
||||||
|
|
||||||
|
def test_get_by_name(self):
|
||||||
|
self.assertEqual(base.FailureRate, base.SLA.get_by_name("FailureRate"))
|
||||||
|
|
||||||
|
def test_get_by_name_by_config_option(self):
|
||||||
|
self.assertEqual(base.FailureRate,
|
||||||
|
base.SLA.get_by_name("failure_rate"))
|
||||||
|
|
||||||
def test_validate(self):
|
def test_validate(self):
|
||||||
cnf = {"test_criterion": 42}
|
cnf = {"test_criterion": 42}
|
||||||
base.SLA.validate(cnf)
|
base.SLA.validate(cnf)
|
||||||
|
@ -32,6 +32,7 @@ SLA = "rally.cmd.commands.info.sla_base.SLA"
|
|||||||
ENGINE = "rally.cmd.commands.info.deploy.EngineFactory"
|
ENGINE = "rally.cmd.commands.info.deploy.EngineFactory"
|
||||||
PROVIDER = "rally.cmd.commands.info.serverprovider.ProviderFactory"
|
PROVIDER = "rally.cmd.commands.info.serverprovider.ProviderFactory"
|
||||||
UTILS = "rally.cmd.commands.info.utils"
|
UTILS = "rally.cmd.commands.info.utils"
|
||||||
|
COMMANDS = "rally.cmd.commands.info.InfoCommands"
|
||||||
|
|
||||||
|
|
||||||
class InfoCommandsTestCase(test.TestCase):
|
class InfoCommandsTestCase(test.TestCase):
|
||||||
@ -65,6 +66,13 @@ class InfoCommandsTestCase(test.TestCase):
|
|||||||
|
|
||||||
@mock.patch(SLA + ".get_by_name", return_value=sla_base.FailureRate)
|
@mock.patch(SLA + ".get_by_name", return_value=sla_base.FailureRate)
|
||||||
def test_find_failure_rate_sla(self, mock_get_by_name):
|
def test_find_failure_rate_sla(self, mock_get_by_name):
|
||||||
|
query = "failure_rate"
|
||||||
|
status = self.info.find(query)
|
||||||
|
mock_get_by_name.assert_called_once_with(query)
|
||||||
|
self.assertIsNone(status)
|
||||||
|
|
||||||
|
@mock.patch(SLA + ".get_by_name", return_value=sla_base.FailureRate)
|
||||||
|
def test_find_failure_rate_sla_by_class_name(self, mock_get_by_name):
|
||||||
query = "FailureRate"
|
query = "FailureRate"
|
||||||
status = self.info.find(query)
|
status = self.info.find(query)
|
||||||
mock_get_by_name.assert_called_once_with(query)
|
mock_get_by_name.assert_called_once_with(query)
|
||||||
@ -86,37 +94,41 @@ class InfoCommandsTestCase(test.TestCase):
|
|||||||
mock_get_by_name.assert_called_once_with(query)
|
mock_get_by_name.assert_called_once_with(query)
|
||||||
self.assertIsNone(status)
|
self.assertIsNone(status)
|
||||||
|
|
||||||
@mock.patch(UTILS + ".itersubclasses", return_value=[dummy.Dummy])
|
@mock.patch(COMMANDS + ".ServerProviders")
|
||||||
def test_list(self, mock_itersubclasses):
|
@mock.patch(COMMANDS + ".DeploymentEngines")
|
||||||
|
@mock.patch(COMMANDS + ".SLA")
|
||||||
|
@mock.patch(COMMANDS + ".BenchmarkScenarios")
|
||||||
|
def test_list(self, mock_BenchmarkScenarios, mock_SLA,
|
||||||
|
mock_DeploymentEngines, mock_ServerProviders):
|
||||||
status = self.info.list()
|
status = self.info.list()
|
||||||
mock_itersubclasses.assert_has_calls([
|
mock_BenchmarkScenarios.assert_called_once_with()
|
||||||
mock.call(scenario_base.Scenario),
|
mock_SLA.assert_called_once_with()
|
||||||
mock.call(sla_base.SLA),
|
mock_DeploymentEngines.assert_called_once_with()
|
||||||
mock.call(deploy.EngineFactory),
|
mock_ServerProviders.assert_called_once_with()
|
||||||
mock.call(serverprovider.ProviderFactory)])
|
|
||||||
self.assertIsNone(status)
|
self.assertIsNone(status)
|
||||||
|
|
||||||
@mock.patch(UTILS + ".itersubclasses", return_value=[dummy.Dummy])
|
@mock.patch(UTILS + ".itersubclasses", return_value=[dummy.Dummy])
|
||||||
def test_BenchmarkScenarios(self, mock_itersubclasses):
|
def test_BenchmarkScenarios(self, mock_itersubclasses):
|
||||||
status = self.info.BenchmarkScenarios()
|
status = self.info.BenchmarkScenarios()
|
||||||
mock_itersubclasses.assert_called_once_with(scenario_base.Scenario)
|
mock_itersubclasses.assert_called_with(scenario_base.Scenario)
|
||||||
self.assertIsNone(status)
|
self.assertIsNone(status)
|
||||||
|
|
||||||
@mock.patch(UTILS + ".itersubclasses", return_value=[dummy.Dummy])
|
@mock.patch(UTILS + ".itersubclasses", return_value=[sla_base.FailureRate])
|
||||||
def test_SLA(self, mock_itersubclasses):
|
def test_SLA(self, mock_itersubclasses):
|
||||||
status = self.info.SLA()
|
status = self.info.SLA()
|
||||||
mock_itersubclasses.assert_called_once_with(sla_base.SLA)
|
mock_itersubclasses.assert_called_with(sla_base.SLA)
|
||||||
self.assertIsNone(status)
|
self.assertIsNone(status)
|
||||||
|
|
||||||
@mock.patch(UTILS + ".itersubclasses", return_value=[dummy.Dummy])
|
@mock.patch(UTILS + ".itersubclasses",
|
||||||
def test_DeployEngines(self, mock_itersubclasses):
|
return_value=[existing_cloud.ExistingCloud])
|
||||||
status = self.info.DeployEngines()
|
def test_DeploymentEngines(self, mock_itersubclasses):
|
||||||
mock_itersubclasses.assert_called_once_with(deploy.EngineFactory)
|
status = self.info.DeploymentEngines()
|
||||||
|
mock_itersubclasses.assert_called_with(deploy.EngineFactory)
|
||||||
self.assertIsNone(status)
|
self.assertIsNone(status)
|
||||||
|
|
||||||
@mock.patch(UTILS + ".itersubclasses", return_value=[dummy.Dummy])
|
@mock.patch(UTILS + ".itersubclasses",
|
||||||
|
return_value=[existing_servers.ExistingServers])
|
||||||
def test_ServerProviders(self, mock_itersubclasses):
|
def test_ServerProviders(self, mock_itersubclasses):
|
||||||
status = self.info.ServerProviders()
|
status = self.info.ServerProviders()
|
||||||
mock_itersubclasses.assert_called_once_with(
|
mock_itersubclasses.assert_called_with(serverprovider.ProviderFactory)
|
||||||
serverprovider.ProviderFactory)
|
|
||||||
self.assertIsNone(status)
|
self.assertIsNone(status)
|
||||||
|
@ -254,8 +254,10 @@ line-
|
|||||||
description.
|
description.
|
||||||
|
|
||||||
:param p1: Param 1 description.
|
:param p1: Param 1 description.
|
||||||
:param p2: Param 2 description.
|
:param p2: Param 2
|
||||||
:returns: Return value description.
|
description.
|
||||||
|
:returns: Return value
|
||||||
|
description.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
dct = utils.parse_docstring(docstring)
|
dct = utils.parse_docstring(docstring)
|
||||||
@ -272,7 +274,8 @@ description.
|
|||||||
docstring = """One-line description.
|
docstring = """One-line description.
|
||||||
|
|
||||||
:param p1: Param 1 description.
|
:param p1: Param 1 description.
|
||||||
:param p2: Param 2 description.
|
:param p2: Param 2
|
||||||
|
description.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
dct = utils.parse_docstring(docstring)
|
dct = utils.parse_docstring(docstring)
|
||||||
@ -292,7 +295,8 @@ Multi-
|
|||||||
line-
|
line-
|
||||||
description.
|
description.
|
||||||
|
|
||||||
:returns: Return value description.
|
:returns: Return value
|
||||||
|
description.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
dct = utils.parse_docstring(docstring)
|
dct = utils.parse_docstring(docstring)
|
||||||
|
@ -8,6 +8,7 @@ _rally()
|
|||||||
|
|
||||||
OPTS["info_BenchmarkScenarios"]=""
|
OPTS["info_BenchmarkScenarios"]=""
|
||||||
OPTS["info_DeployEngines"]=""
|
OPTS["info_DeployEngines"]=""
|
||||||
|
OPTS["info_DeploymentEngines"]=""
|
||||||
OPTS["info_SLA"]=""
|
OPTS["info_SLA"]=""
|
||||||
OPTS["info_ServerProviders"]=""
|
OPTS["info_ServerProviders"]=""
|
||||||
OPTS["info_find"]="--query"
|
OPTS["info_find"]="--query"
|
||||||
|
Loading…
Reference in New Issue
Block a user