Add skip_if_not_implemented to the service client
This patch adds a decorator that wraps the service client methods adding
the ability to raise a skipException if a call to the API returns a
NotImplementedError or UnsupportedOptionError exception.
This is useful for running the tests against provider drivers that do
not support all of the Octavia API features.
Change-Id: I17d4be65130fadf97d6170d22fb07c72672b7573
diff --git a/octavia_tempest_plugin/common/decorators.py b/octavia_tempest_plugin/common/decorators.py
new file mode 100644
index 0000000..b484497
--- /dev/null
+++ b/octavia_tempest_plugin/common/decorators.py
@@ -0,0 +1,54 @@
+# Copyright 2020 Red Hat, Inc. All rights reserved.
+#
+# 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.
+from functools import wraps
+
+import testtools
+
+from oslo_utils import excutils
+from tempest import config
+from tempest.lib import exceptions
+
+CONF = config.CONF
+
+
+def skip_if_not_implemented(f):
+ """A decorator to raise a skip exception for not implemented features.
+
+ This decorator raises a skipException if the method raises a
+ NotImplemented exception. If "skip_if_not_implemented=False"
+ argument was passed to the method, the NotImplemented exception will
+ be raised.
+
+ @param skip_if_not_implemented: If True (default), raise skipException.
+ """
+ @wraps(f)
+ def wrapper(*func_args, **func_kwargs):
+
+ skip = func_kwargs.pop('skip_if_not_implemented', True)
+ if CONF.loadbalancer_feature_enabled.not_implemented_is_error:
+ skip = False
+ try:
+ return f(*func_args, **func_kwargs)
+ except exceptions.NotImplemented as e:
+ with excutils.save_and_reraise_exception():
+ if not skip:
+ raise
+ message = ("The configured provider driver '{driver}' "
+ "does not support a feature required for this "
+ "test.".format(
+ driver=CONF.load_balancer.provider))
+ if hasattr(e, 'resp_body'):
+ message = e.resp_body.get('faultstring', message)
+ raise testtools.TestCase.skipException(message)
+ return wrapper
diff --git a/octavia_tempest_plugin/config.py b/octavia_tempest_plugin/config.py
index fc04c33..8dd0403 100644
--- a/octavia_tempest_plugin/config.py
+++ b/octavia_tempest_plugin/config.py
@@ -209,6 +209,12 @@
lb_feature_enabled_group = cfg.OptGroup(name='loadbalancer-feature-enabled',
title='Enabled/Disabled LB features')
LBFeatureEnabledGroup = [
+ cfg.BoolOpt('not_implemented_is_error',
+ default=True,
+ help="When True, not-implemented responses from the API are "
+ "considered an error and test failure. This should be "
+ "used when a driver should support all of the Octavia "
+ "API features, such as the reference driver."),
cfg.BoolOpt('health_monitor_enabled',
default=True,
help="Whether Health Monitor is available with provider "
diff --git a/octavia_tempest_plugin/services/load_balancer/v2/amphora_client.py b/octavia_tempest_plugin/services/load_balancer/v2/amphora_client.py
index 4094515..aed93b4 100644
--- a/octavia_tempest_plugin/services/load_balancer/v2/amphora_client.py
+++ b/octavia_tempest_plugin/services/load_balancer/v2/amphora_client.py
@@ -16,6 +16,7 @@
from tempest import config
+from octavia_tempest_plugin.common.decorators import skip_if_not_implemented
from octavia_tempest_plugin.services.load_balancer.v2 import base_client
CONF = config.CONF
@@ -28,6 +29,7 @@
stats_root_tag = 'amphora_stats'
base_uri = '/v2.0/octavia/{object}'
+ @skip_if_not_implemented
def show_amphora(self, amphora_id, query_params=None,
return_object_only=True):
"""Get amphora details.
@@ -69,6 +71,7 @@
query_params=query_params,
return_object_only=return_object_only)
+ @skip_if_not_implemented
def list_amphorae(self, query_params=None, return_object_only=True):
"""Get a list of amphora objects.
@@ -107,6 +110,7 @@
return self._list_objects(query_params=query_params,
return_object_only=return_object_only)
+ @skip_if_not_implemented
def get_amphora_stats(self, amphora_id, query_params=None,
return_object_only=True):
"""Get amphora statistics.
@@ -158,6 +162,7 @@
else:
return jsonutils.loads(body.decode('utf-8'))
+ @skip_if_not_implemented
def update_amphora_config(self, amphora_id):
"""Update the amphora agent configuration.
@@ -193,6 +198,7 @@
response, body = self.put(uri, '')
self.expected_success(202, response.status)
+ @skip_if_not_implemented
def amphora_failover(self, amphora_id):
"""Failover an amphora.
diff --git a/octavia_tempest_plugin/services/load_balancer/v2/availability_zone_capabilities_client.py b/octavia_tempest_plugin/services/load_balancer/v2/availability_zone_capabilities_client.py
index 92696a7..679af74 100644
--- a/octavia_tempest_plugin/services/load_balancer/v2/availability_zone_capabilities_client.py
+++ b/octavia_tempest_plugin/services/load_balancer/v2/availability_zone_capabilities_client.py
@@ -14,6 +14,7 @@
# under the License.
#
+from octavia_tempest_plugin.common.decorators import skip_if_not_implemented
from octavia_tempest_plugin.services.load_balancer.v2 import base_client
from octavia_tempest_plugin.services.load_balancer.v2 import provider_client
@@ -36,6 +37,7 @@
object=self.list_root_tag
)
+ @skip_if_not_implemented
def list_availability_zone_capabilities(self, provider, query_params=None,
return_object_only=True):
"""Get a list of provider availability zone capability objects.
diff --git a/octavia_tempest_plugin/services/load_balancer/v2/availability_zone_client.py b/octavia_tempest_plugin/services/load_balancer/v2/availability_zone_client.py
index c729f21..ab87a85 100644
--- a/octavia_tempest_plugin/services/load_balancer/v2/availability_zone_client.py
+++ b/octavia_tempest_plugin/services/load_balancer/v2/availability_zone_client.py
@@ -16,6 +16,7 @@
from oslo_log import log as logging
from tempest.lib import exceptions
+from octavia_tempest_plugin.common.decorators import skip_if_not_implemented
from octavia_tempest_plugin.services.load_balancer.v2 import base_client
LOG = logging.getLogger(__name__)
@@ -33,6 +34,7 @@
super(AvailabilityZoneClient, self).__init__(*args, **kwargs)
self.uri = self.base_uri.format(object=self.resource_path)
+ @skip_if_not_implemented
def create_availability_zone(self, name, availability_zone_profile_id,
description=Unset, enabled=Unset,
return_object_only=True):
@@ -75,6 +77,7 @@
if arg != 'self' and value is not Unset}
return self._create_object(**kwargs)
+ @skip_if_not_implemented
def show_availability_zone(self, availability_zone_name, query_params=None,
return_object_only=True):
"""Get the availability zone details.
@@ -116,6 +119,7 @@
query_params=query_params,
return_object_only=return_object_only)
+ @skip_if_not_implemented
def list_availability_zones(self, query_params=None,
return_object_only=True):
"""Get a list of availability zone objects.
@@ -155,6 +159,7 @@
return self._list_objects(query_params=query_params,
return_object_only=return_object_only)
+ @skip_if_not_implemented
def update_availability_zone(self, availability_zone_name,
description=Unset, enabled=Unset,
return_object_only=True):
@@ -195,6 +200,7 @@
kwargs['obj_id'] = kwargs.pop('availability_zone_name')
return self._update_object(**kwargs)
+ @skip_if_not_implemented
def delete_availability_zone(self, availability_zone_name,
ignore_errors=False):
"""Delete an availability zone.
diff --git a/octavia_tempest_plugin/services/load_balancer/v2/availability_zone_profile_client.py b/octavia_tempest_plugin/services/load_balancer/v2/availability_zone_profile_client.py
index 1aaab90..071b15f 100644
--- a/octavia_tempest_plugin/services/load_balancer/v2/availability_zone_profile_client.py
+++ b/octavia_tempest_plugin/services/load_balancer/v2/availability_zone_profile_client.py
@@ -16,6 +16,7 @@
from oslo_log import log as logging
from tempest.lib import exceptions
+from octavia_tempest_plugin.common.decorators import skip_if_not_implemented
from octavia_tempest_plugin.services.load_balancer.v2 import base_client
LOG = logging.getLogger(__name__)
@@ -33,6 +34,7 @@
super(AvailabilityZoneProfileClient, self).__init__(*args, **kwargs)
self.uri = self.base_uri.format(object=self.resource_path)
+ @skip_if_not_implemented
def create_availability_zone_profile(self, name, provider_name,
availability_zone_data,
return_object_only=True):
@@ -73,6 +75,7 @@
if arg != 'self' and value is not Unset}
return self._create_object(**kwargs)
+ @skip_if_not_implemented
def show_availability_zone_profile(self, availability_zone_profile_id,
query_params=None,
return_object_only=True):
@@ -116,6 +119,7 @@
query_params=query_params,
return_object_only=return_object_only)
+ @skip_if_not_implemented
def list_availability_zone_profiles(self, query_params=None,
return_object_only=True):
"""Get a list of availability zone profile objects.
@@ -155,6 +159,7 @@
return self._list_objects(query_params=query_params,
return_object_only=return_object_only)
+ @skip_if_not_implemented
def update_availability_zone_profile(
self, availability_zone_profile_id, name=Unset,
provider_name=Unset, availability_zone_data=Unset,
@@ -199,6 +204,7 @@
kwargs['obj_id'] = kwargs.pop('availability_zone_profile_id')
return self._update_object(**kwargs)
+ @skip_if_not_implemented
def delete_availability_zone_profile(self, availability_zone_profile_id,
ignore_errors=False):
"""Delete an availability zone profile.
diff --git a/octavia_tempest_plugin/services/load_balancer/v2/flavor_capabilities_client.py b/octavia_tempest_plugin/services/load_balancer/v2/flavor_capabilities_client.py
index 4c23042..eb07faf 100644
--- a/octavia_tempest_plugin/services/load_balancer/v2/flavor_capabilities_client.py
+++ b/octavia_tempest_plugin/services/load_balancer/v2/flavor_capabilities_client.py
@@ -13,6 +13,7 @@
# under the License.
#
+from octavia_tempest_plugin.common.decorators import skip_if_not_implemented
from octavia_tempest_plugin.services.load_balancer.v2 import base_client
from octavia_tempest_plugin.services.load_balancer.v2 import provider_client
@@ -34,6 +35,7 @@
object=self.list_root_tag
)
+ @skip_if_not_implemented
def list_flavor_capabilities(self, provider, query_params=None,
return_object_only=True):
"""Get a list of provider flavor capability objects.
diff --git a/octavia_tempest_plugin/services/load_balancer/v2/flavor_client.py b/octavia_tempest_plugin/services/load_balancer/v2/flavor_client.py
index 085da9e..8a87a33 100644
--- a/octavia_tempest_plugin/services/load_balancer/v2/flavor_client.py
+++ b/octavia_tempest_plugin/services/load_balancer/v2/flavor_client.py
@@ -16,6 +16,7 @@
from oslo_log import log as logging
from tempest.lib import exceptions
+from octavia_tempest_plugin.common.decorators import skip_if_not_implemented
from octavia_tempest_plugin.services.load_balancer.v2 import base_client
LOG = logging.getLogger(__name__)
@@ -27,6 +28,7 @@
root_tag = 'flavor'
list_root_tag = 'flavors'
+ @skip_if_not_implemented
def create_flavor(self, name, flavor_profile_id, description=Unset,
enabled=Unset, return_object_only=True):
"""Create a flavor.
@@ -67,6 +69,7 @@
if arg != 'self' and value is not Unset}
return self._create_object(**kwargs)
+ @skip_if_not_implemented
def show_flavor(self, flavor_id, query_params=None,
return_object_only=True):
"""Get the flavor details.
@@ -108,6 +111,7 @@
query_params=query_params,
return_object_only=return_object_only)
+ @skip_if_not_implemented
def list_flavors(self, query_params=None, return_object_only=True):
"""Get a list of flavor objects.
@@ -146,6 +150,7 @@
return self._list_objects(query_params=query_params,
return_object_only=return_object_only)
+ @skip_if_not_implemented
def update_flavor(self, flavor_id, name=Unset, description=Unset,
enabled=Unset, return_object_only=True):
"""Update a flavor.
@@ -186,6 +191,7 @@
kwargs['obj_id'] = kwargs.pop('flavor_id')
return self._update_object(**kwargs)
+ @skip_if_not_implemented
def delete_flavor(self, flavor_id, ignore_errors=False):
"""Delete a flavor.
diff --git a/octavia_tempest_plugin/services/load_balancer/v2/flavor_profile_client.py b/octavia_tempest_plugin/services/load_balancer/v2/flavor_profile_client.py
index 811cff8..bc0f2fb 100644
--- a/octavia_tempest_plugin/services/load_balancer/v2/flavor_profile_client.py
+++ b/octavia_tempest_plugin/services/load_balancer/v2/flavor_profile_client.py
@@ -16,6 +16,7 @@
from oslo_log import log as logging
from tempest.lib import exceptions
+from octavia_tempest_plugin.common.decorators import skip_if_not_implemented
from octavia_tempest_plugin.services.load_balancer.v2 import base_client
LOG = logging.getLogger(__name__)
@@ -27,6 +28,7 @@
root_tag = 'flavorprofile'
list_root_tag = 'flavorprofiles'
+ @skip_if_not_implemented
def create_flavor_profile(self, name, provider_name, flavor_data,
return_object_only=True):
"""Create a flavor profile.
@@ -65,6 +67,7 @@
if arg != 'self' and value is not Unset}
return self._create_object(**kwargs)
+ @skip_if_not_implemented
def show_flavor_profile(self, flavorprofile_id, query_params=None,
return_object_only=True):
"""Get the flavor profile details.
@@ -106,6 +109,7 @@
query_params=query_params,
return_object_only=return_object_only)
+ @skip_if_not_implemented
def list_flavor_profiles(self, query_params=None, return_object_only=True):
"""Get a list of flavor profile objects.
@@ -144,6 +148,7 @@
return self._list_objects(query_params=query_params,
return_object_only=return_object_only)
+ @skip_if_not_implemented
def update_flavor_profile(
self, flavorprofile_id, name=Unset, provider_name=Unset,
flavor_data=Unset, return_object_only=True):
@@ -185,6 +190,7 @@
kwargs['obj_id'] = kwargs.pop('flavorprofile_id')
return self._update_object(**kwargs)
+ @skip_if_not_implemented
def delete_flavor_profile(self, flavorprofile_id, ignore_errors=False):
"""Delete a flavor profile.
diff --git a/octavia_tempest_plugin/services/load_balancer/v2/healthmonitor_client.py b/octavia_tempest_plugin/services/load_balancer/v2/healthmonitor_client.py
index a7d2e6b..4ce362e 100644
--- a/octavia_tempest_plugin/services/load_balancer/v2/healthmonitor_client.py
+++ b/octavia_tempest_plugin/services/load_balancer/v2/healthmonitor_client.py
@@ -14,6 +14,7 @@
from tempest import config
+from octavia_tempest_plugin.common.decorators import skip_if_not_implemented
from octavia_tempest_plugin.services.load_balancer.v2 import base_client
CONF = config.CONF
@@ -26,6 +27,7 @@
list_root_tag = 'healthmonitors'
resource_name = 'healthmonitor'
+ @skip_if_not_implemented
def create_healthmonitor(self, pool_id, type, delay, timeout, max_retries,
max_retries_down=Unset, name=Unset, tags=Unset,
http_method=Unset, url_path=Unset,
@@ -87,6 +89,7 @@
if arg != 'self' and value is not Unset}
return self._create_object(**kwargs)
+ @skip_if_not_implemented
def show_healthmonitor(self, healthmonitor_id, query_params=None,
return_object_only=True):
"""Get healthmonitor details.
@@ -128,6 +131,7 @@
query_params=query_params,
return_object_only=return_object_only)
+ @skip_if_not_implemented
def list_healthmonitors(self, query_params=None, return_object_only=True):
"""Get a list of healthmonitor objects.
@@ -166,6 +170,7 @@
return self._list_objects(query_params=query_params,
return_object_only=return_object_only)
+ @skip_if_not_implemented
def update_healthmonitor(self, healthmonitor_id, delay=Unset,
timeout=Unset, max_retries=Unset,
max_retries_down=Unset, name=Unset, tags=Unset,
@@ -228,6 +233,7 @@
kwargs['obj_id'] = kwargs.pop('healthmonitor_id')
return self._update_object(**kwargs)
+ @skip_if_not_implemented
def delete_healthmonitor(self, healthmonitor_id, ignore_errors=False):
"""Delete a healthmonitor.
diff --git a/octavia_tempest_plugin/services/load_balancer/v2/l7policy_client.py b/octavia_tempest_plugin/services/load_balancer/v2/l7policy_client.py
index 1feb72f..36eef40 100644
--- a/octavia_tempest_plugin/services/load_balancer/v2/l7policy_client.py
+++ b/octavia_tempest_plugin/services/load_balancer/v2/l7policy_client.py
@@ -14,6 +14,7 @@
from tempest import config
+from octavia_tempest_plugin.common.decorators import skip_if_not_implemented
from octavia_tempest_plugin.services.load_balancer.v2 import base_client
CONF = config.CONF
@@ -26,6 +27,7 @@
list_root_tag = 'l7policies'
resource_name = 'l7policy'
+ @skip_if_not_implemented
def create_l7policy(self, listener_id, action, name=Unset,
description=Unset, tags=Unset, admin_state_up=Unset,
position=Unset, redirect_pool_id=Unset,
@@ -78,6 +80,7 @@
if arg != 'self' and value is not Unset}
return self._create_object(**kwargs)
+ @skip_if_not_implemented
def show_l7policy(self, l7policy_id, query_params=None,
return_object_only=True):
"""Get l7policy details.
@@ -119,6 +122,7 @@
query_params=query_params,
return_object_only=return_object_only)
+ @skip_if_not_implemented
def list_l7policies(self, query_params=None, return_object_only=True):
"""Get a list of l7policy objects.
@@ -157,6 +161,7 @@
return self._list_objects(query_params=query_params,
return_object_only=return_object_only)
+ @skip_if_not_implemented
def update_l7policy(self, l7policy_id, action=Unset, name=Unset,
description=Unset, tags=Unset, admin_state_up=Unset,
position=Unset, redirect_pool_id=Unset,
@@ -210,6 +215,7 @@
kwargs['obj_id'] = kwargs.pop('l7policy_id')
return self._update_object(**kwargs)
+ @skip_if_not_implemented
def delete_l7policy(self, l7policy_id, ignore_errors=False):
"""Delete a l7policy.
diff --git a/octavia_tempest_plugin/services/load_balancer/v2/l7rule_client.py b/octavia_tempest_plugin/services/load_balancer/v2/l7rule_client.py
index be5434d..da40af2 100644
--- a/octavia_tempest_plugin/services/load_balancer/v2/l7rule_client.py
+++ b/octavia_tempest_plugin/services/load_balancer/v2/l7rule_client.py
@@ -14,6 +14,7 @@
from tempest import config
+from octavia_tempest_plugin.common.decorators import skip_if_not_implemented
from octavia_tempest_plugin.services.load_balancer.v2 import base_client
from octavia_tempest_plugin.services.load_balancer.v2 import l7policy_client
@@ -38,6 +39,7 @@
object=self.list_root_tag
)
+ @skip_if_not_implemented
def create_l7rule(self, l7policy_id, type, value, compare_type, tags=Unset,
admin_state_up=Unset, key=Unset, invert=Unset,
return_object_only=True):
@@ -87,6 +89,7 @@
kwargs['parent_id'] = kwargs.pop('l7policy_id')
return self._create_object(**kwargs)
+ @skip_if_not_implemented
def show_l7rule(self, l7rule_id, l7policy_id, query_params=None,
return_object_only=True):
"""Get l7rule details.
@@ -130,6 +133,7 @@
query_params=query_params,
return_object_only=return_object_only)
+ @skip_if_not_implemented
def list_l7rules(self, l7policy_id, query_params=None,
return_object_only=True):
"""Get a list of l7rule objects.
@@ -171,6 +175,7 @@
query_params=query_params,
return_object_only=return_object_only)
+ @skip_if_not_implemented
def update_l7rule(self, l7rule_id, l7policy_id, type=Unset, value=Unset,
compare_type=Unset, tags=Unset, admin_state_up=Unset,
key=Unset, invert=Unset, return_object_only=True):
@@ -222,6 +227,7 @@
kwargs['parent_id'] = kwargs.pop('l7policy_id')
return self._update_object(**kwargs)
+ @skip_if_not_implemented
def delete_l7rule(self, l7rule_id, l7policy_id, ignore_errors=False):
"""Delete a l7rule.
diff --git a/octavia_tempest_plugin/services/load_balancer/v2/listener_client.py b/octavia_tempest_plugin/services/load_balancer/v2/listener_client.py
index eb7690a..c059a84 100644
--- a/octavia_tempest_plugin/services/load_balancer/v2/listener_client.py
+++ b/octavia_tempest_plugin/services/load_balancer/v2/listener_client.py
@@ -17,6 +17,7 @@
from tempest import config
+from octavia_tempest_plugin.common.decorators import skip_if_not_implemented
from octavia_tempest_plugin.services.load_balancer.v2 import base_client
CONF = config.CONF
@@ -28,6 +29,7 @@
root_tag = 'listener'
list_root_tag = 'listeners'
+ @skip_if_not_implemented
def create_listener(self, protocol, protocol_port, loadbalancer_id,
name=Unset, description=Unset, tags=Unset,
admin_state_up=Unset, connection_limit=Unset,
@@ -120,6 +122,7 @@
if arg != 'self' and value is not Unset}
return self._create_object(**kwargs)
+ @skip_if_not_implemented
def show_listener(self, listener_id, query_params=None,
return_object_only=True):
"""Get listener details.
@@ -161,6 +164,7 @@
query_params=query_params,
return_object_only=return_object_only)
+ @skip_if_not_implemented
def list_listeners(self, query_params=None, return_object_only=True):
"""Get a list of listener objects.
@@ -199,6 +203,7 @@
return self._list_objects(query_params=query_params,
return_object_only=return_object_only)
+ @skip_if_not_implemented
def update_listener(self, listener_id, name=Unset, description=Unset,
tags=Unset, admin_state_up=Unset,
connection_limit=Unset, timeout_client_data=Unset,
@@ -289,6 +294,7 @@
kwargs['obj_id'] = kwargs.pop('listener_id')
return self._update_object(**kwargs)
+ @skip_if_not_implemented
def delete_listener(self, listener_id, ignore_errors=False):
"""Delete a listener.
@@ -325,6 +331,7 @@
return self._delete_obj(obj_id=listener_id,
ignore_errors=ignore_errors)
+ @skip_if_not_implemented
def get_listener_stats(self, listener_id, query_params=None,
return_object_only=True):
"""Get listener statistics.
diff --git a/octavia_tempest_plugin/services/load_balancer/v2/loadbalancer_client.py b/octavia_tempest_plugin/services/load_balancer/v2/loadbalancer_client.py
index 0fafbf2..9499d89 100644
--- a/octavia_tempest_plugin/services/load_balancer/v2/loadbalancer_client.py
+++ b/octavia_tempest_plugin/services/load_balancer/v2/loadbalancer_client.py
@@ -17,6 +17,7 @@
from tempest import config
+from octavia_tempest_plugin.common.decorators import skip_if_not_implemented
from octavia_tempest_plugin.services.load_balancer.v2 import base_client
CONF = config.CONF
@@ -34,6 +35,7 @@
self.timeout = CONF.load_balancer.lb_build_timeout
self.build_interval = CONF.load_balancer.lb_build_interval
+ @skip_if_not_implemented
def create_loadbalancer(self, name=Unset, description=Unset,
admin_state_up=Unset, flavor_id=Unset,
listeners=Unset, project_id=Unset, provider=Unset,
@@ -92,6 +94,7 @@
if arg != 'self' and value is not Unset}
return self._create_object(**kwargs)
+ @skip_if_not_implemented
def show_loadbalancer(self, lb_id, query_params=None,
return_object_only=True):
"""Get loadbalancer details.
@@ -133,6 +136,7 @@
query_params=query_params,
return_object_only=return_object_only)
+ @skip_if_not_implemented
def list_loadbalancers(self, query_params=None, return_object_only=True):
"""Get a list of loadbalancer objects.
@@ -171,6 +175,7 @@
return self._list_objects(query_params=query_params,
return_object_only=return_object_only)
+ @skip_if_not_implemented
def update_loadbalancer(self, lb_id, name=Unset, description=Unset,
tags=Unset, admin_state_up=Unset,
vip_qos_policy_id=Unset,
@@ -220,6 +225,7 @@
kwargs['obj_id'] = kwargs.pop('lb_id')
return self._update_object(**kwargs)
+ @skip_if_not_implemented
def delete_loadbalancer(self, lb_id, cascade=False, ignore_errors=False):
"""Delete a loadbalancer.
@@ -259,6 +265,7 @@
ignore_errors=ignore_errors,
cascade=cascade)
+ @skip_if_not_implemented
def failover_loadbalancer(self, lb_id):
"""Failover a loadbalancer.
@@ -295,6 +302,7 @@
self.expected_success(202, response.status)
return
+ @skip_if_not_implemented
def get_loadbalancer_stats(self, lb_id, query_params=None,
return_object_only=True):
"""Get loadbalancer statistics.
@@ -345,6 +353,7 @@
else:
return jsonutils.loads(body.decode('utf-8'))
+ @skip_if_not_implemented
def get_loadbalancer_status(self, lb_id, query_params=None,
return_object_only=True):
"""Get a loadbalancer status tree.
diff --git a/octavia_tempest_plugin/services/load_balancer/v2/member_client.py b/octavia_tempest_plugin/services/load_balancer/v2/member_client.py
index 0f0d639..c0d83da 100644
--- a/octavia_tempest_plugin/services/load_balancer/v2/member_client.py
+++ b/octavia_tempest_plugin/services/load_balancer/v2/member_client.py
@@ -16,6 +16,7 @@
from oslo_serialization import jsonutils
from tempest import config
+from octavia_tempest_plugin.common.decorators import skip_if_not_implemented
from octavia_tempest_plugin.services.load_balancer.v2 import base_client
from octavia_tempest_plugin.services.load_balancer.v2 import pool_client
@@ -39,6 +40,7 @@
object=self.list_root_tag
)
+ @skip_if_not_implemented
def create_member(self, pool_id, address, protocol_port,
name=Unset, tags=Unset, admin_state_up=Unset,
weight=Unset,
@@ -98,6 +100,7 @@
kwargs['parent_id'] = kwargs.pop('pool_id')
return self._create_object(**kwargs)
+ @skip_if_not_implemented
def show_member(self, member_id, pool_id, query_params=None,
return_object_only=True):
"""Get member details.
@@ -141,6 +144,7 @@
query_params=query_params,
return_object_only=return_object_only)
+ @skip_if_not_implemented
def list_members(self, pool_id, query_params=None,
return_object_only=True):
"""Get a list of member objects.
@@ -182,6 +186,7 @@
query_params=query_params,
return_object_only=return_object_only)
+ @skip_if_not_implemented
def update_member(self, member_id, pool_id, name=Unset, tags=Unset,
admin_state_up=Unset, weight=Unset, backup=Unset,
monitor_address=Unset, monitor_port=Unset,
@@ -238,6 +243,7 @@
kwargs['parent_id'] = kwargs.pop('pool_id')
return self._update_object(**kwargs)
+ @skip_if_not_implemented
def update_members(self, pool_id, members_list):
"""Batch update all members on a pool.
@@ -277,6 +283,7 @@
self.expected_success(202, response.status)
return
+ @skip_if_not_implemented
def delete_member(self, member_id, pool_id, ignore_errors=False):
"""Delete a member.
diff --git a/octavia_tempest_plugin/services/load_balancer/v2/pool_client.py b/octavia_tempest_plugin/services/load_balancer/v2/pool_client.py
index 58db1af..98f4bfa 100644
--- a/octavia_tempest_plugin/services/load_balancer/v2/pool_client.py
+++ b/octavia_tempest_plugin/services/load_balancer/v2/pool_client.py
@@ -14,6 +14,7 @@
from tempest import config
+from octavia_tempest_plugin.common.decorators import skip_if_not_implemented
from octavia_tempest_plugin.services.load_balancer.v2 import base_client
CONF = config.CONF
@@ -26,6 +27,7 @@
list_root_tag = 'pools'
resource_name = 'pool'
+ @skip_if_not_implemented
def create_pool(self, protocol, lb_algorithm, loadbalancer_id=Unset,
listener_id=Unset, name=Unset, description=Unset,
tags=Unset,
@@ -79,6 +81,7 @@
if arg != 'self' and value is not Unset}
return self._create_object(**kwargs)
+ @skip_if_not_implemented
def show_pool(self, pool_id, query_params=None, return_object_only=True):
"""Get pool details.
@@ -119,6 +122,7 @@
query_params=query_params,
return_object_only=return_object_only)
+ @skip_if_not_implemented
def list_pools(self, query_params=None, return_object_only=True):
"""Get a list of pool objects.
@@ -157,6 +161,7 @@
return self._list_objects(query_params=query_params,
return_object_only=return_object_only)
+ @skip_if_not_implemented
def update_pool(self, pool_id, lb_algorithm=Unset, name=Unset,
description=Unset, tags=Unset, admin_state_up=Unset,
session_persistence=Unset, return_object_only=True):
@@ -207,6 +212,7 @@
kwargs['obj_id'] = kwargs.pop('pool_id')
return self._update_object(**kwargs)
+ @skip_if_not_implemented
def delete_pool(self, pool_id, ignore_errors=False):
"""Delete a pool.
diff --git a/octavia_tempest_plugin/services/load_balancer/v2/provider_client.py b/octavia_tempest_plugin/services/load_balancer/v2/provider_client.py
index cbef1df..319826e 100644
--- a/octavia_tempest_plugin/services/load_balancer/v2/provider_client.py
+++ b/octavia_tempest_plugin/services/load_balancer/v2/provider_client.py
@@ -13,6 +13,7 @@
# under the License.
#
+from octavia_tempest_plugin.common.decorators import skip_if_not_implemented
from octavia_tempest_plugin.services.load_balancer.v2 import base_client
Unset = base_client.Unset
@@ -22,6 +23,7 @@
list_root_tag = 'providers'
+ @skip_if_not_implemented
def list_providers(self, query_params=None, return_object_only=True):
"""Get a list of provider objects.
diff --git a/requirements.txt b/requirements.txt
index b30b450..e5b93b8 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -16,4 +16,5 @@
six>=1.10.0 # MIT
tempest>=17.1.0 # Apache-2.0
tenacity>=4.4.0 # Apache-2.0
+testtools>=2.2.0 # MIT
keystoneauth1>=3.3.0 # Apache-2.0