Import tempest results into Rally database
Add a new subcommand to the `verify` command to import tempest results into an existing deployment in the Rally database. `verify import` will read a tempest log in subunit format, and import it into the current deployment (or the one specified in the command line) The command should be called as $ rally verify import --file [log_file] --deployment [uuid] This version of the patch will require a normal deployment to be created beforehand. Also, the log_file needs to be a tempest log in subunit format; `--file` parameter is required. Apart from `--file` and `--deployment` parameters, this command understand `--set-name` and `--no-use` from the `start` command. `--set-name` can be used to attach a name or a small description to the tempest result, and `--no-use` will mark the new verification object as a no-current. So, for example, if we want to assign a name to the tempest result we can use: $ rally verify import --file [log_file] --set-name [name] \ --deployment [uuid] Implements: blueprint verification-import Change-Id: I65194a2f456106fa5731a13f53d5985971aad43a
This commit is contained in:
parent
592a4b6cc0
commit
fd245dbd60
@ -49,6 +49,7 @@ _rally()
|
||||
OPTS["verify_compare"]="--uuid-1 --uuid-2 --csv --html --json --output-file --threshold"
|
||||
OPTS["verify_detailed"]="--uuid --sort-by"
|
||||
OPTS["verify_genconfig"]="--deployment --tempest-config --override"
|
||||
OPTS["verify_import"]="--deployment --set-name --file --no-use"
|
||||
OPTS["verify_install"]="--deployment --source"
|
||||
OPTS["verify_list"]=""
|
||||
OPTS["verify_reinstall"]="--deployment --tempest-config --source"
|
||||
|
23
rally/api.py
23
rally/api.py
@ -333,6 +333,29 @@ class Verification(object):
|
||||
|
||||
return verifier
|
||||
|
||||
@classmethod
|
||||
def import_file(cls, deployment, set_name, log_file=None):
|
||||
"""Import tempest log.
|
||||
|
||||
:param deployment: UUID or name of a deployment.
|
||||
:param log_file: User specified Tempest log file name.
|
||||
:returns: Deployment and verification objects
|
||||
"""
|
||||
|
||||
# TODO(aplanas): Create an external deployment if this is
|
||||
# missing, as required in the blueprint [1].
|
||||
# [1] https://blueprints.launchpad.net/rally/+spec/verification-import
|
||||
deployment_uuid = objects.Deployment.get(deployment)["uuid"]
|
||||
|
||||
verification = objects.Verification(deployment_uuid=deployment_uuid)
|
||||
verifier = tempest.Tempest(deployment_uuid, verification=verification)
|
||||
LOG.info("Importing verification of deployment: %s" % deployment_uuid)
|
||||
|
||||
verification.set_running()
|
||||
verifier.import_file(set_name=set_name, log_file=log_file)
|
||||
|
||||
return deployment, verification
|
||||
|
||||
@classmethod
|
||||
def install_tempest(cls, deployment, source=None):
|
||||
"""Install Tempest.
|
||||
|
@ -89,6 +89,36 @@ class VerifyCommands(object):
|
||||
if do_use:
|
||||
self.use(verification["uuid"])
|
||||
|
||||
@cliutils.args("--deployment", dest="deployment", type=str,
|
||||
required=False, help="UUID or name of a deployment.")
|
||||
@cliutils.args("--set-name", dest="set_name", type=str, required=False,
|
||||
help="Name of tempest test set. Available sets: %s" % ", ".
|
||||
join(list(consts.TempestTestsSets) +
|
||||
list(consts.TempestTestsAPI)))
|
||||
@cliutils.args("--file", dest="log_file", type=str,
|
||||
required=True,
|
||||
help="User specified Tempest log file location")
|
||||
@cliutils.args("--no-use", action="store_false", dest="do_use",
|
||||
required=False,
|
||||
help="Don't set new task as default for future operations")
|
||||
@cliutils.alias("import")
|
||||
def import_file(self, deployment=None, set_name=None, log_file=None,
|
||||
do_use=True):
|
||||
"""Import a tempest result into rally.
|
||||
|
||||
:param deployment: UUID or name of a deployment
|
||||
:param set_name: Name of tempest test set
|
||||
:param do_use: Use new task as default for future operations
|
||||
:param log_file: User specified Tempest log file
|
||||
"""
|
||||
|
||||
deployment, verification = api.Verification.import_file(deployment,
|
||||
set_name,
|
||||
log_file)
|
||||
|
||||
if do_use:
|
||||
self.use(verification["uuid"])
|
||||
|
||||
def list(self):
|
||||
"""Display all verifications table, started and finished."""
|
||||
|
||||
|
@ -381,8 +381,8 @@ class Tempest(object):
|
||||
|
||||
@utils.log_verification_wrapper(
|
||||
LOG.info, _("Saving verification results."))
|
||||
def _save_results(self):
|
||||
total, test_cases = self.parse_results()
|
||||
def _save_results(self, log_file=None):
|
||||
total, test_cases = self.parse_results(log_file)
|
||||
if total and test_cases and self.verification:
|
||||
self.verification.finish_verification(total=total,
|
||||
test_cases=test_cases)
|
||||
@ -392,3 +392,10 @@ class Tempest(object):
|
||||
def verify(self, set_name, regex):
|
||||
self._prepare_and_run(set_name, regex)
|
||||
self._save_results()
|
||||
|
||||
def import_file(self, set_name, log_file):
|
||||
if log_file:
|
||||
self.verification.start_verifying(set_name)
|
||||
self._save_results(log_file)
|
||||
else:
|
||||
LOG.error("No import file specified.")
|
||||
|
@ -94,6 +94,29 @@ class VerifyCommandsTestCase(test.TestCase):
|
||||
consts.TempestTestsAPI)
|
||||
self.assertFalse(mock_verification_verify.called)
|
||||
|
||||
@mock.patch("rally.api.Verification.import_file")
|
||||
def test_import_file(self, mock_verification_import_file):
|
||||
deployment_id = "fake_uuid"
|
||||
mock_verification_import_file.return_value = (None, None)
|
||||
self.verify.import_file(deployment=deployment_id, do_use=False)
|
||||
default_set_name = None
|
||||
default_log_file = None
|
||||
|
||||
mock_verification_import_file.assert_called_once_with(
|
||||
deployment_id, default_set_name, default_log_file)
|
||||
|
||||
@mock.patch("rally.api.Verification.import_file")
|
||||
def test_import_file_without_defaults(self, mock_verification_import_file):
|
||||
deployment_id = "fake_uuid"
|
||||
set_name = "fake_set_name"
|
||||
log_file = "fake_log_file"
|
||||
mock_verification_import_file.return_value = (None, None)
|
||||
self.verify.import_file(deployment=deployment_id, set_name=set_name,
|
||||
log_file=log_file, do_use=False)
|
||||
|
||||
mock_verification_import_file.assert_called_once_with(
|
||||
deployment_id, set_name, log_file)
|
||||
|
||||
@mock.patch("rally.cli.cliutils.print_list")
|
||||
@mock.patch("rally.common.db.verification_list")
|
||||
def test_list(self, mock_common_db_verification_list, mock_print_list):
|
||||
|
@ -352,6 +352,20 @@ class VerificationAPITestCase(BaseDeploymentTestCase):
|
||||
self.tempest.verify.assert_called_once_with(set_name="smoke",
|
||||
regex=None)
|
||||
|
||||
@mock.patch("rally.common.objects.Deployment.get")
|
||||
@mock.patch("rally.api.objects.Verification")
|
||||
@mock.patch("rally.verification.tempest.tempest.Tempest")
|
||||
def test_import_file(self, mock_tempest, mock_verification,
|
||||
mock_deployment_get):
|
||||
mock_deployment_get.return_value = {"uuid": self.deployment_uuid}
|
||||
|
||||
mock_tempest.return_value = self.tempest
|
||||
self.tempest.is_installed.return_value = True
|
||||
api.Verification.import_file(self.deployment_uuid, "smoke", "log_file")
|
||||
|
||||
self.tempest.import_file.assert_called_once_with(
|
||||
set_name="smoke", log_file="log_file")
|
||||
|
||||
@mock.patch("rally.api.objects.Deployment.get")
|
||||
@mock.patch("rally.api.tempest.Tempest")
|
||||
def test_install_tempest(self, mock_tempest, mock_deployment_get):
|
||||
|
@ -362,7 +362,7 @@ class TempestVerifyTestCase(BaseTestCase):
|
||||
mock_subprocess.check_call.assert_called_once_with(
|
||||
fake_call, env=mock_tempest_env, cwd=self.verifier.path(),
|
||||
shell=True)
|
||||
mock_tempest_parse_results.assert_called_once_with()
|
||||
mock_tempest_parse_results.assert_called_once_with(None)
|
||||
|
||||
@mock.patch(TEMPEST_PATH + ".tempest.Tempest.parse_results",
|
||||
return_value=(None, None))
|
||||
@ -388,7 +388,7 @@ class TempestVerifyTestCase(BaseTestCase):
|
||||
mock_subprocess.check_call.assert_called_once_with(
|
||||
fake_call, env=mock_tempest_env, cwd=self.verifier.path(),
|
||||
shell=True)
|
||||
mock_tempest_parse_results.assert_called_once_with()
|
||||
mock_tempest_parse_results.assert_called_once_with(None)
|
||||
|
||||
@mock.patch(TEMPEST_PATH + ".tempest.Tempest.parse_results",
|
||||
return_value=(None, None))
|
||||
@ -417,3 +417,13 @@ class TempestVerifyTestCase(BaseTestCase):
|
||||
shell=True)
|
||||
self.assertTrue(mock_tempest_parse_results.called)
|
||||
self.verifier.verification.set_failed.assert_called_once_with()
|
||||
|
||||
def test_import_file(self):
|
||||
set_name = "identity"
|
||||
log_file = "log_file"
|
||||
|
||||
self.verifier._save_results = mock.Mock()
|
||||
self.verifier.import_file(set_name, log_file)
|
||||
mock_start_verifying = self.verifier.verification.start_verifying
|
||||
mock_start_verifying.assert_called_once_with(set_name)
|
||||
self.verifier._save_results.assert_called_once_with(log_file)
|
||||
|
Loading…
Reference in New Issue
Block a user