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": [
|
||||
{
|
||||
"args": {
|
||||
"network_data": {}
|
||||
"network_create_args": {}
|
||||
},
|
||||
"runner": {
|
||||
"type": "constant",
|
||||
@ -13,6 +13,11 @@
|
||||
"users": {
|
||||
"tenants": 1,
|
||||
"users_per_tenant": 1
|
||||
},
|
||||
"quotas": {
|
||||
"neutron": {
|
||||
"network": -1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
NeutronNetworks.create_and_list_networks:
|
||||
-
|
||||
args:
|
||||
network_data:
|
||||
network_create_args:
|
||||
runner:
|
||||
type: "constant"
|
||||
times: 100
|
||||
@ -11,3 +11,6 @@
|
||||
users:
|
||||
tenants: 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": [
|
||||
{
|
||||
"args": {
|
||||
"network_data": {},
|
||||
"subnet_data": {},
|
||||
"network_create_args": {},
|
||||
"subnet_create_args": {},
|
||||
"subnet_cidr_start": "1.1.0.0/30",
|
||||
"subnets_per_network": 2
|
||||
},
|
||||
"runner": {
|
||||
@ -15,6 +16,12 @@
|
||||
"users": {
|
||||
"tenants": 5,
|
||||
"users_per_tenant": 5
|
||||
},
|
||||
"quotas": {
|
||||
"neutron": {
|
||||
"network": -1,
|
||||
"subnet": -1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,14 +2,19 @@
|
||||
NeutronNetworks.create_and_list_subnets:
|
||||
-
|
||||
args:
|
||||
network_data:
|
||||
subnet_data:
|
||||
network_create_args:
|
||||
subnet_create_args:
|
||||
subnet_cidr_start: "1.1.0.0/30"
|
||||
subnets_per_network: 2
|
||||
runner:
|
||||
type: "constant"
|
||||
times: 10
|
||||
concurrency: 5
|
||||
times: 100
|
||||
concurrency: 10
|
||||
context:
|
||||
users:
|
||||
tenants: 5
|
||||
users_per_tenant: 5
|
||||
tenants: 1
|
||||
users_per_tenant: 1
|
||||
quotas:
|
||||
neutron:
|
||||
network: -1
|
||||
subnet: -1
|
||||
|
@ -37,7 +37,7 @@
|
||||
NeutronNetworks.create_and_list_networks:
|
||||
-
|
||||
args:
|
||||
network_data:
|
||||
network_create_args:
|
||||
runner:
|
||||
type: "constant"
|
||||
times: 100
|
||||
@ -53,18 +53,41 @@
|
||||
NeutronNetworks.create_and_list_subnets:
|
||||
-
|
||||
args:
|
||||
network_data:
|
||||
subnet_data:
|
||||
network_create_args:
|
||||
subnet_create_args:
|
||||
subnet_cidr_start: "1.1.0.0/30"
|
||||
subnets_per_network: 2
|
||||
runner:
|
||||
type: "constant"
|
||||
times: 100
|
||||
concurrency: 5
|
||||
concurrency: 10
|
||||
context:
|
||||
users:
|
||||
tenants: 1
|
||||
users_per_tenant: 1
|
||||
quotas:
|
||||
neutron:
|
||||
subnet: -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
|
||||
|
||||
from neutronclient.common import exceptions as neutron_exceptions
|
||||
|
||||
from rally.benchmark.scenarios.keystone import utils as kutils
|
||||
from rally.benchmark import utils as bench_utils
|
||||
|
||||
@ -116,21 +118,36 @@ def delete_keypairs(nova):
|
||||
_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):
|
||||
delete_neutron_subnets(neutron, project_uuid)
|
||||
delete_neutron_networks(neutron, project_uuid)
|
||||
# Ports
|
||||
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):
|
||||
|
@ -15,13 +15,14 @@
|
||||
|
||||
from rally.benchmark.scenarios import base
|
||||
from rally.benchmark.scenarios.neutron import utils
|
||||
from rally.benchmark import validation
|
||||
|
||||
|
||||
class NeutronNetworks(utils.NeutronScenario):
|
||||
|
||||
@base.scenario(context={"cleanup": ["neutron"]})
|
||||
def create_and_list_networks(self, network_data=None):
|
||||
"""Tests creating a network and then listing all networks.
|
||||
def create_and_list_networks(self, network_create_args=None):
|
||||
"""Create a network and then listing all networks.
|
||||
|
||||
This scenario is a very useful tool to measure
|
||||
the "neutron net-list" command performance.
|
||||
@ -32,26 +33,59 @@ class NeutronNetworks(utils.NeutronScenario):
|
||||
performance of the "neutron net-list" command depending on
|
||||
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()
|
||||
|
||||
@base.scenario(context={"cleanup": ["neutron"]})
|
||||
@validation.add(validation.required_parameters(['subnets_per_network']))
|
||||
def create_and_list_subnets(self,
|
||||
network_data=None,
|
||||
subnet_data=None,
|
||||
subnets_per_network=1):
|
||||
"""Tests creating a network, a given number of subnets
|
||||
and then list subnets.
|
||||
network_create_args=None,
|
||||
subnet_create_args=None,
|
||||
subnet_cidr_start=None,
|
||||
subnets_per_network=None):
|
||||
"""Create a network, a given number of subnets
|
||||
and then list all subnets.
|
||||
|
||||
:param network_data: dict, network options
|
||||
:param subnet_data: dict, subnet options
|
||||
: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
|
||||
"""
|
||||
|
||||
network = self._create_network(network_data or {})
|
||||
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):
|
||||
self._create_subnet(network, subnet_data or {})
|
||||
self._create_subnet(network, subnet_create_args or {})
|
||||
|
||||
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
|
||||
# under the License.
|
||||
|
||||
import multiprocessing
|
||||
import netaddr
|
||||
|
||||
from rally.benchmark.scenarios import base
|
||||
from rally.benchmark.scenarios import utils as scenario_utils
|
||||
|
||||
@ -24,62 +27,81 @@ class NeutronScenario(base.Scenario):
|
||||
|
||||
RESOURCE_NAME_PREFIX = "rally_net_"
|
||||
SUBNET_IP_VERSION = 4
|
||||
SUBNET_CIDR_PATTERN = "192.168.%d.0/24"
|
||||
SUBNET_CIDR_START = "1.1.0.0/30"
|
||||
|
||||
_subnet_cidrs = {}
|
||||
|
||||
@classmethod
|
||||
def _generate_subnet_cidr(cls, network_id):
|
||||
"""Generates next subnet CIDR for given network,
|
||||
"""Generate next subnet CIDR for given network,
|
||||
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
|
||||
return cls.SUBNET_CIDR_PATTERN % cidr_no
|
||||
:param network_id: str, network UUID for subnet
|
||||
: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')
|
||||
def _create_network(self, network_data):
|
||||
"""Creates neutron network.
|
||||
def _create_network(self, network_create_args):
|
||||
"""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
|
||||
"""
|
||||
network_data.setdefault("name", self._generate_random_name())
|
||||
return self.clients("neutron").create_network({
|
||||
"network": network_data})
|
||||
network_create_args.setdefault("name", self._generate_random_name())
|
||||
return self.clients("neutron"
|
||||
).create_network({"network": network_create_args})
|
||||
|
||||
@scenario_utils.atomic_action_timer('neutron.list_networks')
|
||||
def _list_networks(self):
|
||||
"""Returns user networks list."""
|
||||
"""Return user networks list."""
|
||||
return self.clients("neutron").list_networks()['networks']
|
||||
|
||||
@scenario_utils.atomic_action_timer('neutron.create_subnet')
|
||||
def _create_subnet(self, network, subnet_data):
|
||||
"""Creates neutron subnet.
|
||||
def _create_subnet(self, network, subnet_create_args):
|
||||
"""Create neutron subnet.
|
||||
|
||||
: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
|
||||
"""
|
||||
network_id = network["network"]["id"]
|
||||
subnet_data["network_id"] = network_id
|
||||
subnet_data.setdefault("cidr",
|
||||
self._generate_subnet_cidr(network_id))
|
||||
subnet_data.setdefault("ip_version", self.SUBNET_IP_VERSION)
|
||||
subnet_create_args["network_id"] = network_id
|
||||
subnet_create_args.setdefault(
|
||||
"name", self._generate_random_name("rally_subnet_"))
|
||||
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')
|
||||
def _list_subnets(self):
|
||||
"""Returns user subnetworks list."""
|
||||
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_glance_resources" % BASE)
|
||||
@mock.patch("%s.utils.delete_cinder_resources" % BASE)
|
||||
def test_cleaner_users_all_services(self, mock_del_cinder,
|
||||
mock_del_glance, mock_del_nova,
|
||||
mock_clients):
|
||||
@mock.patch("%s.utils.delete_neutron_resources" % BASE)
|
||||
def test_cleaner_users_resources(self,
|
||||
mock_del_neutron,
|
||||
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", "glance"]},
|
||||
"config": {"cleanup": ["cinder", "nova", "glance", "neutron"]},
|
||||
"tenants": [mock.MagicMock()]
|
||||
}
|
||||
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_glance.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)
|
||||
def test_cleaner_users_default_behavior(self, mock_cleanup):
|
||||
@ -111,29 +116,3 @@ class ResourceCleanerTestCase(test.TestCase):
|
||||
res_cleaner.setup()
|
||||
|
||||
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):
|
||||
neutron_scenario = network.NeutronNetworks()
|
||||
|
||||
# Empty options are specified
|
||||
network_data = {}
|
||||
neutron_scenario.create_and_list_networks(network_data=network_data)
|
||||
mock_create.assert_called_once_with(network_data)
|
||||
# Default options
|
||||
network_create_args = {}
|
||||
neutron_scenario.create_and_list_networks(
|
||||
network_create_args=network_create_args)
|
||||
mock_create.assert_called_once_with(network_create_args)
|
||||
mock_list.assert_called_once_with()
|
||||
|
||||
mock_create.reset_mock()
|
||||
mock_list.reset_mock()
|
||||
|
||||
# Explicit network name is specified
|
||||
network_data = {"name": "given-name"}
|
||||
neutron_scenario.create_and_list_networks(network_data=network_data)
|
||||
mock_create.assert_called_once_with(network_data)
|
||||
network_create_args = {"name": "given-name"}
|
||||
neutron_scenario.create_and_list_networks(
|
||||
network_create_args=network_create_args)
|
||||
mock_create.assert_called_once_with(network_create_args)
|
||||
mock_list.assert_called_once_with()
|
||||
|
||||
@mock.patch(NEUTRON_NETWORKS + "._generate_random_name")
|
||||
@mock.patch(NEUTRON_NETWORKS + "._list_subnets")
|
||||
@mock.patch(NEUTRON_NETWORKS + "._create_subnet")
|
||||
@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,
|
||||
mock_cidr_start,
|
||||
mock_create_network,
|
||||
mock_create_subnet,
|
||||
mock_list,
|
||||
mock_random_name):
|
||||
mock_list):
|
||||
scenario = network.NeutronNetworks()
|
||||
mock_random_name.return_value = "random-name"
|
||||
mock_create_network.return_value = {"network": {"id": "fake-id"}}
|
||||
subnets_per_network = 4
|
||||
|
||||
# Empty options
|
||||
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()
|
||||
self.assertRaises(TypeError, scenario.create_and_list_subnets)
|
||||
|
||||
mock_create_network.reset_mock()
|
||||
mock_create_subnet.reset_mock()
|
||||
mock_list.reset_mock()
|
||||
|
||||
# Extra options are specified
|
||||
subnets_num = 4
|
||||
scenario.create_and_list_subnets(network_data={"name": "given-name"},
|
||||
subnet_data={"allocation_pools": []},
|
||||
subnets_per_network=subnets_num)
|
||||
mock_create_network.assert_called_once_with({"name": "given-name"})
|
||||
# Default options
|
||||
scenario.create_and_list_subnets(
|
||||
subnets_per_network=subnets_per_network)
|
||||
mock_create_network.assert_called_once_with({})
|
||||
self.assertEqual(mock_create_subnet.mock_calls,
|
||||
[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()
|
||||
|
@ -67,33 +67,36 @@ class NeutronScenarioTestCase(test.TestCase):
|
||||
|
||||
@mock.patch(NEUTRON_UTILS + 'NeutronScenario.clients')
|
||||
def test_list_networks(self, mock_clients):
|
||||
scenario = utils.NeutronScenario()
|
||||
networks_list = []
|
||||
networks_dict = {"networks": networks_list}
|
||||
mock_clients("neutron").list_networks.return_value = networks_dict
|
||||
neutron_scenario = utils.NeutronScenario()
|
||||
return_networks_list = neutron_scenario._list_networks()
|
||||
return_networks_list = scenario._list_networks()
|
||||
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')
|
||||
|
||||
@mock.patch(NEUTRON_UTILS + 'NeutronScenario._generate_random_name')
|
||||
@mock.patch(NEUTRON_UTILS + "NeutronScenario._generate_subnet_cidr")
|
||||
@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"
|
||||
subnet_cidr = "192.168.0.0/24"
|
||||
mock_cidr.return_value = subnet_cidr
|
||||
scenario = utils.NeutronScenario()
|
||||
mock_random_name.return_value = "fake-name"
|
||||
|
||||
network = {"network": {"id": network_id}}
|
||||
expected_subnet_data = {
|
||||
"subnet": {
|
||||
"network_id": network_id,
|
||||
"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}
|
||||
scenario._create_subnet(network, subnet_data)
|
||||
mock_clients("neutron")\
|
||||
@ -103,7 +106,7 @@ class NeutronScenarioTestCase(test.TestCase):
|
||||
|
||||
mock_clients("neutron").create_subnet.reset_mock()
|
||||
|
||||
# Extra options are specified
|
||||
# Custom options
|
||||
extras = {"cidr": "192.168.16.0/24", "allocation_pools": []}
|
||||
subnet_data.update(extras)
|
||||
expected_subnet_data["subnet"].update(extras)
|
||||
@ -122,32 +125,61 @@ class NeutronScenarioTestCase(test.TestCase):
|
||||
self._test_atomic_action_timer(scenario.atomic_actions(),
|
||||
"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):
|
||||
"Curent NeutronScenario implementation supports only IPv4"
|
||||
"""Curent NeutronScenario implementation supports only IPv4."""
|
||||
self.assertEqual(utils.NeutronScenario.SUBNET_IP_VERSION, 4)
|
||||
|
||||
def test_SUBNET_CIDR_PATTERN(self):
|
||||
netaddr.IPNetwork(utils.NeutronScenario.SUBNET_CIDR_PATTERN % 0)
|
||||
self.assertRaises(netaddr.core.AddrFormatError,
|
||||
netaddr.IPNetwork,
|
||||
utils.NeutronScenario.SUBNET_CIDR_PATTERN % 256)
|
||||
def test_SUBNET_CIDR_START(self):
|
||||
"""Valid default CIDR to generate first subnet."""
|
||||
netaddr.IPNetwork(utils.NeutronScenario.SUBNET_CIDR_START)
|
||||
|
||||
def test_generate_subnet_cidr(self):
|
||||
scenario = utils.NeutronScenario()
|
||||
network1_id = "fake1"
|
||||
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,
|
||||
scenario._generate_subnet_cidr,
|
||||
network1_id)
|
||||
|
||||
cidrs2 = map(scenario._generate_subnet_cidr, [network2_id] * 256)
|
||||
|
||||
self.assertRaises(ValueError,
|
||||
scenario._generate_subnet_cidr,
|
||||
network2_id)
|
||||
cidrs2 = map(scenario._generate_subnet_cidr,
|
||||
[network2_id] * subnets_num)
|
||||
|
||||
# All CIDRs must differ
|
||||
self.assertEqual(len(cidrs1), len(set(cidrs1)))
|
||||
|
272
tests/fakes.py
272
tests/fakes.py
@ -13,13 +13,18 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import mock
|
||||
import multiprocessing
|
||||
import random
|
||||
import re
|
||||
import string
|
||||
import uuid
|
||||
|
||||
import mock
|
||||
|
||||
from ceilometerclient import exc as ceilometer_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.scenarios import base
|
||||
from rally.objects import endpoint
|
||||
@ -30,6 +35,49 @@ def generate_uuid():
|
||||
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):
|
||||
|
||||
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)
|
||||
if server is not None:
|
||||
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):
|
||||
server = self._cache(server_class(self))
|
||||
@ -351,7 +399,7 @@ class FakeSecurityGroupManager(FakeManager):
|
||||
break
|
||||
if match:
|
||||
return resource
|
||||
raise exceptions.NotFound('Security Group not found')
|
||||
raise nova_exceptions.NotFound('Security Group not found')
|
||||
|
||||
|
||||
class FakeSecurityGroupRuleManager(FakeManager):
|
||||
@ -559,9 +607,185 @@ class FakeCeilometerClient(object):
|
||||
|
||||
class FakeNeutronClient(object):
|
||||
|
||||
def __init__(self):
|
||||
#TODO(bsemp): Fake Manager subclasses to manage networks.
|
||||
pass
|
||||
def __init__(self, **kwargs):
|
||||
self.__networks = {}
|
||||
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):
|
||||
@ -573,40 +797,46 @@ class FakeIronicClient(object):
|
||||
|
||||
class FakeClients(object):
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self, endpoint_=None):
|
||||
self._nova = None
|
||||
self._glance = None
|
||||
self._keystone = 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):
|
||||
if self._keystone is not None:
|
||||
return self._keystone
|
||||
self._keystone = FakeKeystoneClient()
|
||||
if not self._keystone:
|
||||
self._keystone = FakeKeystoneClient()
|
||||
return self._keystone
|
||||
|
||||
def verified_keystone(self):
|
||||
return self.keystone()
|
||||
|
||||
def nova(self):
|
||||
if self._nova is not None:
|
||||
return self._nova
|
||||
self._nova = FakeNovaClient()
|
||||
if not self._nova:
|
||||
self._nova = FakeNovaClient()
|
||||
return self._nova
|
||||
|
||||
def glance(self):
|
||||
if self._glance is not None:
|
||||
return self._glance
|
||||
self._glance = FakeGlanceClient()
|
||||
if not self._glance:
|
||||
self._glance = FakeGlanceClient()
|
||||
return self._glance
|
||||
|
||||
def cinder(self):
|
||||
if self._cinder is not None:
|
||||
return self._cinder
|
||||
self._cinder = FakeCinderClient()
|
||||
if not self._cinder:
|
||||
self._cinder = FakeCinderClient()
|
||||
return self._cinder
|
||||
|
||||
def neutron(self):
|
||||
if not self._neutron:
|
||||
self._neutron = FakeNeutronClient()
|
||||
return self._neutron
|
||||
|
||||
|
||||
class FakeRunner(object):
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user