From b27d5398109a92ccdbc5f747f5da9f5977317c44 Mon Sep 17 00:00:00 2001 From: tcs Date: Mon, 29 Sep 2014 10:45:03 +0530 Subject: [PATCH] Adds Neutron update Port and router benchmarks: - NeutronNetwork.create_and_update_routers - NeutronNetwork.create_and_update_ports Partial implementation of blueprint benchmark-scenarios-for-neutron-update Change-Id: I35b84b36a8588dbff942014f18f6257959157ca5 --- .../neutron/create_and_update_ports.json | 34 ++ .../neutron/create_and_update_ports.yaml | 24 ++ .../neutron/create_and_update_routers.json | 35 ++ .../neutron/create_and_update_routers.yaml | 25 ++ rally-scenarios/rally-neutron.yaml | 53 ++++ rally/benchmark/scenarios/neutron/network.py | 73 ++++- rally/benchmark/scenarios/neutron/utils.py | 51 +++ .../scenarios/neutron/test_network.py | 298 +++++++++++++----- .../benchmark/scenarios/neutron/test_utils.py | 61 ++++ tests/unit/fakes.py | 10 + 10 files changed, 586 insertions(+), 78 deletions(-) create mode 100644 doc/samples/tasks/scenarios/neutron/create_and_update_ports.json create mode 100644 doc/samples/tasks/scenarios/neutron/create_and_update_ports.yaml create mode 100644 doc/samples/tasks/scenarios/neutron/create_and_update_routers.json create mode 100644 doc/samples/tasks/scenarios/neutron/create_and_update_routers.yaml diff --git a/doc/samples/tasks/scenarios/neutron/create_and_update_ports.json b/doc/samples/tasks/scenarios/neutron/create_and_update_ports.json new file mode 100644 index 0000000000..f9da858e20 --- /dev/null +++ b/doc/samples/tasks/scenarios/neutron/create_and_update_ports.json @@ -0,0 +1,34 @@ +{ + "NeutronNetworks.create_and_update_ports": [ + { + "args": { + "network_create_args": {}, + "port_create_args": {}, + "port_update_args": { + "admin_state_up": false, + "device_id": "dummy_id", + "device_owner": "dummy_owner", + "name": "_port_updated" + }, + "ports_per_network": 5 + }, + "runner": { + "type": "constant", + "times": 10, + "concurrency": 5 + }, + "context": { + "users": { + "tenants": 1, + "users_per_tenant": 1 + }, + "quotas": { + "neutron": { + "network": -1, + "port": -1 + } + } + } + } + ] +} diff --git a/doc/samples/tasks/scenarios/neutron/create_and_update_ports.yaml b/doc/samples/tasks/scenarios/neutron/create_and_update_ports.yaml new file mode 100644 index 0000000000..248a9e26ed --- /dev/null +++ b/doc/samples/tasks/scenarios/neutron/create_and_update_ports.yaml @@ -0,0 +1,24 @@ +--- + NeutronNetworks.create_and_update_ports: + - + args: + network_create_args: {} + port_create_args: {} + ports_per_network: 5 + port_update_args: + admin_state_up: False + device_id: "dummy_id" + device_owner: "dummy_owner" + name: "_port_updated" + runner: + type: "constant" + times: 10 + concurrency: 5 + context: + users: + tenants: 1 + users_per_tenant: 1 + quotas: + neutron: + network: -1 + port: -1 diff --git a/doc/samples/tasks/scenarios/neutron/create_and_update_routers.json b/doc/samples/tasks/scenarios/neutron/create_and_update_routers.json new file mode 100644 index 0000000000..0590376177 --- /dev/null +++ b/doc/samples/tasks/scenarios/neutron/create_and_update_routers.json @@ -0,0 +1,35 @@ +{ + "NeutronNetworks.create_and_update_routers": [ + { + "args": { + "network_create_args": {}, + "subnet_create_args": {}, + "subnet_cidr_start": "1.1.0.0/30", + "subnets_per_network": 2, + "router_create_args": {}, + "router_update_args": { + "admin_state_up": false, + "name": "_router_updated" + } + }, + "runner": { + "type": "constant", + "times": 10, + "concurrency": 5 + }, + "context": { + "users": { + "tenants": 1, + "users_per_tenant": 1 + }, + "quotas": { + "neutron": { + "network": -1, + "subnet": -1, + "router": -1 + } + } + } + } + ] +} diff --git a/doc/samples/tasks/scenarios/neutron/create_and_update_routers.yaml b/doc/samples/tasks/scenarios/neutron/create_and_update_routers.yaml new file mode 100644 index 0000000000..d9a9b3592a --- /dev/null +++ b/doc/samples/tasks/scenarios/neutron/create_and_update_routers.yaml @@ -0,0 +1,25 @@ +--- + NeutronNetworks.create_and_update_routers: + - + args: + network_create_args: {} + subnet_create_args: {} + subnet_cidr_start: "1.1.0.0/30" + subnets_per_network: 2 + router_create_args: {} + router_update_args: + admin_state_up: False + name: "_router_updated" + runner: + type: "constant" + times: 10 + concurrency: 5 + context: + users: + tenants: 1 + users_per_tenant: 1 + quotas: + neutron: + network: -1 + subnet: -1 + router: -1 diff --git a/rally-scenarios/rally-neutron.yaml b/rally-scenarios/rally-neutron.yaml index 77e1f2e45f..647d644345 100644 --- a/rally-scenarios/rally-neutron.yaml +++ b/rally-scenarios/rally-neutron.yaml @@ -169,6 +169,59 @@ sla: max_failure_percent: 0 + NeutronNetworks.create_and_update_routers: + - + args: + network_create_args: {} + subnet_create_args: {} + subnet_cidr_start: "1.1.0.0/30" + subnets_per_network: 2 + router_create_args: {} + router_update_args: + admin_state_up: False + name: "_router_updated" + runner: + type: "constant" + times: 10 + concurrency: 5 + context: + users: + tenants: 1 + users_per_tenant: 1 + quotas: + neutron: + network: -1 + subnet: -1 + router: -1 + sla: + max_failure_percent: 0 + + NeutronNetworks.create_and_update_ports: + - + args: + network_create_args: {} + port_create_args: {} + ports_per_network: 5 + port_update_args: + admin_state_up: False + device_id: "dummy_id" + device_owner: "dummy_owner" + name: "_port_updated" + runner: + type: "constant" + times: 10 + concurrency: 5 + context: + users: + tenants: 1 + users_per_tenant: 1 + quotas: + neutron: + network: -1 + port: -1 + sla: + max_failure_percent: 0 + NeutronNetworks.create_and_delete_networks: - args: diff --git a/rally/benchmark/scenarios/neutron/network.py b/rally/benchmark/scenarios/neutron/network.py index 53a9a68d8a..6041c67a5d 100644 --- a/rally/benchmark/scenarios/neutron/network.py +++ b/rally/benchmark/scenarios/neutron/network.py @@ -175,12 +175,13 @@ class NeutronNetworks(utils.NeutronScenario): :param subnets_per_network: int, number of subnets for one network :param router_create_args: dict, POST /v2.0/routers request options """ - if subnet_cidr_start: - NeutronNetworks.SUBNET_CIDR_START = subnet_cidr_start - network = self._create_network(network_create_args or {}) - for i in range(subnets_per_network): - subnet = self._create_subnet(network, subnets_per_network, - subnet_create_args or {}) + 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"], @@ -188,6 +189,42 @@ class NeutronNetworks(utils.NeutronScenario): self._list_routers() + @validation.number("subnets_per_network", minval=1, integer_only=True) + @validation.required_parameters("subnets_per_network") + @validation.required_services(consts.Service.NEUTRON) + @base.scenario(context={"cleanup": ["neutron"]}) + def create_and_update_routers(self, + router_update_args, + network_create_args=None, + subnet_create_args=None, + subnet_cidr_start=None, + subnets_per_network=None, + router_create_args=None): + """Test creating and updating a given number of routers. + + Create a network, a given number of subnets and routers + 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 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._update_router(router, router_update_args) + @validation.number("ports_per_network", minval=1, integer_only=True) @validation.required_services(consts.Service.NEUTRON) @validation.required_openstack(users=True) @@ -212,6 +249,30 @@ class NeutronNetworks(utils.NeutronScenario): @validation.required_services(consts.Service.NEUTRON) @validation.required_openstack(users=True) @base.scenario(context={"cleanup": ["neutron"]}) + def create_and_update_ports(self, + port_update_args, + network_create_args=None, + port_create_args=None, + ports_per_network=None): + """Test creating and updating a given number of ports. + + This scenario is a very useful tool to measure + the "neutron port-create" and + "neutron port-update" command 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 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 {}) + for i in range(ports_per_network): + port = self._create_port(network, port_create_args or {}) + self._update_port(port, port_update_args) + + @validation.required_parameters("ports_per_network") + @validation.required_services(consts.Service.NEUTRON) + @base.scenario(context={"cleanup": ["neutron"]}) def create_and_delete_ports(self, network_create_args=None, port_create_args=None, diff --git a/rally/benchmark/scenarios/neutron/utils.py b/rally/benchmark/scenarios/neutron/utils.py index 5323ff61d9..db35c6be19 100644 --- a/rally/benchmark/scenarios/neutron/utils.py +++ b/rally/benchmark/scenarios/neutron/utils.py @@ -17,6 +17,7 @@ import netaddr from rally.benchmark.scenarios import base from rally.openstack.common import log as logging +from rally.openstack.common import uuidutils as uid LOG = logging.getLogger(__name__) @@ -170,6 +171,29 @@ class NeutronScenario(base.Scenario): """Returns user routers list.""" return self.clients("neutron").list_routers()["routers"] + @base.atomic_action_timer('neutron.update_router') + def _update_router(self, router, router_update_args): + """Update the neutron router name and admin state. + + This atomic function updates router name by + appending the existing name and admin state with router_update_args. + + :param router: dict, neutron router + :param router_update_args: dict, PUT /v2.0/routers update options + :returns: updated neutron router dict + """ + suffix = router_update_args.get( + "name", self._generate_random_name("_")) + admin_state = router_update_args.get("admin_state_up", True) + body = { + "router": { + "name": router["router"]["name"] + suffix, + "admin_state_up": admin_state + } + } + return self.clients("neutron").update_router( + router["router"]["id"], body) + @base.atomic_action_timer('neutron.create_port') def _create_port(self, network, port_create_args): """Create neutron port. @@ -188,6 +212,33 @@ class NeutronScenario(base.Scenario): """Return user ports list.""" return self.clients("neutron").list_ports()["ports"] + @base.atomic_action_timer('neutron.update_port') + def _update_port(self, port, port_update_args): + """Update the neutron port name, admin state, device id and owner. + + This atomic function updates port name by + appending the existing name, admin state, device id and + device owner with port_update_args. + + :param port: dict, neutron port + :param port_update_args: dict, PUT /v2.0/ports update options + :returns: updated neutron port dict + """ + suffix = port_update_args.get( + "name", self._generate_random_name("_")) + admin_state = port_update_args.get("admin_state_up", True) + device_owner = port_update_args.get("device_owner", "compute:nova") + device_id = port_update_args.get("device_id", uid.generate_uuid()) + body = { + "port": { + "name": port["port"]["name"] + suffix, + "admin_state_up": admin_state, + "device_id": device_id, + "device_owner": device_owner + } + } + return self.clients("neutron").update_port(port["port"]["id"], body) + @base.atomic_action_timer('neutron.delete_port') def _delete_port(self, port): """Delete neutron port. diff --git a/tests/unit/benchmark/scenarios/neutron/test_network.py b/tests/unit/benchmark/scenarios/neutron/test_network.py index 5c90427ef8..751077e402 100644 --- a/tests/unit/benchmark/scenarios/neutron/test_network.py +++ b/tests/unit/benchmark/scenarios/neutron/test_network.py @@ -140,24 +140,26 @@ class NeutronNetworksTestCase(test.TestCase): mock_list.assert_called_once_with() @mock.patch(NEUTRON_NETWORKS + "._update_subnet") - @mock.patch(NEUTRON_NETWORKS + "._create_network_and_subnets", - return_value=({ - "network": { - "id": "network-id" - } - }, [{ - "subnet": { - "name": "subnet-name", - "id": "subnet-id", - "enable_dhcp": False - } - }])) + @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() subnets_per_network = 1 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} mock_create_network_and_subnets.reset_mock() @@ -172,8 +174,7 @@ class NeutronNetworksTestCase(test.TestCase): mock_create_network_and_subnets.assert_has_calls( [mock.call({}, {}, subnets_per_network, subnet_cidr_start)]) mock_update_subnet.assert_has_calls( - [mock.call(mock_create_network_and_subnets.return_value[1][0], - subnet_update_args)]) + [mock.call(subnet, subnet_update_args)]) mock_create_network_and_subnets.reset_mock() mock_update_subnet.reset_mock() @@ -190,26 +191,27 @@ class NeutronNetworksTestCase(test.TestCase): [mock.call({}, {"allocation_pools": []}, subnets_per_network, subnet_cidr_start)]) mock_update_subnet.assert_has_calls( - [mock.call(mock_create_network_and_subnets.return_value[1][0], - subnet_update_args)]) + [mock.call(subnet, subnet_update_args)]) @mock.patch(NEUTRON_NETWORKS + "._delete_subnet") - @mock.patch(NEUTRON_NETWORKS + "._create_network_and_subnets", - return_value=({ - "network": { - "id": "network-id" - } - }, [{ - "subnet": { - "name": "subnet-name", - "id": "subnet-id", - "enable_dhcp": False - } - }])) + @mock.patch(NEUTRON_NETWORKS + "._create_network_and_subnets") def test_create_and_delete_subnets(self, mock_create_network_and_subnets, mock_delete): scenario = network.NeutronNetworks() + 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 subnet_cidr_start = "default_cidr" @@ -225,8 +227,7 @@ class NeutronNetworksTestCase(test.TestCase): [mock.call({}, {}, subnets_per_network, subnet_cidr_start)]) - mock_delete.assert_has_calls( - [mock.call(mock_create_network_and_subnets.return_value[1][0])]) + mock_delete.assert_has_calls([mock.call(subnet)]) mock_create_network_and_subnets.reset_mock() mock_delete.reset_mock() @@ -241,56 +242,66 @@ class NeutronNetworksTestCase(test.TestCase): mock_create_network_and_subnets.assert_has_calls( [mock.call({}, {"allocation_pools": []}, subnets_per_network, subnet_cidr_start)]) - mock_delete.assert_has_calls( - [mock.call(mock_create_network_and_subnets.return_value[1][0])]) + mock_delete.assert_has_calls([mock.call(subnet)]) @mock.patch(NEUTRON_NETWORKS + "._list_routers") @mock.patch(NEUTRON_NETWORKS + "._create_router") - @mock.patch(NEUTRON_NETWORKS + "._create_subnet") - @mock.patch(NEUTRON_NETWORKS + "._create_network") + @mock.patch(NEUTRON_NETWORKS + "._create_network_and_subnets") @mock.patch(NEUTRON_NETWORKS + ".clients") def test_create_and_list_routers(self, mock_clients, - mock_create_network, - mock_create_subnet, + mock_create_network_and_subnets, mock_create_router, mock_list): scenario = network.NeutronNetworks() - subnets_per_network = 4 + subnets_per_network = 1 + 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]) mock_clients("neutron").add_interface_router = mock.Mock() - - net = {"network": {"id": "network-id"}} - mock_create_network.return_value = net - - subnet = {"subnet": {"name": "subnet-name", "id": "subnet-id"}} - mock_create_subnet.return_value = subnet - - router = {"router": {"name": "router-name", "id": "router-id"}} + router = { + "router": { + "name": "router-name", + "id": "router-id" + } + } mock_create_router.return_value = router # Default options scenario.create_and_list_routers( + subnet_cidr_start=subnet_cidr_start, subnets_per_network=subnets_per_network) - mock_create_network.assert_called_once_with({}) - self.assertEqual( - mock_create_subnet.mock_calls, - [mock.call(net, subnets_per_network, {})] * subnets_per_network) - self.assertEqual( - mock_create_router.mock_calls, + 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.assertEqual( - mock_clients("neutron").add_interface_router.mock_calls, + + mock_clients("neutron").add_interface_router.assert_has_calls( [mock.call(router["router"]["id"], {"subnet_id": subnet["subnet"]["id"]}) ] * subnets_per_network) - mock_create_network.reset_mock() - mock_create_subnet.reset_mock() + mock_create_network_and_subnets.reset_mock() mock_create_router.reset_mock() + mock_clients("neutron").add_interface_router.reset_mock() mock_list.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( @@ -298,26 +309,110 @@ class NeutronNetworksTestCase(test.TestCase): subnet_cidr_start="custom_cidr", subnets_per_network=subnets_per_network, router_create_args=router_create_args) - self.assertEqual(scenario.SUBNET_CIDR_START, "custom_cidr") - mock_create_network.assert_called_once_with({}) - self.assertEqual( - mock_create_subnet.mock_calls, [ - mock.call({"network": {"id": "network-id"}}, - subnets_per_network, - subnet_create_args) - ] * subnets_per_network) - self.assertEqual( - mock_create_router.mock_calls, [ - mock.call(router_create_args) - ] * subnets_per_network) - self.assertEqual( - mock_clients("neutron").add_interface_router.mock_calls, [ - mock.call(router["router"]["id"], - {"subnet_id": subnet["subnet"]["id"]}) - ] * subnets_per_network) + + mock_create_network_and_subnets.assert_has_calls( + [mock.call({}, subnet_create_args, subnets_per_network, + subnet_cidr_start)]) + + mock_create_router.assert_has_calls( + [mock.call(router_create_args)] * subnets_per_network) + mock_clients("neutron").add_interface_router.assert_has_calls( + [mock.call(router["router"]["id"], + {"subnet_id": subnet["subnet"]["id"]}) + ] * subnets_per_network) mock_list.assert_called_once_with() + @mock.patch(NEUTRON_NETWORKS + "._update_router") + @mock.patch(NEUTRON_NETWORKS + "._create_router") + @mock.patch(NEUTRON_NETWORKS + "._create_network_and_subnets") + @mock.patch(NEUTRON_NETWORKS + ".clients") + def test_create_and_update_routers(self, + mock_clients, + mock_create_network_and_subnets, + mock_create_router, + mock_update_router): + scenario = network.NeutronNetworks() + subnets_per_network = 1 + subnet_cidr_start = "default_cidr" + + 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]) + mock_clients("neutron").add_interface_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) + mock_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() + mock_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, + subnet_create_args=subnet_create_args, + subnet_cidr_start="custom_cidr", + 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)]) + + mock_create_router.assert_has_calls( + [mock.call(router_create_args)] * subnets_per_network) + mock_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.patch(NEUTRON_NETWORKS + "._generate_random_name") @mock.patch(NEUTRON_NETWORKS + "._list_ports") @mock.patch(NEUTRON_NETWORKS + "._create_port") @@ -359,6 +454,65 @@ class NeutronNetworksTestCase(test.TestCase): [mock.call(net, {"allocation_pools": []})] * ports_per_network) mock_list.assert_called_once_with() + @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_random_name): + scenario = network.NeutronNetworks() + mock_random_name.return_value = "random-name" + ports_per_network = 10 + + 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") diff --git a/tests/unit/benchmark/scenarios/neutron/test_utils.py b/tests/unit/benchmark/scenarios/neutron/test_utils.py index d1a3c0cc88..5c7ce7f8d6 100644 --- a/tests/unit/benchmark/scenarios/neutron/test_utils.py +++ b/tests/unit/benchmark/scenarios/neutron/test_utils.py @@ -224,6 +224,33 @@ class NeutronScenarioTestCase(test.TestCase): self._test_atomic_action_timer(scenario.atomic_actions(), 'neutron.list_routers') + @mock.patch(NEUTRON_UTILS + 'NeutronScenario.clients') + def test_update_router(self, mock_clients): + scenario = utils.NeutronScenario() + expected_router = { + "router": { + "name": "router-name_updated", + 'admin_state_up': False + } + } + mock_clients("neutron").update_router.return_value = expected_router + + router = { + "router": { + "id": "router-id", + "name": "router-name", + 'admin_state_up': True + } + } + router_update_args = {"name": "_updated", "admin_state_up": False} + + result_router = scenario._update_router(router, router_update_args) + mock_clients("neutron").update_router.assert_called_once_with( + router['router']['id'], expected_router) + self.assertEqual(result_router, expected_router) + self._test_atomic_action_timer(scenario.atomic_actions(), + 'neutron.update_router') + def test_SUBNET_IP_VERSION(self): """Curent NeutronScenario implementation supports only IPv4.""" self.assertEqual(utils.NeutronScenario.SUBNET_IP_VERSION, 4) @@ -292,6 +319,40 @@ class NeutronScenarioTestCase(test.TestCase): self._test_atomic_action_timer(scenario.atomic_actions(), "neutron.list_ports") + @mock.patch(NEUTRON_UTILS + 'NeutronScenario.clients') + def test_update_port(self, mock_clients): + scenario = utils.NeutronScenario() + expected_port = { + "port": { + "name": "port-name_updated", + "admin_state_up": False, + "device_id": "dummy_id", + "device_owner": "dummy_owner" + } + } + mock_clients("neutron").update_port.return_value = expected_port + + port = { + "port": { + "id": "port-id", + "name": "port-name", + "admin_state_up": True + } + } + port_update_args = { + "name": "_updated", + "admin_state_up": False, + "device_id": "dummy_id", + "device_owner": "dummy_owner" + } + + result_port = scenario._update_port(port, port_update_args) + mock_clients("neutron").update_port.assert_called_once_with( + port['port']['id'], expected_port) + self.assertEqual(result_port, expected_port) + self._test_atomic_action_timer(scenario.atomic_actions(), + 'neutron.update_port') + @mock.patch(NEUTRON_UTILS + 'NeutronScenario.clients') def test_delete_port(self, mock_clients): scenario = utils.NeutronScenario() diff --git a/tests/unit/fakes.py b/tests/unit/fakes.py index 501a4746bc..dc432f9a30 100644 --- a/tests/unit/fakes.py +++ b/tests/unit/fakes.py @@ -990,6 +990,16 @@ class FakeNeutronClient(object): raise neutron_exceptions.NeutronClientException self.__subnets[subnet_id].update(data) + def update_port(self, port_id, data): + if port_id not in self.__ports: + raise neutron_exceptions.NeutronClientException + self.__ports[port_id].update(data) + + def update_router(self, router_id, data): + if router_id not in self.__routers: + raise neutron_exceptions.NeutronClientException + self.__routers[router_id].update(data) + def delete_network(self, network_id): if network_id not in self.__networks: raise neutron_exceptions.NeutronClientException