From af3239d5d45995bd89c6beb91edae52f133c4790 Mon Sep 17 00:00:00 2001 From: Alexander Maretskiy Date: Mon, 12 May 2014 18:21:58 +0300 Subject: [PATCH] Add Neutron benchmarks scenario for creating and listing ports Scenario NeutronNetworks.create_and_list_ports is added, which does the following: - creates network - creates a given number of ports - lists ports blueprint benchmark-scenarios-for-neutron Change-Id: I029f220dd70beb0c248877bd4bd718dfa63aba40 --- .../tasks/neutron/create_and_list_ports.json | 28 +++++++++++++ .../tasks/neutron/create_and_list_ports.yaml | 19 +++++++++ rally-scenarios/rally-neutron.yaml | 19 +++++++++ rally/benchmark/scenarios/neutron/network.py | 18 ++++++++ rally/benchmark/scenarios/neutron/utils.py | 18 ++++++++ tests/benchmark/context/cleanup/test_utils.py | 7 +++- .../scenarios/neutron/test_network.py | 41 ++++++++++++++++++ .../benchmark/scenarios/neutron/test_utils.py | 42 +++++++++++++++++++ 8 files changed, 190 insertions(+), 2 deletions(-) create mode 100644 doc/samples/tasks/neutron/create_and_list_ports.json create mode 100644 doc/samples/tasks/neutron/create_and_list_ports.yaml diff --git a/doc/samples/tasks/neutron/create_and_list_ports.json b/doc/samples/tasks/neutron/create_and_list_ports.json new file mode 100644 index 0000000000..a792e1f75f --- /dev/null +++ b/doc/samples/tasks/neutron/create_and_list_ports.json @@ -0,0 +1,28 @@ +{ + "NeutronNetworks.create_and_list_ports": [ + { + "args": { + "network_create_args": {}, + "port_create_args": {}, + "ports_per_network": 10 + }, + "runner": { + "type": "constant", + "times": 100, + "concurrency": 10 + }, + "context": { + "users": { + "tenants": 1, + "users_per_tenant": 1 + }, + "quotas": { + "neutron": { + "network": -1, + "port": -1 + } + } + } + } + ] +} diff --git a/doc/samples/tasks/neutron/create_and_list_ports.yaml b/doc/samples/tasks/neutron/create_and_list_ports.yaml new file mode 100644 index 0000000000..b90bf32e21 --- /dev/null +++ b/doc/samples/tasks/neutron/create_and_list_ports.yaml @@ -0,0 +1,19 @@ +--- + NeutronNetworks.create_and_list_ports: + - + args: + network_create_args: + port_create_args: + ports_per_network: 10 + runner: + type: "constant" + times: 100 + concurrency: 10 + context: + users: + tenants: 1 + users_per_tenant: 1 + quotas: + neutron: + network: -1 + port: -1 diff --git a/rally-scenarios/rally-neutron.yaml b/rally-scenarios/rally-neutron.yaml index fe0c44f42c..cd9a6f12bb 100644 --- a/rally-scenarios/rally-neutron.yaml +++ b/rally-scenarios/rally-neutron.yaml @@ -91,3 +91,22 @@ network: -1 subnet: -1 router: -1 + + NeutronNetworks.create_and_list_ports: + - + args: + network_create_args: + port_create_args: + ports_per_network: 5 + runner: + type: "constant" + times: 100 + concurrency: 10 + context: + users: + tenants: 1 + users_per_tenant: 1 + quotas: + neutron: + network: -1 + port: -1 diff --git a/rally/benchmark/scenarios/neutron/network.py b/rally/benchmark/scenarios/neutron/network.py index aaa3c06b43..43411baebd 100644 --- a/rally/benchmark/scenarios/neutron/network.py +++ b/rally/benchmark/scenarios/neutron/network.py @@ -93,3 +93,21 @@ class NeutronNetworks(utils.NeutronScenario): {"subnet_id": subnet["subnet"]["id"]}) self._list_routers() + + @base.scenario(context={"cleanup": ["neutron"]}) + @validation.add(validation.required_parameters(["ports_per_network"])) + def create_and_list_ports(self, + network_create_args=None, + port_create_args=None, + ports_per_network=None): + """Test creating and listing a given number of ports. + + :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): + self._create_port(network, port_create_args or {}) + + self._list_ports() diff --git a/rally/benchmark/scenarios/neutron/utils.py b/rally/benchmark/scenarios/neutron/utils.py index 49b410759b..365821723d 100644 --- a/rally/benchmark/scenarios/neutron/utils.py +++ b/rally/benchmark/scenarios/neutron/utils.py @@ -103,3 +103,21 @@ class NeutronScenario(base.Scenario): def _list_routers(self): """Returns user routers list.""" return self.clients("neutron").list_routers()["routers"] + + @scenario_utils.atomic_action_timer('neutron.create_port') + def _create_port(self, network, port_create_args): + """Create neutron port. + + :param network: neutron network dict + :param port_create_args: POST /v2.0/ports request options + :returns: neutron port dict + """ + port_create_args["network_id"] = network["network"]["id"] + port_create_args.setdefault( + "name", self._generate_random_name("rally_port_")) + return self.clients("neutron").create_port({"port": port_create_args}) + + @scenario_utils.atomic_action_timer('neutron.list_ports') + def _list_ports(self): + """Return user ports list.""" + return self.clients("neutron").list_ports()["ports"] diff --git a/tests/benchmark/context/cleanup/test_utils.py b/tests/benchmark/context/cleanup/test_utils.py index 4970696058..ba0be891d2 100644 --- a/tests/benchmark/context/cleanup/test_utils.py +++ b/tests/benchmark/context/cleanup/test_utils.py @@ -30,17 +30,20 @@ class CleanupUtilsTestCase(test.TestCase): network1 = scenario._create_network({}) subnet1 = scenario._create_subnet(network1, {}) router1 = scenario._create_router({}) + # This also creates a port neutron.add_interface_router(router1["router"]["id"], {"subnet_id": subnet1["subnet"]["id"]}) network2 = scenario._create_network({}) scenario._create_subnet(network2, {}) scenario._create_router({}) + scenario._create_port(network2, {}) total = lambda neutron: (len(neutron.list_networks()["networks"]) + len(neutron.list_subnets()["subnets"]) - + len(neutron.list_routers()["routers"])) + + len(neutron.list_routers()["routers"]) + + len(neutron.list_ports()["ports"])) - self.assertEqual(total(neutron), 6) + self.assertEqual(total(neutron), 8) utils.delete_neutron_resources(neutron, network1["network"]["tenant_id"]) diff --git a/tests/benchmark/scenarios/neutron/test_network.py b/tests/benchmark/scenarios/neutron/test_network.py index f6850c4d41..0cf7256bab 100644 --- a/tests/benchmark/scenarios/neutron/test_network.py +++ b/tests/benchmark/scenarios/neutron/test_network.py @@ -164,3 +164,44 @@ class NeutronNetworksTestCase(test.TestCase): ] * subnets_per_network) mock_list.assert_called_once_with() + + @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, + mock_random_name): + scenario = network.NeutronNetworks() + mock_random_name.return_value = "random-name" + net = {"network": {"id": "fake-id"}} + mock_create_network.return_value = net + ports_per_network = 10 + + self.assertRaises(TypeError, scenario.create_and_list_ports) + + 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.assert_called_once_with() + + mock_create_network.reset_mock() + mock_create_port.reset_mock() + mock_list.reset_mock() + + # Custom options + scenario.create_and_list_ports( + 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"}) + self.assertEqual( + mock_create_port.mock_calls, + [mock.call(net, {"allocation_pools": []})] * ports_per_network) + mock_list.assert_called_once_with() diff --git a/tests/benchmark/scenarios/neutron/test_utils.py b/tests/benchmark/scenarios/neutron/test_utils.py index 0a4a07d854..199723517f 100644 --- a/tests/benchmark/scenarios/neutron/test_utils.py +++ b/tests/benchmark/scenarios/neutron/test_utils.py @@ -187,3 +187,45 @@ class NeutronScenarioTestCase(test.TestCase): # All CIDRs must be valid map(netaddr.IPNetwork, cidrs1 + cidrs2) + + @mock.patch(NEUTRON_UTILS + "NeutronScenario._generate_random_name") + @mock.patch(NEUTRON_UTILS + "NeutronScenario.clients") + def test_create_port(self, mock_clients, mock_rand_name): + scenario = utils.NeutronScenario() + + net_id = "network-id" + net = {"network": {"id": net_id}} + rand_name = "random-name" + mock_rand_name.return_value = rand_name + expected_port_args = { + "port": { + "network_id": net_id, + "name": rand_name + } + } + + # Defaults + port_create_args = {} + scenario._create_port(net, port_create_args) + mock_clients("neutron" + ).create_port.assert_called_once_with(expected_port_args) + self._test_atomic_action_timer(scenario.atomic_actions(), + "neutron.create_port") + + mock_clients("neutron").create_port.reset_mock() + + # Custom options + port_args = {"admin_state_up": True} + expected_port_args["port"].update(port_args) + scenario._create_port(net, port_args) + mock_clients("neutron" + ).create_port.assert_called_once_with(expected_port_args) + + @mock.patch(NEUTRON_UTILS + "NeutronScenario.clients") + def test_list_ports(self, mock_clients): + scenario = utils.NeutronScenario() + ports = [{"name": "port1"}, {"name": "port2"}] + mock_clients("neutron").list_ports.return_value = {"ports": ports} + self.assertEqual(ports, scenario._list_ports()) + self._test_atomic_action_timer(scenario.atomic_actions(), + "neutron.list_ports")