Merge "Move required-api-versions validator to '../validators.py'"
This commit is contained in:
commit
32f481a1f2
|
@ -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})
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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={
|
||||
|
|
Loading…
Reference in New Issue