Adds Networking-bgpvpn scenarios

Create-and-list-bgpvpns and create-and-update_bgpvpns

Change-Id: I098acedc175beebc24535abcd079a708ff47f846
This commit is contained in:
Cedric Savignan 2017-04-13 18:28:59 +02:00 committed by Andrey Kurilin
parent ba73b96349
commit 8300b3adb3
13 changed files with 393 additions and 48 deletions

View File

@ -16,10 +16,36 @@
failure_rate:
max: 0
NeutronBGPVPN.create_and_list_bgpvpns:
-
runner:
type: "constant"
times: 10
concurrency: 2
context:
users:
tenants: 3
users_per_tenant: 2
sla:
failure_rate:
max: 0
NeutronBGPVPN.create_and_update_bgpvpns:
-
runner:
type: "constant"
times: 10
concurrency: 2
context:
users:
tenants: 3
users_per_tenant: 2
sla:
failure_rate:
max: 0
NeutronBGPVPN.create_and_delete_bgpvpns:
-
args:
bgpvpn_create_args: {}
runner:
type: "constant"
times: 10

View File

@ -307,9 +307,11 @@ class NeutronMixin(SynchronizedDeletion, base.ResourceManager):
def list(self):
resources = self._resource + "s"
list_method = getattr(self._manager(), "list_%s" % resources)
result = list_method(tenant_id=self.tenant_uuid)[resources]
if self.tenant_uuid:
result = [r for r in result if r["tenant_id"] == self.tenant_uuid]
return filter(lambda r: r["tenant_id"] == self.tenant_uuid,
list_method(tenant_id=self.tenant_uuid)[resources])
return result
class NeutronLbaasV1Mixin(NeutronMixin):
@ -359,6 +361,15 @@ class NeutronV2Loadbalancer(NeutronLbaasV2Mixin):
return False
@base.resource("neutron", "bgpvpn", order=next(_neutron_order),
admin_required=True, perform_for_admin_only=True)
class NeutronBgpvpn(NeutronMixin):
def list(self):
if self.supports_extension("bgpvpn"):
return self._manager().list_bgpvpns()["bgpvpns"]
return []
# NOTE(andreykurilin): There are scenarios which uses unified way for creating
# and associating floating ips. They do not care about nova-net and neutron.
# We should clean floating IPs for them, but hardcoding "neutron.floatingip"

View File

