Add Neutron Loadbalancer v1 create and update vips

Enable benchmarking of the Neutron LoadBalancer v1
lb-vip-create and lb-vip-update APIs. Due to the
different API scheme and confusing naming conventions
in Neutron (LB is v1 API and LBaaS for v2 API) the
appropriate code is explicitly marked with 'v1'
since this only implements the API v1 benchmarking.

Change-Id: I0b458044891a0931eea99785d088f0851650c3d6
This commit is contained in:
Kiran 2015-06-22 17:02:14 +05:30
parent f3e29fa10a
commit 597336922e
6 changed files with 144 additions and 0 deletions

View File

@ -212,6 +212,31 @@
failure_rate:
max: 0
NeutronLoadbalancerV1.create_and_update_vips:
-
args:
vip_create_args: {}
vip_update_args: {}
pool_create_args: {}
runner:
type: "constant"
times: 20
concurrency: 10
context:
users:
tenants: 4
users_per_tenant: 5
network: {}
quotas:
neutron:
network: -1
subnet: -1
pool: -1
vip: -1
sla:
failure_rate:
max: 0
NeutronNetworks.create_and_update_networks:
-
args:

View File

@ -141,3 +141,34 @@ class NeutronLoadbalancerV1(utils.NeutronScenario):
vips.append(self._create_v1_vip(pool, **vip_create_args))
for vip in vips:
self._delete_v1_vip(vip["vip"])
@validation.restricted_parameters(["pool_id", "subnet_id"],
subdict="vip_create_args")
@validation.required_services(consts.Service.NEUTRON)
@validation.required_openstack(users=True)
@validation.required_contexts("network")
@scenario.configure(context={"cleanup": ["neutron"]})
def create_and_update_vips(self, pool_create_args=None,
vip_update_args=None,
vip_create_args=None):
"""Create vips(v1) and update vips(v1).
Measure the "neutron lb-vip-create" and "neutron lb-vip-update"
command performance. The scenario creates a pool for every subnet
and then update those pools.
:param pool_create_args: dict, POST /lb/pools request options
:param vip_create_args: dict, POST /lb/vips request options
:param vip_update_args: dict, POST /lb/vips update options
"""
vips = []
pool_create_args = pool_create_args or {}
vip_create_args = vip_create_args or {}
vip_update_args = vip_update_args or {}
networks = self.context.get("tenant", {}).get("networks", [])
pools = self._create_v1_pools(networks, **pool_create_args)
with atomic.ActionTimer(self, "neutron.create_%s_vips" % len(pools)):
for pool in pools:
vips.append(self._create_v1_vip(pool, **vip_create_args))
for vip in vips:
self._update_v1_vip(vip, **vip_update_args)

View File

@ -376,3 +376,17 @@ class NeutronScenario(scenario.OpenStackScenario):
:param vip: neutron Virtual IP object
"""
self.clients("neutron").delete_vip(vip["id"])
@atomic.action_timer("neutron.update_vip")
def _update_v1_vip(self, vip, **vip_update_args):
"""Updates vip.
This atomic function updates vip name and admin state
:param vip: Vip object
:param vip_update_args: dict, POST /lb/vips update options
:returns: updated neutron vip dict
"""
self._warn_about_deprecated_name_kwarg(vip, vip_update_args)
body = {"vip": vip_update_args}
return self.clients("neutron").update_vip(vip["vip"]["id"], body)

View File

@ -1189,6 +1189,9 @@ class FakeNeutronClient(object):
def update_pool(self, pool_id, data):
self.update_resource(pool_id, self.__pools, data)
def update_vip(self, vip_id, data):
self.update_resource(vip_id, self.__vips, data)
def update_subnet(self, subnet_id, data):
self.update_resource(subnet_id, self.__subnets, data)

View File

@ -190,3 +190,53 @@ class NeutronLoadbalancerv1TestCase(test.TestCase):
[mock.call(pool, **vip_data) for pool in net["lb_pools"]])
neutron_scenario._delete_v1_vip.assert_has_calls(
[mock.call(vip["vip"])])
@ddt.data(
{},
{"vip_create_args": None},
{"vip_create_args": {}},
{"vip_create_args": {"name": "given-vip-name"}},
{"pool_create_args": None},
{"pool_create_args": {}},
{"pool_create_args": {"name": "given-pool-name"}},
)
@ddt.unpack
def test_create_and_update_vips(self, pool_create_args=None,
vip_create_args=None,
vip_update_args=None):
neutron_scenario = loadbalancer_v1.NeutronLoadbalancerV1(
self._get_context())
pools = [{
"pool": {
"id": "pool-id",
}
}]
expected_vip = {
"vip": {
"id": "vip-id",
"name": "vip-name"
}
}
updated_vip = {
"vip": {
"id": "vip-id",
"name": "updated-vip-name"
}
}
vips = [expected_vip]
vip_data = vip_create_args or {}
vip_update_data = vip_update_args or {}
pool_data = pool_create_args or {}
networks = self._get_context()["tenant"]["networks"]
neutron_scenario._create_v1_pools = mock.Mock(return_value=pools)
neutron_scenario._create_v1_vip = mock.Mock(return_value=expected_vip)
neutron_scenario._update_v1_vip = mock.Mock(return_value=updated_vip)
neutron_scenario.create_and_update_vips(
pool_create_args=pool_create_args, vip_create_args=vip_create_args,
vip_update_args=vip_update_args)
neutron_scenario._create_v1_pools.assert_called_once_with(
networks, **pool_data)
neutron_scenario._create_v1_vip.assert_has_calls(
[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])

View File

@ -496,6 +496,27 @@ class NeutronScenarioTestCase(test.ScenarioTestCase):
self._test_atomic_action_timer(scenario.atomic_actions(),
"neutron.delete_vip")
def test_update_v1_vip(self):
scenario = utils.NeutronScenario()
scenario._generate_random_name = mock.Mock(return_value="random_name")
expected_vip = {
"vip": {
"name": scenario._generate_random_name.return_value,
"admin_state_up": False
}
}
self.clients("neutron").update_vip.return_value = expected_vip
vip = {"vip": {"name": "vip-name", "id": "vip-id"}}
vip_update_args = {"name": "foo", "admin_state_up": False}
result_vip = scenario._update_v1_vip(vip, **vip_update_args)
self.assertEqual(result_vip, expected_vip)
self.clients("neutron").update_vip.assert_called_once_with(
vip["vip"]["id"], expected_vip)
self._test_atomic_action_timer(scenario.atomic_actions(),
"neutron.update_vip")
class NeutronScenarioFunctionalTestCase(test.FakeClientsScenarioTestCase):