Merge "A request hook interface for the functional test client"

This commit is contained in:
Jenkins 2016-02-17 15:08:19 +00:00 committed by Gerrit Code Review
commit 1a4eb3d4e7
4 changed files with 115 additions and 0 deletions

View File

@ -15,6 +15,7 @@ limitations under the License.
"""
import abc
import logging
from config import cfg
from noauth import NoAuthAuthProvider
@ -25,6 +26,9 @@ from tempest_lib.auth import KeystoneV2Credentials
from tempest_lib.auth import KeystoneV2AuthProvider
from functionaltests.common.utils import memoized
from functionaltests.common import hooks
LOG = logging.getLogger(__name__)
class KeystoneV2AuthProviderWithOverridableUrl(KeystoneV2AuthProvider):
@ -59,6 +63,9 @@ class BaseDesignateClient(RestClient):
if not interface.endswith('URL'):
interface += "URL"
self.hooks = []
self._populate_hooks()
super(BaseDesignateClient, self).__init__(
auth_provider=self.get_auth_provider(with_token),
service=cfg.CONF.designate.service,
@ -67,6 +74,32 @@ class BaseDesignateClient(RestClient):
endpoint_type=interface
)
def _populate_hooks(self):
for name in cfg.CONF.testconfig.hooks:
LOG.debug("Loading request hook '%s' from config", name)
try:
cls = hooks.get_class(name)
if not cls:
LOG.debug("'%s' not found. Call register_hook", name)
else:
self.hooks.append(cls)
except Exception as e:
LOG.exception(e)
def request(self, *args, **kwargs):
req_hooks = [hook_class() for hook_class in self.hooks]
try:
for hook in req_hooks:
hook.before(args, kwargs)
r, b = super(BaseDesignateClient, self).request(*args, **kwargs)
for hook in req_hooks:
hook.after(r, b)
return r, b
except Exception as e:
for hook in req_hooks:
hook.on_exception(e)
raise
def get_auth_provider(self, with_token=True):
if cfg.CONF.noauth.use_noauth:
return self._get_noauth_auth_provider()

View File

@ -79,6 +79,8 @@ cfg.CONF.register_opts([
cfg.CONF.register_opts([
cfg.ListOpt('hooks', default=[],
help="The list of request hook class names to enable"),
cfg.StrOpt('v2_path_pattern', default='/v2/{path}',
help="Specifies how to build the path for the request"),
cfg.BoolOpt('no_admin_setup', default=False,

View File

@ -0,0 +1,37 @@
"""
Copyright 2016 Rackspace
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
# a dictionary mapping the class name to the hook class
_HOOKS = {}
def register_hook(cls):
"""Register the request hook. This does not enable the hook. Hooks are
enable via the config file.
Usage:
>>> register_hook(MyHook)
"""
_HOOKS[cls.__name__] = cls
def get_class(name):
"""Get a hook class by it's class name:
Usage:
>>> get_hook_class('MyHook')
"""
return _HOOKS.get(name)

View File

@ -0,0 +1,43 @@
"""
Copyright 2016 Rackspace
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
class BaseRequestHook(object):
"""When writing your own hook, do three things:
1. Implement this hook interface
2. Register your hook in a global lookup using hook.register_hook()
3. Specify the name of your hook in a config file
A new instance of a hook is created before for each request, for storing
per request state if you want.
"""
def before(self, req_args, req_kwargs):
"""A hook called before each request
:param req_args: a list (mutable)
:param req_kwargs: a dictionary
"""
pass
def after(self, resp, resp_body):
"""A hook called after each request"""
pass
def on_exception(self, exception):
"""A hook called when an exception occurs on a request"""
pass