diff --git a/neutron/tests/tempest/api/base_security_groups.py b/neutron/tests/tempest/api/base_security_groups.py index 5028ec121f3..5a2e208f900 100644 --- a/neutron/tests/tempest/api/base_security_groups.py +++ b/neutron/tests/tempest/api/base_security_groups.py @@ -13,11 +13,25 @@ # License for the specific language governing permissions and limitations # under the License. +from neutron_lib import constants from tempest.lib.common.utils import data_utils from neutron.tests.tempest.api import base +V4_PROTOCOL_NAMES = set(key for key in constants.IP_PROTOCOL_MAP if + 'v6' not in key) +V4_PROTOCOL_INTS = set(v for k, v in constants.IP_PROTOCOL_MAP.items() + if 'v6' not in k) +V6_PROTOCOL_LEGACY = set([constants.PROTO_NAME_IPV6_ICMP_LEGACY]) +V6_PROTOCOL_NAMES = ( + set(key for key in constants.IP_PROTOCOL_MAP if 'v6' in key) - + V6_PROTOCOL_LEGACY +) +V6_PROTOCOL_INTS = set(v for k, v in constants.IP_PROTOCOL_MAP.items() if + 'v6' in k) + + class BaseSecGroupTest(base.BaseNetworkTest): def _create_security_group(self, **kwargs): @@ -39,3 +53,41 @@ class BaseSecGroupTest(base.BaseNetworkTest): for secgroup in list_body['security_groups']: secgroup_list.append(secgroup['id']) self.assertNotIn(secgroup_id, secgroup_list) + + def _create_security_group_rule(self, **kwargs): + rule_create_body = self.client.create_security_group_rule(**kwargs) + # List rules and verify created rule is in response + rule_list_body = ( + self.client.list_security_group_rules()) + rule_list = [rule['id'] + for rule in rule_list_body['security_group_rules']] + self.assertIn(rule_create_body['security_group_rule']['id'], + rule_list) + self.addCleanup(self._delete_security_group_rule, + rule_create_body['security_group_rule']['id']) + return rule_create_body + + def _show_security_group_rule(self, **kwargs): + show_rule_body = self.client.show_security_group_rule(kwargs['id']) + for key, value in kwargs.items(): + self.assertEqual(value, + show_rule_body['security_group_rule'][key], + "%s does not match." % key) + + def _delete_security_group_rule(self, secgroup_rule_id): + self.client.delete_security_group_rule(secgroup_rule_id) + rule_list_body = self.client.list_security_group_rules() + rule_list = [rule['id'] + for rule in rule_list_body['security_group_rules']] + self.assertNotIn(secgroup_rule_id, rule_list) + + def _test_create_show_delete_security_group_rule(self, **kwargs): + # The security group rule is deleted by the cleanup call in + # _create_security_group_rule. + rule_create_body = ( + self._create_security_group_rule(**kwargs)['security_group_rule']) + self._show_security_group_rule( + id=rule_create_body['id'], + protocol=rule_create_body['protocol'], + direction=rule_create_body['direction'], + ethertype=rule_create_body['ethertype']) diff --git a/neutron/tests/tempest/api/test_security_groups.py b/neutron/tests/tempest/api/test_security_groups.py index 1d34a5ab0c9..a8d2ed31d4e 100644 --- a/neutron/tests/tempest/api/test_security_groups.py +++ b/neutron/tests/tempest/api/test_security_groups.py @@ -13,6 +13,7 @@ # License for the specific language governing permissions and limitations # under the License. +from neutron_lib import constants from tempest.lib.common.utils import data_utils from tempest.lib import decorators @@ -64,3 +65,60 @@ class SecGroupTest(base.BaseSecGroupTest): secgrp['id']) self.assertIn(secgrp['name'], sec_nm) self.assertIsNotNone(secgrp['id']) + + +class SecGroupProtocolTest(base.BaseSecGroupTest): + + @decorators.idempotent_id('282e3681-aa6e-42a7-b05c-c341aa1e3cdf') + def test_create_show_delete_security_group_rule_names(self): + group_create_body, _ = self._create_security_group() + for protocol in base.V4_PROTOCOL_NAMES: + self._test_create_show_delete_security_group_rule( + security_group_id=group_create_body['security_group']['id'], + protocol=protocol, + direction=constants.INGRESS_DIRECTION, + ethertype=self.ethertype) + + @decorators.idempotent_id('66e47f1f-20b6-4417-8839-3cc671c7afa3') + def test_create_show_delete_security_group_rule_integers(self): + group_create_body, _ = self._create_security_group() + for protocol in base.V4_PROTOCOL_INTS: + self._test_create_show_delete_security_group_rule( + security_group_id=group_create_body['security_group']['id'], + protocol=protocol, + direction=constants.INGRESS_DIRECTION, + ethertype=self.ethertype) + + +class SecGroupProtocolIPv6Test(SecGroupProtocolTest): + _ip_version = constants.IP_VERSION_6 + + @decorators.idempotent_id('1f7cc9f5-e0d5-487c-8384-3d74060ab530') + def test_create_security_group_rule_with_ipv6_protocol_names(self): + group_create_body, _ = self._create_security_group() + for protocol in base.V6_PROTOCOL_NAMES: + self._test_create_show_delete_security_group_rule( + security_group_id=group_create_body['security_group']['id'], + protocol=protocol, + direction=constants.INGRESS_DIRECTION, + ethertype=self.ethertype) + + @decorators.idempotent_id('c7d17b41-3b4e-4add-bb3b-6af59baaaffa') + def test_create_security_group_rule_with_ipv6_protocol_legacy_names(self): + group_create_body, _ = self._create_security_group() + for protocol in base.V6_PROTOCOL_LEGACY: + self._test_create_show_delete_security_group_rule( + security_group_id=group_create_body['security_group']['id'], + protocol=protocol, + direction=constants.INGRESS_DIRECTION, + ethertype=self.ethertype) + + @decorators.idempotent_id('bcfce0b7-bc96-40ae-9b08-3f6774ee0260') + def test_create_security_group_rule_with_ipv6_protocol_integers(self): + group_create_body, _ = self._create_security_group() + for protocol in base.V6_PROTOCOL_INTS: + self._test_create_show_delete_security_group_rule( + security_group_id=group_create_body['security_group']['id'], + protocol=protocol, + direction=constants.INGRESS_DIRECTION, + ethertype=self.ethertype) diff --git a/neutron/tests/tempest/api/test_security_groups_negative.py b/neutron/tests/tempest/api/test_security_groups_negative.py index 649f375099e..e381748e67d 100644 --- a/neutron/tests/tempest/api/test_security_groups_negative.py +++ b/neutron/tests/tempest/api/test_security_groups_negative.py @@ -13,6 +13,7 @@ # License for the specific language governing permissions and limitations # under the License. +from neutron_lib import constants from neutron_lib.db import constants as db_const from tempest.lib import decorators from tempest.lib import exceptions as lib_exc @@ -68,4 +69,31 @@ class NegativeSecGroupTest(base.BaseSecGroupTest): class NegativeSecGroupIPv6Test(NegativeSecGroupTest): - _ip_version = 6 + _ip_version = constants.IP_VERSION_6 + + +class NegativeSecGroupProtocolTest(base.BaseSecGroupTest): + + def _test_create_security_group_rule_with_bad_protocols(self, protocols): + group_create_body, _ = self._create_security_group() + + # bad protocols can include v6 protocols because self.ethertype is v4 + for protocol in protocols: + self.assertRaises( + lib_exc.BadRequest, + self.client.create_security_group_rule, + security_group_id=group_create_body['security_group']['id'], + protocol=protocol, direction=constants.INGRESS_DIRECTION, + ethertype=self.ethertype) + + @decorators.attr(type=['negative']) + @decorators.idempotent_id('cccbb0f3-c273-43ed-b3fc-1efc48833810') + def test_create_security_group_rule_with_ipv6_protocol_names(self): + self._test_create_security_group_rule_with_bad_protocols( + base.V6_PROTOCOL_NAMES) + + @decorators.attr(type=['negative']) + @decorators.idempotent_id('8aa636bd-7060-4fdf-b722-cdae28e2f1ef') + def test_create_security_group_rule_with_ipv6_protocol_integers(self): + self._test_create_security_group_rule_with_bad_protocols( + base.V6_PROTOCOL_INTS)