Merge "Move required-api-versions validator to '../validators.py'"

This commit is contained in:
Jenkins 2017-05-25 14:48:39 +00:00 committed by Gerrit Code Review
commit 32f481a1f2
4 changed files with 155 additions and 112 deletions

View File

@ -469,3 +469,52 @@ class RequiredCinderServicesValidator(validation.Validator):
msg = ("%s service is not available") % self.services
return self.fail(msg)
@validation.add("required_platform", platform="openstack", users=True)
@validation.configure(name="required_api_versions",
namespace="openstack")
class RequiredAPIVersionsValidator(validation.Validator):
def __init__(self, component, versions):
"""Validator checks component API versions.
:param component: name of required component
:param versions: version of required component
"""
super(RequiredAPIVersionsValidator, self).__init__()
self.component = component
self.versions = versions
def validate(self, config, credentials, plugin_cls, plugin_cfg):
versions = [str(v) for v in self.versions]
versions_str = ", ".join(versions)
msg = ("Task was designed to be used with %(component)s "
"V%(version)s, but V%(found_version)s is "
"selected.")
for user in credentials["openstack"]["users"]:
clients = user["credential"].clients()
if self.component == "keystone":
if "2.0" not in versions and hasattr(
clients.keystone(), "tenants"):
return self.fail(msg % {"component": self.component,
"version": versions_str,
"found_version": "2.0"})
if "3" not in versions and hasattr(
clients.keystone(), "projects"):
return self.fail(msg % {"component": self.component,
"version": versions_str,
"found_version": "3"})
else:
used_version = config.get(
"context", {}).get(
"api_versions", {}).get(
self.component, {}).get(
"version", getattr(
clients, self.component).choose_version())
if not used_version:
return self.fail("Unable to determine the API version.")
if str(used_version) not in versions:
return self.fail(msg % {"component": self.component,
"version": versions_str,
"found_version": used_version})

View File

