Merge "Further improvements in rally info"

This commit is contained in:
Jenkins 2014-12-01 18:18:32 +00:00 committed by Gerrit Code Review
commit 80e20252f3
10 changed files with 278 additions and 105 deletions

View File

@ -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."""

View File

@ -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}

View File

@ -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)

View File

@ -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

View File

@ -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")

View File

@ -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):

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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"