From ed524c07c1559a4ed45c5f7eee78c4cac8a3450b Mon Sep 17 00:00:00 2001 From: Sai Sindhur Malleni Date: Wed, 2 Jan 2019 14:18:24 -0500 Subject: [PATCH] Add more trunk scenarios This commit adds three new scenarios for neutron trunk port testing. Also involves some minor refactor of existing NeutronTrunks.create_and_list_trunks scenario. Change-Id: I632837576b353a3bc014577ac102ef0dbcdb019c --- .zuul.d/rally-task-neutron-trunk.yaml | 11 + .zuul.d/rally-task-neutron.yaml | 6 +- .zuul.d/zuul.yaml | 5 + CHANGELOG.rst | 4 + rally-jobs/neutron-trunk.yaml | 125 +++++++++++ rally-jobs/neutron.yaml | 23 -- rally_openstack/cleanup/resources.py | 8 +- rally_openstack/scenarios/neutron/network.py | 41 ---- rally_openstack/scenarios/neutron/trunk.py | 197 ++++++++++++++++++ rally_openstack/scenarios/neutron/utils.py | 1 + .../neutron/boot-server-and-add-subports.json | 46 ++++ .../neutron/boot-server-and-add-subports.yaml | 32 +++ .../boot-server-and-batch-add-subports.json | 47 +++++ .../boot-server-and-batch-add-subports.yaml | 33 +++ .../neutron/boot-server-with-subports.json | 46 ++++ .../neutron/boot-server-with-subports.yaml | 32 +++ .../neutron/create-and-list-trunks.json | 1 - .../neutron/create-and-list-trunks.yaml | 1 - tasks/openstack/scenario/neutron.yaml | 74 ++++++- tests/unit/scenarios/neutron/test_network.py | 22 -- tests/unit/scenarios/neutron/test_trunk.py | 131 ++++++++++++ 21 files changed, 791 insertions(+), 95 deletions(-) create mode 100644 .zuul.d/rally-task-neutron-trunk.yaml create mode 100644 rally-jobs/neutron-trunk.yaml create mode 100644 rally_openstack/scenarios/neutron/trunk.py create mode 100644 samples/tasks/scenarios/neutron/boot-server-and-add-subports.json create mode 100644 samples/tasks/scenarios/neutron/boot-server-and-add-subports.yaml create mode 100644 samples/tasks/scenarios/neutron/boot-server-and-batch-add-subports.json create mode 100644 samples/tasks/scenarios/neutron/boot-server-and-batch-add-subports.yaml create mode 100644 samples/tasks/scenarios/neutron/boot-server-with-subports.json create mode 100644 samples/tasks/scenarios/neutron/boot-server-with-subports.yaml create mode 100644 tests/unit/scenarios/neutron/test_trunk.py diff --git a/.zuul.d/rally-task-neutron-trunk.yaml b/.zuul.d/rally-task-neutron-trunk.yaml new file mode 100644 index 00000000..a16d0331 --- /dev/null +++ b/.zuul.d/rally-task-neutron-trunk.yaml @@ -0,0 +1,11 @@ +- job: + name: rally-task-neutron-trunk + parent: rally-task-at-devstack + vars: + rally_task: rally-jobs/neutron-trunk.yaml + devstack_plugins: + rally-openstack: https://git.openstack.org/openstack/rally-openstack + neutron: https://git.openstack.org/openstack/neutron + devstack_services: + neutron-trunk: true + diff --git a/.zuul.d/rally-task-neutron.yaml b/.zuul.d/rally-task-neutron.yaml index 39667934..d9a7d602 100644 --- a/.zuul.d/rally-task-neutron.yaml +++ b/.zuul.d/rally-task-neutron.yaml @@ -3,8 +3,4 @@ parent: rally-task-at-devstack vars: rally_task: rally-jobs/neutron.yaml - devstack_plugins: - rally-openstack: https://git.openstack.org/openstack/rally-openstack - neutron: https://git.openstack.org/openstack/neutron - devstack_services: - neutron-trunk: true + diff --git a/.zuul.d/zuul.yaml b/.zuul.d/zuul.yaml index 111a4b6b..3ea9b82a 100644 --- a/.zuul.d/zuul.yaml +++ b/.zuul.d/zuul.yaml @@ -54,6 +54,11 @@ #- rally-task-monasca - rally-task-murano - rally-task-neutron + - rally-task-neutron-trunk: + files: + - rally-jobs/neutron-trunk.yaml + - rally_openstack/scenarios/neutron/trunk.py + - rally_openstack/scenarios/neutron/network.py - rally-task-neutron-with-extensions: voting: false - rally-task-nova: diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 5a8d28c5..003ce0da 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -50,6 +50,10 @@ Added * Added property 'floating_ip_enabled' in magnum cluster_templates context. * Enhanced neutron trunk port scenario to create multiple trunks * Enhanced NeutronSecurityGroup.create_and_list_security_group_rules +* Added three new trunk port related scenarios +* [scenario plugin] NeutronTrunks.boot_server_with_subports +* [scenario plugin] NeutronTrunks.boot_server_and_add_subports +* [scenario plugin] NeutronTrunks.boot_server_and_batch_add_subports Changed ~~~~~~~ diff --git a/rally-jobs/neutron-trunk.yaml b/rally-jobs/neutron-trunk.yaml new file mode 100644 index 00000000..a4b7523a --- /dev/null +++ b/rally-jobs/neutron-trunk.yaml @@ -0,0 +1,125 @@ +{% set image_name = "^(cirros.*-disk|TestVM)$" %} +{% set flavor_name = "m1.tiny" %} +--- + + NeutronTrunks.create_and_list_trunks: + - + args: + network_create_args: {} + subport_count: 10 + runner: + type: "constant" + times: 100 + concurrency: 10 + context: + users: + tenants: 3 + users_per_tenant: 3 + quotas: + neutron: + network: -1 + port: -1 + trunk: -1 + sla: + failure_rate: + max: 10 + + NeutronTrunks.boot_server_with_subports: + - + args: + network_create_args: {} + subport_count: 10 + flavor: + name: "{{flavor_name}}" + image: + name: "{{image_name}}" + runner: + type: "constant" + times: 2 + concurrency: 1 + context: + users: + tenants: 3 + users_per_tenant: 3 + roles: + - admin + quotas: + neutron: + network: -1 + subnet: -1 + port: -1 + trunk: -1 + nova: + instances: -1 + cores: -1 + ram: -1 + sla: + failure_rate: + max: 10 + + NeutronTrunks.boot_server_and_add_subports: + - + args: + network_create_args: {} + subport_count: 10 + flavor: + name: "{{flavor_name}}" + image: + name: "{{image_name}}" + runner: + type: "constant" + times: 2 + concurrency: 1 + context: + users: + tenants: 3 + users_per_tenant: 3 + roles: + - admin + quotas: + neutron: + network: -1 + subnet: -1 + port: -1 + trunk: -1 + nova: + instances: -1 + cores: -1 + ram: -1 + sla: + failure_rate: + max: 10 + + NeutronTrunks.boot_server_and_batch_add_subports: + - + args: + network_create_args: {} + subports_per_batch: 10 + batches: 5 + flavor: + name: "{{flavor_name}}" + image: + name: "{{image_name}}" + runner: + type: "constant" + times: 2 + concurrency: 1 + context: + users: + tenants: 3 + users_per_tenant: 3 + roles: + - admin + quotas: + neutron: + network: -1 + subnet: -1 + port: -1 + trunk: -1 + nova: + instances: -1 + cores: -1 + ram: -1 + sla: + failure_rate: + max: 10 diff --git a/rally-jobs/neutron.yaml b/rally-jobs/neutron.yaml index a1a71ef4..13799791 100644 --- a/rally-jobs/neutron.yaml +++ b/rally-jobs/neutron.yaml @@ -619,29 +619,6 @@ failure_rate: max: 20 - NeutronTrunks.create_and_list_trunks: - - - args: - network_create_args: {} - trunk_count: 1 - subport_count: 10 - runner: - type: "constant" - times: 100 - concurrency: 10 - context: - users: - tenants: 3 - users_per_tenant: 3 - quotas: - neutron: - network: -1 - port: -1 - trunk: -1 - sla: - failure_rate: - max: 10 - NeutronSubnets.delete_subnets: - runner: diff --git a/rally_openstack/cleanup/resources.py b/rally_openstack/cleanup/resources.py index 947ec47d..6ba5a483 100644 --- a/rally_openstack/cleanup/resources.py +++ b/rally_openstack/cleanup/resources.py @@ -386,6 +386,13 @@ class NeutronFloatingIP(NeutronMixin): return super(NeutronFloatingIP, self).list() +@base.resource("neutron", "trunk", order=next(_neutron_order), + tenant_resource=True) +class NeutronTrunk(NeutronMixin): + # Trunks must be deleted before the parent/subports are deleted + pass + + @base.resource("neutron", "port", order=next(_neutron_order), tenant_resource=True) class NeutronPort(NeutronMixin): @@ -444,7 +451,6 @@ class NeutronPort(NeutronMixin): self.raw_resource["device_id"], {"port_id": self.id()}) else: from neutronclient.common import exceptions as neutron_exceptions - try: self._manager().delete_port(self.id()) except neutron_exceptions.PortNotFoundClient: diff --git a/rally_openstack/scenarios/neutron/network.py b/rally_openstack/scenarios/neutron/network.py index 680387c9..7ec89b9b 100644 --- a/rally_openstack/scenarios/neutron/network.py +++ b/rally_openstack/scenarios/neutron/network.py @@ -604,44 +604,3 @@ class DeleteSubnets(utils.NeutronScenario): # delete one of subnets based on the user sequential number subnet_id = network["subnets"][number] self._delete_subnet({"subnet": {"id": subnet_id}}) - - -@validation.add("number", param_name="subport_count", minval=1, - integer_only=True) -@validation.add("number", param_name="trunk_count", minval=1, - integer_only=True) -@validation.add("required_services", services=[consts.Service.NEUTRON]) -@validation.add("required_platform", platform="openstack", users=True) -@scenario.configure(context={"cleanup@openstack": ["neutron"]}, - name="NeutronTrunks.create_and_list_trunks") -class CreateAndListTrunks(utils.NeutronScenario): - - def run(self, network_create_args=None, trunk_count=1, subport_count=10): - """Create given number of trunks with subports and list all trunks. - - :param network_create_args: dict, POST /v2.0/networks request - options. Deprecated. - :param trunk_count: int, number of trunk ports - :param subport_count: int, number of subports per trunk - """ - net = self._create_network(network_create_args or {}) - ports = [self._create_port(net, {}) for _ in range( - (trunk_count + trunk_count * subport_count))] - parents, subports = ports[0:trunk_count], ports[trunk_count:] - subport_payload = [{"port_id": p["port"]["id"], - "segmentation_type": "vlan", - "segmentation_id": seg_id} - for seg_id, p in enumerate(subports, start=1)] - subport_index = 0 - for p in parents: - trunk_payload = { - "port_id": p["port"]["id"], - "sub_ports": subport_payload[slice( - subport_index, subport_index + subport_count)] - } - trunk = self._create_trunk(trunk_payload) - self._update_port(p, {"device_id": "sometrunk"}) - self._list_subports_by_trunk(trunk["trunk"]["id"]) - subport_index += subport_count - self._list_trunks() - self._list_ports_by_device_id("sometrunk") diff --git a/rally_openstack/scenarios/neutron/trunk.py b/rally_openstack/scenarios/neutron/trunk.py new file mode 100644 index 00000000..69206f68 --- /dev/null +++ b/rally_openstack/scenarios/neutron/trunk.py @@ -0,0 +1,197 @@ +# Copyright 2014: Intel 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.common import cfg +from rally.task import types +from rally.task import validation + +from rally_openstack import consts +from rally_openstack import scenario +from rally_openstack.scenarios.neutron import utils as neutron_utils +from rally_openstack.scenarios.nova import utils as nova_utils + + +CONF = cfg.CONF + +"""Scenarios for Neutron Trunk.""" + + +@validation.add("number", param_name="subport_count", minval=1, + integer_only=True) +@validation.add("required_services", services=[consts.Service.NEUTRON]) +@validation.add("required_platform", platform="openstack", users=True) +@scenario.configure(context={"cleanup@openstack": ["neutron"]}, + name="NeutronTrunks.create_and_list_trunks") +class CreateAndListTrunks(neutron_utils.NeutronScenario): + + def run(self, network_create_args=None, subport_count=10): + """Create and a given number of trunks with subports and list all trunks + + :param network_create_args: dict, POST /v2.0/networks request + options. Deprecated. + :param trunk_count: int, number of trunk ports + :param subport_count: int, number of subports per trunk + """ + net = self._create_network(network_create_args or {}) + ports = [self._create_port(net, {}) for _ in range(subport_count + 1)] + parent, subports = ports[0], ports[1:] + subport_payload = [{"port_id": p["port"]["id"], + "segmentation_type": "vlan", + "segmentation_id": seg_id} + for seg_id, p in enumerate(subports, start=1)] + trunk_payload = {"port_id": parent["port"]["id"], + "sub_ports": subport_payload} + trunk = self._create_trunk(trunk_payload) + self._update_port(parent, {"device_id": "sometrunk"}) + self._list_trunks() + self._list_subports_by_trunk(trunk["trunk"]["id"]) + self._list_ports_by_device_id("sometrunk") + + +@types.convert(image={"type": "glance_image"}, + flavor={"type": "nova_flavor"}) +@validation.add("image_valid_on_flavor", flavor_param="flavor", + image_param="image") +@validation.add("required_services", services=(consts.Service.NOVA, + consts.Service.NEUTRON)) +@validation.add("required_platform", platform="openstack", users=True) +@scenario.configure(context={"cleanup@openstack": ["neutron", "nova"]}, + name="NeutronTrunks.boot_server_with_subports", + platform="openstack") +class BootServerWithSubports(nova_utils.NovaScenario, + neutron_utils.NeutronScenario): + + def run(self, image, flavor, network_create_args=None, subport_count=10): + """Boot a server with subports. + + Returns when the server is actually booted and in "ACTIVE" state. + :param image: image ID or instance for server creation + :param flavor: int, flavor ID or instance for server creation + :param network_create_args: arguments for creating network + :param subport_count: number of subports for the trunk port + """ + kwargs = {} + ports = [] + network_create_args = network_create_args or {} + for _ in range(subport_count + 1): + net, subnet = self._create_network_and_subnets( + network_create_args=network_create_args) + ports.append(self._create_port( + net, {"fixed_ips": [{ + "subnet_id": subnet[0]["subnet"]["id"]}]})) + parent, subports = ports[0], ports[1:] + subport_payload = [{"port_id": p["port"]["id"], + "segmentation_type": "vlan", + "segmentation_id": seg_id} + for seg_id, p in enumerate(subports, start=1)] + trunk_payload = {"port_id": parent["port"]["id"], + "sub_ports": subport_payload} + self._create_trunk(trunk_payload) + kwargs["nics"] = [{"port-id": parent["port"]["id"]}] + self._boot_server(image, flavor, **kwargs) + + +@types.convert(image={"type": "glance_image"}, + flavor={"type": "nova_flavor"}) +@validation.add("image_valid_on_flavor", flavor_param="flavor", + image_param="image") +@validation.add("required_services", services=(consts.Service.NOVA, + consts.Service.NEUTRON)) +@validation.add("required_platform", platform="openstack", users=True) +@scenario.configure(context={"cleanup@openstack": ["neutron", "nova"]}, + name="NeutronTrunks.boot_server_and_add_subports", + platform="openstack") +class BootServerAndAddSubports(nova_utils.NovaScenario, + neutron_utils.NeutronScenario): + + def run(self, image, flavor, network_create_args=None, subport_count=10): + """Boot a server and add subports. + + Returns when the server is actually booted and in "ACTIVE" state. + :param image: image ID or instance for server creation + :param flavor: int, flavor ID or instance for server creation + :param network_create_args: arguments for creating network + :param subport_count: number of subports for the trunk port + """ + kwargs = {} + ports = [] + network_create_args = network_create_args or {} + for _ in range(subport_count + 1): + net, subnet = self._create_network_and_subnets( + network_create_args=network_create_args) + ports.append(self._create_port( + net, {"fixed_ips": [{ + "subnet_id": subnet[0]["subnet"]["id"]}]})) + parent, subports = ports[0], ports[1:] + trunk_payload = {"port_id": parent["port"]["id"]} + trunk = self._create_trunk(trunk_payload) + kwargs["nics"] = [{"port-id": parent["port"]["id"]}] + self._boot_server(image, flavor, **kwargs) + for seg_id, p in enumerate(subports, start=1): + subport_payload = [{"port_id": p["port"]["id"], + "segmentation_type": "vlan", + "segmentation_id": seg_id}] + self._add_subports_to_trunk(trunk["trunk"]["id"], subport_payload) + + +@types.convert(image={"type": "glance_image"}, + flavor={"type": "nova_flavor"}) +@validation.add("image_valid_on_flavor", flavor_param="flavor", + image_param="image") +@validation.add("required_services", services=(consts.Service.NOVA, + consts.Service.NEUTRON)) +@validation.add("required_platform", platform="openstack", users=True) +@scenario.configure(context={"cleanup@openstack": ["neutron", "nova"]}, + name="NeutronTrunks.boot_server_and_batch_add_subports", + platform="openstack") +class BootServerAndBatchAddSubports(nova_utils.NovaScenario, + neutron_utils.NeutronScenario): + + def run(self, image, flavor, network_create_args=None, + subports_per_batch=10, batches=5): + """Boot a server and add subports in batches. + + Returns when the server is actually booted and in "ACTIVE" state. + :param image: image ID or instance for server creation + :param flavor: int, flavor ID or instance for server creation + :param network_create_args: arguments for creating network + :param subports_per_batch: number of subports per batches + :param batches: number of batches to create subports in + """ + kwargs = {} + ports = [] + network_create_args = network_create_args or {} + for _ in range(subports_per_batch * batches + 1): + net, subnet = self._create_network_and_subnets( + network_create_args=network_create_args) + ports.append(self._create_port( + net, {"fixed_ips": [{ + "subnet_id": subnet[0]["subnet"]["id"]}]})) + parent, subports = ports[0], ports[1:] + trunk_payload = {"port_id": parent["port"]["id"]} + trunk = self._create_trunk(trunk_payload) + kwargs["nics"] = [{"port-id": parent["port"]["id"]}] + self._boot_server(image, flavor, **kwargs) + begin = 0 + for _ in range(0, batches): + end = begin + subports_per_batch + subport_payload = [{"port_id": p["port"]["id"], + "segmentation_type": "vlan", + "segmentation_id": seg_id} + for seg_id, p in enumerate( + subports[slice(begin, end)], + start=begin + 1)] + begin = begin + subports_per_batch + self._add_subports_to_trunk(trunk["trunk"]["id"], subport_payload) diff --git a/rally_openstack/scenarios/neutron/utils.py b/rally_openstack/scenarios/neutron/utils.py index b0811c9c..5e7756c5 100644 --- a/rally_openstack/scenarios/neutron/utils.py +++ b/rally_openstack/scenarios/neutron/utils.py @@ -887,6 +887,7 @@ class NeutronScenario(scenario.OpenStackScenario): @atomic.action_timer("neutron.create_trunk") def _create_trunk(self, trunk_payload): + trunk_payload["name"] = self.generate_random_name() return self.clients("neutron").create_trunk({"trunk": trunk_payload}) @atomic.action_timer("neutron.list_trunks") diff --git a/samples/tasks/scenarios/neutron/boot-server-and-add-subports.json b/samples/tasks/scenarios/neutron/boot-server-and-add-subports.json new file mode 100644 index 00000000..f0129a10 --- /dev/null +++ b/samples/tasks/scenarios/neutron/boot-server-and-add-subports.json @@ -0,0 +1,46 @@ +{% set flavor_name = flavor_name or "m1.tiny" %} +{ + "NeutronTrunks.boot_server_and_add_subports": [ + { + "args": { + "flavor": { + "name": "{{flavor_name}}" + }, + "image": { + "name": "^cirros.*-disk$" + }, + "network_create_args": {}, + "subport_count": 10 + }, + "runner": { + "type": "constant", + "times": 100, + "concurrency": 10 + }, + "context": { + "users": { + "tenants": 3, + "users_per_tenant": 3 + }, + "quotas": { + "neutron": { + "network": -1, + "subnet": -1, + "port": -1, + "trunk": -1 + }, + "nova": { + "instances": -1, + "cores": -1, + "ram": -1 + } + } + }, + "sla": { + "failure_rate": { + "max": 0 + } + } + } + ] +} diff --git a/samples/tasks/scenarios/neutron/boot-server-and-add-subports.yaml b/samples/tasks/scenarios/neutron/boot-server-and-add-subports.yaml new file mode 100644 index 00000000..c811120c --- /dev/null +++ b/samples/tasks/scenarios/neutron/boot-server-and-add-subports.yaml @@ -0,0 +1,32 @@ +{% set flavor_name = flavor_name or "m1.tiny" %} +--- + NeutronTrunks.boot_server_and_add_subports: + - + args: + flavor: + name: "{{flavor_name}}" + image: + name: "^cirros.*-disk$" + network_create_args: {} + subport_count: 10 + runner: + type: "constant" + times: 100 + concurrency: 10 + context: + users: + tenants: 3 + users_per_tenant: 3 + quotas: + neutron: + network: -1 + subnet: -1 + port: -1 + trunk: -1 + nova: + instances: -1 + cores: -1 + ram: -1 + sla: + failure_rate: + max: 0 diff --git a/samples/tasks/scenarios/neutron/boot-server-and-batch-add-subports.json b/samples/tasks/scenarios/neutron/boot-server-and-batch-add-subports.json new file mode 100644 index 00000000..0ea7f5a5 --- /dev/null +++ b/samples/tasks/scenarios/neutron/boot-server-and-batch-add-subports.json @@ -0,0 +1,47 @@ +{% set flavor_name = flavor_name or "m1.tiny" %} +{ + "NeutronTrunks.boot_server_and_batch_add_subports": [ + { + "args": { + "flavor": { + "name": "{{flavor_name}}" + }, + "image": { + "name": "^cirros.*-disk$" + }, + "network_create_args": {}, + "subports_per_batch": 10, + "batches": 5 + }, + "runner": { + "type": "constant", + "times": 100, + "concurrency": 10 + }, + "context": { + "users": { + "tenants": 3, + "users_per_tenant": 3 + }, + "quotas": { + "neutron": { + "network": -1, + "subnet": -1, + "port": -1, + "trunk": -1 + }, + "nova": { + "instances": -1, + "cores": -1, + "ram": -1 + } + } + }, + "sla": { + "failure_rate": { + "max": 0 + } + } + } + ] +} diff --git a/samples/tasks/scenarios/neutron/boot-server-and-batch-add-subports.yaml b/samples/tasks/scenarios/neutron/boot-server-and-batch-add-subports.yaml new file mode 100644 index 00000000..84a6e678 --- /dev/null +++ b/samples/tasks/scenarios/neutron/boot-server-and-batch-add-subports.yaml @@ -0,0 +1,33 @@ +{% set flavor_name = flavor_name or "m1.tiny" %} +--- + NeutronTrunks.boot_server_and_batch_add_subports: + - + args: + flavor: + name: "{{flavor_name}}" + image: + name: "^cirros.*-disk$" + network_create_args: {} + subports_per_batch: 10 + batches: 5 + runner: + type: "constant" + times: 100 + concurrency: 10 + context: + users: + tenants: 3 + users_per_tenant: 3 + quotas: + neutron: + network: -1 + subnet: -1 + port: -1 + trunk: -1 + nova: + instances: -1 + cores: -1 + ram: -1 + sla: + failure_rate: + max: 0 diff --git a/samples/tasks/scenarios/neutron/boot-server-with-subports.json b/samples/tasks/scenarios/neutron/boot-server-with-subports.json new file mode 100644 index 00000000..68ac2031 --- /dev/null +++ b/samples/tasks/scenarios/neutron/boot-server-with-subports.json @@ -0,0 +1,46 @@ +{% set flavor_name = flavor_name or "m1.tiny" %} +{ + "NeutronTrunks.boot_server_with_subports": [ + { + "args": { + "flavor": { + "name": "{{flavor_name}}" + }, + "image": { + "name": "^cirros.*-disk$" + }, + "network_create_args": {}, + "subport_count": 10 + }, + "runner": { + "type": "constant", + "times": 100, + "concurrency": 10 + }, + "context": { + "users": { + "tenants": 3, + "users_per_tenant": 3 + }, + "quotas": { + "neutron": { + "network": -1, + "subnet": -1, + "port": -1, + "trunk": -1 + }, + "nova": { + "instances": -1, + "cores": -1, + "ram": -1 + } + } + }, + "sla": { + "failure_rate": { + "max": 0 + } + } + } + ] +} diff --git a/samples/tasks/scenarios/neutron/boot-server-with-subports.yaml b/samples/tasks/scenarios/neutron/boot-server-with-subports.yaml new file mode 100644 index 00000000..0c64daf7 --- /dev/null +++ b/samples/tasks/scenarios/neutron/boot-server-with-subports.yaml @@ -0,0 +1,32 @@ +{% set flavor_name = flavor_name or "m1.tiny" %} +--- + NeutronTrunks.boot_server_with_subports: + - + args: + flavor: + name: "{{flavor_name}}" + image: + name: "^cirros.*-disk$" + network_create_args: {} + subport_count: 10 + runner: + type: "constant" + times: 100 + concurrency: 10 + context: + users: + tenants: 3 + users_per_tenant: 3 + quotas: + neutron: + network: -1 + subnet: -1 + port: -1 + trunk: -1 + nova: + instances: -1 + cores: -1 + ram: -1 + sla: + failure_rate: + max: 0 diff --git a/samples/tasks/scenarios/neutron/create-and-list-trunks.json b/samples/tasks/scenarios/neutron/create-and-list-trunks.json index a982682f..0656a0be 100644 --- a/samples/tasks/scenarios/neutron/create-and-list-trunks.json +++ b/samples/tasks/scenarios/neutron/create-and-list-trunks.json @@ -3,7 +3,6 @@ { "args": { "network_create_args": {}, - "trunk_count": 1, "subport_count": 10 }, "runner": { diff --git a/samples/tasks/scenarios/neutron/create-and-list-trunks.yaml b/samples/tasks/scenarios/neutron/create-and-list-trunks.yaml index 8cca35a6..ad90bc59 100644 --- a/samples/tasks/scenarios/neutron/create-and-list-trunks.yaml +++ b/samples/tasks/scenarios/neutron/create-and-list-trunks.yaml @@ -4,7 +4,6 @@ - args: network_create_args: {} - trunk_count: 1 subport_count: 10 runner: type: "constant" diff --git a/tasks/openstack/scenario/neutron.yaml b/tasks/openstack/scenario/neutron.yaml index bc3e450d..53f40c93 100644 --- a/tasks/openstack/scenario/neutron.yaml +++ b/tasks/openstack/scenario/neutron.yaml @@ -265,7 +265,6 @@ - args: network_create_args: {} - trunk_count: 1 subport_count: 10 context: {% call user_context(tenants_amount, users_amount, use_existing_users) %} @@ -279,3 +278,76 @@ {{ constant_runner(concurrency=2*controllers_amount, times=8*controllers_amount, is_smoke=smoke) }} sla: {{ no_failures_sla() }} + + NeutronTrunks.boot_server_with_subports: + - + args: + {{ vm_params(image_name, flavor_name) }} + network_create_args: {} + subport_count: 10 + context: + {% call user_context(tenants_amount, users_amount, use_existing_users) %} + quotas: + neutron: + network: -1 + subnet: -1 + port: -1 + trunk: -1 + nova: + instances: -1 + cores: -1 + ram: -1 + {% endcall %} + runner: + {{ constant_runner(concurrency=2*controllers_amount, times=8*controllers_amount, is_smoke=smoke) }} + sla: + {{ no_failures_sla() }} + + NeutronTrunks.boot_server_and_add_subports: + - + args: + {{ vm_params(image_name, flavor_name) }} + network_create_args: {} + subport_count: 10 + context: + {% call user_context(tenants_amount, users_amount, use_existing_users) %} + quotas: + neutron: + network: -1 + subnet: -1 + port: -1 + trunk: -1 + nova: + instances: -1 + cores: -1 + ram: -1 + {% endcall %} + runner: + {{ constant_runner(concurrency=2*controllers_amount, times=8*controllers_amount, is_smoke=smoke) }} + sla: + {{ no_failures_sla() }} + + NeutronTrunks.boot_server_and_batch_add_subports: + - + args: + {{ vm_params(image_name, flavor_name) }} + network_create_args: {} + subports_per_batch: 10 + batches: 5 + context: + {% call user_context(tenants_amount, users_amount, use_existing_users) %} + quotas: + neutron: + network: -1 + subnet: -1 + port: -1 + trunk: -1 + nova: + instances: -1 + cores: -1 + ram: -1 + {% endcall %} + runner: + {{ constant_runner(concurrency=2*controllers_amount, times=8*controllers_amount, is_smoke=smoke) }} + sla: + {{ no_failures_sla() }} diff --git a/tests/unit/scenarios/neutron/test_network.py b/tests/unit/scenarios/neutron/test_network.py index d29338b3..5affc7ce 100644 --- a/tests/unit/scenarios/neutron/test_network.py +++ b/tests/unit/scenarios/neutron/test_network.py @@ -596,25 +596,3 @@ class NeutronNetworksTestCase(test.ScenarioTestCase): mock.call({"subnet": {"id": "subnet-5"}}) ], mock__delete_subnet.call_args_list) - - def test_create_and_list_trunks(self): - trunk_count = 1 - subport_count = 10 - network_create_args = {} - net = mock.MagicMock() - scenario = network.CreateAndListTrunks(self.context) - scenario._create_network = mock.Mock(return_value=net) - scenario._create_port = mock.MagicMock() - scenario._create_trunk = mock.MagicMock() - scenario._update_port = mock.Mock() - scenario._list_ports_by_device_id = mock.Mock() - scenario.run(network_create_args=network_create_args, - subport_count=subport_count) - scenario._create_network.assert_called_once_with( - network_create_args) - scenario._create_port.assert_has_calls( - [mock.call(net, {}) - for _ in range(trunk_count + (trunk_count * subport_count))]) - self.assertEqual(1, scenario._create_trunk.call_count) - self.assertEqual(1, scenario._update_port.call_count) - self.assertEqual(1, scenario._list_ports_by_device_id.call_count) diff --git a/tests/unit/scenarios/neutron/test_trunk.py b/tests/unit/scenarios/neutron/test_trunk.py new file mode 100644 index 00000000..33dea66a --- /dev/null +++ b/tests/unit/scenarios/neutron/test_trunk.py @@ -0,0 +1,131 @@ +# Copyright 2014: Intel 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. + +import mock + +from rally_openstack.scenarios.neutron import trunk +from tests.unit import test + + +class NeutronTrunkTestCase(test.ScenarioTestCase): + + def test_create_and_list_trunks(self): + subport_count = 10 + network_create_args = {} + net = mock.MagicMock() + scenario = trunk.CreateAndListTrunks(self.context) + scenario._create_network = mock.Mock(return_value=net) + scenario._create_port = mock.MagicMock() + scenario._create_trunk = mock.MagicMock() + scenario._list_subports_by_trunk = mock.MagicMock() + scenario._update_port = mock.Mock() + scenario._list_ports_by_device_id = mock.Mock() + scenario.run(network_create_args=network_create_args, + subport_count=subport_count) + scenario._create_network.assert_called_once_with( + network_create_args) + scenario._create_port.assert_has_calls( + [mock.call(net, {}) + for _ in range(subport_count + 1)]) + self.assertEqual(1, scenario._create_trunk.call_count) + self.assertEqual(1, scenario._update_port.call_count) + self.assertEqual(1, scenario._list_subports_by_trunk.call_count) + self.assertEqual(1, scenario._list_ports_by_device_id.call_count) + + def test_boot_server_with_subports(self): + img_name = "img" + flavor_uuid = 0 + subport_count = 10 + network_create_args = {} + net = mock.MagicMock() + port = {"port": {"id": "port-id"}} + kwargs = {"nics": [{"port-id": "port-id"}]} + subnet = {"subnet": {"id": "subnet-id"}} + scenario = trunk.BootServerWithSubports(self.context) + scenario._boot_server = mock.MagicMock() + scenario._create_port = mock.MagicMock(return_value=port) + scenario._create_trunk = mock.MagicMock() + scenario._create_network_and_subnets = mock.MagicMock() + scenario._create_network_and_subnets.return_value = net, [subnet] + scenario.run(img_name, flavor_uuid, + network_create_args=network_create_args, + subport_count=subport_count) + scenario._create_port.assert_has_calls( + [mock.call(net, {"fixed_ips": [{"subnet_id": + subnet["subnet"]["id"]}]}) + for _ in range(subport_count + 1)]) + self.assertEqual(1, scenario._create_trunk.call_count) + self.assertEqual(11, scenario._create_network_and_subnets.call_count) + scenario._boot_server.assert_called_once_with(img_name, flavor_uuid, + **kwargs) + + def test_boot_server_and_add_subports(self): + img_name = "img" + flavor_uuid = 0 + subport_count = 10 + network_create_args = {} + net = mock.MagicMock() + port = {"port": {"id": "port-id"}} + kwargs = {"nics": [{"port-id": "port-id"}]} + subnet = {"subnet": {"id": "subnet-id"}} + scenario = trunk.BootServerAndAddSubports(self.context) + scenario._boot_server = mock.MagicMock() + scenario._create_port = mock.MagicMock(return_value=port) + scenario._create_trunk = mock.MagicMock() + scenario._add_subports_to_trunk = mock.MagicMock() + scenario._create_network_and_subnets = mock.MagicMock() + scenario._create_network_and_subnets.return_value = net, [subnet] + scenario.run(img_name, flavor_uuid, + network_create_args=network_create_args, + subport_count=subport_count) + scenario._create_port.assert_has_calls( + [mock.call(net, {"fixed_ips": [{"subnet_id": + subnet["subnet"]["id"]}]}) + for _ in range(subport_count + 1)]) + self.assertEqual(1, scenario._create_trunk.call_count) + scenario._boot_server.assert_called_once_with(img_name, flavor_uuid, + **kwargs) + self.assertEqual(10, scenario._add_subports_to_trunk.call_count) + self.assertEqual(11, scenario._create_network_and_subnets.call_count) + + def test_boot_server_and_batch_add_subports(self): + img_name = "img" + flavor_uuid = 0 + subports_per_batch = 10 + batches = 5 + network_create_args = {} + net = mock.MagicMock() + port = {"port": {"id": "port-id"}} + kwargs = {"nics": [{"port-id": "port-id"}]} + subnet = {"subnet": {"id": "subnet-id"}} + scenario = trunk.BootServerAndBatchAddSubports(self.context) + scenario._boot_server = mock.MagicMock() + scenario._create_port = mock.MagicMock(return_value=port) + scenario._create_trunk = mock.MagicMock() + scenario._add_subports_to_trunk = mock.MagicMock() + scenario._create_network_and_subnets = mock.MagicMock() + scenario._create_network_and_subnets.return_value = net, [subnet] + scenario.run(img_name, flavor_uuid, + network_create_args=network_create_args, + subports_per_batch=10, batches=5) + scenario._create_port.assert_has_calls( + [mock.call(net, {"fixed_ips": [{"subnet_id": + subnet["subnet"]["id"]}]}) + for _ in range(subports_per_batch * batches + 1)]) + self.assertEqual(1, scenario._create_trunk.call_count) + scenario._boot_server.assert_called_once_with(img_name, flavor_uuid, + **kwargs) + self.assertEqual(5, scenario._add_subports_to_trunk.call_count) + self.assertEqual(51, scenario._create_network_and_subnets.call_count)