From d7af3a40665c0928e162eee6154c324dec1e998c Mon Sep 17 00:00:00 2001 From: Sai Sindhur Malleni Date: Fri, 25 Jan 2019 15:46:14 -0500 Subject: [PATCH] Enhance NeutronSecurityGroup.create_and_list_security_group_rules Now we can create multiple rules per security group Change-Id: I38ca966b40ba16e79d1938316b6c5814fc970c38 --- CHANGELOG.rst | 1 + rally-jobs/neutron.yaml | 2 + .../scenarios/neutron/security_groups.py | 31 +++++---- rally_openstack/scenarios/neutron/utils.py | 2 + .../create-and-list-security-group-rules.json | 6 +- .../create-and-list-security-group-rules.yaml | 2 + .../scenarios/neutron/test_security_groups.py | 69 +++++++++++++------ tests/unit/scenarios/neutron/test_utils.py | 2 + 8 files changed, 81 insertions(+), 34 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 911bdfbd..f32623b5 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -36,6 +36,7 @@ Added * 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 +* Enhanced NeutronSecurityGroup.create_and_list_security_group_rules Changed ~~~~~~~ diff --git a/rally-jobs/neutron.yaml b/rally-jobs/neutron.yaml index 9daa8a46..a1a71ef4 100644 --- a/rally-jobs/neutron.yaml +++ b/rally-jobs/neutron.yaml @@ -216,6 +216,7 @@ args: security_group_args: {} security_group_rule_args: {} + security_group_rules_count: 20 runner: type: "constant" times: {{smoke or 8 }} @@ -227,6 +228,7 @@ quotas: neutron: security_group: -1 + security_group_rule: -1 sla: failure_rate: max: 20 diff --git a/rally_openstack/scenarios/neutron/security_groups.py b/rally_openstack/scenarios/neutron/security_groups.py index b4fdf14b..ebbdfefb 100644 --- a/rally_openstack/scenarios/neutron/security_groups.py +++ b/rally_openstack/scenarios/neutron/security_groups.py @@ -132,34 +132,41 @@ class CreateAndUpdateSecurityGroups(utils.NeutronScenario): platform="openstack") class CreateAndListSecurityGroupRules(utils.NeutronScenario): - def run(self, security_group_args=None, + def run(self, security_group_rules_count=1, + security_group_args=None, security_group_rule_args=None): """Create and list Neutron security-group-rules. Measure the "neutron security-group-rule-create" and "neutron security-group-rule-list" command performance. + :param security_group_rules_count: int, number of rules per + security group :param security_group_args: dict, POST /v2.0/security-groups request options :param security_group_rule_args: dict, POST /v2.0/security-group-rules request options """ security_group_args = security_group_args or {} - security_group_rule_args = security_group_rule_args or {} - security_group = self._create_security_group(**security_group_args) msg = "security_group isn't created" self.assertTrue(security_group, err_msg=msg) - - security_group_rule = self._create_security_group_rule( - security_group["security_group"]["id"], **security_group_rule_args) - msg = "security_group_rule isn't created" - self.assertTrue(security_group_rule, err_msg=msg) - + rules = [] + for rule in range(security_group_rules_count): + security_group_rule_args = security_group_rule_args or {} + security_group_rule_args["port_range_min"] = rule + 1 + security_group_rule_args["port_range_max"] = rule + 1 + security_group_rule = self._create_security_group_rule( + security_group["security_group"]["id"], + **security_group_rule_args) + rules.append(security_group_rule) + msg = "security_group_rule isn't created" + self.assertTrue(security_group_rule, err_msg=msg) security_group_rules = self._list_security_group_rules() - self.assertIn(security_group_rule["security_group_rule"]["id"], - [sgr["id"] for sgr - in security_group_rules["security_group_rules"]]) + for rule in rules: + self.assertIn(rule["security_group_rule"]["id"], + [sgr["id"] for sgr in security_group_rules[ + "security_group_rules"]]) @validation.add("required_services", diff --git a/rally_openstack/scenarios/neutron/utils.py b/rally_openstack/scenarios/neutron/utils.py index c9e0057e..30bbcb6a 100644 --- a/rally_openstack/scenarios/neutron/utils.py +++ b/rally_openstack/scenarios/neutron/utils.py @@ -846,6 +846,8 @@ class NeutronScenario(scenario.OpenStackScenario): security_group_rule_args["security_group_id"] = security_group_id if "direction" not in security_group_rule_args: security_group_rule_args["direction"] = "ingress" + if "protocol" not in security_group_rule_args: + security_group_rule_args["protocol"] = "tcp" return self.clients("neutron").create_security_group_rule( {"security_group_rule": security_group_rule_args}) diff --git a/samples/tasks/scenarios/neutron/create-and-list-security-group-rules.json b/samples/tasks/scenarios/neutron/create-and-list-security-group-rules.json index a7b0a7cd..a200b281 100644 --- a/samples/tasks/scenarios/neutron/create-and-list-security-group-rules.json +++ b/samples/tasks/scenarios/neutron/create-and-list-security-group-rules.json @@ -3,7 +3,8 @@ { "args": { "security_group_args": {}, - "security_group_rule_args":{} + "security_group_rule_args": {}, + "security_group_rules_count": 5 }, "runner": { "type": "constant", @@ -17,7 +18,8 @@ }, "quotas": { "neutron": { - "security_group": -1 + "security_group": -1, + "security_group_rule": -1 } } }, diff --git a/samples/tasks/scenarios/neutron/create-and-list-security-group-rules.yaml b/samples/tasks/scenarios/neutron/create-and-list-security-group-rules.yaml index f39e46ae..97f71ed9 100644 --- a/samples/tasks/scenarios/neutron/create-and-list-security-group-rules.yaml +++ b/samples/tasks/scenarios/neutron/create-and-list-security-group-rules.yaml @@ -4,6 +4,7 @@ args: security_group_args: {} security_group_rule_args: {} + security_group_rules_count: 5 runner: type: "constant" times: 20 @@ -15,6 +16,7 @@ quotas: neutron: security_group: -1 + security_group_rule: -1 sla: failure_rate: max: 0 diff --git a/tests/unit/scenarios/neutron/test_security_groups.py b/tests/unit/scenarios/neutron/test_security_groups.py index d3911b5b..fc9bcf64 100644 --- a/tests/unit/scenarios/neutron/test_security_groups.py +++ b/tests/unit/scenarios/neutron/test_security_groups.py @@ -10,6 +10,7 @@ # License for the specific language governing permissions and limitations # under the License. +import copy import ddt import mock @@ -129,37 +130,53 @@ class NeutronSecurityGroup(test.TestCase): {"security_group_args": {"description": "fake-description"}}, {"security_group_rule_args": {}}, {"security_group_rule_args": {"description": "fake-rule-descr"}}, + {"security_group_rules_count": 2}, ) @ddt.unpack def test_create_and_list_security_group_rules( - self, security_group_args=None, + self, security_group_rules_count=1, + security_group_args=None, security_group_rule_args=None): scenario = security_groups.CreateAndListSecurityGroupRules() - security_group_data = security_group_args or {} security_group_rule_data = security_group_rule_args or {} security_group = mock.MagicMock() - security_group_rule = {"security_group_rule": {"id": 1, "name": "f1"}} scenario._create_security_group = mock.MagicMock() scenario._create_security_group_rule = mock.MagicMock() scenario._list_security_group_rules = mock.MagicMock() # Positive case scenario._create_security_group.return_value = security_group - scenario._create_security_group_rule.return_value = security_group_rule + scenario._create_security_group_rule.side_effect = [ + {"security_group_rule": {"id": 1, "name": "f1", + "port_range_min": 1, + "port_range_max": 1}}, + {"security_group_rule": {"id": 2, "name": "f2", + "port_range_min": 2, + "port_range_max": 2}}] scenario._list_security_group_rules.return_value = { - "security_group_rules": [{"id": 1, "name": "f1"}, - {"id": 2, "name": "f2"}, - {"id": 3, "name": "f3"}]} - scenario.run(security_group_args=security_group_data, + "security_group_rules": [{"id": 1, "name": "f1", + "port_range_min": 1, + "port_range_max": 1}, + {"id": 2, "name": "f2", + "port_range_min": 2, + "port_range_max": 2}, + {"id": 3, "name": "f3", + "port_range_min": 3, + "port_range_max": 3}]} + scenario.run(security_group_rules_count, + security_group_args=security_group_data, security_group_rule_args=security_group_rule_data) - scenario._create_security_group.assert_called_once_with( **security_group_data) - scenario._create_security_group_rule.assert_called_once_with( - security_group["security_group"]["id"], - **security_group_rule_data) + calls = [] + for i in range(security_group_rules_count): + security_group_rule_data["port_range_min"] = i + 1 + security_group_rule_data["port_range_max"] = i + 1 + calls.append(mock.call(security_group["security_group"]["id"], + **security_group_rule_data)) + scenario._create_security_group_rule.assert_has_calls(calls) scenario._list_security_group_rules.assert_called_once_with() @ddt.data( @@ -168,20 +185,22 @@ class NeutronSecurityGroup(test.TestCase): {"security_group_args": {"description": "fake-description"}}, {"security_group_rule_args": {}}, {"security_group_rule_args": {"description": "fake-rule-descr"}}, + {"security_group_rules_count": 2}, ) @ddt.unpack def test_create_and_list_security_group_rules_with_fails( - self, security_group_args=None, - security_group_rule_args=None): + self, security_group_rules_count=1, + security_group_args=None, security_group_rule_args=None): scenario = security_groups.CreateAndListSecurityGroupRules() - security_group_data = security_group_args or {} security_group_rule_data = security_group_rule_args or {} + rule_expected = copy.deepcopy(security_group_rule_data) security_group = mock.MagicMock() security_group_rule = {"security_group_rule": {"id": 1, "name": "f1"}} scenario._create_security_group = mock.MagicMock() scenario._create_security_group_rule = mock.MagicMock() + scenario._list_security_group_rules = mock.MagicMock() scenario._create_security_group_rule.return_value = security_group_rule scenario._list_security_group_rules.return_value = { @@ -193,6 +212,7 @@ class NeutronSecurityGroup(test.TestCase): scenario._create_security_group.return_value = None self.assertRaises(rally_exceptions.RallyAssertionError, scenario.run, + security_group_rules_count, security_group_data, security_group_rule_data) scenario._create_security_group.assert_called_with( @@ -203,27 +223,36 @@ class NeutronSecurityGroup(test.TestCase): scenario._create_security_group_rule.return_value = None self.assertRaises(rally_exceptions.RallyAssertionError, scenario.run, + security_group_rules_count, security_group_data, security_group_rule_data) scenario._create_security_group.assert_called_with( **security_group_data) + rule_expected["port_range_min"] = 1 + rule_expected["port_range_max"] = 1 scenario._create_security_group_rule.assert_called_with( security_group["security_group"]["id"], - **security_group_rule_data) + **rule_expected) # Negative case3: security_group_rule isn't listed scenario._create_security_group.return_value = security_group + scenario._create_security_group_rule.reset_mock() scenario._create_security_group_rule.return_value = mock.MagicMock() self.assertRaises(rally_exceptions.RallyAssertionError, scenario.run, + security_group_rules_count, security_group_data, security_group_rule_data) - scenario._create_security_group.assert_called_with( **security_group_data) - scenario._create_security_group_rule.assert_called_with( - security_group["security_group"]["id"], - **security_group_rule_data) + calls = [] + for i in range(security_group_rules_count): + rule_expected["port_range_min"] = i + 1 + rule_expected["port_range_max"] = i + 1 + calls.append(mock.call(security_group["security_group"]["id"], + **rule_expected)) + scenario._create_security_group_rule.assert_has_calls(calls, + any_order=True) scenario._list_security_group_rules.assert_called_with() @ddt.data( diff --git a/tests/unit/scenarios/neutron/test_utils.py b/tests/unit/scenarios/neutron/test_utils.py index 2ba1a363..643752b1 100644 --- a/tests/unit/scenarios/neutron/test_utils.py +++ b/tests/unit/scenarios/neutron/test_utils.py @@ -845,6 +845,7 @@ class NeutronScenarioTestCase(test.ScenarioTestCase): "id": "fake-id", "security_group_id": "security-group-id", "direction": "ingress", + "protocol": "tcp", "description": "Fake Rule" } } @@ -856,6 +857,7 @@ class NeutronScenarioTestCase(test.ScenarioTestCase): "security_group_rule": {"security_group_id": "security-group-id", "direction": "ingress", + "protocol": "tcp", "description": "Fake Rule"} } result_security_group_rule = self.scenario._create_security_group_rule(