Add Neutron Loadbalancer v1 create and update pools

Enable benchmarking of the Neutron LoadBalancer v1
lb-pool-create and lb-pool-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: I15c9c8878391ba30ec7da6fa91231e8fed1d23cf
This commit is contained in:
Kiran 2015-06-13 09:48:43 +05:30
parent 0e4bdf1fe6
commit 3468e5271b
8 changed files with 191 additions and 12 deletions

View File

@ -137,6 +137,29 @@
failure_rate:
max: 0
NeutronLoadbalancerV1.create_and_update_pools:
-
args:
pool_create_args: {}
pool_update_args: {}
runner:
type: "constant"
times: {{smoke or 20}}
concurrency: 10
context:
users:
tenants: 1
users_per_tenant: 1
network: {}
quotas:
neutron:
network: -1
subnet: -1
pool: -1
sla:
failure_rate:
max: 0
NeutronNetworks.create_and_update_networks:
-
args:

View File

@ -59,3 +59,29 @@ class NeutronLoadbalancerV1(utils.NeutronScenario):
**pool_create_args))
for pool in pools:
self._delete_v1_pool(pool["pool"])
@validation.restricted_parameters("subnet_id", subdict="pool_create_args")
@validation.required_services(consts.Service.NEUTRON)
@validation.required_openstack(users=True)
@validation.required_contexts("network")
@base.scenario(context={"cleanup": ["neutron"]})
def create_and_update_pools(self, pool_update_args=None,
pool_create_args=None):
"""Create pools(v1) and update pools(v1).
Measure the "neutron lb-pool-create" and "neutron lb-pool-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 pool_update_args: dict, POST /lb/pools update options
"""
pools = []
pool_create_args = pool_create_args or {}
pool_update_args = pool_update_args or {}
for net in self.context.get("tenant", {}).get("networks", []):
for subnet_id in net["subnets"]:
pools.append(self._create_v1_pool(subnet_id,
**pool_create_args))
for pool in pools:
self._update_v1_pool(pool, **pool_update_args)

View File

