Merge "Add Neutron LoadBalancer v1 create and list vips"

This commit is contained in:
Jenkins 2015-09-16 09:03:30 +00:00 committed by Gerrit Code Review
commit 20cbd5fb0d
7 changed files with 167 additions and 0 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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