@ -355,37 +355,6 @@ def required_param_or_context(config, clients, deployment,
return ValidationResult(False, message)
@validator
def required_api_versions(config, clients, deployment, component, versions):
"""Validator checks component API versions."""
versions = [str(v) for v in versions]
versions_str = ", ".join(versions)
msg = _("Task was designed to be used with %(component)s "
"V%(version)s, but V%(found_version)s is "
"selected.")
if component == "keystone":
if "2.0" not in versions and hasattr(clients.keystone(), "tenants"):
return ValidationResult(False, msg % {"component": component,
"version": versions_str,
"found_version": "2.0"})
if "3" not in versions and hasattr(clients.keystone(), "projects"):
return ValidationResult(False, msg % {"component": component,
"version": versions_str,
"found_version": "3"})
else:
used_version = config.get("context", {}).get("api_versions", {}).get(
component, {}).get("version",
getattr(clients, component).choose_version())
if not used_version:
return ValidationResult(
False, _("Unable to determine the API version."))
if str(used_version) not in versions:
return ValidationResult(
False, msg % {"component": component,
"version": versions_str,
"found_version": used_version})
@validator
def volume_type_exists(config, clients, deployment, param_name):
"""Returns validator for volume types.
@ -478,6 +447,7 @@ required_services = deprecated_validator("required_services",
validate_heat_template = deprecated_validator("validate_heat_template",
"validate_heat_template",
"0.10.0")
restricted_parameters = deprecated_validator("restricted_parameters",
"restricted_parameters",
"0.10.0")
@ -485,3 +455,7 @@ restricted_parameters = deprecated_validator("restricted_parameters",
required_cinder_services = deprecated_validator("required_cinder_services",
"required_cinder_services",
"0.10.0")
required_api_versions = deprecated_validator("required_api_versions",
"required_api_versions",
"0.10.0")

View File

@ -53,8 +53,8 @@ class ImageExistsValidatorTestCase(test.TestCase):
def setUp(self):
super(ImageExistsValidatorTestCase, self).setUp()
self.validator = validators.ImageExistsValidator("image", True)
self.config = config
self.credentials = credentials
self.config = copy.deepcopy(config)
self.credentials = copy.deepcopy(credentials)
@ddt.unpack
@ddt.data(
@ -115,7 +115,8 @@ class ImageExistsValidatorTestCase(test.TestCase):
for ex in exs:
clients.glance().images.get.side_effect = ex
result = self.validator.validate(config, credentials, None, None)
result = self.validator.validate(config, self.credentials,
None, None)
self.assertEqual("Image 'fake_image' not found", result.msg)
@ -187,7 +188,7 @@ class RequiredNeutronExtensionsValidatorTestCase(test.TestCase):
clients.neutron().list_extensions.return_value = {
"extensions": [{"alias": "existing_extension"}]}
result = validator.validate({}, self.credentials, {}, None)
result = validator.validate({}, self.credentials, None, None)
if err_msg:
self.assertTrue(result)
@ -683,3 +684,99 @@ class RequiredCinderServicesValidatorTestCase(test.TestCase):
self.assertTrue(result)
self.assertEqual("cinder_service service is not available",
result.msg)
@ddt.ddt
class RequiredAPIVersionsValidatorTestCase(test.TestCase):
def setUp(self):
super(RequiredAPIVersionsValidatorTestCase, self).setUp()
self.config = copy.deepcopy(config)
self.credentials = copy.deepcopy(credentials)
def _get_keystone_v2_mock_client(self):
keystone = mock.Mock()
del keystone.projects
keystone.tenants = mock.Mock()
return keystone
def _get_keystone_v3_mock_client(self):
keystone = mock.Mock()
del keystone.tenants
keystone.projects = mock.Mock()
return keystone
@ddt.unpack
@ddt.data(
{"versions": [2.0], "err_msg": "Task was designed to be used with"
" keystone V2.0, but V3 is selected."},
{"versions": [3], "err_msg": "Task was designed to be used with"
" keystone V3, but V2.0 is selected."},
{"versions": [2.0, 3], "err_msg": None}
)
def test_validate_keystone(self, versions, err_msg):
validator = validators.RequiredAPIVersionsValidator("keystone",
versions)
clients = self.credentials["openstack"]["users"][0][
"credential"].clients()
clients.keystone.return_value = self._get_keystone_v3_mock_client()
result = validator.validate(self.config, self.credentials, None, None)
if result:
self.assertEqual(err_msg, result.msg)
clients.keystone.return_value = self._get_keystone_v2_mock_client()
result = validator.validate(self.config, self.credentials, None, None)
if result:
self.assertEqual(err_msg, result.msg)
@ddt.unpack
@ddt.data(
{"nova": 2, "versions": [2], "err_msg": None},
{"nova": 3, "versions": [2],
"err_msg": "Task was designed to be used with nova V2, "
"but V3 is selected."},
{"nova": None, "versions": [2],
"err_msg": "Unable to determine the API version."},
{"nova": 2, "versions": [2, 3], "err_msg": None},
{"nova": 4, "versions": [2, 3],
"err_msg": "Task was designed to be used with nova V2, 3, "
"but V4 is selected."}
)
def test_validate_nova(self, nova, versions, err_msg):
validator = validators.RequiredAPIVersionsValidator("nova",
versions)
clients = self.credentials["openstack"]["users"][0][
"credential"].clients()
clients.nova.choose_version.return_value = nova
result = validator.validate(self.config, self.credentials, None, None)
if err_msg:
self.assertIsNotNone(result)
self.assertEqual(err_msg, result.msg)
else:
self.assertIsNone(result)
@ddt.unpack
@ddt.data({"version": 2, "err_msg": None},
{"version": 3, "err_msg": "Task was designed to be used with "
"nova V3, but V2 is selected."})
def test_validate_context(self, version, err_msg):
validator = validators.RequiredAPIVersionsValidator("nova",
[version])
config = {"context": {"api_versions": {"nova": {"version": 2}}}}
result = validator.validate(config, self.credentials, None, None)
if err_msg:
self.assertIsNotNone(result)
self.assertEqual(err_msg, result.msg)
else:
self.assertIsNone(result)

View File

@ -571,83 +571,6 @@ class ValidatorsTestCase(test.TestCase):
result = validator(context, clients, mock.MagicMock())
self.assertFalse(result.is_valid, result.msg)
def _get_keystone_v2_mock_client(self):
keystone = mock.Mock()
del keystone.projects
keystone.tenants = mock.Mock()
return keystone
def _get_keystone_v3_mock_client(self):
keystone = mock.Mock()
del keystone.tenants
keystone.projects = mock.Mock()
return keystone
def test_required_api_versions_keystonev2(self):
validator = self._unwrap_validator(
validation.required_api_versions, component="keystone",
versions=[2.0])
clients = mock.MagicMock()
clients.keystone.return_value = self._get_keystone_v3_mock_client()
self.assertFalse(validator({}, clients, None).is_valid)
clients.keystone.return_value = self._get_keystone_v2_mock_client()
self.assertTrue(validator({}, clients, None).is_valid)
def test_required_api_versions_keystonev3(self):
validator = self._unwrap_validator(
validation.required_api_versions, component="keystone",
versions=[3])
clients = mock.MagicMock()
clients.keystone.return_value = self._get_keystone_v2_mock_client()
self.assertFalse(validator({}, clients, None).is_valid)
clients.keystone.return_value = self._get_keystone_v3_mock_client()
self.assertTrue(validator({}, clients, None).is_valid)
def test_required_api_versions_keystone_all_versions(self):
validator = self._unwrap_validator(
validation.required_api_versions, component="keystone",
versions=[2.0, 3])
clients = mock.MagicMock()
clients.keystone.return_value = self._get_keystone_v3_mock_client()
self.assertTrue(validator({}, clients, None).is_valid)
clients.keystone.return_value = self._get_keystone_v2_mock_client()
self.assertTrue(validator({}, clients, None).is_valid)
@ddt.data({"nova_version": 2, "required_versions": [2], "valid": True},
{"nova_version": 3, "required_versions": [2], "valid": False},
{"nova_version": None, "required_versions": [2], "valid": False},
{"nova_version": 2, "required_versions": [2, 3], "valid": True},
{"nova_version": 4, "required_versions": [2, 3], "valid": False})
@ddt.unpack
def test_required_api_versions_choose_version(self, nova_version=None,
required_versions=(2,),
valid=False):
validator = self._unwrap_validator(
validation.required_api_versions, component="nova",
versions=required_versions)
clients = mock.MagicMock()
clients.nova.choose_version.return_value = nova_version
self.assertEqual(validator({}, clients, None).is_valid,
valid)
@ddt.data({"required_version": 2, "valid": True},
{"required_version": 3, "valid": False})
@ddt.unpack
def test_required_api_versions_context(self, required_version=None,
valid=False):
validator = self._unwrap_validator(
validation.required_api_versions, component="nova",
versions=[required_version])
clients = mock.MagicMock()
config = {"context": {"api_versions": {"nova": {"version": 2}}}}
self.assertEqual(validator(config, clients, None).is_valid,
valid)
@mock.patch(
"rally.common.yamlutils.safe_load",
return_value={