From ef98859628a32e96d7478bf4d746781c055cada5 Mon Sep 17 00:00:00 2001 From: Nir Magnezi Date: Sun, 18 Mar 2018 22:47:30 +0200 Subject: [PATCH] Port CreateAndListLoadbalancers for Octavia Ia7a83ebe37a49e58400620b7ed3dedac209664f8 added Octavia client support. This patch merely ports the existing load balancer (v2) scenario to use Octavia as an OpenStack top-level project. The follow-up patch would be additional CRUD scenarios for load balancer objects such as load balancer (some actions currently missing), Pools, Health Monitors etc. Change-Id: Ia865bbe72bfcfa9d96d7f4b628d8c2e1758d7007 (cherry picked from commit d4f5d1eacffd49fb89fab700e6eb13c9a7cdd24c) Co-Authored-By: Chuck Short --- CHANGELOG.rst | 1 + rally-jobs/load-balancing.yaml | 18 + rally_openstack/cfg/octavia.py | 28 + rally_openstack/cfg/opts.py | 3 +- rally_openstack/cleanup/resources.py | 29 + rally_openstack/consts.py | 5 +- rally_openstack/scenarios/octavia/__init__.py | 0 .../scenarios/octavia/loadbalancers.py | 59 ++ .../services/loadbalancer/__init__.py | 0 .../services/loadbalancer/octavia.py | 590 ++++++++++++++++++ samples/tasks/contexts/loadbalancers.json | 39 ++ samples/tasks/contexts/loadbalancers.yaml | 26 + ...octavia-create-and-list-loadbalancers.json | 24 + ...octavia-create-and-list-loadbalancers.yaml | 17 + tests/unit/cleanup/test_resources.py | 50 ++ tests/unit/fakes.py | 4 + tests/unit/scenarios/loadbalancer/__init__.py | 0 .../loadbalancer/test_loadbalancers.py | 58 ++ .../unit/scenarios/loadbalancer/test_utils.py | 47 ++ tests/unit/services/loadbalancer/__init__.py | 0 .../services/loadbalancer/test_octavia.py | 400 ++++++++++++ 21 files changed, 1396 insertions(+), 2 deletions(-) create mode 100644 rally_openstack/cfg/octavia.py create mode 100644 rally_openstack/scenarios/octavia/__init__.py create mode 100644 rally_openstack/scenarios/octavia/loadbalancers.py create mode 100644 rally_openstack/services/loadbalancer/__init__.py create mode 100644 rally_openstack/services/loadbalancer/octavia.py create mode 100644 samples/tasks/contexts/loadbalancers.json create mode 100644 samples/tasks/contexts/loadbalancers.yaml create mode 100644 samples/tasks/scenarios/octavia/octavia-create-and-list-loadbalancers.json create mode 100644 samples/tasks/scenarios/octavia/octavia-create-and-list-loadbalancers.yaml create mode 100644 tests/unit/scenarios/loadbalancer/__init__.py create mode 100644 tests/unit/scenarios/loadbalancer/test_loadbalancers.py create mode 100644 tests/unit/scenarios/loadbalancer/test_utils.py create mode 100644 tests/unit/services/loadbalancer/__init__.py create mode 100644 tests/unit/services/loadbalancer/test_octavia.py diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 2cc9a059..3ad7d1e1 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -24,6 +24,7 @@ Added * Added neutron trunk scenarios * Added barbican scenarios. +* Added octavia scenarios. Changed ~~~~~~~ diff --git a/rally-jobs/load-balancing.yaml b/rally-jobs/load-balancing.yaml index ae191762..dfe12cd2 100644 --- a/rally-jobs/load-balancing.yaml +++ b/rally-jobs/load-balancing.yaml @@ -20,3 +20,21 @@ sla: failure_rate: max: 0 + - + title: Test base Octavia actions + workloads: + - + scenario: + Octavia.create_and_list_loadbalancers: {} + runner: + constant: + times: 2 + concurrency: 2 + contexts: + users: + tenants: 2 + roles: ["load-balancer_member"] + network: {} + sla: + failure_rate: + max: 0 diff --git a/rally_openstack/cfg/octavia.py b/rally_openstack/cfg/octavia.py new file mode 100644 index 00000000..42808fe9 --- /dev/null +++ b/rally_openstack/cfg/octavia.py @@ -0,0 +1,28 @@ +# Copyright 2018: 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 rally.common import cfg + +OPTS = {"openstack": [ + cfg.FloatOpt("octavia_create_loadbalancer_timeout", + default=float(500.0), + help="Octavia create loadbalancer timeout"), + cfg.FloatOpt("octavia_delete_loadbalancer_timeout", + default=float(50.0), + help="Octavia delete loadbalancer timeout"), + cfg.FloatOpt("octavia_create_loadbalancer_poll_interval", + default=float(2.0), + help="Octavia create loadbalancer poll interval") +]} diff --git a/rally_openstack/cfg/opts.py b/rally_openstack/cfg/opts.py index 93dce004..5bb27328 100644 --- a/rally_openstack/cfg/opts.py +++ b/rally_openstack/cfg/opts.py @@ -25,6 +25,7 @@ from rally_openstack.cfg import monasca from rally_openstack.cfg import murano from rally_openstack.cfg import neutron from rally_openstack.cfg import nova +from rally_openstack.cfg import octavia from rally_openstack.cfg import osclients from rally_openstack.cfg import profiler from rally_openstack.cfg import sahara @@ -48,7 +49,7 @@ def list_opts(): nova.OPTS, osclients.OPTS, profiler.OPTS, sahara.OPTS, vm.OPTS, glance.OPTS, watcher.OPTS, tempest.OPTS, keystone_roles.OPTS, keystone_users.OPTS, cleanup.OPTS, - senlin.OPTS, neutron.OPTS): + senlin.OPTS, neutron.OPTS, octavia.OPTS): for category, opt in l_opts.items(): opts.setdefault(category, []) opts[category].extend(opt) diff --git a/rally_openstack/cleanup/resources.py b/rally_openstack/cleanup/resources.py index f8f56924..6263353d 100644 --- a/rally_openstack/cleanup/resources.py +++ b/rally_openstack/cleanup/resources.py @@ -21,6 +21,7 @@ from rally_openstack.cleanup import base from rally_openstack.services.identity import identity from rally_openstack.services.image import glance_v2 from rally_openstack.services.image import image +from rally_openstack.services.loadbalancer import octavia CONF = cfg.CONF @@ -323,6 +324,34 @@ class NeutronV2Loadbalancer(NeutronLbaasV2Mixin): return False +@base.resource("octavia", "loadbalancer", order=next(_neutron_order), + tenant_resource=True) +class OctaviaLoadbalancer(base.ResourceManager): + + def _client(self): + return octavia.Octavia(self.admin or self.user) + + def id(self): + return self.raw_resource["id"] + + def name(self): + return self.raw_resource["name"] + + def delete(self): + return self._client().load_balancer_delete(self.id()) + + def is_deleted(self): + try: + self._client().load_balancer_show(self.id()) + except Exception as e: + return True + + return False + + def list(self): + return self._client().load_balancer_list()["loadbalancers"] + + @base.resource("neutron", "bgpvpn", order=next(_neutron_order), admin_required=True, perform_for_admin_only=True) class NeutronBgpvpn(NeutronMixin): diff --git a/rally_openstack/consts.py b/rally_openstack/consts.py index ca657593..062f1329 100644 --- a/rally_openstack/consts.py +++ b/rally_openstack/consts.py @@ -68,6 +68,7 @@ class _Service(utils.ImmutableMixin, utils.EnumMixin): MAGNUM = "magnum" WATCHER = "watcher" BARBICAN = "barbican" + OCTAVIA = "octavia" class _ServiceType(utils.ImmutableMixin, utils.EnumMixin): @@ -100,6 +101,7 @@ class _ServiceType(utils.ImmutableMixin, utils.EnumMixin): CONTAINER_INFRA = "container-infra" INFRA_OPTIM = "infra-optim" KEY_MANAGER = "key-manager" + LOAD_BALANCER = "load-balancer" def __init__(self): self.__names = { @@ -129,7 +131,8 @@ class _ServiceType(utils.ImmutableMixin, utils.EnumMixin): self.METRIC: _Service.GNOCCHI, self.CONTAINER_INFRA: _Service.MAGNUM, self.INFRA_OPTIM: _Service.WATCHER, - self.KEY_MANAGER: _Service.BARBICAN + self.KEY_MANAGER: _Service.BARBICAN, + self.LOAD_BALANCER: _Service.OCTAVIA } def __getitem__(self, service_type): diff --git a/rally_openstack/scenarios/octavia/__init__.py b/rally_openstack/scenarios/octavia/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/rally_openstack/scenarios/octavia/loadbalancers.py b/rally_openstack/scenarios/octavia/loadbalancers.py new file mode 100644 index 00000000..d0b740c5 --- /dev/null +++ b/rally_openstack/scenarios/octavia/loadbalancers.py @@ -0,0 +1,59 @@ +# Copyright 2018: 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 rally.task import validation + +from rally_openstack import consts +from rally_openstack import scenario +from rally_openstack.services.loadbalancer import octavia + +"""Scenarios for Octavia Loadbalancer.""" + + +class OctaviaBase(scenario.OpenStackScenario): + """Base class for Octavia scenarios with basic atomic actions.""" + + def __init__(self, context=None, admin_clients=None, clients=None): + super(OctaviaBase, self).__init__(context, admin_clients, clients) + self.octavia = octavia.Octavia( + self._clients, name_generator=self.generate_random_name, + atomic_inst=self.atomic_actions()) + + +@validation.add("required_services", services=[consts.Service.OCTAVIA]) +@validation.add("required_platform", platform="openstack", users=True) +@validation.add("required_contexts", contexts=["network"]) +@scenario.configure(context={"cleanup@openstack": ["octavia"]}, + name="Octavia.create_and_list_loadbalancers", + platform="openstack") +class CreateAndListLoadbalancers(OctaviaBase): + + def run(self): + """Create a loadbalancer per each subnet and then list loadbalancers. + + Measure the "Octavia loadbalancer list" command performance. + The scenario creates a loadbalancer for every subnet and then lists + loadbalancers. + """ + loadbalancers = [] + networks = self.context.get("tenant", {}).get("networks", []) + for network in networks: + for subnet_id in network.get("subnets", []): + lb = self.octavia.load_balancer_create(subnet_id) + loadbalancers.append(lb) + + for loadbalancer in loadbalancers: + self.octavia.wait_for_loadbalancer_prov_status(loadbalancer) + self.octavia.load_balancer_list() diff --git a/rally_openstack/services/loadbalancer/__init__.py b/rally_openstack/services/loadbalancer/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/rally_openstack/services/loadbalancer/octavia.py b/rally_openstack/services/loadbalancer/octavia.py new file mode 100644 index 00000000..7baccfb5 --- /dev/null +++ b/rally_openstack/services/loadbalancer/octavia.py @@ -0,0 +1,590 @@ +# Copyright 2018 Red Hat, Inc. +# +# 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 rally.common import cfg +from rally.common import logging +from rally import exceptions +from rally.task import atomic +from rally.task import service +from rally.task import utils + +CONF = cfg.CONF + +LOG = logging.getLogger(__name__) + + +class Octavia(service.Service): + + @atomic.action_timer("octavia.load_balancer_list") + def load_balancer_list(self): + """List all load balancers + + :return: + List of load balancers + """ + return self._clients.octavia().load_balancer_list() + + @atomic.action_timer("octavia.load_balancer_show") + def load_balancer_show(self, lb_id): + """Show a load balancer + + :param string lb_id: + ID of the load balancer to show + :return: + A dict of the specified load balancer's settings + """ + return self._clients.octavia().load_balancer_show(lb_id) + + @atomic.action_timer("octavia.load_balancer_create") + def load_balancer_create(self, subnet_id, params=None): + """Create a load balancer + + :param subnet_id: + The ID of the subnet for the Virtual IP (VIP) + :param params: + Paramaters to create the load balancer with (expects json=) + :return: + A dict of the created load balancer's settings + """ + lb_create_args = { + "name": self.generate_random_name(), + "vip_subnet_id": subnet_id, + "admin_state_up": True + } + if params: + lb_create_args.update(params) + return self._clients.octavia().load_balancer_create( + json={"loadbalancer": lb_create_args}) + + @atomic.action_timer("octavia.load_balancer_delete") + def load_balancer_delete(self, lb_id): + """Delete a load balancer + + :param string lb_id: + The ID of the load balancer to zdelete + :return: + Response Code from the API + """ + return self._clients.octavia().load_balancer_delete(lb_id) + + @atomic.action_timer("octavia.load_balancer_set") + def load_balancer_set(self, lb_id, params): + """Update a load balancer's settings + + :param string lb_id: + The ID of the load balancer to update + :param params: + A dict of arguments to update a loadbalancer + :return: + Response Code from API + """ + return self._clients.octavia().load_balancer_set(lb_id, params) + + @atomic.action_timer("octavia.load_balancer_stats_show") + def load_balancer_stats_show(self, lb_id, **kwargs): + """Shows the current statistics for a load balancer. + + :param string lb_id: + ID of the load balancer + :return: + A dict of the specified load balancer's statistics + """ + return self._clients.octavia().load_balancer_stats_show( + lb_id, **kwargs) + + @atomic.action_timer("octavia.load_balancer_failover") + def load_balancer_failover(self, lb_id): + """Trigger load balancer failover + + :param string lb_id: + ID of the load balancer to failover + :return: + Response Code from the API + """ + return self._clients.octavia().load_balancer_failover(lb_id) + + @atomic.action_timer("octavia.listener_list") + def listener_list(self, **kwargs): + """List all listeners + + :param kwargs: + Parameters to filter on + :return: + List of listeners + """ + return self._clients.octavia().listener_list(**kwargs) + + @atomic.action_timer("octavia.listener_show") + def listener_show(self, listener_id): + """Show a listener + + :param string listener_id: + ID of the listener to show + :return: + A dict of the specified listener's settings + """ + return self._clients.octavia().listener_show(listener_id) + + @atomic.action_timer("octavia.listener_create") + def listener_create(self, **kwargs): + """Create a listener + + :param kwargs: + Parameters to create a listener with (expects json=) + :return: + A dict of the created listener's settings + """ + return self._clients.octavia().listener_create(**kwargs) + + @atomic.action_timer("octavia.listener_delete") + def listener_delete(self, listener_id): + """Delete a listener + + :param stirng listener_id: + ID of of listener to delete + :return: + Response Code from the API + """ + return self._clients.octavia().listener_delete(listener_id) + + @atomic.action_timer("octavia.listener_set") + def listener_set(self, listener_id, **kwargs): + """Update a listener's settings + + :param string listener_id: + ID of the listener to update + :param kwargs: + A dict of arguments to update a listener + :return: + Response Code from the API + """ + return self._clients.octavia().listener_set(listener_id, **kwargs) + + @atomic.action_timer("octavia.listener_stats_show") + def listener_stats_show(self, listener_id, **kwargs): + """Shows the current statistics for a listener + + :param string listener_id: + ID of the listener + :return: + A dict of the specified listener's statistics + """ + return self._clients.octavia().listener_stats_show( + listener_id, **kwargs) + + @atomic.action_timer("octavia.pool_list") + def pool_list(self, **kwargs): + """List all pools + + :param kwargs: + Parameters to filter on + :return: + List of pools + """ + return self._clients.octavia().pool_list(**kwargs) + + @atomic.action_timer("octavia.pool_create") + def pool_create(self, **kwargs): + """Create a pool + + :param kwargs: + Parameters to create a listener with (expects json=) + :return: + A dict of the created pool's settings + """ + return self._clients.octavia().pool_create(**kwargs) + + @atomic.action_timer("octavia.pool_delete") + def pool_delete(self, pool_id): + """Delete a pool + + :param string pool_id: + ID of of pool to delete + :return: + Response Code from the API + """ + return self._clients.octavia().pool_delete(pool_id) + + @atomic.action_timer("octavia.pool_show") + def pool_show(self, pool_id): + """Show a pool's settings + + :param string pool_id: + ID of the pool to show + :return: + Dict of the specified pool's settings + """ + return self._clients.octavia().pool_show(pool_id) + + @atomic.action_timer("octavia.pool_set") + def pool_set(self, pool_id, **kwargs): + """Update a pool's settings + + :param pool_id: + ID of the pool to update + :param kwargs: + A dict of arguments to update a pool + :return: + Response Code from the API + """ + return self._clients.octavia().pool_set(pool_id, **kwargs) + + @atomic.action_timer("octavia.member_list") + def member_list(self, pool_id, **kwargs): + """Lists the member from a given pool id + + :param pool_id: + ID of the pool + :param kwargs: + A dict of filter arguments + :return: + Response list members + """ + return self._clients.octavia().member_list(pool_id, **kwargs) + + @atomic.action_timer("octavia.member_show") + def member_show(self, pool_id, member_id): + """Showing a member details of a pool + + :param pool_id: + ID of pool the member is added + :param member_id: + ID of the member + :param kwargs: + A dict of arguments + :return: + Response of member + """ + return self._clients.octavia().member_show(pool_id, member_id) + + @atomic.action_timer("octavia.member_create") + def member_create(self, pool_id, **kwargs): + """Creating a member for the given pool id + + :param pool_id: + ID of pool to which member is added + :param kwargs: + A Dict of arguments + :return: + A member details on successful creation + """ + return self._clients.octavia().member_create(pool_id, **kwargs) + + @atomic.action_timer("octavia.member_delete") + def member_delete(self, pool_id, member_id): + """Removing a member from a pool and mark that member as deleted + + :param pool_id: + ID of the pool + :param member_id: + ID of the member to be deleted + :return: + Response code from the API + """ + return self._clients.octavia().member_delete(pool_id, member_id) + + @atomic.action_timer("octavia.member_set") + def member_set(self, pool_id, member_id, **kwargs): + """Updating a member settings + + :param pool_id: + ID of the pool + :param member_id: + ID of the member to be updated + :param kwargs: + A dict of the values of member to be updated + :return: + Response code from the API + """ + return self._clients.octavia().member_set(pool_id, member_id, **kwargs) + + @atomic.action_timer("octavia.l7policy_list") + def l7policy_list(self, **kwargs): + """List all l7policies + + :param kwargs: + Parameters to filter on + :return: + List of l7policies + """ + return self._clients.octavia().l7policy_list(**kwargs) + + @atomic.action_timer("octavia.l7policy_create") + def l7policy_create(self, **kwargs): + """Create a l7policy + + :param kwargs: + Parameters to create a l7policy with (expects json=) + :return: + A dict of the created l7policy's settings + """ + return self._clients.octavia().l7policy_create(**kwargs) + + @atomic.action_timer("octavia.l7policy_delete") + def l7policy_delete(self, l7policy_id): + """Delete a l7policy + + :param string l7policy_id: + ID of of l7policy to delete + :return: + Response Code from the API + """ + return self._clients.octavia().l7policy_delete(l7policy_id) + + @atomic.action_timer("octavia.l7policy_show") + def l7policy_show(self, l7policy_id): + """Show a l7policy's settings + + :param string l7policy_id: + ID of the l7policy to show + :return: + Dict of the specified l7policy's settings + """ + return self._clients.octavia().l7policy_show(l7policy_id) + + @atomic.action_timer("octavia.l7policy_set") + def l7policy_set(self, l7policy_id, **kwargs): + """Update a l7policy's settings + + :param l7policy_id: + ID of the l7policy to update + :param kwargs: + A dict of arguments to update a l7policy + :return: + Response Code from the API + """ + return self._clients.octavia().l7policy_set(l7policy_id, **kwargs) + + @atomic.action_timer("octavia.l7rule_list") + def l7rule_list(self, l7policy_id, **kwargs): + """List all l7rules for a l7policy + + :param kwargs: + Parameters to filter on + :return: + List of l7policies + """ + return self._clients.octavia().l7rule_list(l7policy_id, **kwargs) + + @atomic.action_timer("octavia.l7rule_create") + def l7rule_create(self, l7policy_id, **kwargs): + """Create a l7rule + + :param string l7policy_id: + The l7policy to create the l7rule for + :param kwargs: + Parameters to create a l7rule with (expects json=) + :return: + A dict of the created l7rule's settings + """ + return self._clients.octavia().l7rule_create(l7policy_id, **kwargs) + + @atomic.action_timer("octavia.l7rule_delete") + def l7rule_delete(self, l7rule_id, l7policy_id): + """Delete a l7rule + + :param string l7rule_id: + ID of of listener to delete + :param string l7policy_id: + ID of the l7policy for this l7rule + :return: + Response Code from the API + """ + return self._clients.octavia().l7rule_delete(l7rule_id, l7policy_id) + + @atomic.action_timer("octavia.l7rule_show") + def l7rule_show(self, l7rule_id, l7policy_id): + """Show a l7rule's settings + + :param string l7rule_id: + ID of the l7rule to show + :param string l7policy_id: + ID of the l7policy for this l7rule + :return: + Dict of the specified l7rule's settings + """ + return self._clients.octavia().l7rule_show(l7rule_id, l7policy_id) + + @atomic.action_timer("octavia.l7rule_set") + def l7rule_set(self, l7rule_id, l7policy_id, **kwargs): + """Update a l7rule's settings + + :param l7rule_id: + ID of the l7rule to update + :param string l7policy_id: + ID of the l7policy for this l7rule + :param kwargs: + A dict of arguments to update a l7rule + :return: + Response Code from the API + """ + return self._clients.octavia().l7rule_set(l7rule_id, l7policy_id, + **kwargs) + + @atomic.action_timer("octavia.health_monitor_list") + def health_monitor_list(self, **kwargs): + """List all health monitors + + :param kwargs: + Parameters to filter on + :return: + A dict containing a list of health monitors + """ + return self._clients.octavia().health_monitor_list(**kwargs) + + @atomic.action_timer("octavia.health_monitor_create") + def health_monitor_create(self, **kwargs): + """Create a health monitor + + :param kwargs: + Parameters to create a health monitor with (expects json=) + :return: + A dict of the created health monitor's settings + """ + return self._clients.octavia().health_monitor_create(**kwargs) + + @atomic.action_timer("octavia.health_monitor_delete") + def health_monitor_delete(self, health_monitor_id): + """Delete a health_monitor + + :param string health_monitor_id: + ID of of health monitor to delete + :return: + Response Code from the API + """ + return self._clients.octavia().health_monitor_delete(health_monitor_id) + + @atomic.action_timer("octavia.health_monitor_show") + def health_monitor_show(self, health_monitor_id): + """Show a health monitor's settings + + :param string health_monitor_id: + ID of the health monitor to show + :return: + Dict of the specified health monitor's settings + """ + return self._clients.octavia().health_monitor_show(health_monitor_id) + + @atomic.action_timer("octavia.health_monitor_set") + def health_monitor_set(self, health_monitor_id, **kwargs): + """Update a health monitor's settings + + :param health_monitor_id: + ID of the health monitor to update + :param kwargs: + A dict of arguments to update a l7policy + :return: + Response Code from the API + """ + return self._clients.octavia().health_monitor_set(health_monitor_id, + **kwargs) + + @atomic.action_timer("octavia.quota_list") + def quota_list(self, params): + """List all quotas + + :param params: + Parameters to filter on (not implemented) + :return: + A ``dict`` representing a list of quotas for the project + """ + return self._clients.octavia().quota_list(params) + + @atomic.action_timer("octavia.quota_show") + def quota_show(self, project_id): + """Show a quota + + :param string project_id: + ID of the project to show + :return: + A ``dict`` representing the quota for the project + """ + return self._clients.octavia().quota_show(project_id) + + @atomic.action_timer("octavia.quota_reset") + def quota_reset(self, project_id): + """Reset a quota + + :param string project_id: + The ID of the project to reset quotas + :return: + ``None`` + """ + return self._clients.octavia().quota_reset(project_id) + + @atomic.action_timer("octavia.quota_set") + def quota_set(self, project_id, params): + """Update a quota's settings + + :param string project_id: + The ID of the project to update + :param params: + A ``dict`` of arguments to update project quota + :return: + A ``dict`` representing the updated quota + """ + return self._clients.octavia().quota_set(project_id, params) + + @atomic.action_timer("octavia.quota_defaults_show") + def quota_defaults_show(self): + """Show quota defaults + + :return: + A ``dict`` representing a list of quota defaults + """ + return self._clients.octavia().quota_defaults_show() + + @atomic.action_timer("octavia.amphora_show") + def amphora_show(self, amphora_id): + """Show an amphora + + :param string amphora_id: + ID of the amphora to show + :return: + A ``dict`` of the specified amphora's attributes + """ + return self._clients.octavia().amphora_show(amphora_id) + + @atomic.action_timer("octavia.amphora_list") + def amphora_list(self, **kwargs): + """List all amphorae + + :param kwargs: + Parameters to filter on + :return: + A ``dict`` containing a list of amphorae + """ + return self._clients.octavia().amphora_list(**kwargs) + + def update_loadbalancer_resource(self, lb): + try: + new_lb = self._clients.octavia().load_balancer_show( + lb["id"]) + except Exception as e: + if getattr(e, "status_code", 400) == 404: + raise exceptions.GetResourceNotFound(resource=lb) + raise exceptions.GetResourceFailure(resource=lb, err=e) + return new_lb + + @atomic.action_timer("octavia.wait_for_loadbalancers") + def wait_for_loadbalancer_prov_status(self, lb, prov_status="ACTIVE"): + return utils.wait_for_status( + lb["loadbalancer"], + ready_statuses=[prov_status], + status_attr="provisioning_status", + update_resource=self.update_loadbalancer_resource, + timeout=CONF.openstack.octavia_create_loadbalancer_timeout, + check_interval=( + CONF.openstack.octavia_create_loadbalancer_poll_interval) + ) diff --git a/samples/tasks/contexts/loadbalancers.json b/samples/tasks/contexts/loadbalancers.json new file mode 100644 index 00000000..e149af90 --- /dev/null +++ b/samples/tasks/contexts/loadbalancers.json @@ -0,0 +1,39 @@ +{ + "Dummy.openstack": [ + { + "args": { + "sleep": 0.1 + }, + "runner": { + "type": "constant", + "times": 4, + "concurrency": 2 + }, + "context": { + "users": { + "tenants": 1, + "users_per_tenant": 2 + }, + "lbaas": { + "pool": {} + } + } + }, + { + "args": { + "sleep": 0.1 + }, + "runner": { + "type": "constant", + "times": 4, + "concurrency": 2 + }, + "context": { + "users": { + "tenants": 1, + "users_per_tenant": 2 + } + } + } + ] +} diff --git a/samples/tasks/contexts/loadbalancers.yaml b/samples/tasks/contexts/loadbalancers.yaml new file mode 100644 index 00000000..48b59d8a --- /dev/null +++ b/samples/tasks/contexts/loadbalancers.yaml @@ -0,0 +1,26 @@ +--- + Dummy.openstack: + - + args: + sleep: 0.1 + runner: + type: "constant" + times: 4 + concurrency: 2 + context: + users: + tenants: 1 + users_per_tenant: 2 + lbaas: + pool: {} + - + args: + sleep: 0.1 + runner: + type: "constant" + times: 4 + concurrency: 2 + context: + users: + tenants: 1 + users_per_tenant: 2 diff --git a/samples/tasks/scenarios/octavia/octavia-create-and-list-loadbalancers.json b/samples/tasks/scenarios/octavia/octavia-create-and-list-loadbalancers.json new file mode 100644 index 00000000..cf8e70d6 --- /dev/null +++ b/samples/tasks/scenarios/octavia/octavia-create-and-list-loadbalancers.json @@ -0,0 +1,24 @@ +{ + "Octavia.create_and_list_loadbalancers": [ + { + "runner": { + "type": "constant", + "times": 5, + "concurrency": 2 + }, + "context": { + "users": { + "tenants": 2, + "users_per_tenant": 2 + }, + "roles": ["load-balancer_member"], + "network": {} + }, + "sla": { + "failure_rate": { + "max": 0 + } + } + } + ] +} diff --git a/samples/tasks/scenarios/octavia/octavia-create-and-list-loadbalancers.yaml b/samples/tasks/scenarios/octavia/octavia-create-and-list-loadbalancers.yaml new file mode 100644 index 00000000..0578e98c --- /dev/null +++ b/samples/tasks/scenarios/octavia/octavia-create-and-list-loadbalancers.yaml @@ -0,0 +1,17 @@ +--- + Octavia.create_and_list_loadbalancers: + - + runner: + type: "constant" + times: 5 + concurrency: 2 + context: + users: + tenants: 2 + users_per_tenant: 2 + roles: + - load-balancer_member + network: {} + sla: + failure_rate: + max: 0 diff --git a/tests/unit/cleanup/test_resources.py b/tests/unit/cleanup/test_resources.py index 1acece3e..500292fa 100644 --- a/tests/unit/cleanup/test_resources.py +++ b/tests/unit/cleanup/test_resources.py @@ -1199,3 +1199,53 @@ class BarbicanSecretsTestCase(test.TestCase): barbican._manager = mock.MagicMock() barbican.raw_resource = mock.MagicMock(uuid="fake_uuid") self.assertFalse(barbican.is_deleted()) + + +class OctaviaResourceTestCase(test.TestCase): + + def get_octavia(self): + octavia = resources.OctaviaLoadbalancer() + octavia._service = "octavia" + octavia._manager = mock.Mock() + return octavia + + def test_name(self): + octavia = self.get_octavia() + octavia.raw_resource = {"name": "test_name"} + self.assertEqual("test_name", octavia.name()) + + def test_id(self): + octavia = self.get_octavia() + octavia.raw_resource = {"id": "test_id"} + self.assertEqual("test_id", octavia.id()) + + def test_delete(self): + octavia = self.get_octavia() + octavia.raw_resource = {"id": "test_id"} + octavia._client = mock.MagicMock() + + octavia.delete() + octavia._client().load_balancer_delete.assert_called_once_with( + "test_id") + + def test_is_deleted_false(self): + octavia = self.get_octavia() + octavia.raw_resource = {"id": "test_id"} + octavia._client = mock.MagicMock() + self.assertFalse(octavia.is_deleted()) + + def test_is_deleted_true(self): + octavia = self.get_octavia() + octavia.raw_resource = {"id": "test_id"} + octavia._client = mock.MagicMock() + ex = Exception() + octavia._client().load_balancer_show.side_effect = ex + self.assertTrue(octavia.is_deleted()) + + def test_list(self): + octavia = self.get_octavia() + octavia.raw_resource = {"id": "test_id"} + octavia._client = mock.MagicMock() + + octavia.list() + octavia._client().load_balancer_list.assert_called_once_with() diff --git a/tests/unit/fakes.py b/tests/unit/fakes.py index c5532b7d..6bde2e06 100644 --- a/tests/unit/fakes.py +++ b/tests/unit/fakes.py @@ -195,6 +195,10 @@ class FakeSecret(FakeResource): self.secret_ref = secret_ref +class FakeLoadBalancer(FakeResource): + pass + + class FakeKeypair(FakeResource): pass diff --git a/tests/unit/scenarios/loadbalancer/__init__.py b/tests/unit/scenarios/loadbalancer/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/unit/scenarios/loadbalancer/test_loadbalancers.py b/tests/unit/scenarios/loadbalancer/test_loadbalancers.py new file mode 100644 index 00000000..55f16400 --- /dev/null +++ b/tests/unit/scenarios/loadbalancer/test_loadbalancers.py @@ -0,0 +1,58 @@ +# Copyright 2018: 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. + +import mock + +from rally_openstack.scenarios.octavia import loadbalancers +from tests.unit import test + + +class LoadBalancersTestCase(test.ScenarioTestCase): + + def get_test_context(self): + context = super(LoadBalancersTestCase, self).get_test_context() + context.update({ + "user": { + "id": "fake_user", + "tenant_id": "fake_tenant", + "credential": mock.MagicMock() + }, + "tenant": {"id": "fake_tenant", + "networks": [{"id": "fake_net", + "subnets": ["fake_subnet"]}]}}) + return context + + def setUp(self): + super(LoadBalancersTestCase, self).setUp() + patch = mock.patch( + "rally_openstack.services.loadbalancer.octavia.Octavia") + self.addCleanup(patch.stop) + self.mock_loadbalancers = patch.start() + + def test_loadbalancers(self): + loadbalancer_service = self.mock_loadbalancers.return_value + scenario = loadbalancers.CreateAndListLoadbalancers(self.context) + scenario.run() + + networks = self.context["tenant"]["networks"] + subnets = [] + mock_has_calls = [] + for network in networks: + subnets.extend(network.get("subnets", [])) + for subnet_id in subnets: + mock_has_calls.append(mock.call(subnet_id)) + loadbalancer_service.load_balancer_create.assert_called_once_with( + subnet_id) + self.assertEqual(1, loadbalancer_service.load_balancer_list.call_count) diff --git a/tests/unit/scenarios/loadbalancer/test_utils.py b/tests/unit/scenarios/loadbalancer/test_utils.py new file mode 100644 index 00000000..d8fa9247 --- /dev/null +++ b/tests/unit/scenarios/loadbalancer/test_utils.py @@ -0,0 +1,47 @@ +# Copyright 2018: 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. + +import mock + +from rally_openstack.scenarios.octavia import loadbalancers +from tests.unit import test + + +class LoadBalancerBaseTestCase(test.ScenarioTestCase): + + def setUp(self): + super(LoadBalancerBaseTestCase, self).setUp() + self.context = super(LoadBalancerBaseTestCase, self).get_test_context() + self.context.update({ + "admin": { + "id": "fake_user_id", + "credential": mock.MagicMock() + }, + "user": { + "id": "fake_user_id", + "credential": mock.MagicMock() + }, + "tenant": {"id": "fake_tenant_id", + "name": "fake_tenant_name"} + }) + patch = mock.patch( + "rally_openstack.services.loadbalancer.octavia.Octavia") + self.addCleanup(patch.stop) + self.mock_service = patch.start() + + def test_octavia_base(self): + base = loadbalancers.OctaviaBase(self.context) + self.assertEqual(base.octavia, + self.mock_service.return_value) diff --git a/tests/unit/services/loadbalancer/__init__.py b/tests/unit/services/loadbalancer/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/unit/services/loadbalancer/test_octavia.py b/tests/unit/services/loadbalancer/test_octavia.py new file mode 100644 index 00000000..1dd71e48 --- /dev/null +++ b/tests/unit/services/loadbalancer/test_octavia.py @@ -0,0 +1,400 @@ +# Copyright 2018: 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. + +import mock + +from rally.common import cfg +from rally import exceptions +from rally_openstack.services.loadbalancer import octavia +from tests.unit import test + +BASE_PATH = "rally_openstack.services.loadbalancer" +CONF = cfg.CONF + + +class LoadBalancerServiceTestCase(test.TestCase): + def setUp(self): + super(LoadBalancerServiceTestCase, self).setUp() + self.clients = mock.MagicMock() + self.name_generator = mock.MagicMock() + self.service = octavia.Octavia(self.clients, + name_generator=self.name_generator) + + def atomic_actions(self): + return self.service._atomic_actions + + def test_load_balancer_list(self): + self.service.load_balancer_list(), + self.service._clients.octavia().load_balancer_list \ + .assert_called_once_with() + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.load_balancer_list") + + def test_load_balancer_show(self): + self.service.load_balancer_show("fake_lb") + self.service._clients.octavia().load_balancer_show \ + .assert_called_once_with("fake_lb") + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.load_balancer_show") + + def test_load_balancer_create(self): + self.service.generate_random_name = mock.MagicMock( + return_value="lb") + self.service.load_balancer_create("fake_subnet") + self.assertEqual( + 1, self.service._clients.octavia().load_balancer_create.call_count) + self.service._clients.octavia().load_balancer_create \ + .assert_called_once_with( + json={"loadbalancer": + { + "vip_subnet_id": "fake_subnet", + "name": "lb", + "admin_state_up": True + }}) + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.load_balancer_create") + + def test_load_balancer_delete(self): + self.service.load_balancer_delete("fake_lb") + self.service._clients.octavia().load_balancer_delete \ + .assert_called_once_with("fake_lb") + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.load_balancer_delete") + + def test_load_balancer_set(self): + self.service.load_balancer_set("fake_lb", params={}) + self.service._clients.octavia().load_balancer_set \ + .assert_called_once_with("fake_lb", {}) + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.load_balancer_set") + + def test_load_balancer_stats_show(self): + self.assertEqual( + self.service.load_balancer_stats_show(lb_id="fake_lb", kwargs={}), + self.service._clients.octavia() + .load_balancer_stats_show.return_value) + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.load_balancer_stats_show") + + def test_load_balancer_failover(self): + self.service.load_balancer_failover(lb_id="fake_lb") + self.service._clients.octavia().load_balancer_failover \ + .assert_called_once_with("fake_lb") + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.load_balancer_failover") + + def test_listener_list(self): + self.service.listener_list() + self.service._clients.octavia().listener_list \ + .assert_called_once_with() + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.listener_list") + + def test_listener_show(self): + self.service.listener_show(listener_id="listener_id") + self.service._clients.octavia().listener_show \ + .assert_called_once_with("listener_id") + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.listener_show") + + def test_listener_create(self): + self.service.listener_create() + self.service._clients.octavia().listener_create \ + .assert_called_once_with() + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.listener_create") + + def test_listener_delete(self): + self.service.listener_delete(listener_id="listener_id") + self.service._clients.octavia().listener_delete \ + .assert_called_once_with("listener_id") + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.listener_delete") + + def test_listener_set(self): + self.service.listener_set(listener_id="listener_id") + self.service._clients.octavia().listener_set \ + .assert_called_once_with("listener_id") + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.listener_set") + + def test_listener_stats_show(self): + self.service.listener_stats_show(listener_id="listener_id") + self.service._clients.octavia().listener_stats_show \ + .assert_called_once_with("listener_id") + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.listener_stats_show") + + def test_pool_list(self): + self.service.pool_list() + self.service._clients.octavia().pool_list \ + .assert_called_once_with() + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.pool_list") + + def test_pool_create(self): + self.service.pool_create() + self.assertEqual( + 1, self.service._clients.octavia().pool_create.call_count) + self.service._clients.octavia().pool_create.assert_called_once_with() + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.pool_create") + + def test_pool_delete(self): + self.service.pool_delete(pool_id="fake_pool") + self.service._clients.octavia().pool_delete \ + .assert_called_once_with("fake_pool") + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.pool_delete") + + def test_pool_show(self): + self.service.pool_show(pool_id="fake_pool") + self.service._clients.octavia().pool_show \ + .assert_called_once_with("fake_pool") + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.pool_show") + + def test_pool_set(self): + self.service.pool_set(pool_id="fake_pool") + self.service._clients.octavia().pool_set \ + .assert_called_once_with("fake_pool") + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.pool_set") + + def test_member_list(self): + self.service.member_list(pool_id="fake_pool") + self.service._clients.octavia().member_list \ + .assert_called_once_with("fake_pool") + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.member_list") + + def test_member_show(self): + self.service.member_show(pool_id="fake_pool", member_id="fake_member") + self.service._clients.octavia().member_show \ + .assert_called_once_with("fake_pool", "fake_member") + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.member_show") + + def test_member_create(self): + self.service.member_create(pool_id="fake_pool") + self.service._clients.octavia().member_create \ + .assert_called_once_with("fake_pool") + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.member_create") + + def test_member_delete(self): + self.service.member_delete( + pool_id="fake_pool", member_id="fake_member") + self.service._clients.octavia().member_delete \ + .assert_called_once_with("fake_pool", "fake_member") + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.member_delete") + + def test_member_set(self): + self.service.member_set(pool_id="fake_pool", member_id="fake_member") + self.service._clients.octavia().member_set \ + .assert_called_once_with("fake_pool", "fake_member") + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.member_set") + + def test_l7policy_list(self): + self.service.l7policy_list() + self.service._clients.octavia().l7policy_list \ + .assert_called_once_with() + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.l7policy_list") + + def test_l7policy_create(self): + self.service.l7policy_create() + self.service._clients.octavia().l7policy_create \ + .assert_called_once_with() + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.l7policy_create") + + def test_l7policy_delete(self): + self.service.l7policy_delete(l7policy_id="fake_policy") + self.service._clients.octavia().l7policy_delete \ + .assert_called_once_with("fake_policy") + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.l7policy_delete") + + def test_l7policy_show(self): + self.service.l7policy_show(l7policy_id="fake_policy") + self.service._clients.octavia().l7policy_show \ + .assert_called_once_with("fake_policy") + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.l7policy_show") + + def test_l7policy_set(self): + self.service.l7policy_set(l7policy_id="fake_policy") + self.service._clients.octavia().l7policy_set \ + .assert_called_once_with("fake_policy") + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.l7policy_set") + + def test_l7rule_list(self): + self.service.l7rule_list(l7policy_id="fake_policy") + self.service._clients.octavia().l7rule_list \ + .assert_called_once_with("fake_policy") + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.l7rule_list") + + def test_l7rule_create(self): + self.service.l7rule_create(l7policy_id="fake_policy") + self.service._clients.octavia().l7rule_create \ + .assert_called_once_with("fake_policy") + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.l7rule_create") + + def test_l7rule_delete(self): + self.service.l7rule_delete( + l7rule_id="fake_id", l7policy_id="fake_policy") + self.service._clients.octavia().l7rule_delete \ + .assert_called_once_with("fake_id", "fake_policy") + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.l7rule_delete") + + def test_l7rule_show(self): + self.service.l7rule_show( + l7rule_id="fake_id", l7policy_id="fake_policy") + self.service._clients.octavia().l7rule_show \ + .assert_called_once_with("fake_id", "fake_policy") + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.l7rule_show") + + def test_l7rule_set(self): + self.service.l7rule_set(l7rule_id="fake_id", l7policy_id="fake_policy") + self.service._clients.octavia().l7rule_set \ + .assert_called_once_with("fake_id", "fake_policy") + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.l7rule_set") + + def test_health_monitor_list(self): + self.service.health_monitor_list() + self.service._clients.octavia().health_monitor_list \ + .assert_called_once_with() + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.health_monitor_list") + + def test_health_monitor_create(self): + self.service.health_monitor_create() + self.service._clients.octavia().health_monitor_create \ + .assert_called_once_with() + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.health_monitor_create") + + def test_health_monitor_delete(self): + self.service.health_monitor_delete(health_monitor_id="fake_monitor_id") + self.service._clients.octavia().health_monitor_delete \ + .assert_called_once_with("fake_monitor_id") + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.health_monitor_delete") + + def test_health_monitor_show(self): + self.service.health_monitor_show(health_monitor_id="fake_monitor_id") + self.service._clients.octavia().health_monitor_show \ + .assert_called_once_with("fake_monitor_id") + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.health_monitor_show") + + def test_health_monitor_set(self): + self.service.health_monitor_set(health_monitor_id="fake_monitor_id") + self.service._clients.octavia().health_monitor_set \ + .assert_called_once_with("fake_monitor_id") + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.health_monitor_set") + + def test_quota_list(self): + self.service.quota_list(params="fake_params") + self.service._clients.octavia().quota_list\ + .assert_called_once_with("fake_params") + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.quota_list") + + def test_quota_show(self): + self.service.quota_show(project_id="fake_project") + self.service._clients.octavia().quota_show\ + .assert_called_once_with("fake_project") + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.quota_show") + + def test_quota_reset(self): + self.service.quota_reset(project_id="fake_project") + self.service._clients.octavia().quota_reset \ + .assert_called_once_with("fake_project") + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.quota_reset") + + def test_quota_set(self): + self.service.quota_set(project_id="fake_project", + params="fake_params") + self.service._clients.octavia().quota_set \ + .assert_called_once_with("fake_project", "fake_params") + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.quota_set") + + def test_quota_defaults_show(self): + self.service.quota_defaults_show() + self.service._clients.octavia().quota_defaults_show \ + .assert_called_once_with() + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.quota_defaults_show") + + def test_amphora_show(self): + self.service.amphora_show(amphora_id="fake_amphora") + self.service._clients.octavia().amphora_show \ + .assert_called_once_with("fake_amphora") + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.amphora_show") + + def test_amphora_list(self): + self.service.amphora_list() + self.service._clients.octavia().amphora_list \ + .assert_called_once_with() + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.amphora_list") + + def test_update_loadbalancer_resource(self): + fake_lb = {"id": "fake_lb"} + self.service.update_loadbalancer_resource(lb=fake_lb) + self.service._clients.octavia().load_balancer_show. \ + assert_called_once_with("fake_lb") + + def test_update_loadbalancer_resource_fail_404(self): + fake_lb = {"id": "fake_lb"} + ex = Exception() + ex.status_code = 404 + self.service._clients.octavia().load_balancer_show.side_effect = \ + ex + self.assertRaises( + exceptions.GetResourceNotFound, + self.service.update_loadbalancer_resource, fake_lb) + + def test_update_loadbalancer_resource_fail(self): + fake_lb = {"id": "fake_lb"} + ex = Exception() + self.service._clients.octavia().load_balancer_show.side_effect = \ + ex + self.assertRaises( + exceptions.GetResourceFailure, + self.service.update_loadbalancer_resource, fake_lb) + + @mock.patch("%s.Ocvita.wait_for_loadbalancer_prov_status" % BASE_PATH) + def wait_for_loadbalancer_prov_status(self, mock_wait_for_status): + fake_lb = {"loadbalancer": {}} + self.service.wait_for_loadbalancer_prov_status(lb=fake_lb) + self.assertTrue(mock_wait_for_status.called) + self._test_atomic_action_timer(self.atomic_actions(), + "octavia.wait_for_loadbalancers")