Add Neutron Loadbalancer v1 create and list pool
Enable benchmarking of the Neutron LoadBalancer v1 pool-create and pool-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: If51f6286be49724c0bc4ae343815704f01153e97
This commit is contained in:
parent
ed2996dac1
commit
bc9e8d0660
@ -91,6 +91,28 @@
|
||||
failure_rate:
|
||||
max: 20
|
||||
|
||||
NeutronLoadbalancerV1.create_and_list_pools:
|
||||
-
|
||||
args:
|
||||
pool_create_args: {}
|
||||
runner:
|
||||
type: "constant"
|
||||
times: 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:
|
||||
|
@ -52,6 +52,10 @@ class NeutronQuotas(object):
|
||||
"security_group_rule": {
|
||||
"type": "integer",
|
||||
"minimum": -1
|
||||
},
|
||||
"pool": {
|
||||
"type": "integer",
|
||||
"minimum": -1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
38
rally/plugins/openstack/scenarios/neutron/loadbalancer_v1.py
Normal file
38
rally/plugins/openstack/scenarios/neutron/loadbalancer_v1.py
Normal file
@ -0,0 +1,38 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from rally.benchmark.scenarios import base
|
||||
from rally.benchmark import validation
|
||||
from rally import consts
|
||||
from rally.plugins.openstack.scenarios.neutron import utils
|
||||
|
||||
|
||||
class NeutronLoadbalancerV1(utils.NeutronScenario):
|
||||
"""Benchmark scenarios for Neutron Loadbalancer v1."""
|
||||
|
||||
@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_list_pools(self, pool_create_args=None):
|
||||
"""Create a pool(v1) and then list pools(v1).
|
||||
|
||||
Measure the "neutron lb-pool-list" command performance.
|
||||
The scenario creates a pool for every subnet and then lists pools.
|
||||
|
||||
:param pool_create_args: dict, POST /lb/pools request options
|
||||
"""
|
||||
for net in self.context.get("tenant", {}).get("networks", []):
|
||||
for subnet_id in net["subnets"]:
|
||||
self._create_v1_pool(subnet_id, **pool_create_args)
|
||||
self._list_v1_pools()
|
@ -28,6 +28,9 @@ class NeutronScenario(base.Scenario):
|
||||
RESOURCE_NAME_PREFIX = "rally_net_"
|
||||
RESOURCE_NAME_LENGTH = 16
|
||||
SUBNET_IP_VERSION = 4
|
||||
# TODO(rkiran): modify in case LBaaS-v2 requires
|
||||
LB_METHOD = "ROUND_ROBIN"
|
||||
LB_PROTOCOL = "HTTP"
|
||||
|
||||
@base.atomic_action_timer("neutron.create_network")
|
||||
def _create_network(self, network_create_args):
|
||||
@ -287,3 +290,22 @@ class NeutronScenario(base.Scenario):
|
||||
"""
|
||||
self.clients("neutron").remove_interface_router(
|
||||
router["id"], {"subnet_id": subnet["id"]})
|
||||
|
||||
@base.atomic_action_timer("neutron.create_pool")
|
||||
def _create_v1_pool(self, subnet_id, **pool_create_args):
|
||||
"""Create pool(v1)
|
||||
|
||||
:parm subnet_id: str, neutron subnet-id
|
||||
:parm pool_create_args: dict, POST /lb/pools request options
|
||||
:returns: obj, neutron lb pool
|
||||
"""
|
||||
args = {"lb_method": self.LB_METHOD, "protocol": self.LB_PROTOCOL,
|
||||
"name": self._generate_random_name("rally_pool_"),
|
||||
"subnet_id": subnet_id}
|
||||
args.update(pool_create_args)
|
||||
return self.clients("neutron").create_pool({"pool": args})
|
||||
|
||||
@base.atomic_action_timer("neutron.list_pools")
|
||||
def _list_v1_pools(self, **kwargs):
|
||||
"""Return user lb pool list(v1)."""
|
||||
return self.clients("neutron").list_pools()
|
||||
|
@ -1064,6 +1064,7 @@ class FakeNeutronClient(object):
|
||||
self.__subnets = {}
|
||||
self.__routers = {}
|
||||
self.__ports = {}
|
||||
self.__pools = {}
|
||||
self.__tenant_id = kwargs.get("tenant_id", generate_uuid())
|
||||
|
||||
self.format = "json"
|
||||
@ -1112,6 +1113,21 @@ class FakeNeutronClient(object):
|
||||
self.__networks[network_id] = network
|
||||
return {"network": network}
|
||||
|
||||
def create_pool(self, data):
|
||||
pool = setup_dict(data["pool"],
|
||||
required=["lb_method", "protocol", "subnet_id"],
|
||||
defaults={"name": generate_name("pool_"),
|
||||
"admin_state_up": True})
|
||||
if pool["subnet_id"] not in self.__subnets:
|
||||
raise neutron_exceptions.NeutronClientException
|
||||
pool_id = generate_uuid()
|
||||
|
||||
pool.update({"id": pool_id,
|
||||
"status": "PENDING_CREATE",
|
||||
"tenant_id": self.__tenant_id})
|
||||
self.__pools[pool_id] = pool
|
||||
return {"pool": pool}
|
||||
|
||||
def create_port(self, data):
|
||||
port = setup_dict(data["port"],
|
||||
required=["network_id"],
|
||||
@ -1238,6 +1254,10 @@ class FakeNeutronClient(object):
|
||||
nets = self._filter(self.__networks.values(), search_opts)
|
||||
return {"networks": nets}
|
||||
|
||||
def list_pools(self, **search_opts):
|
||||
pools = self._filter(self.__pools.values(), search_opts)
|
||||
return {"pools": pools}
|
||||
|
||||
def list_ports(self, **search_opts):
|
||||
ports = self._filter(self.__ports.values(), search_opts)
|
||||
return {"ports": ports}
|
||||
|
@ -0,0 +1,45 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import mock
|
||||
|
||||
from rally.plugins.openstack.scenarios.neutron import loadbalancer_v1
|
||||
from tests.unit import test
|
||||
|
||||
|
||||
class NeutronLoadbalancerv1TestCase(test.TestCase):
|
||||
|
||||
def _get_context(self):
|
||||
return {
|
||||
"user": {"id": "fake_user", "tenant_id": "fake_tenant"},
|
||||
"tenant": {"id": "fake_tenant",
|
||||
"networks": [{"id": "fake_net",
|
||||
"subnets": ["fake_subnet"]}]}}
|
||||
|
||||
def _validate_scenario(self, pool_create_args):
|
||||
neutron_scenario = loadbalancer_v1.NeutronLoadbalancerV1(
|
||||
self._get_context())
|
||||
neutron_scenario._create_v1_pool = mock.Mock()
|
||||
neutron_scenario._list_v1_pools = mock.Mock()
|
||||
neutron_scenario.create_and_list_pools(
|
||||
pool_create_args=pool_create_args)
|
||||
for net in self._get_context()["tenant"]["networks"]:
|
||||
for subnet_id in net["subnets"]:
|
||||
neutron_scenario._create_v1_pool.assert_called_once_with(
|
||||
subnet_id, **pool_create_args)
|
||||
neutron_scenario._list_v1_pools.assert_called_once_with()
|
||||
|
||||
def test_create_and_list_pools_default(self):
|
||||
self._validate_scenario(pool_create_args={})
|
||||
|
||||
def test_create_and_list_pools_explicit(self):
|
||||
self._validate_scenario(pool_create_args={"name": "given-name"})
|
@ -391,6 +391,56 @@ class NeutronScenarioTestCase(test.ClientsTestCase):
|
||||
{"allocation_pools": []},
|
||||
"10.10.10.0/24")] * subnets_per_network)
|
||||
|
||||
def test_create_v1_pool_explicit(self):
|
||||
neutron_scenario = utils.NeutronScenario()
|
||||
lb_method = "LEAST_CONNECTIONS"
|
||||
subnet = "fake-id"
|
||||
pool = mock.Mock()
|
||||
self.clients("neutron").create_pool.return_value = pool
|
||||
# Explicit options
|
||||
pool_data = {"lb_method": lb_method, "name": "explicit-name"}
|
||||
args = {"lb_method": "ROUND_ROBIN", "protocol": "HTTP",
|
||||
"name": "random_name", "subnet_id": subnet}
|
||||
args.update(pool_data)
|
||||
expected_pool_data = {"pool": args}
|
||||
pool = neutron_scenario._create_v1_pool(
|
||||
subnet_id=subnet, **pool_data)
|
||||
self.clients("neutron").create_pool.assert_called_once_with(
|
||||
expected_pool_data)
|
||||
self._test_atomic_action_timer(
|
||||
neutron_scenario.atomic_actions(), "neutron.create_pool")
|
||||
|
||||
@mock.patch(NEUTRON_UTILS + "NeutronScenario._generate_random_name")
|
||||
def test_create_v1_pool_default(self, mock_random_name):
|
||||
neutron_scenario = utils.NeutronScenario()
|
||||
random_name = "random_name"
|
||||
subnet = "fake-id"
|
||||
pool = mock.Mock()
|
||||
self.clients("neutron").create_pool.return_value = pool
|
||||
mock_random_name.return_value = random_name
|
||||
# Random pool name
|
||||
pool_data = {}
|
||||
args = {"lb_method": "ROUND_ROBIN", "protocol": "HTTP",
|
||||
"name": "random_name", "subnet_id": subnet}
|
||||
args.update(pool_data)
|
||||
expected_pool_data = {"pool": args}
|
||||
pool = neutron_scenario._create_v1_pool(
|
||||
subnet_id=subnet, **pool_data)
|
||||
self.clients("neutron").create_pool.assert_called_once_with(
|
||||
expected_pool_data)
|
||||
self._test_atomic_action_timer(
|
||||
neutron_scenario.atomic_actions(), "neutron.create_pool")
|
||||
|
||||
def test_list_v1_pools(self):
|
||||
scenario = utils.NeutronScenario()
|
||||
pools_list = []
|
||||
pools_dict = {"pools": pools_list}
|
||||
self.clients("neutron").list_pools.return_value = pools_dict
|
||||
return_pools_dict = scenario._list_v1_pools()
|
||||
self.assertEqual(pools_dict, return_pools_dict)
|
||||
self._test_atomic_action_timer(scenario.atomic_actions(),
|
||||
"neutron.list_pools")
|
||||
|
||||
|
||||
class NeutronScenarioFunctionalTestCase(test.FakeClientsTestCase):
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user