Add Neutron LoadBalancer v1 create and list vips
Enable benchmarking of the Neutron LoadBalancer v1 lb-vip-create and lb-vip-list 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: I8a4f85bb62ae2a44be0a25d9a8327fd1ee48336b
This commit is contained in:
parent
f139d3bd5c
commit
2352e8565e
@ -163,6 +163,29 @@
|
||||
failure_rate:
|
||||
max: 0
|
||||
|
||||
NeutronLoadbalancerV1.create_and_list_vips:
|
||||
-
|
||||
args:
|
||||
vip_create_args: {}
|
||||
runner:
|
||||
type: "constant"
|
||||
times: 20
|
||||
concurrency: 10
|
||||
context:
|
||||
users:
|
||||
tenants: 5
|
||||
users_per_tenant: 4
|
||||
network: {}
|
||||
quotas:
|
||||
neutron:
|
||||
network: -1
|
||||
subnet: -1
|
||||
pool: -1
|
||||
vip: -1
|
||||
sla:
|
||||
failure_rate:
|
||||
max: 0
|
||||
|
||||
NeutronNetworks.create_and_update_networks:
|
||||
-
|
||||
args:
|
||||
|
@ -56,6 +56,10 @@ class NeutronQuotas(object):
|
||||
"pool": {
|
||||
"type": "integer",
|
||||
"minimum": -1
|
||||
},
|
||||
"vip": {
|
||||
"type": "integer",
|
||||
"minimum": -1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
from rally import consts
|
||||
from rally.plugins.openstack import scenario
|
||||
from rally.plugins.openstack.scenarios.neutron import utils
|
||||
from rally.task import atomic
|
||||
from rally.task import validation
|
||||
|
||||
|
||||
@ -85,3 +86,30 @@ class NeutronLoadbalancerV1(utils.NeutronScenario):
|
||||
pools = self._create_v1_pools(networks, **pool_create_args)
|
||||
for pool in pools:
|
||||
self._update_v1_pool(pool, **pool_update_args)
|
||||
|
||||
@validation.restricted_parameters(["pool_id", "subnet_id"],
|
||||
subdict="vip_create_args")
|
||||
@validation.required_neutron_extensions("lbaas")
|
||||
@validation.required_services(consts.Service.NEUTRON)
|
||||
@validation.required_openstack(admin=True)
|
||||
@validation.required_contexts("network")
|
||||
@scenario.configure(context={"cleanup": ["neutron"]})
|
||||
def create_and_list_vips(self, pool_create_args=None,
|
||||
vip_create_args=None):
|
||||
"""Create a vip(v1) and then list vips(v1).
|
||||
|
||||
Measure the "neutron lb-vip-create" and "neutron lb-vip-list" command
|
||||
performance. The scenario creates a vip for every pool created and
|
||||
then lists vips.
|
||||
|
||||
:param vip_create_args: dict, POST /lb/vips request options
|
||||
:param pool_create_args: dict, POST /lb/pools request options
|
||||
"""
|
||||
vip_create_args = vip_create_args or {}
|
||||
pool_create_args = pool_create_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:
|
||||
self._create_v1_vip(pool, **vip_create_args)
|
||||
self._list_v1_vips()
|
||||
|
@ -31,6 +31,7 @@ class NeutronScenario(scenario.OpenStackScenario):
|
||||
# TODO(rkiran): modify in case LBaaS-v2 requires
|
||||
LB_METHOD = "ROUND_ROBIN"
|
||||
LB_PROTOCOL = "HTTP"
|
||||
LB_PROTOCOL_PORT = 80
|
||||
|
||||
def _warn_about_deprecated_name_kwarg(self, resource, kwargs):
|
||||
"""Warn about use of a deprecated 'name' kwarg and replace it.
|
||||
@ -347,3 +348,23 @@ class NeutronScenario(scenario.OpenStackScenario):
|
||||
self._warn_about_deprecated_name_kwarg(pool, pool_update_args)
|
||||
body = {"pool": pool_update_args}
|
||||
return self.clients("neutron").update_pool(pool["pool"]["id"], body)
|
||||
|
||||
def _create_v1_vip(self, pool, **vip_create_args):
|
||||
"""Create VIP(v1)
|
||||
|
||||
:parm pool: dict, neutron lb-pool
|
||||
:parm vip_create_args: dict, POST /lb/vips request options
|
||||
:returns: dict, neutron lb vip
|
||||
"""
|
||||
args = {"protocol": self.LB_PROTOCOL,
|
||||
"protocol_port": self.LB_PROTOCOL_PORT,
|
||||
"name": self._generate_random_name("rally_vip_"),
|
||||
"pool_id": pool["pool"]["id"],
|
||||
"subnet_id": pool["pool"]["subnet_id"]}
|
||||
args.update(vip_create_args)
|
||||
return self.clients("neutron").create_vip({"vip": args})
|
||||
|
||||
@atomic.action_timer("neutron.list_vips")
|
||||
def _list_v1_vips(self, **kwargs):
|
||||
"""Return user lb vip list(v1)."""
|
||||
return self.clients("neutron").list_vips(**kwargs)
|
||||
|
@ -1035,6 +1035,7 @@ class FakeNeutronClient(object):
|
||||
self.__routers = {}
|
||||
self.__ports = {}
|
||||
self.__pools = {}
|
||||
self.__vips = {}
|
||||
self.__tenant_id = kwargs.get("tenant_id", generate_uuid())
|
||||
|
||||
self.format = "json"
|
||||
@ -1098,6 +1099,23 @@ class FakeNeutronClient(object):
|
||||
self.__pools[pool_id] = pool
|
||||
return {"pool": pool}
|
||||
|
||||
def create_vip(self, data):
|
||||
vip = setup_dict(data["vip"],
|
||||
required=["protocol_port", "protocol", "subnet_id",
|
||||
"pool_id"],
|
||||
defaults={"name": generate_name("vip_"),
|
||||
"admin_state_up": True})
|
||||
if (vip["subnet_id"] not in self.__subnets) or (vip["pool_id"] not in
|
||||
self.__pools):
|
||||
raise neutron_exceptions.NeutronClientException
|
||||
vip_id = generate_uuid()
|
||||
|
||||
vip.update({"id": vip_id,
|
||||
"status": "PENDING_CREATE",
|
||||
"tenant_id": self.__tenant_id})
|
||||
self.__vips[vip_id] = vip
|
||||
return {"vip": vip}
|
||||
|
||||
def create_port(self, data):
|
||||
port = setup_dict(data["port"],
|
||||
required=["network_id"],
|
||||
@ -1234,6 +1252,10 @@ class FakeNeutronClient(object):
|
||||
pools = self._filter(self.__pools.values(), search_opts)
|
||||
return {"pools": pools}
|
||||
|
||||
def list_vips(self, **search_opts):
|
||||
vips = self._filter(self.__vips.values(), search_opts)
|
||||
return {"vips": vips}
|
||||
|
||||
def list_ports(self, **search_opts):
|
||||
ports = self._filter(self.__ports.values(), search_opts)
|
||||
return {"ports": ports}
|
||||
|
@ -125,3 +125,36 @@ class NeutronLoadbalancerv1TestCase(test.TestCase):
|
||||
for pool in pools:
|
||||
neutron_scenario._update_v1_pool.assert_called_once_with(
|
||||
pool, **pool_update_args)
|
||||
|
||||
@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_list_vips(self, pool_create_args=None,
|
||||
vip_create_args=None):
|
||||
neutron_scenario = loadbalancer_v1.NeutronLoadbalancerV1(
|
||||
self._get_context())
|
||||
pools = [{
|
||||
"pool": {
|
||||
"id": "pool-id"
|
||||
}
|
||||
}]
|
||||
vip_data = vip_create_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()
|
||||
neutron_scenario._list_v1_vips = mock.Mock()
|
||||
neutron_scenario.create_and_list_vips(
|
||||
pool_create_args=pool_create_args, vip_create_args=vip_create_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._list_v1_vips.assert_called_once_with()
|
||||
|
@ -476,6 +476,16 @@ class NeutronScenarioTestCase(test.ScenarioTestCase):
|
||||
self._test_atomic_action_timer(scenario.atomic_actions(),
|
||||
"neutron.list_pools")
|
||||
|
||||
def test_list_v1_vips(self):
|
||||
scenario = utils.NeutronScenario()
|
||||
vips_list = []
|
||||
vips_dict = {"vips": vips_list}
|
||||
self.clients("neutron").list_vips.return_value = vips_dict
|
||||
return_vips_dict = scenario._list_v1_vips()
|
||||
self.assertEqual(vips_dict, return_vips_dict)
|
||||
self._test_atomic_action_timer(scenario.atomic_actions(),
|
||||
"neutron.list_vips")
|
||||
|
||||
|
||||
class NeutronScenarioFunctionalTestCase(test.FakeClientsScenarioTestCase):
|
||||
|
||||
@ -572,3 +582,29 @@ class NeutronLoadbalancerScenarioTestCase(test.ScenarioTestCase):
|
||||
if atomic_action:
|
||||
self._test_atomic_action_timer(
|
||||
neutron_scenario.atomic_actions(), "neutron.create_pool")
|
||||
|
||||
@ddt.data(
|
||||
{},
|
||||
{"vip_create_args": {}},
|
||||
{"vip_create_args": {"name": "given-name"}},
|
||||
)
|
||||
@ddt.unpack
|
||||
def test__create_v1_vip(self, vip_create_args=None):
|
||||
neutron_scenario = utils.NeutronScenario()
|
||||
vip = {"vip": {"id": "vip-id"}}
|
||||
pool = {"pool": {"id": "pool-id", "subnet_id": "subnet-id"}}
|
||||
vip_create_args = vip_create_args or {}
|
||||
if vip_create_args.get("name") is None:
|
||||
neutron_scenario._generate_random_name = mock.Mock(
|
||||
return_value="random_name")
|
||||
self.clients("neutron").create_vip.return_value = vip
|
||||
args = {"protocol_port": 80, "protocol": "HTTP", "name": "random_name",
|
||||
"subnet_id": pool["pool"]["subnet_id"],
|
||||
"pool_id": pool["pool"]["id"]}
|
||||
args.update(vip_create_args)
|
||||
expected_vip_data = {"vip": args}
|
||||
resultant_vip = neutron_scenario._create_v1_vip(
|
||||
pool, **vip_create_args)
|
||||
self.assertEqual(resultant_vip, vip)
|
||||
self.clients("neutron").create_vip.assert_called_once_with(
|
||||
expected_vip_data)
|
||||
|
Loading…
x
Reference in New Issue
Block a user