@ -317,3 +317,24 @@ class NeutronScenario(base.Scenario):
:param pool: Pool object
"""
self.clients("neutron").delete_pool(pool["id"])
@base.atomic_action_timer("neutron.update_pool")
def _update_v1_pool(self, pool, **pool_update_args):
"""Update pool.
This atomic function updates pool name by
appending the existing name and admin state with pool_update_args.
:param pool: Pool object
:param pool_update_args: dict, POST /lb/pools update options
:returns: updated neutron pool dict
"""
suffix = pool_update_args.get("name", None)
body = {
"pool": {
"name": pool["pool"]["name"] + suffix if suffix is not None
else self._generate_random_name("_"),
"admin_state_up": pool_update_args.get("admin_state_up", True)
}
}
return self.clients("neutron").update_pool(pool["pool"]["id"], body)

View File

@ -0,0 +1,29 @@
{
"NeutronLoadbalancerV1.create_and_update_pools": [
{
"args": {
"pool_create_args":{},
"pool_update_args":{}
},
"runner": {
"type": "constant",
"times": 100,
"concurrency": 10
},
"context": {
"users": {
"tenants": 1,
"users_per_tenant": 1
},
"network":{},
"quotas": {
"neutron": {
"network": -1,
"subnet": -1,
"pool": -1
}
}
}
}
]
}

View File

@ -0,0 +1,20 @@
---
NeutronLoadbalancerV1.create_and_update_pools:
-
args:
pool_create_args: {}
pool_update_args: {}
runner:
type: "constant"
times: 100
concurrency: 10
context:
users:
tenants: 1
users_per_tenant: 1
network: {}
quotas:
neutron:
network: -1
subnet: -1
pool: -1

View File

@ -1190,25 +1190,25 @@ class FakeNeutronClient(object):
self.__subnets[subnet_id] = subnet
return {"subnet": subnet}
def update_network(self, network_id, data):
if network_id not in self.__networks:
def update_resource(self, resource_id, resource_dict, data):
if resource_id not in resource_dict:
raise neutron_exceptions.NeutronClientException
self.__networks[network_id].update(data)
self.resource_list[resource_id].update(data)
def update_network(self, network_id, data):
self.update_resource(network_id, self.__networks, data)
def update_pool(self, pool_id, data):
self.update_resource(pool_id, self.__pools, data)
def update_subnet(self, subnet_id, data):
if subnet_id not in self.__subnets:
raise neutron_exceptions.NeutronClientException
self.__subnets[subnet_id].update(data)
self.update_resource(subnet_id, self.__subnets, data)
def update_port(self, port_id, data):
if port_id not in self.__ports:
raise neutron_exceptions.NeutronClientException
self.__ports[port_id].update(data)
self.update_resource(port_id, self.__ports, data)
def update_router(self, router_id, data):
if router_id not in self.__routers:
raise neutron_exceptions.NeutronClientException
self.__routers[router_id].update(data)
self.update_resource(router_id, self.__routers, data)
def delete_network(self, network_id):
if network_id not in self.__networks:

View File

@ -59,6 +59,39 @@ class NeutronLoadbalancerv1TestCase(test.TestCase):
for pool in pools:
self.assertEqual(1, neutron_scenario._delete_v1_pool.call_count)
def _validate_create_and_update_pools_scenario(self, pool_create_args):
neutron_scenario = loadbalancer_v1.NeutronLoadbalancerV1(
self._get_context())
pool = {
"pool": {
"id": "pool-id"
}
}
updated_pool = {
"pool": {
"id": "pool-id",
"name": "updated-pool",
"admin_state_up": True
}
}
pool_update_args = {"name": "_updated", "admin_state_up": True}
neutron_scenario._create_v1_pool = mock.Mock(return_value=pool)
neutron_scenario._update_v1_pool = mock.Mock(
return_value=updated_pool)
neutron_scenario.create_and_update_pools(
pool_create_args=pool_create_args,
pool_update_args=pool_update_args)
pools = []
for net in self._get_context()["tenant"]["networks"]:
for subnet_id in net["subnets"]:
pools.append(
neutron_scenario._create_v1_pool.assert_called_once_with(
subnet_id, **pool_create_args))
for pool in pools:
neutron_scenario._update_v1_pool.assert_called_once_with(
neutron_scenario._create_v1_pool.return_value,
**pool_update_args)
def test_create_and_list_pools_default(self):
self._validate_create_and_list_pools_scenario(pool_create_args={})
@ -72,3 +105,10 @@ class NeutronLoadbalancerv1TestCase(test.TestCase):
def test_create_and_delete_pools_explicit(self):
self._validate_create_and_delete_pools_scenario(
pool_create_args={"name": "given-name"})
def test_create_and_update_pools_default(self):
self._validate_create_and_update_pools_scenario(pool_create_args={})
def test_create_and_update_pools_explicit(self):
self._validate_create_and_update_pools_scenario(
pool_create_args={"name": "given-name"})

View File

@ -441,6 +441,26 @@ class NeutronScenarioTestCase(test.ClientsTestCase):
self._test_atomic_action_timer(scenario.atomic_actions(),
"neutron.delete_pool")
def test_update_pool(self):
scenario = utils.NeutronScenario()
expected_pool = {
"pool": {
"name": "pool-name_updated",
"admin_state_up": False
}
}
self.clients("neutron").update_pool.return_value = expected_pool
pool = {"pool": {"name": "pool-name", "id": "pool-id"}}
pool_update_args = {"name": "_updated", "admin_state_up": False}
result_pool = scenario._update_v1_pool(pool, **pool_update_args)
self.assertEqual(result_pool, expected_pool)
self.clients("neutron").update_pool.assert_called_once_with(
pool["pool"]["id"], expected_pool)
self._test_atomic_action_timer(scenario.atomic_actions(),
"neutron.update_pool")
def test_list_v1_pools(self):
scenario = utils.NeutronScenario()
pools_list = []