diff --git a/CHANGELOG.rst b/CHANGELOG.rst index fcfeacd1..911bdfbd 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -35,6 +35,7 @@ Added * [scenario plugin] Octavia.create_and_show_pools * Support for osprofiler config in Devstack plugin. * Added property 'floating_ip_enabled' in magnum cluster_templates context. +* Enhanced neutron trunk port scenario to create multiple trunks Changed ~~~~~~~ diff --git a/rally-jobs/neutron.yaml b/rally-jobs/neutron.yaml index 5a4ddb7c..9daa8a46 100644 --- a/rally-jobs/neutron.yaml +++ b/rally-jobs/neutron.yaml @@ -621,6 +621,7 @@ - args: network_create_args: {} + trunk_count: 1 subport_count: 10 runner: type: "constant" diff --git a/rally_openstack/scenarios/neutron/network.py b/rally_openstack/scenarios/neutron/network.py index 3143b504..680387c9 100644 --- a/rally_openstack/scenarios/neutron/network.py +++ b/rally_openstack/scenarios/neutron/network.py @@ -608,14 +608,16 @@ class DeleteSubnets(utils.NeutronScenario): @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, subport_count=10): - """Create and a given number of trunks with subports and list all trunks + 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. @@ -623,15 +625,23 @@ class CreateAndListTrunks(utils.NeutronScenario): :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)] - parent, subports = ports[0], ports[1:] + 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)] - trunk_payload = {"port_id": parent["port"]["id"], - "sub_ports": subport_payload} - self._create_trunk(trunk_payload) - self._update_port(parent, {"device_id": "sometrunk"}) + 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/utils.py b/rally_openstack/scenarios/neutron/utils.py index 58d59b08..51ce9702 100644 --- a/rally_openstack/scenarios/neutron/utils.py +++ b/rally_openstack/scenarios/neutron/utils.py @@ -894,3 +894,7 @@ class NeutronScenario(scenario.OpenStackScenario): @atomic.optional_action_timer("neutron.list_ports_by_device_id") def _list_ports_by_device_id(self, device_id): return self.clients("neutron").list_ports(device_id=device_id) + + @atomic.optional_action_timer("neutron.list_subports_by_trunk") + def _list_subports_by_trunk(self, trunk_id): + return self.clients("neutron").trunk_get_subports(trunk_id) diff --git a/samples/tasks/scenarios/neutron/create-and-list-trunks.json b/samples/tasks/scenarios/neutron/create-and-list-trunks.json index 0656a0be..a982682f 100644 --- a/samples/tasks/scenarios/neutron/create-and-list-trunks.json +++ b/samples/tasks/scenarios/neutron/create-and-list-trunks.json @@ -3,6 +3,7 @@ { "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 ad90bc59..8cca35a6 100644 --- a/samples/tasks/scenarios/neutron/create-and-list-trunks.yaml +++ b/samples/tasks/scenarios/neutron/create-and-list-trunks.yaml @@ -4,6 +4,7 @@ - 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 005beb54..bc3e450d 100644 --- a/tasks/openstack/scenario/neutron.yaml +++ b/tasks/openstack/scenario/neutron.yaml @@ -265,6 +265,7 @@ - args: network_create_args: {} + trunk_count: 1 subport_count: 10 context: {% call user_context(tenants_amount, users_amount, use_existing_users) %} diff --git a/tests/unit/scenarios/neutron/test_network.py b/tests/unit/scenarios/neutron/test_network.py index 7aea31c9..d29338b3 100644 --- a/tests/unit/scenarios/neutron/test_network.py +++ b/tests/unit/scenarios/neutron/test_network.py @@ -598,6 +598,7 @@ class NeutronNetworksTestCase(test.ScenarioTestCase): 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() @@ -613,7 +614,7 @@ class NeutronNetworksTestCase(test.ScenarioTestCase): network_create_args) scenario._create_port.assert_has_calls( [mock.call(net, {}) - for _ in range(subport_count)]) + 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_utils.py b/tests/unit/scenarios/neutron/test_utils.py index df768c36..caf46d80 100644 --- a/tests/unit/scenarios/neutron/test_utils.py +++ b/tests/unit/scenarios/neutron/test_utils.py @@ -1331,6 +1331,14 @@ class NeutronScenarioTestCase(test.ScenarioTestCase): self.clients("neutron").list_ports.assert_called_once_with( device_id=device_id) + def test__list_subports_by_trunk(self): + trunk_id = "trunk-id" + self.scenario._list_subports_by_trunk(trunk_id) + self.clients("neutron").trunk_get_subports.assert_called_once_with( + trunk_id) + self._test_atomic_action_timer(self.scenario.atomic_actions(), + "neutron.list_subports_by_trunk") + class NeutronScenarioFunctionalTestCase(test.FakeClientsScenarioTestCase):