Merge "Add Neutron LBaaS V1 healthmonitor scenarios"
This commit is contained in:
commit
b601251e9c
@ -255,6 +255,65 @@
|
||||
failure_rate:
|
||||
max: 0
|
||||
|
||||
NeutronLoadbalancerV1.create_and_list_healthmonitors:
|
||||
-
|
||||
args:
|
||||
healthmonitor_create_args: {}
|
||||
runner:
|
||||
type: "constant"
|
||||
times: {{smoke or 20}}
|
||||
concurrency: {{smoke or 10}}
|
||||
context:
|
||||
users:
|
||||
tenants: {{smoke or 5}}
|
||||
users_per_tenant: {{smoke or 2}}
|
||||
quotas:
|
||||
neutron:
|
||||
health_monitor: -1
|
||||
sla:
|
||||
failure_rate:
|
||||
max: 0
|
||||
|
||||
NeutronLoadbalancerV1.create_and_delete_healthmonitors:
|
||||
-
|
||||
args:
|
||||
healthmonitor_create_args: {}
|
||||
runner:
|
||||
type: "constant"
|
||||
times: {{smoke or 20}}
|
||||
concurrency: {{smoke or 10}}
|
||||
context:
|
||||
users:
|
||||
tenants: {{smoke or 5}}
|
||||
users_per_tenant: {{smoke or 2}}
|
||||
quotas:
|
||||
neutron:
|
||||
health_monitor: -1
|
||||
sla:
|
||||
failure_rate:
|
||||
max: 0
|
||||
|
||||
NeutronLoadbalancerV1.create_and_update_healthmonitors:
|
||||
-
|
||||
args:
|
||||
healthmonitor_create_args: {}
|
||||
healthmonitor_update_args:
|
||||
admin_state_up: False
|
||||
runner:
|
||||
type: "constant"
|
||||
times: {{smoke or 20}}
|
||||
concurrency: {{smoke or 10}}
|
||||
context:
|
||||
users:
|
||||
tenants: {{smoke or 5}}
|
||||
users_per_tenant: {{smoke or 2}}
|
||||
quotas:
|
||||
neutron:
|
||||
health_monitor: -1
|
||||
sla:
|
||||
failure_rate:
|
||||
max: 0
|
||||
|
||||
NeutronNetworks.create_and_update_networks:
|
||||
-
|
||||
args:
|
||||
|
@ -60,6 +60,10 @@ class NeutronQuotas(object):
|
||||
"vip": {
|
||||
"type": "integer",
|
||||
"minimum": -1
|
||||
},
|
||||
"health_monitor": {
|
||||
"type": "integer",
|
||||
"minimum": -1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,8 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import random
|
||||
|
||||
from rally import consts
|
||||
from rally.plugins.openstack import scenario
|
||||
from rally.plugins.openstack.scenarios.neutron import utils
|
||||
@ -174,3 +176,65 @@ class NeutronLoadbalancerV1(utils.NeutronScenario):
|
||||
vips.append(self._create_v1_vip(pool, **vip_create_args))
|
||||
for vip in vips:
|
||||
self._update_v1_vip(vip, **vip_update_args)
|
||||
|
||||
@validation.required_neutron_extensions("lbaas")
|
||||
@validation.required_services(consts.Service.NEUTRON)
|
||||
@validation.required_openstack(users=True)
|
||||
@scenario.configure(context={"cleanup": ["neutron"]})
|
||||
def create_and_list_healthmonitors(self, healthmonitor_create_args=None):
|
||||
"""Create healthmonitors(v1) and list healthmonitors(v1).
|
||||
|
||||
Measure the "neutron lb-healthmonitor-list" command performance. This
|
||||
scenario creates healthmonitors and lists them.
|
||||
|
||||
:param healthmonitor_create_args: dict, POST /lb/healthmonitors request
|
||||
options
|
||||
"""
|
||||
healthmonitor_create_args = healthmonitor_create_args or {}
|
||||
self._create_v1_healthmonitor(**healthmonitor_create_args)
|
||||
self._list_v1_healthmonitors()
|
||||
|
||||
@validation.required_neutron_extensions("lbaas")
|
||||
@validation.required_services(consts.Service.NEUTRON)
|
||||
@validation.required_openstack(users=True)
|
||||
@scenario.configure(context={"cleanup": ["neutron"]})
|
||||
def create_and_delete_healthmonitors(self, healthmonitor_create_args=None):
|
||||
"""Create a healthmonitor(v1) and delete healthmonitors(v1).
|
||||
|
||||
Measure the "neutron lb-healthmonitor-create" and "neutron
|
||||
lb-healthmonitor-delete" command performance. The scenario creates
|
||||
healthmonitors and deletes those healthmonitors.
|
||||
|
||||
:param healthmonitor_create_args: dict, POST /lb/healthmonitors request
|
||||
options
|
||||
"""
|
||||
healthmonitor_create_args = healthmonitor_create_args or {}
|
||||
healthmonitor = self._create_v1_healthmonitor(
|
||||
**healthmonitor_create_args)
|
||||
self._delete_v1_healthmonitor(healthmonitor["health_monitor"])
|
||||
|
||||
@validation.required_neutron_extensions("lbaas")
|
||||
@validation.required_services(consts.Service.NEUTRON)
|
||||
@validation.required_openstack(users=True)
|
||||
@scenario.configure(context={"cleanup": ["neutron"]})
|
||||
def create_and_update_healthmonitors(self,
|
||||
healthmonitor_create_args=None,
|
||||
healthmonitor_update_args=None):
|
||||
"""Create a healthmonitor(v1) and update healthmonitors(v1).
|
||||
|
||||
Measure the "neutron lb-healthmonitor-create" and "neutron
|
||||
lb-healthmonitor-update" command performance. The scenario creates
|
||||
healthmonitors and then updates them.
|
||||
|
||||
:param healthmonitor_create_args: dict, POST /lb/healthmonitors request
|
||||
options
|
||||
:param healthmonitor_update_args: dict, POST /lb/healthmonitors update
|
||||
options
|
||||
"""
|
||||
healthmonitor_create_args = healthmonitor_create_args or {}
|
||||
healthmonitor_update_args = healthmonitor_update_args or {
|
||||
"max_retries": random.choice(range(1, 10))}
|
||||
healthmonitor = self._create_v1_healthmonitor(
|
||||
**healthmonitor_create_args)
|
||||
self._update_v1_healthmonitor(healthmonitor,
|
||||
**healthmonitor_update_args)
|
||||
|
@ -33,6 +33,10 @@ class NeutronScenario(scenario.OpenStackScenario):
|
||||
LB_METHOD = "ROUND_ROBIN"
|
||||
LB_PROTOCOL = "HTTP"
|
||||
LB_PROTOCOL_PORT = 80
|
||||
HM_TYPE = "PING"
|
||||
HM_MAX_RETRIES = 3
|
||||
HM_DELAY = 20
|
||||
HM_TIMEOUT = 10
|
||||
|
||||
def _warn_about_deprecated_name_kwarg(self, resource, kwargs):
|
||||
"""Warn about use of a deprecated 'name' kwarg and replace it.
|
||||
@ -439,3 +443,59 @@ class NeutronScenario(scenario.OpenStackScenario):
|
||||
:param: dict, floating IP object
|
||||
"""
|
||||
return self.clients("neutron").delete_floatingip(floating_ip["id"])
|
||||
|
||||
def _create_v1_healthmonitor(self, atomic_action=True,
|
||||
**healthmonitor_create_args):
|
||||
"""Create LB healthmonitor.
|
||||
|
||||
This atomic function creates healthmonitor with the provided
|
||||
healthmonitor_create_args.
|
||||
|
||||
:param atomic_action: True if this is an atomic action
|
||||
:param healthmonitor_create_args: dict, POST /lb/healthmonitors
|
||||
:returns: neutron healthmonitor dict
|
||||
"""
|
||||
args = {"type": self.HM_TYPE,
|
||||
"delay": self.HM_DELAY,
|
||||
"max_retries": self.HM_MAX_RETRIES,
|
||||
"timeout": self.HM_TIMEOUT}
|
||||
args.update(healthmonitor_create_args)
|
||||
if atomic_action:
|
||||
with atomic.ActionTimer(self, "neutron.create_healthmonitor"):
|
||||
return self.clients("neutron").create_health_monitor(
|
||||
{"health_monitor": args})
|
||||
return self.clients("neutron").create_health_monitor(
|
||||
{"health_monitor": args})
|
||||
|
||||
@atomic.action_timer("neutron.list_healthmonitors")
|
||||
def _list_v1_healthmonitors(self, **kwargs):
|
||||
"""List LB healthmonitors.
|
||||
|
||||
This atomic function lists all helthmonitors.
|
||||
|
||||
:param kwargs: optional parameters
|
||||
:returns neutron lb healthmonitor list
|
||||
"""
|
||||
return self.clients("neutron").list_health_monitors(**kwargs)
|
||||
|
||||
@atomic.action_timer("neutron.delete_healthmonitor")
|
||||
def _delete_v1_healthmonitor(self, healthmonitor):
|
||||
"""Delete neutron healthmonitor.
|
||||
|
||||
:param healthmonitor: neutron healthmonitor dict
|
||||
"""
|
||||
self.clients("neutron").delete_health_monitor(healthmonitor["id"])
|
||||
|
||||
@atomic.action_timer("neutron.update_healthmonitor")
|
||||
def _update_v1_healthmonitor(self, healthmonitor,
|
||||
**healthmonitor_update_args):
|
||||
"""Update neutron healthmonitor.
|
||||
|
||||
:param healthmonitor: neutron lb healthmonitor dict
|
||||
:param healthmonitor_update_args: POST /lb/healthmonitors
|
||||
update options
|
||||
:returns updated neutron lb healthmonitor dict
|
||||
"""
|
||||
body = {"health_monitor": healthmonitor_update_args}
|
||||
return self.clients("neutron").update_health_monitor(
|
||||
healthmonitor["health_monitor"]["id"], body)
|
||||
|
@ -1037,6 +1037,7 @@ class FakeNeutronClient(object):
|
||||
self.__pools = {}
|
||||
self.__vips = {}
|
||||
self.__fips = {}
|
||||
self.__healthmonitors = {}
|
||||
self.__tenant_id = kwargs.get("tenant_id", generate_uuid())
|
||||
|
||||
self.format = "json"
|
||||
@ -1130,6 +1131,19 @@ class FakeNeutronClient(object):
|
||||
self.__fips[fip_id] = fip
|
||||
return {"fip": fip}
|
||||
|
||||
def create_health_monitor(self, data):
|
||||
healthmonitor = setup_dict(data["healthmonitor"],
|
||||
required=["type", "timeout", "delay",
|
||||
"max_retries"],
|
||||
defaults={"admin_state_up": True})
|
||||
healthmonitor_id = generate_uuid()
|
||||
|
||||
healthmonitor.update({"id": healthmonitor_id,
|
||||
"status": "PENDING_CREATE",
|
||||
"tenant_id": self.__tenant_id})
|
||||
self.__healthmonitors[healthmonitor_id] = healthmonitor
|
||||
return {"healthmonitor": healthmonitor}
|
||||
|
||||
def create_port(self, data):
|
||||
port = setup_dict(data["port"],
|
||||
required=["network_id"],
|
||||
@ -1206,6 +1220,9 @@ class FakeNeutronClient(object):
|
||||
def update_vip(self, vip_id, data):
|
||||
self.update_resource(vip_id, self.__vips, data)
|
||||
|
||||
def update_health_monitor(self, healthmonitor_id, data):
|
||||
self.update_resource(healthmonitor_id, self.__healthmonitors, data)
|
||||
|
||||
def update_subnet(self, subnet_id, data):
|
||||
self.update_resource(subnet_id, self.__subnets, data)
|
||||
|
||||
@ -1235,6 +1252,11 @@ class FakeNeutronClient(object):
|
||||
if vip_id not in self.__vips:
|
||||
raise neutron_exceptions.NeutronClientException
|
||||
del self.__vips[vip_id]
|
||||
|
||||
def delete_health_monitor(self, healthmonitor_id):
|
||||
if healthmonitor_id not in self.__healthmonitors:
|
||||
raise neutron_exceptions.NeutronClientException
|
||||
del self.__healthmonitors[healthmonitor_id]
|
||||
return ""
|
||||
|
||||
def delete_floatingip(self, fip_id):
|
||||
@ -1285,6 +1307,11 @@ class FakeNeutronClient(object):
|
||||
vips = self._filter(self.__vips.values(), search_opts)
|
||||
return {"vips": vips}
|
||||
|
||||
def list_health_monitors(self, **search_opts):
|
||||
healthmonitors = self._filter(
|
||||
self.__healthmonitors.values(), search_opts)
|
||||
return {"healthmonitors": healthmonitors}
|
||||
|
||||
def list_ports(self, **search_opts):
|
||||
ports = self._filter(self.__ports.values(), search_opts)
|
||||
return {"ports": ports}
|
||||
@ -1322,6 +1349,22 @@ class FakeNeutronClient(object):
|
||||
|
||||
raise neutron_exceptions.NeutronClientException
|
||||
|
||||
def associate_health_monitor(self, pool_id, healthmonitor_id):
|
||||
if pool_id not in self.__pools:
|
||||
raise neutron_exceptions.NeutronClientException
|
||||
if healthmonitor_id not in self.__healthmonitors:
|
||||
raise neutron_exceptions.NeutronClientException
|
||||
self.__pools[pool_id]["pool"]["healthmonitors"] = healthmonitor_id
|
||||
return {"pool": self.__pools[pool_id]}
|
||||
|
||||
def disassociate_health_monitor(self, pool_id, healthmonitor_id):
|
||||
if pool_id not in self.__pools:
|
||||
raise neutron_exceptions.NeutronClientException
|
||||
if healthmonitor_id not in self.__healthmonitors:
|
||||
raise neutron_exceptions.NeutronClientException
|
||||
del self.__pools[pool_id]["pool"]["healthmonitors"][healthmonitor_id]
|
||||
return ""
|
||||
|
||||
|
||||
class FakeIronicClient(object):
|
||||
|
||||
|
@ -250,3 +250,74 @@ class NeutronLoadbalancerv1TestCase(test.TestCase):
|
||||
[mock.call(pool, **vip_data) for pool in pools])
|
||||
neutron_scenario._update_v1_vip.assert_has_calls(
|
||||
[mock.call(vip, **vip_update_data) for vip in vips])
|
||||
|
||||
@ddt.data(
|
||||
{},
|
||||
{"healthmonitor_create_args": None},
|
||||
{"healthmonitor_create_args": {}},
|
||||
{"healthmonitor_create_args": {"name": "given-name"}},
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_create_and_list_healthmonitors(self,
|
||||
healthmonitor_create_args=None):
|
||||
neutron_scenario = loadbalancer_v1.NeutronLoadbalancerV1(
|
||||
self._get_context())
|
||||
hm_data = healthmonitor_create_args or {}
|
||||
neutron_scenario._create_v1_healthmonitor = mock.Mock()
|
||||
neutron_scenario._list_v1_healthmonitors = mock.Mock()
|
||||
neutron_scenario.create_and_list_healthmonitors(
|
||||
healthmonitor_create_args=healthmonitor_create_args)
|
||||
neutron_scenario._create_v1_healthmonitor.assert_called_once_with(
|
||||
**hm_data)
|
||||
neutron_scenario._list_v1_healthmonitors.assert_called_once_with()
|
||||
|
||||
@ddt.data(
|
||||
{},
|
||||
{"healthmonitor_create_args": None},
|
||||
{"healthmonitor_create_args": {}},
|
||||
{"healthmonitor_create_args": {"name": "given-name"}},
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_create_and_delete_healthmonitors(self,
|
||||
healthmonitor_create_args=None):
|
||||
neutron_scenario = loadbalancer_v1.NeutronLoadbalancerV1(
|
||||
self._get_context())
|
||||
hm = {"health_monitor": {"id": "hm-id"}}
|
||||
hm_data = healthmonitor_create_args or {}
|
||||
neutron_scenario._create_v1_healthmonitor = mock.Mock(return_value=hm)
|
||||
neutron_scenario._delete_v1_healthmonitor = mock.Mock()
|
||||
neutron_scenario.create_and_delete_healthmonitors(
|
||||
healthmonitor_create_args=healthmonitor_create_args)
|
||||
neutron_scenario._create_v1_healthmonitor.assert_called_once_with(
|
||||
**hm_data)
|
||||
neutron_scenario._delete_v1_healthmonitor.assert_called_once_with(
|
||||
neutron_scenario._create_v1_healthmonitor.return_value[
|
||||
"health_monitor"])
|
||||
|
||||
@ddt.data(
|
||||
{},
|
||||
{"healthmonitor_create_args": None},
|
||||
{"healthmonitor_create_args": {}},
|
||||
{"healthmonitor_create_args": {"name": "given-name"}},
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_create_and_update_healthmonitors(self,
|
||||
healthmonitor_create_args=None,
|
||||
healthmonitor_update_args=None):
|
||||
neutron_scenario = loadbalancer_v1.NeutronLoadbalancerV1(
|
||||
self._get_context())
|
||||
mock_random = loadbalancer_v1.random = mock.Mock()
|
||||
hm = {"healthmonitor": {"id": "hm-id"}}
|
||||
hm_data = healthmonitor_create_args or {}
|
||||
hm_update_data = healthmonitor_update_args or {
|
||||
"max_retries": mock_random.choice.return_value}
|
||||
neutron_scenario._create_v1_healthmonitor = mock.Mock(return_value=hm)
|
||||
neutron_scenario._update_v1_healthmonitor = mock.Mock()
|
||||
neutron_scenario.create_and_update_healthmonitors(
|
||||
healthmonitor_create_args=healthmonitor_create_args,
|
||||
healthmonitor_update_args=healthmonitor_update_args)
|
||||
neutron_scenario._create_v1_healthmonitor.assert_called_once_with(
|
||||
**hm_data)
|
||||
neutron_scenario._update_v1_healthmonitor.assert_called_once_with(
|
||||
neutron_scenario._create_v1_healthmonitor.return_value,
|
||||
**hm_update_data)
|
||||
|
@ -725,3 +725,69 @@ class NeutronLoadbalancerScenarioTestCase(test.ScenarioTestCase):
|
||||
mock_get_network_id.assert_called_once_with(floating_network)
|
||||
self._test_atomic_action_timer(neutron_scenario.atomic_actions(),
|
||||
"neutron.create_floating_ip")
|
||||
|
||||
@ddt.data(
|
||||
{},
|
||||
{"healthmonitor_create_args": {}},
|
||||
{"healthmonitor_create_args": {"type": "TCP"}},
|
||||
{"atomic_action": False},
|
||||
{"atomic_action": False,
|
||||
"healthmonitor_create_args": {"type": "TCP"}},
|
||||
{"healthmonitor_create_args": {},
|
||||
"atomic_action": False},
|
||||
)
|
||||
@ddt.unpack
|
||||
def test__create_v1_healthmonitor(self, atomic_action=True,
|
||||
healthmonitor_create_args=None):
|
||||
neutron_scenario = utils.NeutronScenario()
|
||||
hm = {"health_monitor": {"id": "hm-id"}}
|
||||
healthmonitor_create_args = healthmonitor_create_args or {}
|
||||
self.clients("neutron").create_health_monitor.return_value = hm
|
||||
args = {"type": "PING", "delay": 20,
|
||||
"timeout": 10, "max_retries": 3}
|
||||
args.update(healthmonitor_create_args)
|
||||
expected_hm_data = {"health_monitor": args}
|
||||
resultant_hm = neutron_scenario._create_v1_healthmonitor(
|
||||
atomic_action=atomic_action,
|
||||
**healthmonitor_create_args)
|
||||
self.assertEqual(resultant_hm, hm)
|
||||
self.clients("neutron").create_health_monitor.assert_called_once_with(
|
||||
expected_hm_data)
|
||||
if atomic_action:
|
||||
self._test_atomic_action_timer(
|
||||
neutron_scenario.atomic_actions(),
|
||||
"neutron.create_healthmonitor")
|
||||
|
||||
def test_list_v1_healthmonitors(self):
|
||||
scenario = utils.NeutronScenario()
|
||||
hm_list = []
|
||||
hm_dict = {"health_monitors": hm_list}
|
||||
self.clients("neutron").list_health_monitors.return_value = hm_dict
|
||||
return_hm_dict = scenario._list_v1_healthmonitors()
|
||||
self.assertEqual(hm_dict, return_hm_dict)
|
||||
self._test_atomic_action_timer(scenario.atomic_actions(),
|
||||
"neutron.list_healthmonitors")
|
||||
|
||||
def test_delete_v1_healthmonitor(self):
|
||||
scenario = utils.NeutronScenario()
|
||||
healthmonitor = {"health_monitor": {"id": "fake-id"}}
|
||||
scenario._delete_v1_healthmonitor(healthmonitor["health_monitor"])
|
||||
self.clients("neutron").delete_health_monitor.assert_called_once_with(
|
||||
healthmonitor["health_monitor"]["id"])
|
||||
self._test_atomic_action_timer(scenario.atomic_actions(),
|
||||
"neutron.delete_healthmonitor")
|
||||
|
||||
def test_update_healthmonitor(self):
|
||||
scenario = utils.NeutronScenario()
|
||||
expected_hm = {"health_monitor": {"admin_state_up": False}}
|
||||
mock_update = self.clients("neutron").update_health_monitor
|
||||
mock_update.return_value = expected_hm
|
||||
hm = {"health_monitor": {"id": "pool-id"}}
|
||||
healthmonitor_update_args = {"admin_state_up": False}
|
||||
result_hm = scenario._update_v1_healthmonitor(
|
||||
hm, **healthmonitor_update_args)
|
||||
self.assertEqual(result_hm, expected_hm)
|
||||
mock_update.assert_called_once_with(
|
||||
hm["health_monitor"]["id"], expected_hm)
|
||||
self._test_atomic_action_timer(scenario.atomic_actions(),
|
||||
"neutron.update_healthmonitor")
|
||||
|
Loading…
Reference in New Issue
Block a user