Merge "Add Neutron Loadbalancer v1 create and list pool"

This commit is contained in:
Jenkins 2015-06-13 01:30:59 +00:00 committed by Gerrit Code Review
commit c52f111a98
7 changed files with 201 additions and 0 deletions

View File

@ -91,6 +91,28 @@
failure_rate: failure_rate:
max: 20 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: NeutronNetworks.create_and_update_networks:
- -
args: args:

View File

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

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

View File

@ -28,6 +28,9 @@ class NeutronScenario(base.Scenario):
RESOURCE_NAME_PREFIX = "rally_net_" RESOURCE_NAME_PREFIX = "rally_net_"
RESOURCE_NAME_LENGTH = 16 RESOURCE_NAME_LENGTH = 16
SUBNET_IP_VERSION = 4 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") @base.atomic_action_timer("neutron.create_network")
def _create_network(self, network_create_args): def _create_network(self, network_create_args):
@ -287,3 +290,22 @@ class NeutronScenario(base.Scenario):
""" """
self.clients("neutron").remove_interface_router( self.clients("neutron").remove_interface_router(
router["id"], {"subnet_id": subnet["id"]}) 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()

View File

@ -1064,6 +1064,7 @@ class FakeNeutronClient(object):
self.__subnets = {} self.__subnets = {}
self.__routers = {} self.__routers = {}
self.__ports = {} self.__ports = {}
self.__pools = {}
self.__tenant_id = kwargs.get("tenant_id", generate_uuid()) self.__tenant_id = kwargs.get("tenant_id", generate_uuid())
self.format = "json" self.format = "json"
@ -1112,6 +1113,21 @@ class FakeNeutronClient(object):
self.__networks[network_id] = network self.__networks[network_id] = network
return {"network": 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): def create_port(self, data):
port = setup_dict(data["port"], port = setup_dict(data["port"],
required=["network_id"], required=["network_id"],
@ -1238,6 +1254,10 @@ class FakeNeutronClient(object):
nets = self._filter(self.__networks.values(), search_opts) nets = self._filter(self.__networks.values(), search_opts)
return {"networks": nets} 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): def list_ports(self, **search_opts):
ports = self._filter(self.__ports.values(), search_opts) ports = self._filter(self.__ports.values(), search_opts)
return {"ports": ports} return {"ports": ports}

View File

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

View File

@ -391,6 +391,56 @@ class NeutronScenarioTestCase(test.ClientsTestCase):
{"allocation_pools": []}, {"allocation_pools": []},
"10.10.10.0/24")] * subnets_per_network) "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): class NeutronScenarioFunctionalTestCase(test.FakeClientsTestCase):