From cee6df2f80bb2e3450b982a1d68047bc92b1f567 Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Fri, 7 Aug 2015 10:48:55 -0500 Subject: [PATCH] Use network context for Neutron scenarios This permits users to create a network with the network context, or use the new exiting_network context, to provide networks to Neutron scenarios instead of always creating a new network. This makes it possible to run Rally against Neutron Provider Network deployments with "dumb" routers. It will also eventually permit us to deduplicate some code by moving network creation into the network context. Neutron scenarios that are benchmarking network creation continue to create networks. This deprecates network creation inside the other scenarios. Warning messages are produced where appropriate. Change-Id: I404eee0f14f40e348b2916854ed193c59364c31b --- .../openstack/scenarios/neutron/network.py | 109 ++- .../openstack/scenarios/neutron/utils.py | 99 ++- .../neutron/create_and_delete_ports.json | 1 + .../neutron/create_and_delete_ports.yaml | 1 + .../neutron/create_and_delete_routers.json | 1 + .../neutron/create_and_delete_routers.yaml | 1 + .../neutron/create_and_delete_subnets.json | 1 + .../neutron/create_and_delete_subnets.yaml | 1 + .../neutron/create_and_list_ports.json | 1 + .../neutron/create_and_list_ports.yaml | 1 + .../neutron/create_and_list_routers.json | 1 + .../neutron/create_and_list_routers.yaml | 1 + .../neutron/create_and_list_subnets.json | 1 + .../neutron/create_and_list_subnets.yaml | 1 + .../neutron/create_and_update_ports.json | 1 + .../neutron/create_and_update_ports.yaml | 1 + .../neutron/create_and_update_routers.json | 1 + .../neutron/create_and_update_routers.yaml | 1 + .../neutron/create_and_update_subnets.json | 1 + .../neutron/create_and_update_subnets.yaml | 1 + .../scenarios/neutron/test_network.py | 633 +++++------------- .../openstack/scenarios/neutron/test_utils.py | 114 ++++ 22 files changed, 445 insertions(+), 528 deletions(-) diff --git a/rally/plugins/openstack/scenarios/neutron/network.py b/rally/plugins/openstack/scenarios/neutron/network.py index ee92943db9..c3e32a0b79 100644 --- a/rally/plugins/openstack/scenarios/neutron/network.py +++ b/rally/plugins/openstack/scenarios/neutron/network.py @@ -83,15 +83,15 @@ class NeutronNetworks(utils.NeutronScenario): The scenario creates a network, a given number of subnets and then lists subnets. - :param network_create_args: dict, POST /v2.0/networks request options + :param network_create_args: dict, POST /v2.0/networks request + options. Deprecated :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 """ - self._create_network_and_subnets(network_create_args or {}, - subnet_create_args or {}, - subnets_per_network, - subnet_cidr_start) + network = self._get_or_create_network(network_create_args) + self._create_subnets(network, subnet_create_args, subnet_cidr_start, + subnets_per_network) self._list_subnets() @validation.number("subnets_per_network", minval=1, integer_only=True) @@ -111,16 +111,15 @@ class NeutronNetworks(utils.NeutronScenario): "neutron subnet-update" command performance. :param subnet_update_args: dict, PUT /v2.0/subnets update options - :param network_create_args: dict, POST /v2.0/networks request options + :param network_create_args: dict, POST /v2.0/networks request + options. Deprecated. :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, subnets = self._create_network_and_subnets( - network_create_args or {}, - subnet_create_args or {}, - subnets_per_network, - subnet_cidr_start) + network = self._get_or_create_network(network_create_args) + subnets = self._create_subnets(network, subnet_create_args, + subnet_cidr_start, subnets_per_network) for subnet in subnets: self._update_subnet(subnet, subnet_update_args) @@ -138,16 +137,15 @@ class NeutronNetworks(utils.NeutronScenario): The scenario creates a network, a given number of subnets and then deletes subnets. - :param network_create_args: dict, POST /v2.0/networks request options + :param network_create_args: dict, POST /v2.0/networks request + options. Deprecated. :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, subnets = self._create_network_and_subnets( - network_create_args or {}, - subnet_create_args or {}, - subnets_per_network, - subnet_cidr_start) + network = self._get_or_create_network(network_create_args) + subnets = self._create_subnets(network, subnet_create_args, + subnet_cidr_start, subnets_per_network) for subnet in subnets: self._delete_subnet(subnet) @@ -167,24 +165,16 @@ class NeutronNetworks(utils.NeutronScenario): 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 network_create_args: dict, POST /v2.0/networks request + options. Deprecated. :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 """ - network, subnets = self._create_network_and_subnets( - network_create_args or {}, - subnet_create_args or {}, - subnets_per_network, - subnet_cidr_start) - - for subnet in subnets: - router = self._create_router(router_create_args or {}) - self.clients("neutron").add_interface_router( - router["router"]["id"], - {"subnet_id": subnet["subnet"]["id"]}) - + self._create_network_structure(network_create_args, subnet_create_args, + subnet_cidr_start, subnets_per_network, + router_create_args) self._list_routers() @validation.number("subnets_per_network", minval=1, integer_only=True) @@ -204,23 +194,18 @@ class NeutronNetworks(utils.NeutronScenario): and then updating all routers. :param router_update_args: dict, PUT /v2.0/routers update options - :param network_create_args: dict, POST /v2.0/networks request options + :param network_create_args: dict, POST /v2.0/networks request + options. Deprecated. :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 """ - network, subnets = self._create_network_and_subnets( - network_create_args or {}, - subnet_create_args or {}, - subnets_per_network, - subnet_cidr_start) + network, subnets, routers = self._create_network_structure( + network_create_args, subnet_create_args, subnet_cidr_start, + subnets_per_network, router_create_args) - for subnet in subnets: - router = self._create_router(router_create_args or {}) - self.clients("neutron").add_interface_router( - router["router"]["id"], - {"subnet_id": subnet["subnet"]["id"]}) + for router in routers: self._update_router(router, router_update_args) @validation.required_parameters("subnets_per_network") @@ -237,32 +222,21 @@ class NeutronNetworks(utils.NeutronScenario): Create a network, a given number of subnets and routers and then delete all routers. - :param network_create_args: dict, POST /v2.0/networks request options + :param network_create_args: dict, POST /v2.0/networks request + options. Deprecated. :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 """ - network, subnets = self._create_network_and_subnets( - network_create_args or {}, - subnet_create_args or {}, - subnets_per_network, - subnet_cidr_start) - - routers = [] - for subnet in subnets: - router = self._create_router(router_create_args or {}) - self.clients("neutron").add_interface_router( - router["router"]["id"], - {"subnet_id": subnet["subnet"]["id"]}) - routers.append(router) + network, subnets, routers = self._create_network_structure( + network_create_args, subnet_create_args, subnet_cidr_start, + subnets_per_network, router_create_args) for e in range(subnets_per_network): router = routers[e] subnet = subnets[e] - self.clients("neutron").remove_interface_router( - router["router"]["id"], - {"subnet_id": subnet["subnet"]["id"]}) + self._remove_interface_router(subnet["subnet"], router["router"]) self._delete_router(router) @validation.number("ports_per_network", minval=1, integer_only=True) @@ -275,11 +249,12 @@ class NeutronNetworks(utils.NeutronScenario): ports_per_network=None): """Create and a given number of ports and list all ports. - :param network_create_args: dict, POST /v2.0/networks request options + :param network_create_args: dict, POST /v2.0/networks request + options. Deprecated. :param port_create_args: dict, POST /v2.0/ports request options :param ports_per_network: int, number of ports for one network """ - network = self._create_network(network_create_args or {}) + network = self._get_or_create_network(network_create_args) for i in range(ports_per_network): self._create_port(network, port_create_args or {}) @@ -300,13 +275,14 @@ class NeutronNetworks(utils.NeutronScenario): performance. :param port_update_args: dict, PUT /v2.0/ports update request options - :param network_create_args: dict, POST /v2.0/networks request options + :param network_create_args: dict, POST /v2.0/networks request + options. Deprecated. :param port_create_args: dict, POST /v2.0/ports request options :param ports_per_network: int, number of ports for one network """ - network = self._create_network(network_create_args or {}) + network = self._get_or_create_network(network_create_args) for i in range(ports_per_network): - port = self._create_port(network, port_create_args or {}) + port = self._create_port(network, port_create_args) self._update_port(port, port_update_args) @validation.required_parameters("ports_per_network") @@ -321,13 +297,14 @@ class NeutronNetworks(utils.NeutronScenario): Measure the "neutron port-create" and "neutron port-delete" commands performance. - :param network_create_args: dict, POST /v2.0/networks request options + :param network_create_args: dict, POST /v2.0/networks request + options. Deprecated. :param port_create_args: dict, POST /v2.0/ports request options :param ports_per_network: int, number of ports for one network """ - network = self._create_network(network_create_args or {}) + network = self._get_or_create_network(network_create_args) for i in range(ports_per_network): - port = self._create_port(network, port_create_args or {}) + port = self._create_port(network, port_create_args) self._delete_port(port) @validation.required_services(consts.Service.NEUTRON) diff --git a/rally/plugins/openstack/scenarios/neutron/utils.py b/rally/plugins/openstack/scenarios/neutron/utils.py index 36f2b8ee11..9768de01b8 100644 --- a/rally/plugins/openstack/scenarios/neutron/utils.py +++ b/rally/plugins/openstack/scenarios/neutron/utils.py @@ -13,6 +13,8 @@ # License for the specific language governing permissions and limitations # under the License. +import random + from rally.common.i18n import _ from rally.common import log as logging from rally import exceptions @@ -263,6 +265,67 @@ class NeutronScenario(scenario.OpenStackScenario): """ self.clients("neutron").delete_port(port["port"]["id"]) + @logging.log_deprecated_args(_("network_create_args is deprecated; " + "use the network context instead"), + "0.1.0", "network_create_args") + def _get_or_create_network(self, network_create_args=None): + """Get a network from context, or create a new one. + + This lets users either create networks with the 'network' + context, provide existing networks with the 'existing_network' + context, or let the scenario create a default network for + them. Running this without one of the network contexts is + deprecated. + + :param network_create_args: Deprecated way to provide network + creation args; use the network + context instead. + :returns: Network dict + """ + if "networks" not in self.context["tenant"]: + LOG.warning(_("Running this scenario without either the 'network' " + "or 'existing_network' context is deprecated")) + elif network_create_args is None: + return random.choice(self.context["tenant"]["networks"]) + + return self._create_network(network_create_args or {}) + + def _get_or_create_subnets(self, network, + subnet_create_args=None, + subnet_cidr_start=None, + subnets_per_network=1): + """Get subnets from a network, or create new subnets. + + Existing subnets are preferred to creating new ones. + + :param network: network to create subnets in + :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 + :returns: List of subnet dicts + """ + if len(network.get("subnets", [])): + return network["subnets"] + else: + return self._create_subnets(network, subnet_create_args, + subnet_cidr_start, subnets_per_network) + + def _create_subnets(self, network, + subnet_create_args=None, + subnet_cidr_start=None, + subnets_per_network=1): + """Create new subnets in the given network. + + :param network: network to create subnets in + :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 + :returns: List of subnet dicts + """ + return [self._create_subnet(network, subnet_create_args or {}, + subnet_cidr_start) + for i in range(subnets_per_network)] + def _create_network_and_subnets(self, network_create_args=None, subnet_create_args=None, @@ -276,15 +339,39 @@ class NeutronScenario(scenario.OpenStackScenario): :parm subnet_cidr_start: str, start value for subnets CIDR :returns: tuple of result network and subnets list """ - subnets = [] network = self._create_network(network_create_args or {}) - - for i in range(subnets_per_network): - subnet = self._create_subnet(network, subnet_create_args or {}, - subnet_cidr_start) - subnets.append(subnet) + subnets = self._create_subnets(network, subnet_create_args, + subnet_cidr_start, subnets_per_network) return network, subnets + def _create_network_structure(self, network_create_args=None, + subnet_create_args=None, + subnet_cidr_start=None, + subnets_per_network=None, + router_create_args=None): + """Create a network and a given number of subnets and 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 + :returns: tuple of (network, subnets, routers) + """ + network = self._get_or_create_network(network_create_args) + subnets = self._get_or_create_subnets(network, subnet_create_args, + subnet_cidr_start, + subnets_per_network) + + routers = [] + for subnet in subnets: + router = self._create_router(router_create_args or {}) + self._add_interface_router(subnet["subnet"], + router["router"]) + routers.append(router) + + return (network, subnets, routers) + @atomic.action_timer("neutron.add_interface_router") def _add_interface_router(self, subnet, router): """Connect subnet to router. diff --git a/samples/tasks/scenarios/neutron/create_and_delete_ports.json b/samples/tasks/scenarios/neutron/create_and_delete_ports.json index 3e058b1093..406f393c0c 100644 --- a/samples/tasks/scenarios/neutron/create_and_delete_ports.json +++ b/samples/tasks/scenarios/neutron/create_and_delete_ports.json @@ -12,6 +12,7 @@ "concurrency": 10 }, "context": { + "network": {}, "users": { "tenants": 3, "users_per_tenant": 3 diff --git a/samples/tasks/scenarios/neutron/create_and_delete_ports.yaml b/samples/tasks/scenarios/neutron/create_and_delete_ports.yaml index d3d41166de..c09bb85a05 100644 --- a/samples/tasks/scenarios/neutron/create_and_delete_ports.yaml +++ b/samples/tasks/scenarios/neutron/create_and_delete_ports.yaml @@ -10,6 +10,7 @@ times: 100 concurrency: 10 context: + network: {} users: tenants: 3 users_per_tenant: 3 diff --git a/samples/tasks/scenarios/neutron/create_and_delete_routers.json b/samples/tasks/scenarios/neutron/create_and_delete_routers.json index e51118eddc..951b7c80c5 100644 --- a/samples/tasks/scenarios/neutron/create_and_delete_routers.json +++ b/samples/tasks/scenarios/neutron/create_and_delete_routers.json @@ -14,6 +14,7 @@ "concurrency": 10 }, "context": { + "network": {}, "users": { "tenants": 3, "users_per_tenant": 3 diff --git a/samples/tasks/scenarios/neutron/create_and_delete_routers.yaml b/samples/tasks/scenarios/neutron/create_and_delete_routers.yaml index 5eed8db3d3..7d5f7f654b 100644 --- a/samples/tasks/scenarios/neutron/create_and_delete_routers.yaml +++ b/samples/tasks/scenarios/neutron/create_and_delete_routers.yaml @@ -12,6 +12,7 @@ times: 30 concurrency: 10 context: + network: {} users: tenants: 3 users_per_tenant: 3 diff --git a/samples/tasks/scenarios/neutron/create_and_delete_subnets.json b/samples/tasks/scenarios/neutron/create_and_delete_subnets.json index 1db8b34427..25f424bfe9 100644 --- a/samples/tasks/scenarios/neutron/create_and_delete_subnets.json +++ b/samples/tasks/scenarios/neutron/create_and_delete_subnets.json @@ -13,6 +13,7 @@ "concurrency": 10 }, "context": { + "network": {}, "users": { "tenants": 3, "users_per_tenant": 3 diff --git a/samples/tasks/scenarios/neutron/create_and_delete_subnets.yaml b/samples/tasks/scenarios/neutron/create_and_delete_subnets.yaml index db6501b974..e97f3902b7 100644 --- a/samples/tasks/scenarios/neutron/create_and_delete_subnets.yaml +++ b/samples/tasks/scenarios/neutron/create_and_delete_subnets.yaml @@ -11,6 +11,7 @@ times: 100 concurrency: 10 context: + network: {} users: tenants: 3 users_per_tenant: 3 diff --git a/samples/tasks/scenarios/neutron/create_and_list_ports.json b/samples/tasks/scenarios/neutron/create_and_list_ports.json index 6674e8f420..c387f62321 100644 --- a/samples/tasks/scenarios/neutron/create_and_list_ports.json +++ b/samples/tasks/scenarios/neutron/create_and_list_ports.json @@ -12,6 +12,7 @@ "concurrency": 10 }, "context": { + "network": {}, "users": { "tenants": 3, "users_per_tenant": 3 diff --git a/samples/tasks/scenarios/neutron/create_and_list_ports.yaml b/samples/tasks/scenarios/neutron/create_and_list_ports.yaml index bcdfcdeb3f..b10c674e34 100644 --- a/samples/tasks/scenarios/neutron/create_and_list_ports.yaml +++ b/samples/tasks/scenarios/neutron/create_and_list_ports.yaml @@ -10,6 +10,7 @@ times: 100 concurrency: 10 context: + network: {} users: tenants: 3 users_per_tenant: 3 diff --git a/samples/tasks/scenarios/neutron/create_and_list_routers.json b/samples/tasks/scenarios/neutron/create_and_list_routers.json index 857f5a290c..8f16e9be68 100644 --- a/samples/tasks/scenarios/neutron/create_and_list_routers.json +++ b/samples/tasks/scenarios/neutron/create_and_list_routers.json @@ -14,6 +14,7 @@ "concurrency": 10 }, "context": { + "network": {}, "users": { "tenants": 3, "users_per_tenant": 3 diff --git a/samples/tasks/scenarios/neutron/create_and_list_routers.yaml b/samples/tasks/scenarios/neutron/create_and_list_routers.yaml index f346635b94..22cd13b5fe 100644 --- a/samples/tasks/scenarios/neutron/create_and_list_routers.yaml +++ b/samples/tasks/scenarios/neutron/create_and_list_routers.yaml @@ -12,6 +12,7 @@ times: 100 concurrency: 10 context: + network: {} users: tenants: 3 users_per_tenant: 3 diff --git a/samples/tasks/scenarios/neutron/create_and_list_subnets.json b/samples/tasks/scenarios/neutron/create_and_list_subnets.json index 08201d9f00..46956b8bdb 100644 --- a/samples/tasks/scenarios/neutron/create_and_list_subnets.json +++ b/samples/tasks/scenarios/neutron/create_and_list_subnets.json @@ -13,6 +13,7 @@ "concurrency": 5 }, "context": { + "network": {}, "users": { "tenants": 2, "users_per_tenant": 3 diff --git a/samples/tasks/scenarios/neutron/create_and_list_subnets.yaml b/samples/tasks/scenarios/neutron/create_and_list_subnets.yaml index a6993ab390..0450e703bf 100644 --- a/samples/tasks/scenarios/neutron/create_and_list_subnets.yaml +++ b/samples/tasks/scenarios/neutron/create_and_list_subnets.yaml @@ -11,6 +11,7 @@ times: 10 concurrency: 5 context: + network: {} users: tenants: 2 users_per_tenant: 3 diff --git a/samples/tasks/scenarios/neutron/create_and_update_ports.json b/samples/tasks/scenarios/neutron/create_and_update_ports.json index f605f17b1a..4c7dbdb6ef 100644 --- a/samples/tasks/scenarios/neutron/create_and_update_ports.json +++ b/samples/tasks/scenarios/neutron/create_and_update_ports.json @@ -18,6 +18,7 @@ "concurrency": 5 }, "context": { + "network": {}, "users": { "tenants": 2, "users_per_tenant": 3 diff --git a/samples/tasks/scenarios/neutron/create_and_update_ports.yaml b/samples/tasks/scenarios/neutron/create_and_update_ports.yaml index 6bcc71965c..eae30bb22d 100644 --- a/samples/tasks/scenarios/neutron/create_and_update_ports.yaml +++ b/samples/tasks/scenarios/neutron/create_and_update_ports.yaml @@ -15,6 +15,7 @@ times: 10 concurrency: 5 context: + network: {} users: tenants: 2 users_per_tenant: 3 diff --git a/samples/tasks/scenarios/neutron/create_and_update_routers.json b/samples/tasks/scenarios/neutron/create_and_update_routers.json index 453cc8ae66..8e299fab0a 100644 --- a/samples/tasks/scenarios/neutron/create_and_update_routers.json +++ b/samples/tasks/scenarios/neutron/create_and_update_routers.json @@ -18,6 +18,7 @@ "concurrency": 5 }, "context": { + "network": {}, "users": { "tenants": 2, "users_per_tenant": 3 diff --git a/samples/tasks/scenarios/neutron/create_and_update_routers.yaml b/samples/tasks/scenarios/neutron/create_and_update_routers.yaml index 6b7cdeac12..98bb6669e2 100644 --- a/samples/tasks/scenarios/neutron/create_and_update_routers.yaml +++ b/samples/tasks/scenarios/neutron/create_and_update_routers.yaml @@ -15,6 +15,7 @@ times: 10 concurrency: 5 context: + network: {} users: tenants: 2 users_per_tenant: 3 diff --git a/samples/tasks/scenarios/neutron/create_and_update_subnets.json b/samples/tasks/scenarios/neutron/create_and_update_subnets.json index 1e17653c67..8d9e893377 100644 --- a/samples/tasks/scenarios/neutron/create_and_update_subnets.json +++ b/samples/tasks/scenarios/neutron/create_and_update_subnets.json @@ -17,6 +17,7 @@ "concurrency": 5 }, "context": { + "network": {}, "users": { "tenants": 2, "users_per_tenant": 3 diff --git a/samples/tasks/scenarios/neutron/create_and_update_subnets.yaml b/samples/tasks/scenarios/neutron/create_and_update_subnets.yaml index d568027ef4..c759c8bfca 100644 --- a/samples/tasks/scenarios/neutron/create_and_update_subnets.yaml +++ b/samples/tasks/scenarios/neutron/create_and_update_subnets.yaml @@ -14,6 +14,7 @@ times: 10 concurrency: 5 context: + network: {} users: tenants: 2 users_per_tenant: 3 diff --git a/tests/unit/plugins/openstack/scenarios/neutron/test_network.py b/tests/unit/plugins/openstack/scenarios/neutron/test_network.py index f9ddbd32a1..41fec73154 100644 --- a/tests/unit/plugins/openstack/scenarios/neutron/test_network.py +++ b/tests/unit/plugins/openstack/scenarios/neutron/test_network.py @@ -111,524 +111,245 @@ class NeutronNetworksTestCase(test.ScenarioTestCase): mock__create_network.assert_called_once_with(network_create_args) self.assertEqual(1, mock__delete_network.call_count) - @mock.patch(NEUTRON_NETWORKS + "._list_subnets") - @mock.patch(NEUTRON_NETWORKS + "._create_network_and_subnets") - def test_create_and_list_subnets(self, - mock__create_network_and_subnets, - mock__list_subnets): - scenario = network.NeutronNetworks(self.context) - subnets_per_network = 4 + def test_create_and_list_subnets(self): + network_create_args = {"router:external": True} + subnet_create_args = {"allocation_pools": []} subnet_cidr_start = "default_cidr" + subnets_per_network = 5 + net = mock.MagicMock() + + scenario = network.NeutronNetworks(self.context) + scenario._get_or_create_network = mock.Mock(return_value=net) + scenario._create_subnets = mock.Mock() + scenario._list_subnets = mock.Mock() - # Default options scenario.create_and_list_subnets( - subnets_per_network=subnets_per_network, - subnet_cidr_start=subnet_cidr_start) - - mock__create_network_and_subnets.assert_has_calls( - [mock.call({}, {}, subnets_per_network, - subnet_cidr_start)]) - mock__list_subnets.assert_called_once_with() - - mock__create_network_and_subnets.reset_mock() - mock__list_subnets.reset_mock() - - # Custom options - scenario.create_and_list_subnets( - subnet_create_args={"allocation_pools": []}, - subnet_cidr_start="custom_cidr", + network_create_args=network_create_args, + subnet_create_args=subnet_create_args, + subnet_cidr_start=subnet_cidr_start, subnets_per_network=subnets_per_network) - mock__create_network_and_subnets.assert_has_calls( - [mock.call({}, {"allocation_pools": []}, - subnets_per_network, "custom_cidr")]) - mock__list_subnets.assert_called_once_with() + scenario._get_or_create_network.assert_called_once_with( + network_create_args) + scenario._create_subnets.assert_called_once_with( + net, subnet_create_args, subnet_cidr_start, subnets_per_network) - @mock.patch(NEUTRON_NETWORKS + "._update_subnet") - @mock.patch(NEUTRON_NETWORKS + "._create_network_and_subnets") - def test_create_and_update_subnets(self, - mock__create_network_and_subnets, - mock__update_subnet): - scenario = network.NeutronNetworks(self.context) - subnets_per_network = 1 + scenario._list_subnets.assert_called_once_with() + + def test_create_and_update_subnets(self): + network_create_args = {"router:external": True} + subnet_create_args = {"allocation_pools": []} + subnet_update_args = {"enabled_dhcp": True} subnet_cidr_start = "default_cidr" - net = { - "network": { - "id": "network-id" - } - } - subnet = { - "subnet": { - "name": "subnet-name", - "id": "subnet-id", - "enable_dhcp": False - } - } - mock__create_network_and_subnets.return_value = (net, [subnet]) - subnet_update_args = {"name": "_updated", "enable_dhcp": True} + subnets_per_network = 5 + net = mock.MagicMock() + subnets = [mock.MagicMock() for i in range(subnets_per_network)] + + scenario = network.NeutronNetworks(self.context) + scenario._get_or_create_network = mock.Mock(return_value=net) + scenario._create_subnets = mock.Mock(return_value=subnets) + scenario._update_subnet = mock.Mock() - # Default options scenario.create_and_update_subnets( - subnet_update_args=subnet_update_args, + subnet_update_args, + network_create_args=network_create_args, + subnet_create_args=subnet_create_args, subnet_cidr_start=subnet_cidr_start, subnets_per_network=subnets_per_network) - mock__create_network_and_subnets.assert_has_calls( - [mock.call({}, {}, subnets_per_network, subnet_cidr_start)]) - mock__update_subnet.assert_has_calls( - [mock.call(subnet, subnet_update_args)]) + scenario._get_or_create_network.assert_called_once_with( + network_create_args) + scenario._create_subnets.assert_called_once_with( + net, subnet_create_args, subnet_cidr_start, subnets_per_network) + scenario._update_subnet.assert_has_calls( + [mock.call(s, subnet_update_args) for s in subnets]) - mock__create_network_and_subnets.reset_mock() - mock__update_subnet.reset_mock() - - # Custom options - subnet_cidr_start = "custom_cidr" - scenario.create_and_update_subnets( - subnet_update_args=subnet_update_args, - subnet_create_args={"allocation_pools": []}, - subnet_cidr_start=subnet_cidr_start, - subnets_per_network=subnets_per_network) - - mock__create_network_and_subnets.assert_has_calls( - [mock.call({}, {"allocation_pools": []}, subnets_per_network, - subnet_cidr_start)]) - mock__update_subnet.assert_has_calls( - [mock.call(subnet, subnet_update_args)]) - - @mock.patch(NEUTRON_NETWORKS + "._delete_subnet") - @mock.patch(NEUTRON_NETWORKS + "._create_network_and_subnets") - def test_create_and_delete_subnets(self, - mock__create_network_and_subnets, - mock__delete_subnet): - scenario = network.NeutronNetworks(self.context) - net = { - "network": { - "id": "network-id" - } - } - subnet = { - "subnet": { - "name": "subnet-name", - "id": "subnet-id", - "enable_dhcp": False - } - } - mock__create_network_and_subnets.return_value = (net, [subnet]) - subnets_per_network = 1 + def test_create_and_delete_subnets(self): + network_create_args = {"router:external": True} + subnet_create_args = {"allocation_pools": []} subnet_cidr_start = "default_cidr" + subnets_per_network = 5 + net = mock.MagicMock() + subnets = [mock.MagicMock() for i in range(subnets_per_network)] + + scenario = network.NeutronNetworks(self.context) + scenario._get_or_create_network = mock.Mock(return_value=net) + scenario._create_subnets = mock.Mock(return_value=subnets) + scenario._delete_subnet = mock.Mock() - # Default options scenario.create_and_delete_subnets( - subnets_per_network=subnets_per_network, - subnet_cidr_start=subnet_cidr_start) - - mock__create_network_and_subnets.assert_has_calls( - [mock.call({}, {}, subnets_per_network, - subnet_cidr_start)]) - - mock__delete_subnet.assert_has_calls([mock.call(subnet)]) - - mock__create_network_and_subnets.reset_mock() - mock__delete_subnet.reset_mock() - - # Custom options - subnet_cidr_start = "custom_cidr" - scenario.create_and_delete_subnets( - subnet_create_args={"allocation_pools": []}, - subnet_cidr_start="custom_cidr", + network_create_args=network_create_args, + subnet_create_args=subnet_create_args, + subnet_cidr_start=subnet_cidr_start, subnets_per_network=subnets_per_network) - mock__create_network_and_subnets.assert_has_calls( - [mock.call({}, {"allocation_pools": []}, subnets_per_network, - subnet_cidr_start)]) - mock__delete_subnet.assert_has_calls([mock.call(subnet)]) + scenario._get_or_create_network.assert_called_once_with( + network_create_args) + scenario._create_subnets.assert_called_once_with( + net, subnet_create_args, subnet_cidr_start, subnets_per_network) + scenario._delete_subnet.assert_has_calls( + [mock.call(s) for s in subnets]) - @mock.patch(NEUTRON_NETWORKS + "._list_routers") - @mock.patch(NEUTRON_NETWORKS + "._create_router") - @mock.patch(NEUTRON_NETWORKS + "._create_network_and_subnets") - def test_create_and_list_routers(self, - mock__create_network_and_subnets, - mock__create_router, - mock__list_routers): - scenario = network.NeutronNetworks(self.context) - subnets_per_network = 1 + def test_create_and_list_routers(self): + network_create_args = {"router:external": True} + subnet_create_args = {"allocation_pools": []} subnet_cidr_start = "default_cidr" + subnets_per_network = 5 + router_create_args = {"admin_state_up": True} - net = { - "network": { - "id": "network-id" - } - } - subnet = { - "subnet": { - "name": "subnet-name", - "id": "subnet-id", - "enable_dhcp": False - } - } - mock__create_network_and_subnets.return_value = (net, [subnet]) - self.clients("neutron").add_interface_router = mock.Mock() - router = { - "router": { - "name": "router-name", - "id": "router-id" - } - } - mock__create_router.return_value = router + scenario = network.NeutronNetworks(self.context) + scenario._create_network_structure = mock.Mock() + scenario._list_routers = mock.Mock() - # Default options - scenario.create_and_list_routers( - subnet_cidr_start=subnet_cidr_start, - subnets_per_network=subnets_per_network) - mock__create_network_and_subnets.assert_has_calls( - [mock.call({}, {}, subnets_per_network, subnet_cidr_start)]) - - mock__create_router.assert_has_calls( - [mock.call({})] * subnets_per_network) - - self.clients("neutron").add_interface_router.assert_has_calls( - [mock.call(router["router"]["id"], - {"subnet_id": subnet["subnet"]["id"]}) - ] * subnets_per_network) - - mock__create_network_and_subnets.reset_mock() - mock__create_router.reset_mock() - - self.clients("neutron").add_interface_router.reset_mock() - mock__list_routers.reset_mock() - - # Custom options - subnet_cidr_start = "custom_cidr" - subnet_create_args = {"allocation_pools": []} - router_create_args = {"admin_state_up": False} scenario.create_and_list_routers( + network_create_args=network_create_args, subnet_create_args=subnet_create_args, - subnet_cidr_start="custom_cidr", + subnet_cidr_start=subnet_cidr_start, subnets_per_network=subnets_per_network, router_create_args=router_create_args) - mock__create_network_and_subnets.assert_has_calls( - [mock.call({}, subnet_create_args, subnets_per_network, - subnet_cidr_start)]) + scenario._create_network_structure.assert_called_once_with( + network_create_args, subnet_create_args, subnet_cidr_start, + subnets_per_network, router_create_args) + scenario._list_routers.assert_called_once_with() - mock__create_router.assert_has_calls( - [mock.call(router_create_args)] * subnets_per_network) - self.clients("neutron").add_interface_router.assert_has_calls( - [mock.call(router["router"]["id"], - {"subnet_id": subnet["subnet"]["id"]}) - ] * subnets_per_network) - - mock__list_routers.assert_called_once_with() - - @mock.patch(NEUTRON_NETWORKS + "._update_router") - @mock.patch(NEUTRON_NETWORKS + "._create_router") - @mock.patch(NEUTRON_NETWORKS + "._create_network_and_subnets") - def test_create_and_update_routers(self, - mock__create_network_and_subnets, - mock__create_router, - mock__update_router): - scenario = network.NeutronNetworks(self.context) - subnets_per_network = 1 + def test_create_and_update_routers(self): + router_update_args = {"admin_state_up": False} + network_create_args = {"router:external": True} + subnet_create_args = {"allocation_pools": []} subnet_cidr_start = "default_cidr" + subnets_per_network = 5 + router_create_args = {"admin_state_up": True} + net = mock.MagicMock() + subnets = [mock.MagicMock() for i in range(subnets_per_network)] + routers = [mock.MagicMock() for i in range(subnets_per_network)] - net = { - "network": { - "id": "network-id" - } - } - subnet = { - "subnet": { - "name": "subnet-name", - "id": "subnet-id", - "enable_dhcp": False - } - } - router = { - "router": { - "name": "router-name", - "id": "router-id" - } - } - router_update_args = { - "name": "_updated", - "admin_state_up": False - } - mock__create_router.return_value = router - mock__create_network_and_subnets.return_value = (net, [subnet]) - self.clients("neutron").add_interface_router = mock.Mock() + scenario = network.NeutronNetworks(self.context) + scenario._create_network_structure = mock.Mock( + return_value=(net, subnets, routers)) + scenario._update_router = mock.Mock() - # Default options scenario.create_and_update_routers( - router_update_args=router_update_args, - subnet_cidr_start=subnet_cidr_start, - subnets_per_network=subnets_per_network) - - mock__create_network_and_subnets.assert_has_calls( - [mock.call({}, {}, subnets_per_network, subnet_cidr_start)]) - - mock__create_router.assert_has_calls( - [mock.call({})] * subnets_per_network) - self.clients("neutron").add_interface_router.assert_has_calls( - [mock.call(router["router"]["id"], - {"subnet_id": subnet["subnet"]["id"]}) - ] * subnets_per_network) - - mock__update_router.assert_has_calls( - [mock.call(router, router_update_args) - ] * subnets_per_network) - - mock__create_network_and_subnets.reset_mock() - mock__create_router.reset_mock() - self.clients("neutron").add_interface_router.reset_mock() - mock__update_router.reset_mock() - - # Custom options - subnet_cidr_start = "custom_cidr" - subnet_create_args = {"allocation_pools": []} - router_create_args = {"admin_state_up": False} - scenario.create_and_update_routers( - router_update_args=router_update_args, + router_update_args, + network_create_args=network_create_args, subnet_create_args=subnet_create_args, - subnet_cidr_start="custom_cidr", + subnet_cidr_start=subnet_cidr_start, subnets_per_network=subnets_per_network, router_create_args=router_create_args) - mock__create_network_and_subnets.assert_has_calls( - [mock.call({}, subnet_create_args, subnets_per_network, - subnet_cidr_start)]) + scenario._create_network_structure.assert_called_once_with( + network_create_args, subnet_create_args, subnet_cidr_start, + subnets_per_network, router_create_args) - mock__create_router.assert_has_calls( - [mock.call(router_create_args)] * subnets_per_network) - self.clients("neutron").add_interface_router.assert_has_calls( - [mock.call(router["router"]["id"], - {"subnet_id": subnet["subnet"]["id"]}) - ] * subnets_per_network) + update_calls = [mock.call(router, router_update_args) + for router in routers] + scenario._update_router.assert_has_calls(update_calls) - mock__update_router.assert_has_calls( - [mock.call(router, router_update_args) - ] * subnets_per_network) - - @mock.patch(NEUTRON_NETWORKS + "._delete_router") - @mock.patch(NEUTRON_NETWORKS + "._create_router") - @mock.patch(NEUTRON_NETWORKS + "._create_network_and_subnets") - def test_create_and_delete_routers(self, - mock__create_network_and_subnets, - mock__create_router, - mock__delete_router): - scenario = network.NeutronNetworks(self.context) - subnets_per_network = 1 + def test_create_and_delete_routers(self): + network_create_args = {"router:external": True} + subnet_create_args = {"allocation_pools": []} subnet_cidr_start = "default_cidr" + subnets_per_network = 5 + router_create_args = {"admin_state_up": True} + net = mock.MagicMock() + subnets = [mock.MagicMock() for i in range(subnets_per_network)] + routers = [mock.MagicMock() for i in range(subnets_per_network)] - net = { - "network": { - "id": "network-id" - } - } - subnet = { - "subnet": { - "name": "subnet-name", - "id": "subnet-id", - "enable_dhcp": False - } - } - router = { - "router": { - "name": "router-name", - "id": "router-id" - } - } + scenario = network.NeutronNetworks(self.context) + scenario._create_network_structure = mock.Mock( + return_value=(net, subnets, routers)) + scenario._remove_interface_router = mock.Mock() + scenario._delete_router = mock.Mock() - mock__create_router.return_value = router - mock__create_network_and_subnets.return_value = (net, [subnet]) - self.clients("neutron").add_interface_router = mock.Mock() - - # Default options - scenario.create_and_delete_routers( - subnet_cidr_start=subnet_cidr_start, - subnets_per_network=subnets_per_network) - - mock__create_network_and_subnets.assert_has_calls( - [mock.call({}, {}, subnets_per_network, subnet_cidr_start)]) - - mock__create_router.assert_has_calls( - [mock.call({})] * subnets_per_network) - self.clients("neutron").add_interface_router.assert_has_calls( - [mock.call(router["router"]["id"], - {"subnet_id": subnet["subnet"]["id"]}) - ] * subnets_per_network) - - mock__delete_router.assert_has_calls( - [mock.call(router)] * subnets_per_network) - - mock__create_network_and_subnets.reset_mock() - mock__create_router.reset_mock() - self.clients("neutron").add_interface_router.reset_mock() - mock__delete_router.reset_mock() - - # Custom options - subnet_cidr_start = "custom_cidr" - subnet_create_args = {"allocation_pools": []} - router_create_args = {"admin_state_up": False} scenario.create_and_delete_routers( + network_create_args=network_create_args, subnet_create_args=subnet_create_args, - subnet_cidr_start="custom_cidr", + subnet_cidr_start=subnet_cidr_start, subnets_per_network=subnets_per_network, router_create_args=router_create_args) - mock__create_network_and_subnets.assert_has_calls( - [mock.call({}, subnet_create_args, subnets_per_network, - subnet_cidr_start)]) + scenario._create_network_structure.assert_called_once_with( + network_create_args, subnet_create_args, subnet_cidr_start, + subnets_per_network, router_create_args) - mock__create_router.assert_has_calls( - [mock.call(router_create_args)] * subnets_per_network) - self.clients("neutron").add_interface_router.assert_has_calls( - [mock.call(router["router"]["id"], - {"subnet_id": subnet["subnet"]["id"]}) - ] * subnets_per_network) + scenario._remove_interface_router.assert_has_calls([ + mock.call(subnets[i]["subnet"], routers[i]["router"]) + for i in range(subnets_per_network)]) + scenario._delete_router.assert_has_calls([mock.call(router) + for router in routers]) - mock__delete_router.assert_has_calls( - [mock.call(router)] * subnets_per_network) - - @mock.patch(NEUTRON_NETWORKS + ".generate_random_name") - @mock.patch(NEUTRON_NETWORKS + "._list_ports") - @mock.patch(NEUTRON_NETWORKS + "._create_port") - @mock.patch(NEUTRON_NETWORKS + "._create_network") - def test_create_and_list_ports(self, - mock__create_network, - mock__create_port, - mock__list_ports, - mock_generate_random_name): - scenario = network.NeutronNetworks(self.context) - mock_generate_random_name.return_value = "random-name" - net = {"network": {"id": "fake-id"}} - mock__create_network.return_value = net + def test_create_and_list_ports(self): + port_create_args = {"allocation_pools": []} ports_per_network = 10 + network_create_args = {"router:external": True} + net = mock.MagicMock() - self.assertRaises(TypeError, scenario.create_and_list_ports) + scenario = network.NeutronNetworks(self.context) + scenario._get_or_create_network = mock.Mock(return_value=net) + scenario._create_port = mock.MagicMock() + scenario._list_ports = mock.Mock() - mock__create_network.reset_mock() - - # Defaults - scenario.create_and_list_ports(ports_per_network=ports_per_network) - mock__create_network.assert_called_once_with({}) - self.assertEqual(mock__create_port.mock_calls, - [mock.call(net, {})] * ports_per_network) - mock__list_ports.assert_called_once_with() - - mock__create_network.reset_mock() - mock__create_port.reset_mock() - mock__list_ports.reset_mock() - - # Custom options scenario.create_and_list_ports( - network_create_args={"name": "given-name"}, - port_create_args={"allocation_pools": []}, + network_create_args=network_create_args, + port_create_args=port_create_args, ports_per_network=ports_per_network) - mock__create_network.assert_called_once_with({"name": "given-name"}) - self.assertEqual( - mock__create_port.mock_calls, - [mock.call(net, {"allocation_pools": []})] * ports_per_network) - mock__list_ports.assert_called_once_with() + scenario._get_or_create_network.assert_called_once_with( + network_create_args) + scenario._create_port.assert_has_calls( + [mock.call(net, port_create_args) + for i in range(ports_per_network)]) - @mock.patch(NEUTRON_NETWORKS + ".generate_random_name") - @mock.patch(NEUTRON_NETWORKS + "._update_port") - @mock.patch(NEUTRON_NETWORKS + "._create_port", return_value={ - "port": { - "name": "port-name", - "id": "port-id", - "admin_state_up": True - } - }) - @mock.patch(NEUTRON_NETWORKS + "._create_network", return_value={ - "network": {"id": "fake-id"}}) - def test_create_and_update_ports(self, - mock__create_network, - mock__create_port, - mock__update_port, - mock_generate_random_name): - scenario = network.NeutronNetworks(self.context) - mock_generate_random_name.return_value = "random-name" + scenario._list_ports.assert_called_once_with() + + def test_create_and_update_ports(self): + port_update_args = {"admin_state_up": False}, + port_create_args = {"allocation_pools": []} ports_per_network = 10 + network_create_args = {"router:external": True} + net = mock.MagicMock() + ports = [mock.MagicMock() for i in range(ports_per_network)] - port_update_args = { - "name": "_updated", - "admin_state_up": False - } - - # Defaults - scenario.create_and_update_ports( - port_update_args=port_update_args, - ports_per_network=ports_per_network) - mock__create_network.assert_called_once_with({}) - - mock__create_port.assert_has_calls( - [mock.call({"network": {"id": "fake-id"}}, - {})] * ports_per_network) - mock__update_port.assert_has_calls( - [mock.call(mock__create_port.return_value, port_update_args) - ] * ports_per_network) - - mock__create_network.reset_mock() - mock__create_port.reset_mock() - mock__update_port.reset_mock() - - # Custom options - scenario.create_and_update_ports( - port_update_args=port_update_args, - network_create_args={"name": "given-name"}, - port_create_args={"allocation_pools": []}, - ports_per_network=ports_per_network) - mock__create_network.assert_called_once_with({"name": "given-name"}) - mock__create_port.assert_has_calls( - [mock.call({"network": {"id": "fake-id"}}, - {"allocation_pools": []})] * ports_per_network) - mock__update_port.assert_has_calls( - [mock.call(mock__create_port.return_value, port_update_args) - ] * ports_per_network) - - @mock.patch(NEUTRON_NETWORKS + ".generate_random_name") - @mock.patch(NEUTRON_NETWORKS + "._delete_port") - @mock.patch(NEUTRON_NETWORKS + "._create_port") - @mock.patch(NEUTRON_NETWORKS + "._create_network") - def test_create_and_delete_ports(self, - mock__create_network, - mock__create_port, - mock__delete_port, - mock_generate_random_name): scenario = network.NeutronNetworks(self.context) - mock_generate_random_name.return_value = "random-name" - net = {"network": {"id": "fake-id"}} - mock__create_network.return_value = net + scenario._get_or_create_network = mock.Mock(return_value=net) + scenario._create_port = mock.Mock(side_effect=ports) + scenario._update_port = mock.Mock() + + scenario.create_and_update_ports( + port_update_args, + network_create_args=network_create_args, + port_create_args=port_create_args, + ports_per_network=ports_per_network) + scenario._get_or_create_network.assert_called_once_with( + network_create_args) + scenario._create_port.assert_has_calls( + [mock.call(net, port_create_args) + for i in range(ports_per_network)]) + scenario._update_port.assert_has_calls( + [mock.call(p, port_update_args) for p in ports]) + + def test_create_and_delete_ports(self): + port_create_args = {"allocation_pools": []} ports_per_network = 10 + network_create_args = {"router:external": True} + net = mock.MagicMock() + ports = [mock.MagicMock() for i in range(ports_per_network)] - self.assertRaises(TypeError, scenario.create_and_delete_ports) + scenario = network.NeutronNetworks(self.context) + scenario._get_or_create_network = mock.Mock(return_value=net) + scenario._create_port = mock.Mock(side_effect=ports) + scenario._delete_port = mock.Mock() - mock__create_network.reset_mock() - - # Default options - scenario.create_and_delete_ports(ports_per_network=ports_per_network) - mock__create_network.assert_called_once_with({}) - self.assertEqual(mock__create_port.mock_calls, - [mock.call(net, {})] * ports_per_network) - self.assertEqual(mock__delete_port.mock_calls, - [mock.call(mock__create_port())] * ports_per_network) - - mock__create_network.reset_mock() - mock__create_port.reset_mock() - mock__delete_port.reset_mock() - - # Custom options scenario.create_and_delete_ports( - network_create_args={"name": "given-name"}, - port_create_args={"allocation_pools": []}, + network_create_args=network_create_args, + port_create_args=port_create_args, ports_per_network=ports_per_network) - mock__create_network.assert_called_once_with({"name": "given-name"}) - self.assertEqual( - mock__create_port.mock_calls, - [mock.call(net, {"allocation_pools": []})] * ports_per_network) - self.assertEqual( - mock__delete_port.mock_calls, - [mock.call(mock__create_port.return_value)] * ports_per_network) + scenario._get_or_create_network.assert_called_once_with( + network_create_args) + scenario._create_port.assert_has_calls( + [mock.call(net, port_create_args) + for i in range(ports_per_network)]) + scenario._delete_port.assert_has_calls( + [mock.call(p) for p in ports]) @ddt.data( {"floating_network": "ext-net"}, diff --git a/tests/unit/plugins/openstack/scenarios/neutron/test_utils.py b/tests/unit/plugins/openstack/scenarios/neutron/test_utils.py index 048f1039df..299d415d39 100644 --- a/tests/unit/plugins/openstack/scenarios/neutron/test_utils.py +++ b/tests/unit/plugins/openstack/scenarios/neutron/test_utils.py @@ -24,6 +24,7 @@ from tests.unit import test NEUTRON_UTILS = "rally.plugins.openstack.scenarios.neutron.utils." +@ddt.ddt class NeutronScenarioTestCase(test.ScenarioTestCase): def setUp(self): @@ -420,6 +421,67 @@ class NeutronScenarioTestCase(test.ScenarioTestCase): self._test_atomic_action_timer(scenario.atomic_actions(), "neutron.create_port") + @ddt.data( + {}, + {"network_create_args": {"fakearg": "fake"}}, + {"context": {"tenant": {"networks": + [mock.MagicMock(), mock.MagicMock()]}}}, + {"network_create_args": {"fakearg": "fake"}, + "context": {"tenant": {"networks": + [mock.MagicMock(), mock.MagicMock()]}}}) + @ddt.unpack + @mock.patch("random.choice", side_effect=lambda l: l[0]) + def test_get_or_create_network(self, mock_random_choice, + network_create_args=None, context=None): + if context is None: + context = {"tenant": {}} + scenario = utils.NeutronScenario(context=context) + scenario._create_network = mock.Mock() + + network = scenario._get_or_create_network(network_create_args) + + if "networks" in context["tenant"]: + self.assertEqual(network, context["tenant"]["networks"][0]) + self.assertFalse(scenario._create_network.called) + else: + self.assertEqual(network, scenario._create_network.return_value) + scenario._create_network.assert_called_once_with( + network_create_args or {}) + + @ddt.data( + {}, + {"subnets": [mock.Mock(), mock.Mock()]}, + {"subnets": [mock.Mock(), mock.Mock()], + "subnet_create_args": {"fakearg": "fake"}, + "subnet_cidr_start": "cidr", + "subnets_per_network": 5}, + {"subnet_create_args": {"fakearg": "fake"}, + "subnet_cidr_start": "cidr", + "subnets_per_network": 5}) + @ddt.unpack + def test_get_or_create_subnets(self, subnets=None, + subnet_create_args=None, + subnet_cidr_start=None, + subnets_per_network=1): + subnets = subnets or [] + network = mock.MagicMock(get=mock.Mock(return_value=subnets)) + scenario = utils.NeutronScenario() + scenario._create_subnets = mock.Mock() + + actual = scenario._get_or_create_subnets(network, + subnet_create_args, + subnet_cidr_start, + subnets_per_network) + + if subnets: + self.assertItemsEqual(actual, subnets) + self.assertFalse(scenario._create_subnets.called) + else: + self.assertEqual(actual, scenario._create_subnets.return_value) + scenario._create_subnets.assert_called_once_with( + network, subnet_create_args, subnet_cidr_start, + subnets_per_network) + @mock.patch(NEUTRON_UTILS + "NeutronScenario._create_subnet", return_value={ "subnet": { @@ -489,6 +551,58 @@ class NeutronScenarioTestCase(test.ScenarioTestCase): self._test_atomic_action_timer(scenario.atomic_actions(), "neutron.delete_floating_ip") + @ddt.data( + {}, + {"router_create_args": {"admin_state_up": False}}, + {"network_create_args": {"router:external": True}, + "subnet_create_args": {"allocation_pools": []}, + "subnet_cidr_start": "default_cidr", + "subnets_per_network": 3, + "router_create_args": {"admin_state_up": False}}) + @ddt.unpack + def test_create_network_structure(self, network_create_args=None, + subnet_create_args=None, + subnet_cidr_start=None, + subnets_per_network=None, + router_create_args=None): + network = mock.MagicMock() + + router_create_args = router_create_args or {} + + subnets = [] + routers = [] + router_create_calls = [] + for i in range(subnets_per_network or 1): + subnets.append(mock.MagicMock()) + routers.append(mock.MagicMock()) + router_create_calls.append(mock.call(router_create_args)) + + scenario = utils.NeutronScenario() + scenario._get_or_create_network = mock.Mock(return_value=network) + scenario._get_or_create_subnets = mock.Mock(return_value=subnets) + scenario._create_router = mock.Mock(side_effect=routers) + scenario._add_interface_router = mock.Mock() + + actual = scenario._create_network_structure(network_create_args, + subnet_create_args, + subnet_cidr_start, + subnets_per_network, + router_create_args) + self.assertEqual(actual, (network, subnets, routers)) + scenario._get_or_create_network.assert_called_once_with( + network_create_args) + scenario._get_or_create_subnets.assert_called_once_with( + network, + subnet_create_args, + subnet_cidr_start, + subnets_per_network) + scenario._create_router.assert_has_calls(router_create_calls) + + add_iface_calls = [mock.call(subnets[i]["subnet"], + routers[i]["router"]) + for i in range(subnets_per_network or 1)] + scenario._add_interface_router.assert_has_calls(add_iface_calls) + def test_delete_v1_pool(self): scenario = utils.NeutronScenario(context=self.context)