[plugins] Introduce <name>@<platform> syntax

Simplify and unify full naming of plugins
The new logic is pretty strightforward and simple to understand:

1) Full name provided
   -> Try to find exact match or raise NotFound
2) Only name provided
   -> Finds all plugins with exact name match:
      A) if one found -> return it
      B) if multiple found -> raise error MultiMatch with infomration
         of platforms
      c) if none found -> return error

This approach is going to force people to be explicit about platform
when they use multiple platforms in same task if there are name colisions

However, it won't be redunant in case when you are using one platform and
don't want to explicitly specify it.

Auto-magic discovering of platform should be disabled because:
1) it's unclear how it works and hard to explain which is very bad
2) is going to produce random limitations and unexpected behaviors

   One of example is if we decided to write large libs for:
   HTTP, DNS, FTP, and other kind of scenarios and context and have
   separated platforms for them e.g. @http, @dns, @ftp, ....
   they are going to be run against "default" platform which doesn't
   contain any information however they are not @default platform

Change-Id: I8ae5369bcf5ef3aba0fa39a95d8c40cf75edb4bf
This commit is contained in:
Boris Pavlovic 2017-07-28 20:26:34 -07:00
parent f390b10ca0
commit 76a1e23df6
6 changed files with 30 additions and 12 deletions

View File

@ -110,9 +110,12 @@ class UserGenerator(context.Context):
super(UserGenerator, self).__init__(context)
deployment = objects.Deployment.get(context["task"]["deployment_uuid"])
existing_users = deployment.get_credentials_for("openstack")["users"]
if existing_users and not (set(self.config) - {"user_choice_method"}):
self.existing_users = existing_users
creds = deployment.get_credentials_for("openstack")
if creds.get("admin"):
context["admin"] = {"credential": creds["admin"]}
if creds["users"] and not (set(self.config) - {"user_choice_method"}):
self.existing_users = creds["users"]
else:
self.existing_users = []
self.credential = context["admin"]["credential"]

View File

@ -91,6 +91,10 @@ class OpenStackCredential(credential.Credential):
for stype, sname in self.clients().services().items()],
key=lambda s: s["name"])
@classmethod
def get_validation_context(cls):
return {"users@openstack": {}}
def clients(self, api_info=None):
return osclients.Clients(self, api_info=api_info,
cache=self._clients_cache)

View File

@ -18,7 +18,9 @@ import random
from oslo_config import cfg
from osprofiler import profiler
from rally.common.plugin import plugin
from rally import osclients
from rally.task import context
from rally.task import scenario
configure = functools.partial(scenario.configure, platform="openstack")
@ -26,6 +28,8 @@ configure = functools.partial(scenario.configure, platform="openstack")
CONF = cfg.CONF
@context.add_default_context("users@openstack", {})
@plugin.default_meta(inherit=False)
class OpenStackScenario(scenario.Scenario):
"""Base class for all OpenStack scenarios."""
@ -33,8 +37,8 @@ class OpenStackScenario(scenario.Scenario):
super(OpenStackScenario, self).__init__(context)
if context:
api_info = {}
if "api_versions" in context.get("config", {}):
api_versions = context["config"]["api_versions"]
if "api_versions@openstack" in context.get("config", {}):
api_versions = context["config"]["api_versions@openstack"]
for service in api_versions:
api_info[service] = {
"version": api_versions[service].get("version"),

View File

@ -406,7 +406,7 @@ class RequiredServicesValidator(validation.Validator):
# NOTE(andreykurilin): validator should ignore services configured
# via context(a proper validation should be in context)
service_config = config.get("context", {}).get(
"api_versions", {}).get(service, {})
"api_versions@openstack", {}).get(service, {})
if (service not in available_services and
not ("service_type" in service_config or
@ -531,7 +531,7 @@ class RequiredAPIVersionsValidator(validation.Validator):
else:
used_version = config.get(
"context", {}).get(
"api_versions", {}).get(
"api_versions@openstack", {}).get(
self.component, {}).get(
"version", getattr(
clients, self.component).choose_version())

View File

@ -1857,6 +1857,12 @@ class FakeDeployment(dict):
def get_credentials_for(self, namespace):
return self["credentials"][namespace][0]
def verify_connections(self):
pass
def get_validation_context(self):
return {}
class FakeTask(dict, object):

View File

@ -43,7 +43,7 @@ config = dict(args={"image": {"id": "fake_id",
"foo_image": {"id": "fake_image_id"}
},
context={"images": {"image_name": "foo_image"},
"api_versions": mock.MagicMock()}
"api_versions@openstack": mock.MagicMock()}
)
@ -534,7 +534,7 @@ class RequiredServicesValidatorTestCase(test.TestCase):
def test_validator(self):
self.config["context"]["api_versions"].get = mock.Mock(
self.config["context"]["api_versions@openstack"].get = mock.Mock(
return_value={consts.Service.KEYSTONE: "service_type"})
clients = self.credentials["openstack"]["admin"].clients()
@ -575,7 +575,7 @@ class RequiredServicesValidatorTestCase(test.TestCase):
def test_validator_wrong_service(self):
self.config["context"]["api_versions"].get = mock.Mock(
self.config["context"]["api_versions@openstack"].get = mock.Mock(
return_value={consts.Service.KEYSTONE: "service_type",
consts.Service.NOVA: "service_name"})
@ -761,7 +761,7 @@ class RequiredAPIVersionsValidatorTestCase(test.TestCase):
"credential"].clients()
clients.nova.choose_version.return_value = nova
config = {"context": {"api_versions": {}}}
config = {"context": {"api_versions@openstack": {}}}
result = validator.validate(config, self.credentials, None, None)
@ -779,7 +779,8 @@ class RequiredAPIVersionsValidatorTestCase(test.TestCase):
validator = validators.RequiredAPIVersionsValidator("nova",
[version])
config = {"context": {"api_versions": {"nova": {"version": 2}}}}
config = {
"context": {"api_versions@openstack": {"nova": {"version": 2}}}}
result = validator.validate(config, self.credentials, None, None)