Merge "Add Neutron LBaaS V1 healthmonitor scenarios"

This commit is contained in:
Jenkins 2015-10-12 08:50:46 +00:00 committed by Gerrit Code Review
commit b601251e9c
7 changed files with 367 additions and 0 deletions

View File

@ -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:

View File

@ -60,6 +60,10 @@ class NeutronQuotas(object):
"vip": {
"type": "integer",
"minimum": -1
},
"health_monitor": {
"type": "integer",
"minimum": -1
}
}
}

View File

@ -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)

View File

@ -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)

View File

@ -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):

View File

@ -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)

View File

@ -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")