@ -18,21 +18,115 @@ from rally.task import validation
"""Scenarios for Neutron Networking-Bgpvpn."""
@validation.restricted_parameters(["name"])
@validation.add("required_neutron_extensions", extensions=["bgpvpn"])
@validation.required_services(consts.Service.NEUTRON)
@validation.add("required_platform", platform="openstack", users=True)
@validation.add("required_platform", platform="openstack", admin=True)
@scenario.configure(context={"admin_cleanup": ["neutron"]},
name="NeutronBGPVPN.create_and_delete_bgpvpns")
class CreateAndDeleteBgpvpns(utils.NeutronScenario):
def run(self, bgpvpn_create_args=None):
def run(self, route_targets=None, import_targets=None,
export_targets=None, route_distinguishers=None, type="l3"):
"""Create bgpvpn and delete the bgpvpn.
Measure the "neutron bgpvpn-create" and bgpvpn-delete
Measure the "neutron bgpvpn-create" and neutron bgpvpn-delete
command performance.
:param bgpvpn_create_args: dict, POST /v2.0/bgpvpn/bgpvpns request
options
:param route_targets: Route Targets that will be both imported and
used for export
:param import_targets: Additional Route Targets that will be imported
:param export_targets: Additional Route Targets that will be used
for export.
:param route_distinguishers: List of route distinguisher strings
:param type: type of VPN and the technology behind it.
Acceptable formats: l2 and l3
"""
bgpvpn = self._create_bgpvpn(bgpvpn_create_args or {})
bgpvpn = self._create_bgpvpn(route_targets=route_targets,
import_targets=import_targets,
export_targets=export_targets,
route_distinguishers=route_distinguishers,
type=type)
self._delete_bgpvpn(bgpvpn)
@validation.add("required_neutron_extensions", extensions=["bgpvpn"])
@validation.required_services(consts.Service.NEUTRON)
@validation.add("required_platform", platform="openstack", admin=True)
@scenario.configure(context={"admin_cleanup": ["neutron"]},
name="NeutronBGPVPN.create_and_list_bgpvpns")
class CreateAndListBgpvpns(utils.NeutronScenario):
def run(self, route_targets=None, import_targets=None,
export_targets=None, route_distinguishers=None, type="l3"):
"""Create a bgpvpn and then list all bgpvpns
Measure the "neutron bgpvpn-list" command performance.
:param route_targets: Route Targets that will be both imported and
used for export
:param import_targets: Additional Route Targets that will be imported
:param export_targets: Additional Route Targets that will be used
for export.
:param route_distinguishers: List of route distinguisher strings
:param type: type of VPN and the technology behind it.
Acceptable formats: l2 and l3
"""
bgpvpn = self._create_bgpvpn(route_targets=route_targets,
import_targets=import_targets,
export_targets=export_targets,
route_distinguishers=route_distinguishers,
type=type)
bgpvpns = self._list_bgpvpns()
self.assertIn(bgpvpn["bgpvpn"]["id"], [b["id"] for b in bgpvpns])
@validation.add("required_neutron_extensions", extensions=["bgpvpn"])
@validation.required_services(consts.Service.NEUTRON)
@validation.add("required_platform", platform="openstack", admin=True)
@scenario.configure(context={"admin_cleanup": ["neutron"]},
name="NeutronBGPVPN.create_and_update_bgpvpns")
class CreateAndUpdateBgpvpns(utils.NeutronScenario):
def run(self, update_name=False, route_targets=None,
import_targets=None, export_targets=None,
route_distinguishers=None, updated_route_targets=None,
updated_import_targets=None, updated_export_targets=None,
updated_route_distinguishers=None, bgpvpn_type="l3"):
"""Create and Update bgpvpns
Measure the "neutron bgpvpn-update" command performance.
:param update_name: bool, whether or not to modify BGP VPN name
:param route_targets: Route Targets that will be both imported
and used for export
:param updated_route_targets: Updated Route Targets that will be both
imported and used for export
:param import_targets: Additional Route Targets that will be imported
:param updated_import_targets: Updated additional Route Targets that
will be imported
:param export_targets: additional Route Targets that will be used
for export.
:param updated_export_targets: Updated additional Route Targets that
will be used for export.
:param route_distinguishers: list of route distinguisher strings
:param updated_route_distinguishers: Updated list of route
distinguisher strings
:param bgpvpn_type: type of VPN and the technology behind it.
Acceptable formats: l2 and l3
"""
create_bgpvpn_args = {
"route_targets": route_targets,
"import_targets": import_targets,
"export_targets": export_targets,
"route_distinguishers": route_distinguishers,
"type": bgpvpn_type
}
bgpvpn = self._create_bgpvpn(**create_bgpvpn_args)
update_bgpvpn_args = {
"update_name": update_name,
"route_targets": updated_route_targets,
"import_targets": updated_import_targets,
"export_targets": updated_export_targets,
"route_distinguishers": updated_route_distinguishers,
}
self._update_bgpvpn(bgpvpn, **update_bgpvpn_args)

View File

