Add Neutron benchmarks scenario for creating and listing routers
In this patch: * scenario NeutronNetworks.create_and_list_routers is added, which does the following: - creates networks, subnets, routers according to scenario file - adds routers interfaces to created subnets - lists routers * refactoring in NeutronNetworks class for PEP257 and methods arguments * a piece of rafactoring in ResourceCleaner tests * classmethod NeutronScenario._generate_subnet_cidr is re-implemented for using netaddr.IPNetwork class * base implementation for class fakes.FakeNeutronClient * some improvements and refactoring for fakes blueprint benchmark-scenarios-for-neutron Change-Id: I6dbbe9e476cdf0f1fd4c7f1387e830b5a46e2aa6
This commit is contained in:
parent
e1c555c7cf
commit
4c77a8748d
@ -2,7 +2,7 @@
|
|||||||
"NeutronNetworks.create_and_list_networks": [
|
"NeutronNetworks.create_and_list_networks": [
|
||||||
{
|
{
|
||||||
"args": {
|
"args": {
|
||||||
"network_data": {}
|
"network_create_args": {}
|
||||||
},
|
},
|
||||||
"runner": {
|
"runner": {
|
||||||
"type": "constant",
|
"type": "constant",
|
||||||
@ -13,6 +13,11 @@
|
|||||||
"users": {
|
"users": {
|
||||||
"tenants": 1,
|
"tenants": 1,
|
||||||
"users_per_tenant": 1
|
"users_per_tenant": 1
|
||||||
|
},
|
||||||
|
"quotas": {
|
||||||
|
"neutron": {
|
||||||
|
"network": -1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
NeutronNetworks.create_and_list_networks:
|
NeutronNetworks.create_and_list_networks:
|
||||||
-
|
-
|
||||||
args:
|
args:
|
||||||
network_data:
|
network_create_args:
|
||||||
runner:
|
runner:
|
||||||
type: "constant"
|
type: "constant"
|
||||||
times: 100
|
times: 100
|
||||||
@ -11,3 +11,6 @@
|
|||||||
users:
|
users:
|
||||||
tenants: 1
|
tenants: 1
|
||||||
users_per_tenant: 1
|
users_per_tenant: 1
|
||||||
|
quotas:
|
||||||
|
neutron:
|
||||||
|
network: -1
|
||||||
|
31
doc/samples/tasks/neutron/create_and_list_routers.json
Normal file
31
doc/samples/tasks/neutron/create_and_list_routers.json
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"NeutronNetworks.create_and_list_routers": [
|
||||||
|
{
|
||||||
|
"args": {
|
||||||
|
"network_create_args": {},
|
||||||
|
"subnet_create_args": {},
|
||||||
|
"subnet_cidr_start": "1.1.0.0/30",
|
||||||
|
"subnets_per_network": 2,
|
||||||
|
"router_create_args": {}
|
||||||
|
},
|
||||||
|
"runner": {
|
||||||
|
"type": "constant",
|
||||||
|
"times": 100,
|
||||||
|
"concurrency": 10
|
||||||
|
},
|
||||||
|
"context": {
|
||||||
|
"users": {
|
||||||
|
"tenants": 1,
|
||||||
|
"users_per_tenant": 1
|
||||||
|
},
|
||||||
|
"quotas": {
|
||||||
|
"neutron": {
|
||||||
|
"network": -1,
|
||||||
|
"subnet": -1,
|
||||||
|
"router": -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
22
doc/samples/tasks/neutron/create_and_list_routers.yaml
Normal file
22
doc/samples/tasks/neutron/create_and_list_routers.yaml
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
---
|
||||||
|
NeutronNetworks.create_and_list_routers:
|
||||||
|
-
|
||||||
|
args:
|
||||||
|
network_create_args:
|
||||||
|
subnet_create_args:
|
||||||
|
subnet_cidr_start: "1.1.0.0/30"
|
||||||
|
subnets_per_network: 2
|
||||||
|
router_create_args:
|
||||||
|
runner:
|
||||||
|
type: "constant"
|
||||||
|
times: 100
|
||||||
|
concurrency: 10
|
||||||
|
context:
|
||||||
|
users:
|
||||||
|
tenants: 1
|
||||||
|
users_per_tenant: 1
|
||||||
|
quotas:
|
||||||
|
neutron:
|
||||||
|
network: -1
|
||||||
|
subnet: -1
|
||||||
|
router: -1
|
@ -2,8 +2,9 @@
|
|||||||
"NeutronNetworks.create_and_list_subnets": [
|
"NeutronNetworks.create_and_list_subnets": [
|
||||||
{
|
{
|
||||||
"args": {
|
"args": {
|
||||||
"network_data": {},
|
"network_create_args": {},
|
||||||
"subnet_data": {},
|
"subnet_create_args": {},
|
||||||
|
"subnet_cidr_start": "1.1.0.0/30",
|
||||||
"subnets_per_network": 2
|
"subnets_per_network": 2
|
||||||
},
|
},
|
||||||
"runner": {
|
"runner": {
|
||||||
@ -15,6 +16,12 @@
|
|||||||
"users": {
|
"users": {
|
||||||
"tenants": 5,
|
"tenants": 5,
|
||||||
"users_per_tenant": 5
|
"users_per_tenant": 5
|
||||||
|
},
|
||||||
|
"quotas": {
|
||||||
|
"neutron": {
|
||||||
|
"network": -1,
|
||||||
|
"subnet": -1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,14 +2,19 @@
|
|||||||
NeutronNetworks.create_and_list_subnets:
|
NeutronNetworks.create_and_list_subnets:
|
||||||
-
|
-
|
||||||
args:
|
args:
|
||||||
network_data:
|
network_create_args:
|
||||||
subnet_data:
|
subnet_create_args:
|
||||||
|
subnet_cidr_start: "1.1.0.0/30"
|
||||||
subnets_per_network: 2
|
subnets_per_network: 2
|
||||||
runner:
|
runner:
|
||||||
type: "constant"
|
type: "constant"
|
||||||
times: 10
|
times: 100
|
||||||
concurrency: 5
|
concurrency: 10
|
||||||
context:
|
context:
|
||||||
users:
|
users:
|
||||||
tenants: 5
|
tenants: 1
|
||||||
users_per_tenant: 5
|
users_per_tenant: 1
|
||||||
|
quotas:
|
||||||
|
neutron:
|
||||||
|
network: -1
|
||||||
|
subnet: -1
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
NeutronNetworks.create_and_list_networks:
|
NeutronNetworks.create_and_list_networks:
|
||||||
-
|
-
|
||||||
args:
|
args:
|
||||||
network_data:
|
network_create_args:
|
||||||
runner:
|
runner:
|
||||||
type: "constant"
|
type: "constant"
|
||||||
times: 100
|
times: 100
|
||||||
@ -53,18 +53,41 @@
|
|||||||
NeutronNetworks.create_and_list_subnets:
|
NeutronNetworks.create_and_list_subnets:
|
||||||
-
|
-
|
||||||
args:
|
args:
|
||||||
network_data:
|
network_create_args:
|
||||||
subnet_data:
|
subnet_create_args:
|
||||||
|
subnet_cidr_start: "1.1.0.0/30"
|
||||||
subnets_per_network: 2
|
subnets_per_network: 2
|
||||||
runner:
|
runner:
|
||||||
type: "constant"
|
type: "constant"
|
||||||
times: 100
|
times: 100
|
||||||
concurrency: 5
|
concurrency: 10
|
||||||
context:
|
context:
|
||||||
users:
|
users:
|
||||||
tenants: 1
|
tenants: 1
|
||||||
users_per_tenant: 1
|
users_per_tenant: 1
|
||||||
quotas:
|
quotas:
|
||||||
neutron:
|
neutron:
|
||||||
subnet: -1
|
|
||||||
network: -1
|
network: -1
|
||||||
|
subnet: -1
|
||||||
|
|
||||||
|
NeutronNetworks.create_and_list_routers:
|
||||||
|
-
|
||||||
|
args:
|
||||||
|
network_create_args:
|
||||||
|
subnet_create_args:
|
||||||
|
subnet_cidr_start: "1.1.0.0/30"
|
||||||
|
subnets_per_network: 2
|
||||||
|
router_create_args:
|
||||||
|
runner:
|
||||||
|
type: "constant"
|
||||||
|
times: 100
|
||||||
|
concurrency: 10
|
||||||
|
context:
|
||||||
|
users:
|
||||||
|
tenants: 1
|
||||||
|
users_per_tenant: 1
|
||||||
|
quotas:
|
||||||
|
neutron:
|
||||||
|
network: -1
|
||||||
|
subnet: -1
|
||||||
|
router: -1
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
from neutronclient.common import exceptions as neutron_exceptions
|
||||||
|
|
||||||
from rally.benchmark.scenarios.keystone import utils as kutils
|
from rally.benchmark.scenarios.keystone import utils as kutils
|
||||||
from rally.benchmark import utils as bench_utils
|
from rally.benchmark import utils as bench_utils
|
||||||
|
|
||||||
@ -116,21 +118,36 @@ def delete_keypairs(nova):
|
|||||||
_wait_for_empty_list(nova.keypairs)
|
_wait_for_empty_list(nova.keypairs)
|
||||||
|
|
||||||
|
|
||||||
def delete_neutron_networks(neutron, project_uuid):
|
|
||||||
for network in neutron.list_networks()['networks']:
|
|
||||||
if network['tenant_id'] == project_uuid:
|
|
||||||
neutron.delete_network(network['id'])
|
|
||||||
|
|
||||||
|
|
||||||
def delete_neutron_subnets(neutron, project_uuid):
|
|
||||||
for subnet in neutron.list_subnets()['subnets']:
|
|
||||||
if subnet['tenant_id'] == project_uuid:
|
|
||||||
neutron.delete_subnet(subnet['id'])
|
|
||||||
|
|
||||||
|
|
||||||
def delete_neutron_resources(neutron, project_uuid):
|
def delete_neutron_resources(neutron, project_uuid):
|
||||||
delete_neutron_subnets(neutron, project_uuid)
|
# Ports
|
||||||
delete_neutron_networks(neutron, project_uuid)
|
for port in neutron.list_ports()["ports"]:
|
||||||
|
if port["tenant_id"] == project_uuid:
|
||||||
|
|
||||||
|
# Detach routers
|
||||||
|
for fip in port["fixed_ips"]:
|
||||||
|
neutron.remove_interface_router(
|
||||||
|
port["device_id"], {
|
||||||
|
"subnet_id": fip["subnet_id"]
|
||||||
|
})
|
||||||
|
try:
|
||||||
|
neutron.delete_port(port["id"])
|
||||||
|
except neutron_exceptions.PortNotFoundClient:
|
||||||
|
# Port can be already auto-deleted, skip silently
|
||||||
|
pass
|
||||||
|
# Routers
|
||||||
|
for router in neutron.list_routers()["routers"]:
|
||||||
|
if router["tenant_id"] == project_uuid:
|
||||||
|
neutron.delete_router(router["id"])
|
||||||
|
|
||||||
|
# Subnets
|
||||||
|
for subnet in neutron.list_subnets()["subnets"]:
|
||||||
|
if subnet["tenant_id"] == project_uuid:
|
||||||
|
neutron.delete_subnet(subnet["id"])
|
||||||
|
|
||||||
|
# Networks
|
||||||
|
for network in neutron.list_networks()["networks"]:
|
||||||
|
if network["tenant_id"] == project_uuid:
|
||||||
|
neutron.delete_network(network["id"])
|
||||||
|
|
||||||
|
|
||||||
def delete_ceilometer_resources(ceilometer, project_uuid):
|
def delete_ceilometer_resources(ceilometer, project_uuid):
|
||||||
|
@ -15,13 +15,14 @@
|
|||||||
|
|
||||||
from rally.benchmark.scenarios import base
|
from rally.benchmark.scenarios import base
|
||||||
from rally.benchmark.scenarios.neutron import utils
|
from rally.benchmark.scenarios.neutron import utils
|
||||||
|
from rally.benchmark import validation
|
||||||
|
|
||||||
|
|
||||||
class NeutronNetworks(utils.NeutronScenario):
|
class NeutronNetworks(utils.NeutronScenario):
|
||||||
|
|
||||||
@base.scenario(context={"cleanup": ["neutron"]})
|
@base.scenario(context={"cleanup": ["neutron"]})
|
||||||
def create_and_list_networks(self, network_data=None):
|
def create_and_list_networks(self, network_create_args=None):
|
||||||
"""Tests creating a network and then listing all networks.
|
"""Create a network and then listing all networks.
|
||||||
|
|
||||||
This scenario is a very useful tool to measure
|
This scenario is a very useful tool to measure
|
||||||
the "neutron net-list" command performance.
|
the "neutron net-list" command performance.
|
||||||
@ -32,26 +33,59 @@ class NeutronNetworks(utils.NeutronScenario):
|
|||||||
performance of the "neutron net-list" command depending on
|
performance of the "neutron net-list" command depending on
|
||||||
the number of networks owned by users.
|
the number of networks owned by users.
|
||||||
|
|
||||||
:param network_data: dict, network options
|
:param network_create_args: dict, POST /v2.0/networks request options
|
||||||
"""
|
"""
|
||||||
self._create_network(network_data or {})
|
self._create_network(network_create_args or {})
|
||||||
self._list_networks()
|
self._list_networks()
|
||||||
|
|
||||||
@base.scenario(context={"cleanup": ["neutron"]})
|
@base.scenario(context={"cleanup": ["neutron"]})
|
||||||
|
@validation.add(validation.required_parameters(['subnets_per_network']))
|
||||||
def create_and_list_subnets(self,
|
def create_and_list_subnets(self,
|
||||||
network_data=None,
|
network_create_args=None,
|
||||||
subnet_data=None,
|
subnet_create_args=None,
|
||||||
subnets_per_network=1):
|
subnet_cidr_start=None,
|
||||||
"""Tests creating a network, a given number of subnets
|
subnets_per_network=None):
|
||||||
and then list subnets.
|
"""Create a network, a given number of subnets
|
||||||
|
and then list all subnets.
|
||||||
|
|
||||||
:param network_data: dict, network options
|
:param network_create_args: dict, POST /v2.0/networks request options
|
||||||
:param subnet_data: dict, subnet options
|
:param subnet_create_args: dict, POST /v2.0/subnets request options
|
||||||
|
:param subnet_cidr_start: str, start value for subnets CIDR
|
||||||
:param subnets_per_network: int, number of subnets for one network
|
:param subnets_per_network: int, number of subnets for one network
|
||||||
"""
|
"""
|
||||||
|
if subnet_cidr_start:
|
||||||
network = self._create_network(network_data or {})
|
NeutronNetworks.SUBNET_CIDR_START = subnet_cidr_start
|
||||||
|
network = self._create_network(network_create_args or {})
|
||||||
for i in range(subnets_per_network):
|
for i in range(subnets_per_network):
|
||||||
self._create_subnet(network, subnet_data or {})
|
self._create_subnet(network, subnet_create_args or {})
|
||||||
|
|
||||||
self._list_subnets()
|
self._list_subnets()
|
||||||
|
|
||||||
|
@base.scenario(context={"cleanup": ["neutron"]})
|
||||||
|
@validation.add(validation.required_parameters(['subnets_per_network']))
|
||||||
|
def create_and_list_routers(self,
|
||||||
|
network_create_args=None,
|
||||||
|
subnet_create_args=None,
|
||||||
|
subnet_cidr_start=None,
|
||||||
|
subnets_per_network=None,
|
||||||
|
router_create_args=None):
|
||||||
|
"""Create a network, a given number of subnets and routers
|
||||||
|
and then list all routers.
|
||||||
|
|
||||||
|
:param network_create_args: dict, POST /v2.0/networks request options
|
||||||
|
:param subnet_create_args: dict, POST /v2.0/subnets request options
|
||||||
|
:param subnet_cidr_start: str, start value for subnets CIDR
|
||||||
|
:param subnets_per_network: int, number of subnets for one network
|
||||||
|
:param router_create_args: dict, POST /v2.0/routers request options
|
||||||
|
"""
|
||||||
|
if subnet_cidr_start:
|
||||||
|
NeutronNetworks.SUBNET_CIDR_START = subnet_cidr_start
|
||||||
|
network = self._create_network(network_create_args or {})
|
||||||
|
for i in range(subnets_per_network):
|
||||||
|
subnet = self._create_subnet(network, subnet_create_args or {})
|
||||||
|
router = self._create_router(router_create_args or {})
|
||||||
|
self.clients("neutron").add_interface_router(
|
||||||
|
router["router"]["id"],
|
||||||
|
{"subnet_id": subnet["subnet"]["id"]})
|
||||||
|
|
||||||
|
self._list_routers()
|
||||||
|
@ -13,6 +13,9 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import multiprocessing
|
||||||
|
import netaddr
|
||||||
|
|
||||||
from rally.benchmark.scenarios import base
|
from rally.benchmark.scenarios import base
|
||||||
from rally.benchmark.scenarios import utils as scenario_utils
|
from rally.benchmark.scenarios import utils as scenario_utils
|
||||||
|
|
||||||
@ -24,62 +27,81 @@ class NeutronScenario(base.Scenario):
|
|||||||
|
|
||||||
RESOURCE_NAME_PREFIX = "rally_net_"
|
RESOURCE_NAME_PREFIX = "rally_net_"
|
||||||
SUBNET_IP_VERSION = 4
|
SUBNET_IP_VERSION = 4
|
||||||
SUBNET_CIDR_PATTERN = "192.168.%d.0/24"
|
SUBNET_CIDR_START = "1.1.0.0/30"
|
||||||
|
|
||||||
_subnet_cidrs = {}
|
_subnet_cidrs = {}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _generate_subnet_cidr(cls, network_id):
|
def _generate_subnet_cidr(cls, network_id):
|
||||||
"""Generates next subnet CIDR for given network,
|
"""Generate next subnet CIDR for given network,
|
||||||
without IP overlapping.
|
without IP overlapping.
|
||||||
"""
|
|
||||||
if network_id in cls._subnet_cidrs:
|
|
||||||
cidr_no = cls._subnet_cidrs[network_id]
|
|
||||||
if cidr_no > 255:
|
|
||||||
# NOTE(amaretskiy): consider whether max number of
|
|
||||||
# 255 subnets per network is enough.
|
|
||||||
raise ValueError(
|
|
||||||
"can not generate more than 255 subnets CIDRs "
|
|
||||||
"per one network due to IP pattern limitation")
|
|
||||||
else:
|
|
||||||
cidr_no = 0
|
|
||||||
|
|
||||||
cls._subnet_cidrs[network_id] = cidr_no + 1
|
:param network_id: str, network UUID for subnet
|
||||||
return cls.SUBNET_CIDR_PATTERN % cidr_no
|
:returns: str, next available subnet CIDR
|
||||||
|
"""
|
||||||
|
with multiprocessing.Lock():
|
||||||
|
if network_id in cls._subnet_cidrs:
|
||||||
|
crnt_cidr = cls._subnet_cidrs[network_id]
|
||||||
|
cidr = str(netaddr.IPNetwork(crnt_cidr).next())
|
||||||
|
else:
|
||||||
|
cidr = str(netaddr.IPNetwork(cls.SUBNET_CIDR_START))
|
||||||
|
cls._subnet_cidrs[network_id] = cidr
|
||||||
|
return cidr
|
||||||
|
|
||||||
@scenario_utils.atomic_action_timer('neutron.create_network')
|
@scenario_utils.atomic_action_timer('neutron.create_network')
|
||||||
def _create_network(self, network_data):
|
def _create_network(self, network_create_args):
|
||||||
"""Creates neutron network.
|
"""Create neutron network.
|
||||||
|
|
||||||
:param network_data: options for API v2.0 networks POST request
|
:param network_create_args: dict, POST /v2.0/networks request options
|
||||||
:returns: neutron network dict
|
:returns: neutron network dict
|
||||||
"""
|
"""
|
||||||
network_data.setdefault("name", self._generate_random_name())
|
network_create_args.setdefault("name", self._generate_random_name())
|
||||||
return self.clients("neutron").create_network({
|
return self.clients("neutron"
|
||||||
"network": network_data})
|
).create_network({"network": network_create_args})
|
||||||
|
|
||||||
@scenario_utils.atomic_action_timer('neutron.list_networks')
|
@scenario_utils.atomic_action_timer('neutron.list_networks')
|
||||||
def _list_networks(self):
|
def _list_networks(self):
|
||||||
"""Returns user networks list."""
|
"""Return user networks list."""
|
||||||
return self.clients("neutron").list_networks()['networks']
|
return self.clients("neutron").list_networks()['networks']
|
||||||
|
|
||||||
@scenario_utils.atomic_action_timer('neutron.create_subnet')
|
@scenario_utils.atomic_action_timer('neutron.create_subnet')
|
||||||
def _create_subnet(self, network, subnet_data):
|
def _create_subnet(self, network, subnet_create_args):
|
||||||
"""Creates neutron subnet.
|
"""Create neutron subnet.
|
||||||
|
|
||||||
:param network: neutron network dict
|
:param network: neutron network dict
|
||||||
:param subnet_data: options for API v2.0 subnets POST request
|
:param subnet_create_args: POST /v2.0/subnets request options
|
||||||
:returns: neutron subnet dict
|
:returns: neutron subnet dict
|
||||||
"""
|
"""
|
||||||
network_id = network["network"]["id"]
|
network_id = network["network"]["id"]
|
||||||
subnet_data["network_id"] = network_id
|
subnet_create_args["network_id"] = network_id
|
||||||
subnet_data.setdefault("cidr",
|
subnet_create_args.setdefault(
|
||||||
self._generate_subnet_cidr(network_id))
|
"name", self._generate_random_name("rally_subnet_"))
|
||||||
subnet_data.setdefault("ip_version", self.SUBNET_IP_VERSION)
|
subnet_create_args.setdefault(
|
||||||
|
"cidr", self._generate_subnet_cidr(network_id))
|
||||||
|
subnet_create_args.setdefault(
|
||||||
|
"ip_version", self.SUBNET_IP_VERSION)
|
||||||
|
|
||||||
return self.clients("neutron").create_subnet({"subnet": subnet_data})
|
return self.clients("neutron"
|
||||||
|
).create_subnet({"subnet": subnet_create_args})
|
||||||
|
|
||||||
@scenario_utils.atomic_action_timer('neutron.list_subnets')
|
@scenario_utils.atomic_action_timer('neutron.list_subnets')
|
||||||
def _list_subnets(self):
|
def _list_subnets(self):
|
||||||
"""Returns user subnetworks list."""
|
"""Returns user subnetworks list."""
|
||||||
return self.clients("neutron").list_subnets()["subnets"]
|
return self.clients("neutron").list_subnets()["subnets"]
|
||||||
|
|
||||||
|
@scenario_utils.atomic_action_timer('neutron.create_router')
|
||||||
|
def _create_router(self, router_create_args):
|
||||||
|
"""Create neutron router.
|
||||||
|
|
||||||
|
:param router_create_args: POST /v2.0/routers request options
|
||||||
|
:returns: neutron router dict
|
||||||
|
"""
|
||||||
|
router_create_args.setdefault(
|
||||||
|
"name", self._generate_random_name("rally_router_"))
|
||||||
|
return self.clients("neutron"
|
||||||
|
).create_router({"router": router_create_args})
|
||||||
|
|
||||||
|
@scenario_utils.atomic_action_timer('neutron.list_routers')
|
||||||
|
def _list_routers(self):
|
||||||
|
"""Returns user routers list."""
|
||||||
|
return self.clients("neutron").list_routers()["routers"]
|
||||||
|
@ -75,14 +75,18 @@ class ResourceCleanerTestCase(test.TestCase):
|
|||||||
@mock.patch("%s.utils.delete_nova_resources" % BASE)
|
@mock.patch("%s.utils.delete_nova_resources" % BASE)
|
||||||
@mock.patch("%s.utils.delete_glance_resources" % BASE)
|
@mock.patch("%s.utils.delete_glance_resources" % BASE)
|
||||||
@mock.patch("%s.utils.delete_cinder_resources" % BASE)
|
@mock.patch("%s.utils.delete_cinder_resources" % BASE)
|
||||||
def test_cleaner_users_all_services(self, mock_del_cinder,
|
@mock.patch("%s.utils.delete_neutron_resources" % BASE)
|
||||||
mock_del_glance, mock_del_nova,
|
def test_cleaner_users_resources(self,
|
||||||
|
mock_del_neutron,
|
||||||
|
mock_del_cinder,
|
||||||
|
mock_del_glance,
|
||||||
|
mock_del_nova,
|
||||||
mock_clients):
|
mock_clients):
|
||||||
context = {
|
context = {
|
||||||
"task": mock.MagicMock(),
|
"task": mock.MagicMock(),
|
||||||
"users": [{"endpoint": mock.MagicMock()},
|
"users": [{"endpoint": mock.MagicMock()},
|
||||||
{"endpoint": mock.MagicMock()}],
|
{"endpoint": mock.MagicMock()}],
|
||||||
"config": {"cleanup": ["cinder", "nova", "glance"]},
|
"config": {"cleanup": ["cinder", "nova", "glance", "neutron"]},
|
||||||
"tenants": [mock.MagicMock()]
|
"tenants": [mock.MagicMock()]
|
||||||
}
|
}
|
||||||
res_cleaner = cleanup_ctx.ResourceCleaner(context)
|
res_cleaner = cleanup_ctx.ResourceCleaner(context)
|
||||||
@ -97,6 +101,7 @@ class ResourceCleanerTestCase(test.TestCase):
|
|||||||
self.assertEqual(mock_del_nova.call_count, 2)
|
self.assertEqual(mock_del_nova.call_count, 2)
|
||||||
self.assertEqual(mock_del_glance.call_count, 2)
|
self.assertEqual(mock_del_glance.call_count, 2)
|
||||||
self.assertEqual(mock_del_cinder.call_count, 2)
|
self.assertEqual(mock_del_cinder.call_count, 2)
|
||||||
|
self.assertEqual(mock_del_neutron.call_count, 2)
|
||||||
|
|
||||||
@mock.patch("%s.ResourceCleaner._cleanup_users_resources" % BASE)
|
@mock.patch("%s.ResourceCleaner._cleanup_users_resources" % BASE)
|
||||||
def test_cleaner_users_default_behavior(self, mock_cleanup):
|
def test_cleaner_users_default_behavior(self, mock_cleanup):
|
||||||
@ -111,29 +116,3 @@ class ResourceCleanerTestCase(test.TestCase):
|
|||||||
res_cleaner.setup()
|
res_cleaner.setup()
|
||||||
|
|
||||||
self.assertEqual(mock_cleanup.call_count, 0)
|
self.assertEqual(mock_cleanup.call_count, 0)
|
||||||
|
|
||||||
@mock.patch("%s.osclients.Clients" % BASE)
|
|
||||||
@mock.patch("%s.utils.delete_nova_resources" % BASE)
|
|
||||||
@mock.patch("%s.utils.delete_glance_resources" % BASE)
|
|
||||||
@mock.patch("%s.utils.delete_cinder_resources" % BASE)
|
|
||||||
def test_cleaner_users_by_service(self, mock_del_cinder, mock_del_glance,
|
|
||||||
mock_del_nova, mock_clients):
|
|
||||||
context = {
|
|
||||||
"task": mock.MagicMock(),
|
|
||||||
"users": [{"endpoint": mock.MagicMock()},
|
|
||||||
{"endpoint": mock.MagicMock()}],
|
|
||||||
"config": {"cleanup": ["cinder", "nova"]},
|
|
||||||
"tenants": [mock.MagicMock()]
|
|
||||||
}
|
|
||||||
res_cleaner = cleanup_ctx.ResourceCleaner(context)
|
|
||||||
|
|
||||||
with res_cleaner:
|
|
||||||
res_cleaner.setup()
|
|
||||||
|
|
||||||
expected = [mock.call(context["users"][0]["endpoint"]),
|
|
||||||
mock.call(context["users"][1]["endpoint"])]
|
|
||||||
mock_clients.assert_has_calls(expected, any_order=True)
|
|
||||||
|
|
||||||
self.assertEqual(mock_del_nova.call_count, 2)
|
|
||||||
self.assertEqual(mock_del_glance.call_count, 0)
|
|
||||||
self.assertEqual(mock_del_cinder.call_count, 2)
|
|
||||||
|
48
tests/benchmark/context/cleanup/test_utils.py
Normal file
48
tests/benchmark/context/cleanup/test_utils.py
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
# Copyright 2014: Mirantis Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# 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.context.cleanup import utils
|
||||||
|
from rally.benchmark import scenarios
|
||||||
|
from tests import fakes
|
||||||
|
from tests import test
|
||||||
|
|
||||||
|
|
||||||
|
class CleanupUtilsTestCase(test.TestCase):
|
||||||
|
|
||||||
|
def test_delete_neutron_resources(self):
|
||||||
|
neutron = fakes.FakeClients().neutron()
|
||||||
|
scenario = scenarios.neutron.utils.NeutronScenario()
|
||||||
|
scenario.clients = lambda ins: neutron
|
||||||
|
|
||||||
|
network1 = scenario._create_network({})
|
||||||
|
subnet1 = scenario._create_subnet(network1, {})
|
||||||
|
router1 = scenario._create_router({})
|
||||||
|
neutron.add_interface_router(router1["router"]["id"],
|
||||||
|
{"subnet_id": subnet1["subnet"]["id"]})
|
||||||
|
network2 = scenario._create_network({})
|
||||||
|
scenario._create_subnet(network2, {})
|
||||||
|
scenario._create_router({})
|
||||||
|
|
||||||
|
total = lambda neutron: (len(neutron.list_networks()["networks"])
|
||||||
|
+ len(neutron.list_subnets()["subnets"])
|
||||||
|
+ len(neutron.list_routers()["routers"]))
|
||||||
|
|
||||||
|
self.assertEqual(total(neutron), 6)
|
||||||
|
|
||||||
|
utils.delete_neutron_resources(neutron,
|
||||||
|
network1["network"]["tenant_id"])
|
||||||
|
|
||||||
|
self.assertEqual(total(neutron), 0)
|
@ -29,52 +29,139 @@ class NeutronNetworksTestCase(test.TestCase):
|
|||||||
def test_create_and_list_networks(self, mock_create, mock_list):
|
def test_create_and_list_networks(self, mock_create, mock_list):
|
||||||
neutron_scenario = network.NeutronNetworks()
|
neutron_scenario = network.NeutronNetworks()
|
||||||
|
|
||||||
# Empty options are specified
|
# Default options
|
||||||
network_data = {}
|
network_create_args = {}
|
||||||
neutron_scenario.create_and_list_networks(network_data=network_data)
|
neutron_scenario.create_and_list_networks(
|
||||||
mock_create.assert_called_once_with(network_data)
|
network_create_args=network_create_args)
|
||||||
|
mock_create.assert_called_once_with(network_create_args)
|
||||||
mock_list.assert_called_once_with()
|
mock_list.assert_called_once_with()
|
||||||
|
|
||||||
mock_create.reset_mock()
|
mock_create.reset_mock()
|
||||||
mock_list.reset_mock()
|
mock_list.reset_mock()
|
||||||
|
|
||||||
# Explicit network name is specified
|
# Explicit network name is specified
|
||||||
network_data = {"name": "given-name"}
|
network_create_args = {"name": "given-name"}
|
||||||
neutron_scenario.create_and_list_networks(network_data=network_data)
|
neutron_scenario.create_and_list_networks(
|
||||||
mock_create.assert_called_once_with(network_data)
|
network_create_args=network_create_args)
|
||||||
|
mock_create.assert_called_once_with(network_create_args)
|
||||||
mock_list.assert_called_once_with()
|
mock_list.assert_called_once_with()
|
||||||
|
|
||||||
@mock.patch(NEUTRON_NETWORKS + "._generate_random_name")
|
|
||||||
@mock.patch(NEUTRON_NETWORKS + "._list_subnets")
|
@mock.patch(NEUTRON_NETWORKS + "._list_subnets")
|
||||||
@mock.patch(NEUTRON_NETWORKS + "._create_subnet")
|
@mock.patch(NEUTRON_NETWORKS + "._create_subnet")
|
||||||
@mock.patch(NEUTRON_NETWORKS + "._create_network")
|
@mock.patch(NEUTRON_NETWORKS + "._create_network")
|
||||||
|
@mock.patch(NEUTRON_NETWORKS + ".SUBNET_CIDR_START",
|
||||||
|
new_callable=mock.PropertyMock(return_value="default_cidr"))
|
||||||
def test_create_and_list_subnets(self,
|
def test_create_and_list_subnets(self,
|
||||||
|
mock_cidr_start,
|
||||||
mock_create_network,
|
mock_create_network,
|
||||||
mock_create_subnet,
|
mock_create_subnet,
|
||||||
mock_list,
|
mock_list):
|
||||||
mock_random_name):
|
|
||||||
scenario = network.NeutronNetworks()
|
scenario = network.NeutronNetworks()
|
||||||
mock_random_name.return_value = "random-name"
|
|
||||||
mock_create_network.return_value = {"network": {"id": "fake-id"}}
|
mock_create_network.return_value = {"network": {"id": "fake-id"}}
|
||||||
|
subnets_per_network = 4
|
||||||
|
|
||||||
# Empty options
|
self.assertRaises(TypeError, scenario.create_and_list_subnets)
|
||||||
scenario.create_and_list_subnets()
|
|
||||||
mock_create_network.assert_called_once_with({})
|
|
||||||
mock_create_subnet.assert_called_once_with(
|
|
||||||
{"network": {"id": "fake-id"}}, {})
|
|
||||||
mock_list.assert_called_once_with()
|
|
||||||
|
|
||||||
mock_create_network.reset_mock()
|
mock_create_network.reset_mock()
|
||||||
mock_create_subnet.reset_mock()
|
mock_create_subnet.reset_mock()
|
||||||
mock_list.reset_mock()
|
mock_list.reset_mock()
|
||||||
|
|
||||||
# Extra options are specified
|
# Default options
|
||||||
subnets_num = 4
|
scenario.create_and_list_subnets(
|
||||||
scenario.create_and_list_subnets(network_data={"name": "given-name"},
|
subnets_per_network=subnets_per_network)
|
||||||
subnet_data={"allocation_pools": []},
|
mock_create_network.assert_called_once_with({})
|
||||||
subnets_per_network=subnets_num)
|
|
||||||
mock_create_network.assert_called_once_with({"name": "given-name"})
|
|
||||||
self.assertEqual(mock_create_subnet.mock_calls,
|
self.assertEqual(mock_create_subnet.mock_calls,
|
||||||
[mock.call({"network": {"id": "fake-id"}},
|
[mock.call({"network": {"id": "fake-id"}},
|
||||||
{"allocation_pools": []})] * subnets_num)
|
{})] * subnets_per_network)
|
||||||
|
mock_list.assert_called_once_with()
|
||||||
|
self.assertEqual(scenario.SUBNET_CIDR_START, "default_cidr")
|
||||||
|
|
||||||
|
mock_create_network.reset_mock()
|
||||||
|
mock_create_subnet.reset_mock()
|
||||||
|
mock_list.reset_mock()
|
||||||
|
|
||||||
|
# Custom options
|
||||||
|
scenario.create_and_list_subnets(
|
||||||
|
subnet_create_args={"allocation_pools": []},
|
||||||
|
subnet_cidr_start="custom_cidr",
|
||||||
|
subnets_per_network=subnets_per_network)
|
||||||
|
self.assertEqual(scenario.SUBNET_CIDR_START, "custom_cidr")
|
||||||
|
mock_create_network.assert_called_once_with({})
|
||||||
|
self.assertEqual(
|
||||||
|
mock_create_subnet.mock_calls,
|
||||||
|
[mock.call({"network": {"id": "fake-id"}},
|
||||||
|
{"allocation_pools": []})] * subnets_per_network)
|
||||||
|
mock_list.assert_called_once_with()
|
||||||
|
|
||||||
|
@mock.patch(NEUTRON_NETWORKS + "._list_routers")
|
||||||
|
@mock.patch(NEUTRON_NETWORKS + "._create_router")
|
||||||
|
@mock.patch(NEUTRON_NETWORKS + "._create_subnet")
|
||||||
|
@mock.patch(NEUTRON_NETWORKS + "._create_network")
|
||||||
|
@mock.patch(NEUTRON_NETWORKS + ".clients")
|
||||||
|
def test_create_and_list_routers(self,
|
||||||
|
mock_clients,
|
||||||
|
mock_create_network,
|
||||||
|
mock_create_subnet,
|
||||||
|
mock_create_router,
|
||||||
|
mock_list):
|
||||||
|
scenario = network.NeutronNetworks()
|
||||||
|
subnets_per_network = 4
|
||||||
|
mock_clients("neutron").add_interface_router = mock.Mock()
|
||||||
|
|
||||||
|
net = {"network": {"id": "network-id"}}
|
||||||
|
mock_create_network.return_value = net
|
||||||
|
|
||||||
|
subnet = {"subnet": {"name": "subnet-name", "id": "subnet-id"}}
|
||||||
|
mock_create_subnet.return_value = subnet
|
||||||
|
|
||||||
|
router = {"router": {"name": "router-name", "id": "router-id"}}
|
||||||
|
mock_create_router.return_value = router
|
||||||
|
|
||||||
|
# Default options
|
||||||
|
scenario.create_and_list_routers(
|
||||||
|
subnets_per_network=subnets_per_network)
|
||||||
|
mock_create_network.assert_called_once_with({})
|
||||||
|
self.assertEqual(
|
||||||
|
mock_create_subnet.mock_calls,
|
||||||
|
[mock.call(net, {})] * subnets_per_network)
|
||||||
|
self.assertEqual(
|
||||||
|
mock_create_router.mock_calls,
|
||||||
|
[mock.call({})] * subnets_per_network)
|
||||||
|
self.assertEqual(
|
||||||
|
mock_clients("neutron").add_interface_router.mock_calls,
|
||||||
|
[mock.call(router["router"]["id"],
|
||||||
|
{"subnet_id": subnet["subnet"]["id"]})
|
||||||
|
] * subnets_per_network)
|
||||||
|
|
||||||
|
mock_create_network.reset_mock()
|
||||||
|
mock_create_subnet.reset_mock()
|
||||||
|
mock_create_router.reset_mock()
|
||||||
|
mock_clients("neutron").add_interface_router.reset_mock()
|
||||||
|
mock_list.reset_mock()
|
||||||
|
|
||||||
|
# Custom options
|
||||||
|
subnet_create_args = {"allocation_pools": []}
|
||||||
|
router_create_args = {"admin_state_up": False}
|
||||||
|
scenario.create_and_list_routers(
|
||||||
|
subnet_create_args=subnet_create_args,
|
||||||
|
subnet_cidr_start="custom_cidr",
|
||||||
|
subnets_per_network=subnets_per_network,
|
||||||
|
router_create_args=router_create_args)
|
||||||
|
self.assertEqual(scenario.SUBNET_CIDR_START, "custom_cidr")
|
||||||
|
mock_create_network.assert_called_once_with({})
|
||||||
|
self.assertEqual(
|
||||||
|
mock_create_subnet.mock_calls, [
|
||||||
|
mock.call({"network": {"id": "network-id"}},
|
||||||
|
subnet_create_args)
|
||||||
|
] * subnets_per_network)
|
||||||
|
self.assertEqual(
|
||||||
|
mock_create_router.mock_calls, [
|
||||||
|
mock.call(router_create_args)
|
||||||
|
] * subnets_per_network)
|
||||||
|
self.assertEqual(
|
||||||
|
mock_clients("neutron").add_interface_router.mock_calls, [
|
||||||
|
mock.call(router["router"]["id"],
|
||||||
|
{"subnet_id": subnet["subnet"]["id"]})
|
||||||
|
] * subnets_per_network)
|
||||||
|
|
||||||
mock_list.assert_called_once_with()
|
mock_list.assert_called_once_with()
|
||||||
|
@ -67,33 +67,36 @@ class NeutronScenarioTestCase(test.TestCase):
|
|||||||
|
|
||||||
@mock.patch(NEUTRON_UTILS + 'NeutronScenario.clients')
|
@mock.patch(NEUTRON_UTILS + 'NeutronScenario.clients')
|
||||||
def test_list_networks(self, mock_clients):
|
def test_list_networks(self, mock_clients):
|
||||||
|
scenario = utils.NeutronScenario()
|
||||||
networks_list = []
|
networks_list = []
|
||||||
networks_dict = {"networks": networks_list}
|
networks_dict = {"networks": networks_list}
|
||||||
mock_clients("neutron").list_networks.return_value = networks_dict
|
mock_clients("neutron").list_networks.return_value = networks_dict
|
||||||
neutron_scenario = utils.NeutronScenario()
|
return_networks_list = scenario._list_networks()
|
||||||
return_networks_list = neutron_scenario._list_networks()
|
|
||||||
self.assertEqual(networks_list, return_networks_list)
|
self.assertEqual(networks_list, return_networks_list)
|
||||||
self._test_atomic_action_timer(neutron_scenario.atomic_actions(),
|
self._test_atomic_action_timer(scenario.atomic_actions(),
|
||||||
'neutron.list_networks')
|
'neutron.list_networks')
|
||||||
|
|
||||||
|
@mock.patch(NEUTRON_UTILS + 'NeutronScenario._generate_random_name')
|
||||||
@mock.patch(NEUTRON_UTILS + "NeutronScenario._generate_subnet_cidr")
|
@mock.patch(NEUTRON_UTILS + "NeutronScenario._generate_subnet_cidr")
|
||||||
@mock.patch(NEUTRON_UTILS + "NeutronScenario.clients")
|
@mock.patch(NEUTRON_UTILS + "NeutronScenario.clients")
|
||||||
def test_create_subnet(self, mock_clients, mock_cidr):
|
def test_create_subnet(self, mock_clients, mock_cidr, mock_random_name):
|
||||||
|
scenario = utils.NeutronScenario()
|
||||||
network_id = "fake-id"
|
network_id = "fake-id"
|
||||||
subnet_cidr = "192.168.0.0/24"
|
subnet_cidr = "192.168.0.0/24"
|
||||||
mock_cidr.return_value = subnet_cidr
|
mock_cidr.return_value = subnet_cidr
|
||||||
scenario = utils.NeutronScenario()
|
mock_random_name.return_value = "fake-name"
|
||||||
|
|
||||||
network = {"network": {"id": network_id}}
|
network = {"network": {"id": network_id}}
|
||||||
expected_subnet_data = {
|
expected_subnet_data = {
|
||||||
"subnet": {
|
"subnet": {
|
||||||
"network_id": network_id,
|
"network_id": network_id,
|
||||||
"cidr": subnet_cidr,
|
"cidr": subnet_cidr,
|
||||||
"ip_version": scenario.SUBNET_IP_VERSION
|
"ip_version": scenario.SUBNET_IP_VERSION,
|
||||||
|
"name": "fake-name"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# No extra options
|
# Default options
|
||||||
subnet_data = {"network_id": network_id}
|
subnet_data = {"network_id": network_id}
|
||||||
scenario._create_subnet(network, subnet_data)
|
scenario._create_subnet(network, subnet_data)
|
||||||
mock_clients("neutron")\
|
mock_clients("neutron")\
|
||||||
@ -103,7 +106,7 @@ class NeutronScenarioTestCase(test.TestCase):
|
|||||||
|
|
||||||
mock_clients("neutron").create_subnet.reset_mock()
|
mock_clients("neutron").create_subnet.reset_mock()
|
||||||
|
|
||||||
# Extra options are specified
|
# Custom options
|
||||||
extras = {"cidr": "192.168.16.0/24", "allocation_pools": []}
|
extras = {"cidr": "192.168.16.0/24", "allocation_pools": []}
|
||||||
subnet_data.update(extras)
|
subnet_data.update(extras)
|
||||||
expected_subnet_data["subnet"].update(extras)
|
expected_subnet_data["subnet"].update(extras)
|
||||||
@ -122,32 +125,61 @@ class NeutronScenarioTestCase(test.TestCase):
|
|||||||
self._test_atomic_action_timer(scenario.atomic_actions(),
|
self._test_atomic_action_timer(scenario.atomic_actions(),
|
||||||
"neutron.list_subnets")
|
"neutron.list_subnets")
|
||||||
|
|
||||||
|
@mock.patch(NEUTRON_UTILS + 'NeutronScenario._generate_random_name')
|
||||||
|
@mock.patch(NEUTRON_UTILS + 'NeutronScenario.clients')
|
||||||
|
def test_create_router(self, mock_clients, mock_random_name):
|
||||||
|
scenario = utils.NeutronScenario()
|
||||||
|
router = mock.Mock()
|
||||||
|
explicit_name = "explicit_name"
|
||||||
|
random_name = "random_name"
|
||||||
|
mock_random_name.return_value = random_name
|
||||||
|
mock_clients("neutron").create_router.return_value = router
|
||||||
|
|
||||||
|
# Default options
|
||||||
|
result_router = scenario._create_router({})
|
||||||
|
mock_clients("neutron").create_router.assert_called_once_with(
|
||||||
|
{"router": {"name": random_name}})
|
||||||
|
self.assertEqual(result_router, router)
|
||||||
|
self._test_atomic_action_timer(scenario.atomic_actions(),
|
||||||
|
'neutron.create_router')
|
||||||
|
|
||||||
|
mock_clients("neutron").create_router.reset_mock()
|
||||||
|
|
||||||
|
# Custom options
|
||||||
|
router_data = {"name": explicit_name, "admin_state_up": True}
|
||||||
|
result_router = scenario._create_router(router_data)
|
||||||
|
mock_clients("neutron").create_router.assert_called_once_with(
|
||||||
|
{"router": router_data})
|
||||||
|
|
||||||
|
@mock.patch(NEUTRON_UTILS + 'NeutronScenario.clients')
|
||||||
|
def test_list_routers(self, mock_clients):
|
||||||
|
scenario = utils.NeutronScenario()
|
||||||
|
routers = [mock.Mock()]
|
||||||
|
mock_clients("neutron").list_routers.return_value = {
|
||||||
|
"routers": routers}
|
||||||
|
self.assertEqual(routers, scenario._list_routers())
|
||||||
|
self._test_atomic_action_timer(scenario.atomic_actions(),
|
||||||
|
'neutron.list_routers')
|
||||||
|
|
||||||
def test_SUBNET_IP_VERSION(self):
|
def test_SUBNET_IP_VERSION(self):
|
||||||
"Curent NeutronScenario implementation supports only IPv4"
|
"""Curent NeutronScenario implementation supports only IPv4."""
|
||||||
self.assertEqual(utils.NeutronScenario.SUBNET_IP_VERSION, 4)
|
self.assertEqual(utils.NeutronScenario.SUBNET_IP_VERSION, 4)
|
||||||
|
|
||||||
def test_SUBNET_CIDR_PATTERN(self):
|
def test_SUBNET_CIDR_START(self):
|
||||||
netaddr.IPNetwork(utils.NeutronScenario.SUBNET_CIDR_PATTERN % 0)
|
"""Valid default CIDR to generate first subnet."""
|
||||||
self.assertRaises(netaddr.core.AddrFormatError,
|
netaddr.IPNetwork(utils.NeutronScenario.SUBNET_CIDR_START)
|
||||||
netaddr.IPNetwork,
|
|
||||||
utils.NeutronScenario.SUBNET_CIDR_PATTERN % 256)
|
|
||||||
|
|
||||||
def test_generate_subnet_cidr(self):
|
def test_generate_subnet_cidr(self):
|
||||||
scenario = utils.NeutronScenario()
|
scenario = utils.NeutronScenario()
|
||||||
network1_id = "fake1"
|
network1_id = "fake1"
|
||||||
network2_id = "fake2"
|
network2_id = "fake2"
|
||||||
|
subnets_num = 300
|
||||||
|
|
||||||
cidrs1 = map(scenario._generate_subnet_cidr, [network1_id] * 256)
|
cidrs1 = map(scenario._generate_subnet_cidr,
|
||||||
|
[network1_id] * subnets_num)
|
||||||
|
|
||||||
self.assertRaises(ValueError,
|
cidrs2 = map(scenario._generate_subnet_cidr,
|
||||||
scenario._generate_subnet_cidr,
|
[network2_id] * subnets_num)
|
||||||
network1_id)
|
|
||||||
|
|
||||||
cidrs2 = map(scenario._generate_subnet_cidr, [network2_id] * 256)
|
|
||||||
|
|
||||||
self.assertRaises(ValueError,
|
|
||||||
scenario._generate_subnet_cidr,
|
|
||||||
network2_id)
|
|
||||||
|
|
||||||
# All CIDRs must differ
|
# All CIDRs must differ
|
||||||
self.assertEqual(len(cidrs1), len(set(cidrs1)))
|
self.assertEqual(len(cidrs1), len(set(cidrs1)))
|
||||||
|
264
tests/fakes.py
264
tests/fakes.py
@ -13,13 +13,18 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import mock
|
|
||||||
import multiprocessing
|
import multiprocessing
|
||||||
|
import random
|
||||||
|
import re
|
||||||
|
import string
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
|
import mock
|
||||||
|
|
||||||
from ceilometerclient import exc as ceilometer_exc
|
from ceilometerclient import exc as ceilometer_exc
|
||||||
from glanceclient import exc
|
from glanceclient import exc
|
||||||
from novaclient import exceptions
|
from neutronclient.common import exceptions as neutron_exceptions
|
||||||
|
from novaclient import exceptions as nova_exceptions
|
||||||
from rally.benchmark.context import base as base_ctx
|
from rally.benchmark.context import base as base_ctx
|
||||||
from rally.benchmark.scenarios import base
|
from rally.benchmark.scenarios import base
|
||||||
from rally.objects import endpoint
|
from rally.objects import endpoint
|
||||||
@ -30,6 +35,49 @@ def generate_uuid():
|
|||||||
return str(uuid.uuid4())
|
return str(uuid.uuid4())
|
||||||
|
|
||||||
|
|
||||||
|
def generate_name(prefix="", length=12, choices=string.lowercase):
|
||||||
|
"""Generate pseudo-random name.
|
||||||
|
|
||||||
|
:param prefix: str, custom prefix for genertated name
|
||||||
|
:param length: int, length of autogenerated part of result name
|
||||||
|
:param choices: str, chars that accurs in generated name
|
||||||
|
:returns: str, pseudo-random name
|
||||||
|
"""
|
||||||
|
return prefix + ''.join(random.choice(choices) for i in range(length))
|
||||||
|
|
||||||
|
|
||||||
|
def generate_mac():
|
||||||
|
"""Generate pseudo-random MAC address.
|
||||||
|
|
||||||
|
:returns: str, MAC address
|
||||||
|
"""
|
||||||
|
rand_str = generate_name(choices="0123456789abcdef", length=12)
|
||||||
|
return ":".join(re.findall("..", rand_str))
|
||||||
|
|
||||||
|
|
||||||
|
def setup_dict(data, required=None, defaults=None):
|
||||||
|
"""Setup and validate dict based on mandatory keys and default data.
|
||||||
|
This function reduces code that constructs dict objects
|
||||||
|
with specific schema (e.g. for API data).
|
||||||
|
|
||||||
|
:param data: dict, input data
|
||||||
|
:param required: list, mandatory keys to check
|
||||||
|
:param defaults: dict, default data
|
||||||
|
:returns: dict, with all keys set
|
||||||
|
:raises: IndexError, ValueError
|
||||||
|
"""
|
||||||
|
required = required or []
|
||||||
|
for i in set(required) - set(data.keys()):
|
||||||
|
raise IndexError("Missed: %s" % i)
|
||||||
|
|
||||||
|
defaults = defaults or {}
|
||||||
|
for i in set(data.keys()) - set(required + defaults.keys()):
|
||||||
|
raise ValueError("Unexpected: %s" % i)
|
||||||
|
|
||||||
|
defaults.update(data)
|
||||||
|
return defaults
|
||||||
|
|
||||||
|
|
||||||
class FakeResource(object):
|
class FakeResource(object):
|
||||||
|
|
||||||
def __init__(self, manager=None, name=None, status="ACTIVE", items=None,
|
def __init__(self, manager=None, name=None, status="ACTIVE", items=None,
|
||||||
@ -227,7 +275,7 @@ class FakeServerManager(FakeManager):
|
|||||||
server = self.cache.get(resource_uuid, None)
|
server = self.cache.get(resource_uuid, None)
|
||||||
if server is not None:
|
if server is not None:
|
||||||
return server
|
return server
|
||||||
raise exceptions.NotFound("Server %s not found" % (resource_uuid))
|
raise nova_exceptions.NotFound("Server %s not found" % (resource_uuid))
|
||||||
|
|
||||||
def _create(self, server_class=FakeServer, name=None):
|
def _create(self, server_class=FakeServer, name=None):
|
||||||
server = self._cache(server_class(self))
|
server = self._cache(server_class(self))
|
||||||
@ -351,7 +399,7 @@ class FakeSecurityGroupManager(FakeManager):
|
|||||||
break
|
break
|
||||||
if match:
|
if match:
|
||||||
return resource
|
return resource
|
||||||
raise exceptions.NotFound('Security Group not found')
|
raise nova_exceptions.NotFound('Security Group not found')
|
||||||
|
|
||||||
|
|
||||||
class FakeSecurityGroupRuleManager(FakeManager):
|
class FakeSecurityGroupRuleManager(FakeManager):
|
||||||
@ -559,9 +607,185 @@ class FakeCeilometerClient(object):
|
|||||||
|
|
||||||
class FakeNeutronClient(object):
|
class FakeNeutronClient(object):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, **kwargs):
|
||||||
#TODO(bsemp): Fake Manager subclasses to manage networks.
|
self.__networks = {}
|
||||||
pass
|
self.__subnets = {}
|
||||||
|
self.__routers = {}
|
||||||
|
self.__ports = {}
|
||||||
|
self.__tenant_id = kwargs.get("tenant_id", generate_uuid())
|
||||||
|
|
||||||
|
self.format = "json"
|
||||||
|
self.version = "2.0"
|
||||||
|
|
||||||
|
def add_interface_router(self, router_id, data):
|
||||||
|
subnet_id = data["subnet_id"]
|
||||||
|
|
||||||
|
if router_id not in self.__routers\
|
||||||
|
or subnet_id not in self.__subnets:
|
||||||
|
raise neutron_exceptions.NeutronClientException
|
||||||
|
|
||||||
|
subnet = self.__subnets[subnet_id]
|
||||||
|
|
||||||
|
port = self.create_port(
|
||||||
|
{"port": {"network_id": subnet["network_id"]}})["port"]
|
||||||
|
port["device_id"] = router_id
|
||||||
|
port["fixed_ips"].append({"subnet_id": subnet_id,
|
||||||
|
"ip_address": subnet["gateway_ip"]})
|
||||||
|
|
||||||
|
return {"subnet_id": subnet_id,
|
||||||
|
"tenant_id": port["tenant_id"],
|
||||||
|
"port_id": port["id"],
|
||||||
|
"id": router_id}
|
||||||
|
|
||||||
|
def create_network(self, data):
|
||||||
|
network = setup_dict(data["network"],
|
||||||
|
defaults={"name": generate_name("net_"),
|
||||||
|
"admin_state_up": True})
|
||||||
|
network_id = generate_uuid()
|
||||||
|
network.update({"id": network_id,
|
||||||
|
"status": "ACTIVE",
|
||||||
|
"subnets": [],
|
||||||
|
"provider:physical_network": None,
|
||||||
|
"tenant_id": self.__tenant_id,
|
||||||
|
"provider:network_type": "local",
|
||||||
|
"router:external": True,
|
||||||
|
"shared": False,
|
||||||
|
"provider:segmentation_id": None})
|
||||||
|
self.__networks[network_id] = network
|
||||||
|
return {"network": network}
|
||||||
|
|
||||||
|
def create_port(self, data):
|
||||||
|
port = setup_dict(data["port"],
|
||||||
|
required=["network_id"],
|
||||||
|
defaults={"name": generate_name("port_"),
|
||||||
|
"admin_state_up": True})
|
||||||
|
if port["network_id"] not in self.__networks:
|
||||||
|
raise neutron_exceptions.NeutronClientException
|
||||||
|
|
||||||
|
port_id = generate_uuid()
|
||||||
|
port.update({"id": port_id,
|
||||||
|
"status": "ACTIVE",
|
||||||
|
"binding:host_id": "fakehost",
|
||||||
|
"extra_dhcp_opts": [],
|
||||||
|
"binding:vnic_type": "normal",
|
||||||
|
"binding:vif_type": "ovs",
|
||||||
|
"device_owner": "",
|
||||||
|
"mac_address": generate_mac(),
|
||||||
|
"binding:profile": {},
|
||||||
|
"binding:vif_details": {u'port_filter': True},
|
||||||
|
"security_groups": [],
|
||||||
|
"fixed_ips": [],
|
||||||
|
"device_id": "",
|
||||||
|
"tenant_id": self.__tenant_id,
|
||||||
|
"allowed_address_pairs": []})
|
||||||
|
self.__ports[port_id] = port
|
||||||
|
return {"port": port}
|
||||||
|
|
||||||
|
def create_router(self, data):
|
||||||
|
router = setup_dict(data["router"],
|
||||||
|
defaults={"name": generate_name("router_"),
|
||||||
|
"admin_state_up": True})
|
||||||
|
router_id = generate_uuid()
|
||||||
|
router.update({"id": router_id,
|
||||||
|
"status": "ACTIVE",
|
||||||
|
"external_gateway_info": None,
|
||||||
|
"tenant_id": self.__tenant_id})
|
||||||
|
self.__routers[router_id] = router
|
||||||
|
return {"router": router}
|
||||||
|
|
||||||
|
def create_subnet(self, data):
|
||||||
|
subnet = setup_dict(data["subnet"],
|
||||||
|
required=["network_id", "cidr", "ip_version"],
|
||||||
|
defaults={"name": generate_name("subnet_")})
|
||||||
|
if subnet["network_id"] not in self.__networks:
|
||||||
|
raise neutron_exceptions.NeutronClientException
|
||||||
|
|
||||||
|
subnet_id = generate_uuid()
|
||||||
|
subnet.update({"id": subnet_id,
|
||||||
|
"enable_dhcp": True,
|
||||||
|
"tenant_id": self.__tenant_id,
|
||||||
|
"dns_nameservers": [],
|
||||||
|
"ipv6_ra_mode": None,
|
||||||
|
"allocation_pools": [],
|
||||||
|
"gateway_ip": re.sub('./.*$', '1', subnet["cidr"]),
|
||||||
|
"ipv6_address_mode": None,
|
||||||
|
"ip_version": 4,
|
||||||
|
"host_routes": []})
|
||||||
|
self.__subnets[subnet_id] = subnet
|
||||||
|
return {"subnet": subnet}
|
||||||
|
|
||||||
|
def delete_network(self, network_id):
|
||||||
|
if network_id not in self.__networks:
|
||||||
|
raise neutron_exceptions.NeutronClientException
|
||||||
|
for port in self.__ports.values():
|
||||||
|
if port["network_id"] == network_id:
|
||||||
|
# Network is in use by port
|
||||||
|
raise neutron_exceptions.NeutronClientException
|
||||||
|
del self.__networks[network_id]
|
||||||
|
return ""
|
||||||
|
|
||||||
|
def delete_port(self, port_id):
|
||||||
|
if port_id not in self.__ports:
|
||||||
|
raise neutron_exceptions.PortNotFoundClient
|
||||||
|
if self.__ports[port_id]["device_owner"]:
|
||||||
|
# Port is owned by some device
|
||||||
|
raise neutron_exceptions.NeutronClientException
|
||||||
|
del self.__ports[port_id]
|
||||||
|
return ""
|
||||||
|
|
||||||
|
def delete_router(self, router_id):
|
||||||
|
if router_id not in self.__routers:
|
||||||
|
raise neutron_exceptions.NeutronClientException
|
||||||
|
for port in self.__ports.values():
|
||||||
|
if port["device_id"] == router_id:
|
||||||
|
# Router has active port
|
||||||
|
raise neutron_exceptions.NeutronClientException
|
||||||
|
del self.__routers[router_id]
|
||||||
|
return ""
|
||||||
|
|
||||||
|
def delete_subnet(self, subnet_id):
|
||||||
|
if subnet_id not in self.__subnets:
|
||||||
|
raise neutron_exceptions.NeutronClientException
|
||||||
|
for port in self.__ports.values():
|
||||||
|
for fip in port["fixed_ips"]:
|
||||||
|
if fip["subnet_id"] == subnet_id:
|
||||||
|
# Subnet has IP allocation from some port
|
||||||
|
raise neutron_exceptions.NeutronClientException
|
||||||
|
del self.__subnets[subnet_id]
|
||||||
|
return ""
|
||||||
|
|
||||||
|
def list_networks(self):
|
||||||
|
return {"networks": self.__networks.values()}
|
||||||
|
|
||||||
|
def list_ports(self):
|
||||||
|
return {"ports": self.__ports.values()}
|
||||||
|
|
||||||
|
def list_routers(self):
|
||||||
|
return {"routers": self.__routers.values()}
|
||||||
|
|
||||||
|
def list_subnets(self):
|
||||||
|
return {"subnets": self.__subnets.values()}
|
||||||
|
|
||||||
|
def remove_interface_router(self, router_id, data):
|
||||||
|
subnet_id = data["subnet_id"]
|
||||||
|
|
||||||
|
if router_id not in self.__routers\
|
||||||
|
or subnet_id not in self.__subnets:
|
||||||
|
raise neutron_exceptions.NeutronClientException
|
||||||
|
|
||||||
|
subnet = self.__subnets[subnet_id]
|
||||||
|
|
||||||
|
for port_id, port in self.__ports.items():
|
||||||
|
if port["device_id"] == router_id:
|
||||||
|
for fip in port["fixed_ips"]:
|
||||||
|
if fip["subnet_id"] == subnet_id:
|
||||||
|
del self.__ports[port_id]
|
||||||
|
return {"subnet_id": subnet_id,
|
||||||
|
"tenant_id": subnet["tenant_id"],
|
||||||
|
"port_id": port_id,
|
||||||
|
"id": router_id}
|
||||||
|
|
||||||
|
raise neutron_exceptions.NeutronClientException
|
||||||
|
|
||||||
|
|
||||||
class FakeIronicClient(object):
|
class FakeIronicClient(object):
|
||||||
@ -573,16 +797,20 @@ class FakeIronicClient(object):
|
|||||||
|
|
||||||
class FakeClients(object):
|
class FakeClients(object):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, endpoint_=None):
|
||||||
self._nova = None
|
self._nova = None
|
||||||
self._glance = None
|
self._glance = None
|
||||||
self._keystone = None
|
self._keystone = None
|
||||||
self._cinder = None
|
self._cinder = None
|
||||||
self._endpoint = None
|
self._neutron = None
|
||||||
|
self._endpoint = endpoint_ or endpoint.Endpoint(
|
||||||
|
"http://fake.example.org:5000/v2.0/",
|
||||||
|
"fake_username",
|
||||||
|
"fake_password",
|
||||||
|
"fake_tenant_name")
|
||||||
|
|
||||||
def keystone(self):
|
def keystone(self):
|
||||||
if self._keystone is not None:
|
if not self._keystone:
|
||||||
return self._keystone
|
|
||||||
self._keystone = FakeKeystoneClient()
|
self._keystone = FakeKeystoneClient()
|
||||||
return self._keystone
|
return self._keystone
|
||||||
|
|
||||||
@ -590,23 +818,25 @@ class FakeClients(object):
|
|||||||
return self.keystone()
|
return self.keystone()
|
||||||
|
|
||||||
def nova(self):
|
def nova(self):
|
||||||
if self._nova is not None:
|
if not self._nova:
|
||||||
return self._nova
|
|
||||||
self._nova = FakeNovaClient()
|
self._nova = FakeNovaClient()
|
||||||
return self._nova
|
return self._nova
|
||||||
|
|
||||||
def glance(self):
|
def glance(self):
|
||||||
if self._glance is not None:
|
if not self._glance:
|
||||||
return self._glance
|
|
||||||
self._glance = FakeGlanceClient()
|
self._glance = FakeGlanceClient()
|
||||||
return self._glance
|
return self._glance
|
||||||
|
|
||||||
def cinder(self):
|
def cinder(self):
|
||||||
if self._cinder is not None:
|
if not self._cinder:
|
||||||
return self._cinder
|
|
||||||
self._cinder = FakeCinderClient()
|
self._cinder = FakeCinderClient()
|
||||||
return self._cinder
|
return self._cinder
|
||||||
|
|
||||||
|
def neutron(self):
|
||||||
|
if not self._neutron:
|
||||||
|
self._neutron = FakeNeutronClient()
|
||||||
|
return self._neutron
|
||||||
|
|
||||||
|
|
||||||
class FakeRunner(object):
|
class FakeRunner(object):
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user