Add FloatingIP scenarios
As discussed on the neutron-performance meeting [1] floating IP operations should be covered in the neutron gate rally job. As I set out to write the missing tests I discovered that some of them were already written by rally folks. For example see [2]. Keep in mind the test code has been relocated since to the rally-openstack repository. For example see [3]. They were later added to neutron's rally job definition [4]. Here we add one more scenario to exercise the floating IP operations left uncovered by the above changes: associate and dissociate. [1] http://eavesdrop.openstack.org/meetings/neutron_performance/2018/neutron_performance.2018-10-22-16.02.log.html#l-143 [2] https://review.openstack.org/225223 [3] https://github.com/openstack/rally-openstack/blob/4e4bfc5/rally_openstack/scenarios/neutron/network.py [4] https://review.openstack.org/620952 Change-Id: I32f3bad82fa0ca822e80d51220c120568a709332 Needed-By: https://review.openstack.org/624038
This commit is contained in:
parent
0cce343d6c
commit
3acde99264
@ -290,6 +290,29 @@
|
||||
failure_rate:
|
||||
max: 0
|
||||
|
||||
NeutronNetworks.associate_and_dissociate_floating_ips:
|
||||
-
|
||||
args:
|
||||
floating_network: "public"
|
||||
runner:
|
||||
type: "constant"
|
||||
times: {{smoke or 8}}
|
||||
concurrency: {{smoke or 4}}
|
||||
context:
|
||||
users:
|
||||
tenants: {{smoke or 2}}
|
||||
users_per_tenant: {{smoke or 1}}
|
||||
quotas:
|
||||
neutron:
|
||||
floatingip: -1
|
||||
network: -1
|
||||
port: -1
|
||||
router: -1
|
||||
subnet: -1
|
||||
sla:
|
||||
failure_rate:
|
||||
max: 0
|
||||
|
||||
NeutronNetworks.create_and_list_routers:
|
||||
-
|
||||
args:
|
||||
|
@ -557,6 +557,61 @@ class CreateAndDeleteFloatingIps(utils.NeutronScenario):
|
||||
self._delete_floating_ip(floating_ip["floatingip"])
|
||||
|
||||
|
||||
@validation.add("required_services",
|
||||
services=[consts.Service.NEUTRON])
|
||||
@validation.add("required_platform", platform="openstack", users=True)
|
||||
@validation.add("external_network_exists", param_name="floating_network")
|
||||
@scenario.configure(
|
||||
context={"cleanup@openstack": ["neutron"]},
|
||||
name="NeutronNetworks.associate_and_dissociate_floating_ips",
|
||||
platform="openstack")
|
||||
class AssociateAndDissociateFloatingIps(utils.NeutronScenario):
|
||||
|
||||
def run(self, floating_network=None):
|
||||
"""Associate and dissociate floating IPs.
|
||||
|
||||
Measure the "openstack floating ip set" and
|
||||
"openstack floating ip unset" commands performance.
|
||||
Because of the prerequisites for "floating ip set/unset" we also
|
||||
measure the performance of the following commands:
|
||||
* "openstack network create"
|
||||
* "openstack subnet create"
|
||||
* "openstack port create"
|
||||
* "openstack router create"
|
||||
* "openstack router set --external-gateway"
|
||||
* "openstack router add subnet"
|
||||
|
||||
:param floating_network: str, external network for floating IP creation
|
||||
"""
|
||||
floating_ip = self._create_floatingip(
|
||||
floating_network)
|
||||
|
||||
private_network = self._create_network(
|
||||
network_create_args={})
|
||||
subnet = self._create_subnet(
|
||||
network=private_network,
|
||||
subnet_create_args={})
|
||||
port = self._create_port(
|
||||
network=private_network,
|
||||
port_create_args={})
|
||||
|
||||
router = self._create_router(
|
||||
router_create_args={})
|
||||
floating_network_id = self._get_network_id(floating_network)
|
||||
self._add_gateway_router(
|
||||
router,
|
||||
{"network": {"id": floating_network_id}})
|
||||
self._add_interface_router(
|
||||
subnet["subnet"],
|
||||
router["router"])
|
||||
|
||||
self._associate_floating_ip(
|
||||
floatingip=floating_ip["floatingip"],
|
||||
port=port["port"])
|
||||
self._dissociate_floating_ip(
|
||||
floatingip=floating_ip["floatingip"])
|
||||
|
||||
|
||||
@validation.add("required_services",
|
||||
services=[consts.Service.NEUTRON])
|
||||
@validation.add("required_platform", platform="openstack", users=True)
|
||||
|
@ -410,16 +410,17 @@ class NeutronScenario(scenario.OpenStackScenario):
|
||||
router["id"], {"subnet_id": subnet["id"]})
|
||||
|
||||
@atomic.action_timer("neutron.add_gateway_router")
|
||||
def _add_gateway_router(self, router, ext_net, enable_snat):
|
||||
def _add_gateway_router(self, router, ext_net, enable_snat=None):
|
||||
"""Set the external network gateway for a router.
|
||||
|
||||
:param router: dict, neutron router
|
||||
:param ext_net: external network for the gateway
|
||||
:param enable_snat: True if enable snat
|
||||
:param enable_snat: True if enable snat, None to avoid update
|
||||
"""
|
||||
gw_info = {"network_id": ext_net["network"]["id"]}
|
||||
if self._ext_gw_mode_enabled:
|
||||
gw_info["enable_snat"] = enable_snat
|
||||
if enable_snat is not None:
|
||||
if self._ext_gw_mode_enabled:
|
||||
gw_info["enable_snat"] = enable_snat
|
||||
self.clients("neutron").add_gateway_router(
|
||||
router["router"]["id"], gw_info)
|
||||
|
||||
@ -573,6 +574,29 @@ class NeutronScenario(scenario.OpenStackScenario):
|
||||
"""
|
||||
return self.clients("neutron").delete_floatingip(floating_ip["id"])
|
||||
|
||||
@atomic.action_timer("neutron.associate_floating_ip")
|
||||
def _associate_floating_ip(self, floatingip, port):
|
||||
"""Associate floating IP with port.
|
||||
|
||||
:param floatingip: floating IP dict
|
||||
:param port: port dict
|
||||
:returns: updated floating IP dict
|
||||
"""
|
||||
return self.clients("neutron").update_floatingip(
|
||||
floatingip["id"],
|
||||
{"floatingip": {"port_id": port["id"]}})["floatingip"]
|
||||
|
||||
@atomic.action_timer("neutron.dissociate_floating_ip")
|
||||
def _dissociate_floating_ip(self, floatingip):
|
||||
"""Dissociate floating IP from ports.
|
||||
|
||||
:param floatingip: floating IP dict
|
||||
:returns: updated floating IP dict
|
||||
"""
|
||||
return self.clients("neutron").update_floatingip(
|
||||
floatingip["id"],
|
||||
{"floatingip": {"port_id": None}})["floatingip"]
|
||||
|
||||
@atomic.action_timer("neutron.create_healthmonitor")
|
||||
def _create_v1_healthmonitor(self, **healthmonitor_create_args):
|
||||
"""Create LB healthmonitor.
|
||||
|
@ -0,0 +1,34 @@
|
||||
{
|
||||
"NeutronNetworks.associate_and_dissociate_floating_ips": [
|
||||
{
|
||||
"args": {
|
||||
"floating_network": "public"
|
||||
},
|
||||
"runner": {
|
||||
"type": "constant",
|
||||
"times": 10,
|
||||
"concurrency": 5
|
||||
},
|
||||
"context": {
|
||||
"users": {
|
||||
"tenants": 2,
|
||||
"users_per_tenant": 3
|
||||
},
|
||||
"quotas": {
|
||||
"neutron": {
|
||||
"floatingip": -1,
|
||||
"network": -1,
|
||||
"port": -1,
|
||||
"router": -1,
|
||||
"subnet": -1
|
||||
}
|
||||
}
|
||||
},
|
||||
"sla": {
|
||||
"failure_rate": {
|
||||
"max": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
---
|
||||
NeutronNetworks.associate_and_dissociate_floating_ips:
|
||||
-
|
||||
args:
|
||||
floating_network: "public"
|
||||
runner:
|
||||
type: "constant"
|
||||
times: 10
|
||||
concurrency: 5
|
||||
context:
|
||||
users:
|
||||
tenants: 2
|
||||
users_per_tenant: 3
|
||||
quotas:
|
||||
neutron:
|
||||
floatingip: -1
|
||||
network: -1
|
||||
port: -1
|
||||
router: -1
|
||||
subnet: -1
|
||||
sla:
|
||||
failure_rate:
|
||||
max: 0
|
@ -550,6 +550,33 @@ class NeutronNetworksTestCase(test.ScenarioTestCase):
|
||||
scenario._delete_floating_ip.assert_called_once_with(
|
||||
scenario._create_floatingip.return_value["floatingip"])
|
||||
|
||||
def test_associate_and_dissociate_floating_ips(self):
|
||||
scenario = network.AssociateAndDissociateFloatingIps(self.context)
|
||||
|
||||
fip = {"floatingip": {"id": "floating-ip-id"}}
|
||||
subnet = {"subnet": {}}
|
||||
port = {"port": {"id": "port-id"}}
|
||||
router = {"router": {}}
|
||||
|
||||
scenario._create_floatingip = mock.Mock(return_value=fip)
|
||||
scenario._create_network = mock.Mock()
|
||||
scenario._create_subnet = mock.Mock(return_value=subnet)
|
||||
scenario._create_port = mock.Mock(return_value=port)
|
||||
scenario._create_router = mock.Mock(return_value=router)
|
||||
scenario._get_network_id = mock.Mock()
|
||||
scenario._add_gateway_router = mock.Mock()
|
||||
scenario._add_interface_router = mock.Mock()
|
||||
|
||||
scenario._associate_floating_ip = mock.Mock()
|
||||
scenario._dissociate_floating_ip = mock.Mock()
|
||||
|
||||
scenario.run(floating_network="public")
|
||||
|
||||
scenario._associate_floating_ip.assert_called_once_with(
|
||||
floatingip=fip["floatingip"], port=port["port"])
|
||||
scenario._dissociate_floating_ip.assert_called_once_with(
|
||||
floatingip=fip["floatingip"])
|
||||
|
||||
@mock.patch("%s.DeleteSubnets._delete_subnet" % BASE)
|
||||
def test_delete_subnets(self, mock__delete_subnet):
|
||||
# do not guess what user will be used
|
||||
|
@ -413,6 +413,29 @@ class NeutronScenarioTestCase(test.ScenarioTestCase):
|
||||
self._test_atomic_action_timer(self.scenario.atomic_actions(),
|
||||
"neutron.add_gateway_router")
|
||||
|
||||
def test_add_gateway_router_no_snat_update(self):
|
||||
ext_net = {
|
||||
"network": {
|
||||
"name": "extnet-name",
|
||||
"id": "extnet-id"
|
||||
}
|
||||
}
|
||||
router = {
|
||||
"router": {
|
||||
"name": "router-name",
|
||||
"id": "router-id"
|
||||
}
|
||||
}
|
||||
gw_info = {"network_id": ext_net["network"]["id"]}
|
||||
self.clients("neutron").list_extensions.return_value = {
|
||||
"extensions": [{"alias": "ext-gw-mode"}]}
|
||||
|
||||
self.scenario._add_gateway_router(router, ext_net)
|
||||
self.clients("neutron").add_gateway_router.assert_called_once_with(
|
||||
router["router"]["id"], gw_info)
|
||||
self._test_atomic_action_timer(self.scenario.atomic_actions(),
|
||||
"neutron.add_gateway_router")
|
||||
|
||||
def test_add_gateway_router_without_ext_gw_mode_extension(self):
|
||||
ext_net = {
|
||||
"network": {
|
||||
@ -627,6 +650,23 @@ class NeutronScenarioTestCase(test.ScenarioTestCase):
|
||||
self._test_atomic_action_timer(self.scenario.atomic_actions(),
|
||||
"neutron.delete_floating_ip")
|
||||
|
||||
def test_associate_floating_ip(self):
|
||||
fip = {"id": "fip-id"}
|
||||
port = {"id": "port-id"}
|
||||
self.scenario._associate_floating_ip(fip, port)
|
||||
self.clients("neutron").update_floatingip.assert_called_once_with(
|
||||
"fip-id", {"floatingip": {"port_id": "port-id"}})
|
||||
self._test_atomic_action_timer(self.scenario.atomic_actions(),
|
||||
"neutron.associate_floating_ip")
|
||||
|
||||
def test_dissociate_floating_ip(self):
|
||||
fip = {"id": "fip-id"}
|
||||
self.scenario._dissociate_floating_ip(fip)
|
||||
self.clients("neutron").update_floatingip.assert_called_once_with(
|
||||
"fip-id", {"floatingip": {"port_id": None}})
|
||||
self._test_atomic_action_timer(self.scenario.atomic_actions(),
|
||||
"neutron.dissociate_floating_ip")
|
||||
|
||||
@ddt.data(
|
||||
{},
|
||||
{"router_create_args": {"admin_state_up": False}},
|
||||
|
Loading…
x
Reference in New Issue
Block a user