@ -44,9 +44,6 @@ class NeutronScenario(scenario.OpenStackScenario):
HM_MAX_RETRIES = 3
HM_DELAY = 20
HM_TIMEOUT = 10
# BGPVPN
BGPVPNS_PATH = "/bgpvpn/bgpvpns"
BGPVPN_PATH = "/bgpvpn/bgpvpns/%s"
def _get_network_id(self, network, **kwargs):
"""Get Neutron network ID for the network name.
@ -701,23 +698,46 @@ class NeutronScenario(scenario.OpenStackScenario):
**lb_list_args)
@atomic.action_timer("neutron.create_bgpvpn")
def _create_bgpvpn(self, bgpvpn_create_args):
def _create_bgpvpn(self, **kwargs):
"""Create Bgpvpn resource (POST /bgpvpn/bgpvpn)
param: bgpvpn_create_args: dict bgpvpn options
returns: dict, bgpvpn resource details
:param kwargs: optional parameters to create BGP VPN
:returns dict, bgpvpn resource details
"""
if "name" not in bgpvpn_create_args:
bgpvpn_create_args["name"] = self.generate_random_name()
return self.admin_clients("neutron").create_ext(
self.BGPVPNS_PATH, {"bgpvpn": bgpvpn_create_args})
kwargs["name"] = self.generate_random_name()
return self.admin_clients("neutron").create_bgpvpn({"bgpvpn": kwargs})
@atomic.action_timer("neutron.delete_bgpvpn")
def _delete_bgpvpn(self, bgpvpn):
"""Delete Bgpvpn resource.(DELETE /bgpvpn/bgpvpns/{id})
param: bgpvpn: dict, bgpvpn
return: dict, bgpvpn
:param bgpvpn: dict, bgpvpn
:return dict, bgpvpn
"""
return self.admin_clients("neutron").delete_ext(
self.BGPVPN_PATH, bgpvpn["bgpvpn"]["id"])
return self.admin_clients("neutron").delete_bgpvpn(
bgpvpn["bgpvpn"]["id"])
@atomic.action_timer("neutron.list_bgpvpns")
def _list_bgpvpns(self, **kwargs):
"""Return bgpvpns list.
:param kwargs: dict, POST /bgpvpn/bgpvpns request options
:returns: bgpvpns list
"""
return self.admin_clients("neutron").list_bgpvpns(
True, **kwargs)["bgpvpns"]
@atomic.action_timer("neutron.update_bgpvpn")
def _update_bgpvpn(self, bgpvpn, update_name=False, **kwargs):
"""Update a bgpvpn.
:param bgpvpn: dict, bgpvpn
:param update_name: update_name: bool, whether or not to modify
BGP VPN name
:param **kwargs: dict, PUT /bgpvpn/bgpvpns update options
:return dict, updated bgpvpn
"""
if update_name or "name" in kwargs:
kwargs["name"] = self.generate_random_name()
return self.admin_clients("neutron").update_bgpvpn(
bgpvpn["bgpvpn"]["id"], {"bgpvpn": kwargs})

View File

@ -42,7 +42,7 @@ python-manilaclient>=1.12.0,<=1.14.0 # Apache Software License
python-mistralclient>=2.0.0,<=3.0.0 # Apache Software License
python-monascaclient>=1.1.0,<=1.5.0 # Apache Software License
python-muranoclient>=0.8.2,<=0.12.0 # Apache License, Version 2.0
python-neutronclient>=5.1.0,<=6.1.0 # Apache Software License
python-neutronclient==6.2.0 # Apache Software License
python-novaclient==7.1.0 # Apache License, Version 2.0
python-saharaclient==1.1.0 # Apache License, Version 2.0
python-senlinclient>=1.1.0,<=1.2.0 # Apache Software License

View File

@ -0,0 +1,23 @@
{
"NeutronBGPVPN.create_and_list_bgpvpns": [
{
"args":{},
"runner": {
"type": "constant",
"times": 10,
"concurrency": 2
},
"context": {
"users": {
"tenants": 1,
"users_per_tenant": 1
}
},
"sla": {
"failure_rate": {
"max": 0
}
}
}
]
}

View File

@ -0,0 +1,15 @@
---
NeutronBGPVPN.create_and_list_bgpvpns:
-
args: {}
runner:
type: "constant"
times: 10
concurrency: 2
context:
users:
tenants: 1
users_per_tenant: 1
sla:
failure_rate:
max: 0

View File

@ -0,0 +1,19 @@
{
"NeutronBGPVPN.create_and_update_bgpvpns": [
{
"args":{},
"runner": {
"type": "constant",
"times": 10,
"concurrency": 2
},
"context": {
"users": {
"tenants": 1,
"users_per_tenant": 1
}
}
}
]
}

View File

@ -0,0 +1,12 @@
---
NeutronBGPVPN.create_and_update_bgpvpns:
-
args: {}
runner:
type: "constant"
times: 10
concurrency: 2
context:
users:
tenants: 1
users_per_tenant: 1

View File

@ -250,6 +250,10 @@ class Neutron(ResourceManager):
if self.has_extension("lbaas"):
return self.client.list_vips()["vips"]
def list_bgpvpns(self):
if self.has_extension("bgpvpn"):
return self.client.list_bgpvpns()["bgpvpns"]
class Glance(ResourceManager):

View File

@ -413,6 +413,38 @@ class NeutronV2LoadbalancerTestCase(test.TestCase):
neutron_lb.id())
class NeutronBgpvpnTestCase(test.TestCase):
def get_neutron_bgpvpn_mixin(self, extensions=None):
if extensions is None:
extensions = []
admin = mock.Mock()
neut = resources.NeutronBgpvpn(admin=admin)
neut._manager = mock.Mock()
neut._manager().list_extensions.return_value = {
"extensions": [{"alias": ext} for ext in extensions]
}
return neut
def test_list_user(self):
neut = self.get_neutron_bgpvpn_mixin(extensions=["bgpvpn"])
user_bgpvpns = {"bgpvpns": [{"tenant_id": "foo", "id": "bgpvpn_id"}]}
neut._manager().list_bgpvpns.return_value = user_bgpvpns
bgpvpns_list = neut.list()
self.assertEqual("bgpvpn", neut._resource)
neut._manager().list_bgpvpns.assert_called_once_with()
self.assertEqual(bgpvpns_list, user_bgpvpns["bgpvpns"])
def test_list_admin(self):
neut = self.get_neutron_bgpvpn_mixin(extensions=["bgpvpn"])
admin_bgpvpns = {"bgpvpns": [{"tenant_id": "foo", "id": "bgpvpn_id"}]}
neut._manager().list_bgpvpns.return_value = admin_bgpvpns
self.assertEqual("bgpvpn", neut._resource)
self.assertEqual(neut.list(), admin_bgpvpns["bgpvpns"])
class NeutronFloatingIPTestCase(test.TestCase):
def test_name(self):

View File

@ -24,19 +24,85 @@ class NeutronBgpvpnTestCase(test.TestCase):
context = test.get_test_context()
return context
def _get_bgpvpn_create_data(self):
return {
"route_targets": None,
"import_targets": None,
"export_targets": None,
"route_distinguishers": None}
def _get_bgpvpn_update_data(self):
return {
"route_targets": None,
"import_targets": None,
"export_targets": None,
"route_distinguishers": None}
@ddt.data(
{},
{"bgpvpn_create_args": None},
{"bgpvpn_create_args": {}},
{"bgpvpn_create_args": {"name": "given-name"}},
)
@ddt.unpack
def test_create_and_delete_bgpvpns(self, bgpvpn_create_args=None):
scenario = bgpvpn.CreateAndDeleteBgpvpns(self._get_context())
bgpvpn_create_data = bgpvpn_create_args or {}
create_data = self._get_bgpvpn_create_data()
create_data.update(bgpvpn_create_data)
scenario._create_bgpvpn = mock.Mock()
scenario._delete_bgpvpn = mock.Mock()
scenario.run(bgpvpn_create_args=bgpvpn_create_data)
scenario._create_bgpvpn.assert_called_once_with(bgpvpn_create_data)
scenario.run(**create_data)
scenario._create_bgpvpn.assert_called_once_with(
type="l3", **create_data)
scenario._delete_bgpvpn.assert_called_once_with(
scenario._create_bgpvpn.return_value)
@ddt.data(
{},
{"bgpvpn_create_args": None},
{"bgpvpn_create_args": {}},
)
@ddt.unpack
def test_create_and_list_bgpvpns(self, bgpvpn_create_args=None):
scenario = bgpvpn.CreateAndListBgpvpns(self._get_context())
bgpvpn_create_data = bgpvpn_create_args or {}
create_data = self._get_bgpvpn_create_data()
create_data.update(bgpvpn_create_data)
bgpvpn_created = {"bgpvpn": {"id": 1, "name": "b1"}}
bgpvpn_listed = [{"id": 1}]
scenario._create_bgpvpn = mock.Mock(return_value=bgpvpn_created)
scenario._list_bgpvpns = mock.Mock(return_value=bgpvpn_listed)
scenario.run(**create_data)
scenario._create_bgpvpn.assert_called_once_with(
type="l3", **create_data)
scenario._list_bgpvpns.assert_called_once_with()
@ddt.data(
{},
{"bgpvpn_create_args": {}},
{"bgpvpn_update_args": {}},
{"bgpvpn_update_args": {"update_name": True}},
{"bgpvpn_update_args": {"update_name": False}},
)
@ddt.unpack
def test_create_and_update_bgpvpns(self, bgpvpn_create_args=None,
bgpvpn_update_args=None):
scenario = bgpvpn.CreateAndUpdateBgpvpns(self._get_context())
bgpvpn_create_data = bgpvpn_create_args or {}
bgpvpn_update_data = bgpvpn_update_args or {}
create_data = self._get_bgpvpn_create_data()
create_data.update(bgpvpn_create_data)
update_data = self._get_bgpvpn_update_data()
update_data.update(bgpvpn_update_data)
if "update_name" not in update_data:
update_data["update_name"] = False
bgpvpn_data = {}
bgpvpn_data.update(bgpvpn_create_data)
bgpvpn_data.update(bgpvpn_update_data)
scenario._create_bgpvpn = mock.Mock()
scenario._update_bgpvpn = mock.Mock()
scenario.run(**bgpvpn_data)
scenario._create_bgpvpn.assert_called_once_with(
type="l3", **create_data)
scenario._update_bgpvpn.assert_called_once_with(
scenario._create_bgpvpn.return_value, **update_data)

View File

@ -1017,37 +1017,60 @@ class NeutronScenarioTestCase(test.ScenarioTestCase):
self._test_atomic_action_timer(self.scenario.atomic_actions(),
"neutron.list_lbaasv2_loadbalancers")
@ddt.data(
{"bgpvpn_create_args": {}},
{"bgpvpn_create_args": {"name": "given-name"}}
)
@ddt.unpack
def test__create_bgpvpn(self, atomic_action=True, bgpvpn_create_args=None):
bgpvpn_create_args = bgpvpn_create_args or {}
def test__create_bgpvpn(self, atomic_action=True):
bv = {"bgpvpn": {"id": "bgpvpn-id"}}
self.admin_clients("neutron").create_ext.return_value = bv
if bgpvpn_create_args.get("name") is None:
self.scenario.generate_random_name = mock.Mock(
return_value="random_name")
args = {"name": "random_name"}
args.update(bgpvpn_create_args)
expected_bv_data = {"bgpvpn": args}
resultant_bv = self.scenario._create_bgpvpn(
bgpvpn_create_args=bgpvpn_create_args)
self.admin_clients("neutron").create_bgpvpn.return_value = bv
self.scenario.generate_random_name = mock.Mock(
return_value="random_name")
expected_bv_data = {"bgpvpn": {"name": "random_name"}}
resultant_bv = self.scenario._create_bgpvpn()
self.assertEqual(bv, resultant_bv)
self.admin_clients("neutron").create_ext.assert_called_once_with(
self.scenario.BGPVPNS_PATH, expected_bv_data)
self.admin_clients("neutron").create_bgpvpn.assert_called_once_with(
expected_bv_data)
if atomic_action:
self._test_atomic_action_timer(self.scenario.atomic_actions(),
"neutron.create_bgpvpn")
def test_delete_bgpvpn(self):
bgpvpn_create_args = {}
bgpvpn = self.scenario._create_bgpvpn(bgpvpn_create_args)
bgpvpn = self.scenario._create_bgpvpn(**bgpvpn_create_args)
self.scenario._delete_bgpvpn(bgpvpn)
self._test_atomic_action_timer(self.scenario.atomic_actions(),
"neutron.delete_bgpvpn")
def test__list_bgpvpns(self):
bgpvpns_list = []
bgpvpns_dict = {"bgpvpns": bgpvpns_list}
self.admin_clients("neutron").list_bgpvpns.return_value = bgpvpns_dict
return_bgpvpns_list = self.scenario._list_bgpvpns()
self.assertEqual(bgpvpns_list, return_bgpvpns_list)
self._test_atomic_action_timer(self.scenario.atomic_actions(),
"neutron.list_bgpvpns")
@ddt.data(
{},
{"bgpvpn_update_args": {"update_name": True}},
{"bgpvpn_update_args": {"update_name": False}},
)
@ddt.unpack
def test__update_bgpvpn(self, bgpvpn_update_args=None):
expected_bgpvpn = {"bgpvpn": {}}
bgpvpn_update_data = bgpvpn_update_args or {}
if bgpvpn_update_data.get("update_name"):
expected_bgpvpn = {"bgpvpn": {"name": "updated_name"}}
self.admin_clients(
"neutron").update_bgpvpn.return_value = expected_bgpvpn
self.scenario.generate_random_name = mock.Mock(
return_value="updated_name")
bgpvpn = {"bgpvpn": {"name": "bgpvpn-name", "id": "bgpvpn-id"}}
result_bgpvpn = self.scenario._update_bgpvpn(bgpvpn,
**bgpvpn_update_data)
self.admin_clients("neutron").update_bgpvpn.assert_called_once_with(
bgpvpn["bgpvpn"]["id"], expected_bgpvpn)
self.assertEqual(result_bgpvpn, expected_bgpvpn)
self._test_atomic_action_timer(self.scenario.atomic_actions(),
"neutron.update_bgpvpn")
class NeutronScenarioFunctionalTestCase(test.FakeClientsScenarioTestCase):